Repository navigation
fix(always-on): a SessionStart hook that didn't run can't read as zero - #17
Open
DojoGenesis wants to merge 1 commit into
Open
DojoGenesis wants to merge 1 commit into
DojoGenesis wants to merge 1 commit into
Conversation
injection_chars() ran the raw hooks.json command with shell=True and added
to the total only when the hook exited 0, so a failed hook counted as 0
tokens with no error. On Windows that was every hook: cmd.exe leaves
${CLAUDE_PLUGIN_ROOT} as it is, the hook exits 2, and the always-on row read
PASS at ~1,288 when the suite was ~1,856, so it could have passed over budget.
- Fill in ${CLAUDE_PLUGIN_ROOT} before the shell sees the command.
- A hook that exits non-zero is now a RunError (exit 2) that names the plugin
and the last line of its stderr. No marketplace SessionStart hook is meant
to exit non-zero: dojo-protocol, bring-loop and kata-harness all end in
sys.exit(0).
- Make the plugin path absolute. Hooks run from a temporary project, so a
relative --repo also read as zero, on POSIX too.
Tests: the stand-in claude in test_always_on.py was a #! file Windows can't
start, so those tests never ran on the platform with this bug; it now gets a
.cmd launcher there. New tests cover a failing hook, a command that can't
start, a hook that exits clean and silent, the command handed to the shell, a
relative --repo, and the marketplace's real hooks through the real shell.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
scripts/always_on.pyis the gate for the suite's 2,000-token budget. On Windows it read low and could pass while over budget. It now measures correctly there, and a hook that didn't run stops the check instead of counting as zero.Cause
injection_chars()ran the rawhooks.jsoncommand withshell=True, and only added to the total when the hook exited 0. A hook that failed counted as 0 tokens, with no error.On Windows that shell is
cmd.exe, which leaves${CLAUDE_PLUGIN_ROOT}as it is, so the hook exits 2. That happened to every SessionStart hook in the marketplace.suite ~1500 tokens, 0 over budgets1: SessionStart hook exited 1: note from the hookThe fix
${CLAUDE_PLUGIN_ROOT}before the shell sees the command.RunError(exit 2) naming the plugin and the last line of the hook's stderr. No marketplace hook is meant to exit non-zero: dojo-protocol, bring-loop and kata-harness are the only three SessionStart hooks, and all three end insys.exit(0).--repo .also read as zero, on POSIX too. Without this it would now be a hard error.Tests
The stand-in
claudeintest_always_on.pywas a#!file, which Windows can't start, so 4 of its 5 tests never reached the code on the platform with this bug. It now gets a.cmdlauncher there. Six new tests:--repoPROTOCOL.mdmainMost of this suite already fails on Windows on
main, so that row only shows nothing new broke; WSL is the meaningful pass, and its 2 failures (test_unittest_with_zero_tests_fails,test_python_310_apis) also fail onmain. Compared by test name against a clean tree. Run against the oldalways_on.py, the new test file fails 7 tests on Windows and 4 on WSL.release-check.sh --only always-onon Windows readsPASS,suite ~1856 tokens. The fresh table is byte-identical to the one inALWAYS-ON.md, so the numbers there didn't need a refresh; only one sentence on the method was added.Limits
try/exceptstill reads as zero on thealways-onrow. All three hooks are fail-open: they exit 0 and print nothing. An exit code can't tell that from a hook that's quiet by design, such as bring-loop in a project that doesn't use it. The new marketplace test catches this on theself-testrow for dojo-protocol, the only hook that adds text by default (checked by breaking the hook in a scratch copy:{} != {'dojo-protocol': 1987}). bring-loop and kata-harness have no such check, but they add nothing in an empty project anyway.denylistrow, because its local lists aren't on this machine. Nothing ran on a Mac; WSL's Linux shell is the only POSIX coverage, and it has noclaude, so the realalways_on.pytable was measured on Windows only.Fixes DGS-261
🤖 Generated with Claude Code