Skip to content

Fix #275: wire workspace trust end to end (dialog → bootstrap → hooks gate)#306

Open
ericleepi314 wants to merge 1 commit into
fix/issue-274-permission-context-defaultfrom
fix/issue-275-trust-dialog-wiring
Open

Fix #275: wire workspace trust end to end (dialog → bootstrap → hooks gate)#306
ericleepi314 wants to merge 1 commit into
fix/issue-274-permission-context-defaultfrom
fix/issue-275-trust-dialog-wiring

Conversation

@ericleepi314

Copy link
Copy Markdown
Collaborator

Closes #275
Closes #169 (duplicate)

Stacked on #305 (← #304). Merge in order; GitHub retargets automatically.

Summary

The trust flow was broken in both directions:

  • init.py unconditionally set session trust to True — every surface implicitly trusted the workspace (the issue's complaint), and
  • nothing ever read that flag into ToolContext.workspace_trusted (default False), so the hook trust gate actually skipped all non-policy hooks regardless — including after the user accepted the trust dialog.

The C8 trust dialog (TrustFolderScreen + startup_gates) shipped earlier but was wired to a dead store. This PR connects the chain:

  • init.py: seeds session trust from the persisted per-project decision (check_trust_accepted(): session flag, then cwd + parent walk in the user-owned global config), failing closed on error.
  • ToolContext.workspace_trusted: default_factory seeded from the bootstrap flag at construction; subagent forks inherit the parent's value (trust stays monotone, fork path independent of mutable globals).
  • TUI accept path: flips the already-built context so hooks unblock mid-session (record_trust_accepted covers contexts built later).
  • Hook executor: logs a one-line breadcrumb when the gate actually filters configured hooks.
  • Test hygiene: reset_session_trust_for_testing also resets the bootstrap flag (without this, record_trust_accepted in the C8 tests would leak trust into later-collected tests).

Surface behavior

Surface Never-trusted dir Previously-trusted dir
TUI dialog on first visit; accept → hooks run, decline → exit 1 trusted at start
headless -p / legacy REPL non-policy hooks skipped (fail-safe, TS shouldSkipHookDueToTrust parity — TS non-interactive sessions can't accept the dialog either) trusted at start

Test plan

  • New: pre_action seeding (trusted/untrusted/error→fail-closed), ToolContext seeding (incl. explicit-value-wins), fork inheritance (incl. untrusted-parent + trusted-global), TUI accept propagation
  • Full trust-gate matrix + all hook tests (261) pass
  • Full suite on the stack: 7772 passed, 0 failed, 5 skipped
  • Critic review loop: APPROVE (fork inheritance + skip-breadcrumb folded in from review)

🤖 Generated with Claude Code

…ry session (#275)

pre_action hardcoded session trust to True, and nothing read the flag
into ToolContext.workspace_trusted (default False) — so consent was
implicit everywhere while the hook trust gate skipped non-policy hooks
unconditionally. Now:

- init.py seeds session trust from the persisted per-project decision
  (startup_gates.check_trust_accepted), failing closed on error
- ToolContext.workspace_trusted seeds from the bootstrap flag at
  construction; subagent forks inherit the parent's value (monotone,
  no mutable-global dependence)
- the TUI's trust-accept path flips the already-built context so hooks
  unblock mid-session; record_trust_accepted covers later contexts
- hook executor logs a breadcrumb when the trust gate actually skips
  configured hooks (else "why don't my hooks run" is undiagnosable)
- reset_session_trust_for_testing also resets the bootstrap flag so
  acceptance can't leak across tests

Headless/-p/legacy-REPL sessions in never-trusted dirs now run with
non-policy hooks skipped (fail-safe, TS shouldSkipHookDueToTrust
parity) until the directory is trusted once via the TUI.

Closes #275, closes #169

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant