Hooks: Muse's owed reads of #643 and #652, a nested backtick's comment is tested and the spelt reading asks about a session
Ā
DO
7h ago+23+23+01234567890123456789-4-4-0123456789
The follow-on under the merged-early rule: Muse could not read #643 or #652 before they merged (quota). These are its reads, done after the merge, and what they found.
The protected edits to tools/hooks/ are pre-approved by the Maintainer 2026-11-08, ruled by the Factory Builder. Hooks are mistake guards (decision 0038's triage rule), and this PR is held to that standard.
What changes
| From | Finding | Now |
|---|---|---|
| Muse on #643 | The line in shell._inside that ends a nested backtick at a comment's backtick had no test that killed it | echo "$(echo "echo #"" "${?+'ā¦'}")" holds it, with a mutant |
| Muse on #643 | Two more lines with no killing test: braces reset entering a nested substitution, and restored leaving it | No test can reach them from _held. A ${...} in a held substitution is refused at its start or skipped whole, so _inside never begins inside a nested substitution with braces open. Left as they are |
| Muse on #652 | The protected hook's second, spelt reading never reached sessions(), so a Claude Code session after a nested substitution went unasked | Asked about, with a test and a mutant |
| Muse and the Claude review of this PR | With $(which claude) anywhere in the command, sessions() read the rewritten text flat, whatever reading it was given | The spelt reading reads it spelt, with a test and a mutant |
| Muse on #652 | A spelt reading that fails drops it whole; past 8 KB it is skipped | Both evasion only, the same as main before #652: #665's items (a) and (b) |
Decision 0032 gains one row, naming three mutants.
Checks
tests/test_hooks.py::test_a_substitutions_own_quotes_are_read_as_the_shell_reads_themand::test_a_double_quoted_substitution_in_a_double_quoted_one_hides_no_command_after_itgain the cases.- At bd4834de:
make verifypasses,check_decisionsis clean, and the mutants oftools/hooks/shell.py,identity.pyandprotected.pyare all killed (38 at 237592da, 18 again at bd4834de).
Reviews
| Reader | Findings | Disposition |
|---|---|---|
| Argon (gemini-4-argon-high) | None | ā |
| Muse (muse-wonder-full-1.0) | 1, the $(which claude) gap, marked blocking; not a regression | Fixed in bd4834de |
| Claude review and security pass | Nothing major. The same $(which claude) gap, the same on main | Fixed in bd4834de. Two cosmetic points: a session the second reading finds with a backtick asks command_unreadable, as main does at the top level, and one prompt can list that code twice. Left as they are |
All read 237592da. bd4834de is the fix.
š¤ Generated with Claude Code