A guard that stops a doc edit now names a tool that can write a doc - #12
Merged
Conversation
The `PreToolUse` guard asks before any `Edit` or `Write` to a `.md` under the protocol root, which is right — the write would skip the lock, the revision check and validation. What it said while asking was not: it named `project_card_patch, project_card_write, project_card_note` for every record type. An agent stopped while writing a doc was handed three tools that cannot open a doc, found nothing that fit, and reached for `Edit` again, so the guard asked again. Nothing the user can switch off ends that loop. A hook's `ask` outranks `bypassPermissions` by design — T-0099 established that and it is still correct — so the symptom presents as the permission mode having stopped working rather than as a guard doing its job. Reported from a session in another repository running with bypass on. `.project/agents/**` was the worst of it: generated and digest-stamped, so no record tool opens it at all and a hand edit survives only until the next `agents sync` reverts it. Routed on the first segment under the protocol root now. Cards, docs, memory and changelog each name their own tools plus the matching CLI noun; `agents` is sent to `agents sync`; anything else keeps the generic wording rather than inventing a tool name it cannot know. The segment names are the layout `config/defaults.ts` ships, which is the assumption `buildBoard` already makes one function above — a project that moves `cards.path` gets the fallback. The table is hardcoded because the runtime imports nothing from the package on purpose and the latency budget depends on that, so the test pins every name the guard can emit against `listMcpTools()`. Pointing at a tool that was since renamed is the original dead end with extra steps. Verified against the built runtime a session actually loads, one real payload per shape, and by patching that runtime back to the single card-tools string: the new test fails alone and nothing else moves. 269 + 7 tests, strict ratchet held at 588 across 57 files, doctor 0/0, plugin copy byte-identical to source. Carded as T-0144, in review until this ships and the reporting repository upgrades. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WFQ2juk8bVSQQ8QivjopBR
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
The
PreToolUseguard asks before anyEditorWriteto a.mdunder the protocol root, which is right — the write would skip the lock, the revision check and validation. What it said while asking was not. It named the same three card tools for every record type:An agent stopped while writing a doc was handed three tools that cannot open a doc, found nothing that fit, and reached for
Editagain — so the guard asked again.Nothing the user can switch off ends that loop. A hook's
askoutranksbypassPermissionsby design (T-0099 established that, and it is still correct), so the symptom presents as the permission mode having stopped working rather than as a guard doing its job. Reported from a session in another repository running with bypass on..project/agents/**was the worst of it: generated and digest-stamped, so no record tool opens it at all and a hand edit survives only until the nextagents syncreverts it.What changed
Routed on the first segment under the protocol root:
.project/cards/project_card_patch, project_card_write, project_card_note+workfile card patch.project/docs/project_doc_patch, project_doc_create, project_doc_move+workfile doc patch.project/memory/project_memory_patch, project_memory_add+workfile memory patch.project/changelog/project_changelog_patch, project_changelog_add+workfile changelog patch.project/agents/workfile agents sync— generated and digest-stamped, no record tool opens itThe table is hardcoded because the runtime imports nothing from the package on purpose and the latency budget depends on that, so the test pins every name the guard can emit against
listMcpTools(). Pointing at a tool that was since renamed is the original dead end with extra steps.Known limit
The segment names are the layout
config/defaults.tsships, which is the assumptionbuildBoardalready makes one function above. A project that movescards.pathgets the generic fallback rather than a wrong tool.Verification
PreToolUsepayload per shape, driven against the built runtime a session actually loads — each returns the tools that open that record.pnpm run checkgreen — 269 + 7 tests, strict ratchet held at 588 across 57 files, plugin copy byte-identical to source.pnpm workfile doctor0 errors, 0 warnings.Carded as T-0144 (
reviewuntil this ships and the reporting repository upgrades), fragment CHG-0100.🤖 Generated with Claude Code
https://claude.ai/code/session_01WFQ2juk8bVSQQ8QivjopBR