docs(adr): defer Claude Code mods with five go criteria - #4241
Conversation
Claude Code mods (plugins whose hooks are one TypeScript hooks module) work behind an undocumented flag at 2.1.278 but are off by default, absent from the official docs and changelog, and pre-contract. A bare passthrough Bash hook reproduces anthropics/claude-code#92533 on this repo's worktree-isolation flow. Records the verdict as ADR 0035, a Defer row in Recorded gate runs, and a pointer in the Hooks stance. docs/upstream/claude-code-mods/ carries the recheck runbook, the rerunnable experiments, a cited source index, and a dated snapshot of the verified research. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 2m 0s —— View job Claude is reviewing this PR
|
|
Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 55714e418f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Criterion 4 grepped a mods/README.md only criterion 5 fetched, so a top-to-bottom run died on a missing file. The fetch moves to "Before you start" and criterion 5 reuses it. Criterion 4 was also the only criterion with no recorded baseline, and its docs-site grep returns 5 today from Claude Apps Gateway spend-limit text, none of it about hooks. Record all four outputs and say in Risks that the count alone means nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX
Three fixes from the worktree review's optional list, each a gap against a rule the docs already carry: - The max-shaped hook budget claim now points at its owner doc, docs/conventions/hook-budget/README.md, which states it. - The agents-md default-mode claim gains its SOURCE label, and sources.md gains the mods/agents-md/README.md row it was relying on unindexed. - Criterion 2's met-bar no longer hard-codes a control floor of 67, which a docs reorganisation could make unmeetable; it reads non-zero against the recorded baseline instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX
E6's loop loads $P/e6a-node and $P/e6b-bash, which the document described in prose but never gave the files for, so both classic arms failed to load and the comparison could not be rerun. Arm (c) already reused $P/e2 from E2; say so, and give the manifest, the hooks configuration and the one-statement probe body for each of the other two. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX
…ed files The two classic-arm directories added in the previous commit are built to the arm descriptions, not copied from the 2026-09-19 run, whose files were machine-local like the parser beside them. A rerunner comparing against the +60 ms and +12 ms medians should know which of the two they are holding. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX
… tab (#4290) No related issue: the Desktop probe was left as an open manual step inside PR #4241's own committed trail, and this PR records the maintainer's result in that same trail. No tracker item was ever filed for it. ## Summary PR #4241 deferred adopting Claude Code "mods" and listed "does Desktop's Code tab load a user-authored mod?" as an open probe with a by-hand procedure. The maintainer has now run it. Without this, the next reader of ADR 0035 reasons from a stale unknown and repeats a finished experiment. ## Fix - `docs/upstream/claude-code-mods/experiments.md` — the Desktop probe section now opens with the dated result (`OBSERVED`: a user-authored mod loads in Desktop's Code tab) rather than "Unanswered", records Desktop build `app-2.2553.1` and its bundled Claude Code 2.1.275 against 2.1.278 on `PATH`, and lists the untested arms. Step 3 gains route (c), the route that actually worked: the fully quit app launched from PowerShell with the enable flag set for that process only, resting on the documented Windows rule that the app inherits user and system environment variables. Route (a), the local environment editor's gear icon, is marked absent in that build. The negative-reading paragraph now names where the bundled version is read. - What enabled the load is labelled `INFERRED`, not `OBSERVED`: the flag-unset arm was never run in Desktop, so the probe cannot separate "the variable reached the bundled process" from "the rollout gate is already on in that build". Still open: that unset arm, cloud sessions, Cowork, and mods that draw UI. - `docs/adr/0035-defer-claude-code-mods-with-five-go-criteria.md` — the "two probes are open" bullet becomes one open (rollout switch) and one partly answered, with the observed result and what remains. **The Defer verdict and the five go criteria do not change; Desktop loading is in no criterion.** Note that go-no-go.md's after-run rule says a runbook run does not amend an accepted ADR by itself; this is not a runbook run but a correction of a factual open-unknown statement, made at the owner's direction, and it leaves the decision untouched. - `docs/upstream/claude-code-mods/go-no-go.md` — that file never named Desktop, so its only inaccurate line was the pointer calling experiments.md's manual probes wholly open. It now states the observed result and that the other arms stay untested. - `docs/upstream/claude-code-mods/sources.md` — the `code.claude.com/docs/en/desktop` row gains the Windows environment-inheritance sentence the route relies on, and experiments.md in its used-by column, per the runbook's own after-run rule. - `docs/upstream/claude-code-mods/research-2026-09-19/` is frozen and untouched. `docs/plugin-philosophy.md` is untouched: its mods row makes no Desktop claim. ## Verification - `node_modules/.bin/markdownlint-cli2` on all four touched files: 0 issues. - `scripts/check-docs-naming.sh --check`: every tracked file under `docs/` is lower-kebab-case. - Relative links added resolve: `../upstream/claude-code-mods/experiments.md` from `docs/adr/`. - Diff grepped for personal data and absolute machine paths: none. The bundled-CLI location is written as a `%APPDATA%` placeholder. - Docs only; no code, config, or CI change. ## Related - PR #4241, which deferred mods and left this probe open. - [ADR 0035](https://github.com/melodic-software/claude-code-plugins/blob/main/docs/adr/0035-defer-claude-code-mods-with-five-go-criteria.md). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
#4288) (#4787) <!-- CURSOR_AGENT_PR_BODY_BEGIN --> Closes #4288 ## Summary `docs/upstream/claude-code-mods/` is first-party ADR 0035 evidence (not third-party). Purges 74 em dashes in README/sources/go-no-go/experiments and declares those paths. Header reworded so third-party exemption is only `docs/upstream/*.md` ledgers. Frozen `research-2026-09-19/` stays undeclared (same reason as `docs/adr/**`). ## Verification - [x] check-purged-em-dashes + test 24/0; markdownlint; ai-slop (per [Settle mechanical needs-human](bc-bf52ecee-310b-5da9-8455-e23be553c2fd)) ## Related - #4241, ADR 0035 <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-ab53da24-b89d-4314-a060-0da474e837e9?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-ab53da24-b89d-4314-a060-0da474e837e9&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
#4288) (#4787) <!-- CURSOR_AGENT_PR_BODY_BEGIN --> Closes #4288 ## Summary `docs/upstream/claude-code-mods/` is first-party ADR 0035 evidence (not third-party). Purges 74 em dashes in README/sources/go-no-go/experiments and declares those paths. Header reworded so third-party exemption is only `docs/upstream/*.md` ledgers. Frozen `research-2026-09-19/` stays undeclared (same reason as `docs/adr/**`). ## Verification - [x] check-purged-em-dashes + test 24/0; markdownlint; ai-slop (per [Settle mechanical needs-human](bc-bf52ecee-310b-5da9-8455-e23be553c2fd)) ## Related - #4241, ADR 0035 <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-ab53da24-b89d-4314-a060-0da474e837e9?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-ab53da24-b89d-4314-a060-0da474e837e9&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>

No related issue: records a platform-surface gate run; the decision and its recheck trail are the deliverable.
Summary
Claude Code "mods" are plugins whose hooks are one TypeScript hooks module running inside Claude Code. At 2.1.278 they work behind an undocumented flag, are off by default behind a rollout gate, appear nowhere in the official docs or the changelog, and carry an explicit "may change between releases without notice" warning. This PR records a Defer verdict and leaves everything a later agent needs to answer "what about mods?" with a rerun instead of a guess.
Fix
docs/adr/0035-defer-claude-code-mods-with-five-go-criteria.md: the verdict, the nine decisions, five go criteria (all required), and two recheck triggers (Claude Code pin-bump PRs run criteria 1 to 3; on demand runs all). Guard-hook conversion stays off the table until Any function-hook tool.call on Bash breaks Agent isolation: "worktree" — every Bash call refused with "isolation context for this agent was lost" anthropics/claude-code#92533 is fixed, throw and timeout semantics are settled upstream, and mods leave early access. No CI enforcement;scripts/check-hook-exec-form.shis unchanged.docs/plugin-philosophy.md: one Defer row in "Recorded gate runs" and one pointer sentence in the Hooks stance row.docs/upstream/claude-code-mods/:go-no-go.md(runbook with exact commands, today's baselines, and the false-result risks),experiments.md(six rerunnable experiments plus open probes),sources.md(cited index of 131 links by trust tier), andresearch-2026-09-19/(dated snapshot of the verified research).Verification
tool.callhook on Bash reproduces #92533 while the control run succeeds; a well-formed{ deny }returned instead ofnext(e)blocks a tool call; a throw or a 10 s overrun fails open unless the hook uses.catch.markdownlint-cli20 issues on every new or changed file;scripts/check-docs-naming.sh --checkclean; relative links resolve; no machine paths or personal data; nothing underdocs/topics/.Related
mods/tree).0020-defer-three-medley-surfaces-with-explicit-recheck-triggers.mdis the precedent for a Defer with triggers.🤖 Generated with Claude Code
https://claude.ai/code/session_01LZaei9mJtbHVmC7kqnsayX