Skip to content

feat(safety): ordered bash command policy seam (#405 S1) - #915

Open
danielgap wants to merge 3 commits into
Gentleman-Programming:mainfrom
danielgap:feat/405-bash-policy-seam
Open

danielgap wants to merge 3 commits into
Gentleman-Programming:mainfrom
danielgap:feat/405-bash-policy-seam

Conversation

@danielgap

@danielgap danielgap commented Sep 11, 2026

Copy link
Copy Markdown

Part of #405 (work unit S1 of 4; the issue stays open until S2-S4 land).

Problem

#405 asks for structured, ordered evaluation of high-risk model-initiated Bash operations. Today the bash tool_call tail evaluates protections as an ordered if/else chain inside the single handler, which leaves no deterministic place to compose future policy modules (npm/pnpm package acquisition, destructive direct SQL) without duplicating authority or making precedence hard to reason about.

What this adds

Unit S1 from the decomposition posted on the issue: a behavior-preserving evaluation seam.

  • Restructures the model-initiated bash tool_call tail into an ordered, named policy list (BASH_COMMAND_POLICIES) evaluated by evaluateBashPolicies: first non-undefined verdict wins, undefined defers to the next policy, overall undefined allows.
  • The only entry is the runtime-guardrails adapter over the byte-identical confirmCommand, so every verdict, block reason, emitted event sequence, headless fail-safe, and config precedence is unchanged.
  • Exposed via __testing with order, short-circuit, and allow tests (tests/autonomous-guard.test.ts).

No new policy modules, no second authority, no sandbox semantics; S2 (npm/pnpm recognition), S3 (probes and evidence), and S4 (direct SQL DROP) build on this seam as separate chained units.

File Change
extensions/gentle-ai.ts Ordered policy list + evaluateBashPolicies + guardrails adapter (+63)
tests/autonomous-guard.test.ts Seam order/short-circuit/allow tests (+132)

Verification

  • evaluateBashPolicies seam tests: 5/5.
  • Full tests/autonomous-guard.test.ts: 56/56.
  • Full tests/gentle-ai.test.ts (integration, guards the unchanged-behavior claim): 36/36.
  • Originally built 2026-09-09 with strict TDD; rebased today onto current main (127 commits, clean, no conflicts) with git range-diff reviewed and all suites re-run green.
  • Native four-lens review could not start this round: the consent-gated START loops with instantly-expiring bindings (gentle-pi#748, recurrences documented there today, including the new tier-pattern data point). To be re-run once bug(review): host consent prompt outlives its binding TTL, silently drops late answers, and loops START #748 is fixed; verification above is tests plus the rebase audit.

Label request: type:feature (pull-only author, maintainer needs to apply it).

Summary by CodeRabbit

  • Safety Improvements
    • AI-initiated Bash commands now pass through an ordered safety evaluation before execution.
    • Destructive commands, such as rm -rf /, remain blocked or require confirmation, while safe commands such as echo hello can proceed.
    • Evaluation stops when a policy returns a blocking or confirmation decision.
    • Additional safety policies can be evaluated in sequence, with later checks still available when earlier policies allow the command.

…#405 S1)

Restructure the model-initiated bash tool_call tail into an ordered,
named policy list (BASH_COMMAND_POLICIES) evaluated by
evaluateBashPolicies: first non-undefined verdict wins, undefined
defers to the next policy, overall undefined allows. The only entry is
the runtime-guardrails adapter over the byte-identical confirmCommand,
so every verdict, block reason, emitted event sequence, headless
fail-safe, and config precedence is unchanged. Exposed via __testing
with order/short-circuit/allow tests.

Work unit S1 of Gentleman-Programming#405: no new policy modules, no config schema change,
no second tool_call handler.
Copilot AI lite review requested due to automatic review settings September 11, 2026 21:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 556d7368-2669-4523-984e-169eb40e8580

📥 Commits

Reviewing files that changed from the base of the PR and between 4a8ec6e and 2d5869b.

📒 Files selected for processing (1)
  • extensions/gentle-ai.ts

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The bash tool-call path now evaluates an ordered policy list. The initial runtime-guardrails policy delegates to confirmCommand. Tests cover policy ordering, short-circuiting, and destructive-command handling.

Changes

Bash policy evaluation

Layer / File(s) Summary
Policy contract and runtime integration
extensions/gentle-ai.ts
Adds BashCommandPolicy, the ordered BASH_COMMAND_POLICIES list, and evaluateBashPolicies. The bash tool-call handler uses the evaluator.
Policy seam validation
tests/autonomous-guard.test.ts
Tests policy registration, evaluation order, short-circuiting, and runtime guardrail results for destructive and non-guarded commands.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant BashToolCallHandler
  participant evaluateBashPolicies
  participant runtime-guardrails
  participant confirmCommand
  BashToolCallHandler->>evaluateBashPolicies: evaluate command
  evaluateBashPolicies->>runtime-guardrails: evaluate command
  runtime-guardrails->>confirmCommand: confirm command
  confirmCommand-->>runtime-guardrails: return verdict
  runtime-guardrails-->>evaluateBashPolicies: return verdict
  evaluateBashPolicies-->>BashToolCallHandler: return first non-undefined verdict
Loading

Suggested reviewers: alan-thegentleman

Merge Risk: ⚪ Minimal · up to 2d586

The command-safety behavior remains preserved while gaining an ordered policy seam. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding an ordered Bash command policy seam for safety evaluation. It is concise and specific.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…interface

The seam harness mocked ExtensionAPI["events"] as
{ emit: () => {}, on: () => {} } with an `as` cast, which trips TS2352:
EventBus.on must return an unsubscribe function, and a void-returning
stub does not overlap. Give the mock the real emit/on signatures so it
matches EventBus structurally and the cast disappears entirely, keeping
the typecheck ratchet baseline at 205.
@danielgap

Copy link
Copy Markdown
Author

Adding review provenance: the branch went through a four-lens native review (risk, resilience, readability, reliability) on top of CI and CodeRabbit: approved with 8 informational advisories and no corrections required.

The advisories worth a skim before merge, all non-blocking:

  • The evaluateBashPolicies call site in the bash handler carries one extra indentation level left over from an earlier guard shape.
  • The policies parameter seam exists for tests and future composition; reviewers suggest making the "production callers use the default ordered list" contract more explicit at the seam.
  • Minor test duplication in env restore plus a few contract documentation notes on verdict semantics and error isolation.

Verification state: 56/56 autonomous-guard tests pass, biome clean, CI green, CodeRabbit reports no actionable comments. No code changed since the last push, so the diff under review is unchanged.

@danielgap

Copy link
Copy Markdown
Author

@Alan-TheGentleman consolidated status of my open gentle-shell PRs, since they all sit green and unlabeled and I want to make sure they are on your radar rather than lost.

Merge-ready, blocked only on the type:* label (every linked issue carries status:approved):

Needs triage rather than review: #605 closes #593, which has no labels yet. The PR itself merges clean, so an approval decision on the issue is the only open question.

#915, #1009 and #605 were dry-run verified today as zero-conflict against current main. Happy to rebase, split, or close any of them if the direction changed on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants