Skip to content

fix(hooks): relay Bash-written files to the Write-shaped PostToolUse hooks (#2079) - #2082

Open
Bowlerjim wants to merge 1 commit into
danielmiessler:mainfrom
Bowlerjim:fix/2079-bash-write-relay
Open

Bowlerjim wants to merge 1 commit into
danielmiessler:mainfrom
Bowlerjim:fix/2079-bash-write-relay

Conversation

@Bowlerjim

Copy link
Copy Markdown

Fixes #2079.

The problem

permissions.defaultMode: "auto" tells the model to prefer Bash for file writes, and ISASync, CheckpointPerISC, ConfigEvalFire and SystemChangeSurface are registered on Write/Edit/MultiEdit only. A file written by heredoc or a script therefore fires none of them: an ISA never reaches work.json, the per-claim commit never runs, the eval suite never fires, and the SYSTEM disclosure line stays silent. Reproduced on a live install exactly as the issue describes.

The change

One new hook and one registration line; the four existing hooks are untouched.

hooks/BashWriteRelay.hook.ts (PostToolUse, matcher Bash):

  • finds files changed under a bounded set of watched roots (doctrine, prompt, ALGORITHM, RULES, TOOLS, hooks, skills, settings, USER identity files, MEMORY/WORK ISAs, plus ISA paths already in work.json) since the session's last Bash call
  • mtime narrows the candidates; a content hash against a shared per-path claims ledger decides, so byte-identical rewrites and sibling sessions' writes are never attributed (first claimer wins, exactly once)
  • replays each changed file through the four hooks with a synthesized Write payload carrying file_path, and returns their additionalContext concatenated
  • never parses the command; the first Bash call of a session only records a baseline; change sets over 40 files are logged and skipped; every failure path exits 0 with no output

Registered in hooks/hooks.json on the existing Bash matcher. Documented in HookSystem.md.

Verification

  • Live install: a Bash-only edit to a registered ISA moved its work.json progress on the same call and produced the SYSTEM line, with no Write or Edit involved.
  • A no-change scan costs 0.02 s wall.
  • Four concurrent sessions ran the claims ledger without double attribution.
  • bun build --no-bundle --target=bun passes.

Known limit

A brand-new project ISA outside MEMORY/WORK written by Bash is invisible until it is first touched by Write or registered; MEMORY/WORK ISAs and already-registered paths are covered.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KdVkxUPGxFm91bsNDxyi5M

…hooks (danielmiessler#2079)

defaultMode "auto" steers file writes to Bash, and ISASync, CheckpointPerISC,
ConfigEvalFire and SystemChangeSurface are registered on Write/Edit/MultiEdit
only, so an ISA written by heredoc never reaches work.json, the per-claim
commit never fires, the eval suite never runs and the SYSTEM disclosure line
stays silent.

BashWriteRelay.hook.ts (PostToolUse, matcher Bash) finds files changed under a
bounded set of watched roots since its last run for the session and replays the
four hooks with a synthesized Write payload carrying file_path. mtime narrows
the candidates; a content hash against a shared per-path claims ledger decides,
so byte-identical rewrites and sibling sessions' writes are never attributed
(first claimer wins, exactly once). Never parses the command. The first Bash
call of a session only records a baseline; change sets over 40 files are
logged and skipped; every failure path exits 0 with no output.

Registered in hooks.json on the existing Bash matcher; documented in
HookSystem.md.

Verified on a live install: a Bash-only edit to a registered ISA moved its
work.json progress and produced the SYSTEM line on the same call; a no-change
scan costs 0.02 s wall; four concurrent sessions ran the claims ledger without
double attribution.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdVkxUPGxFm91bsNDxyi5M
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.

Shipped defaultMode: "auto" steers writes to Bash, silencing four PostToolUse hooks

1 participant