Symptom: You start a fresh claude session and it immediately fires session limit warnings or blocks tools.
Cause: .session/state.json has stale data from a previous session (e.g. stopped: 2). This happens when session_init.py fails to run on SessionStart — usually an import error when running from a different project directory.
Fix:
rm -rf .sessionThen start a new claude session. session_init.py will create fresh state.
Prevention: The import fix in commit e56f458 ensures session_init.py works from any CWD. If you see this again, run update.sh or git pull in the toolkit directory to get the latest hooks.
Symptom: Hooks don't seem to run — no skill routing, no TDD checks, no session monitoring.
Fix:
cd /path/to/agent-toolkit && ./install.shThis re-registers hooks in ~/.claude/settings.json.
Symptom: Session start shows HARNESS INTEGRITY WARNINGS: MISSING hook: gate_hook.py even though ./install.sh ran successfully.
Cause: Hooks live in the agent-toolkit clone (e.g. /path/to/agent-toolkit/hooks/) and are registered in ~/.claude/settings.json. They are not under your project's hooks/ directory.
Fix: Run ./install.sh from the toolkit clone. If warnings persist, check that ~/.claude/settings.json contains commands pointing at your toolkit path. Re-run ./install.sh to dedupe stale entries.
Symptom: /precommit finalize passes but tests didn't actually run, or python3 can't find your venv packages.
Cause: finalize_report.py must run test/lint against the git project root, not the shell's last cd. Custom test_command values using bare python3 may hit system Python instead of the active venv.
Fix:
- Re-run finalize from your project — it resolves git root from the
.scratch/.../findings.jsonpath (not shell cwd). - If you set a custom
test_commandwithpython3, it is rewritten to the active interpreter (venv-safe). - Omit
test_command/lint_commandto use auto-detect, or set project-specific values in yourgates.json.
Symptom: git commit blocked even after running /precommit.
Check: .gates/precommit-passed must contain READY. Verify:
cat .gates/precommit-passedIf missing or empty, run /precommit again (including the finalize_report.py step).
Symptom: git push blocked even after running /evaluate.
Check: .gates/evaluate-passed must contain PASSED and a score ≥ eval_threshold in gates.json (default 95). Verify:
cat .gates/evaluate-passed
grep eval_threshold gates.jsonWith default gate_protect: true, only finalize_report.py writes this file — run:
python3 hooks/finalize_report.py evaluate .scratch/evaluate_<slug>/findings.jsonExit code 0 means the gate unlocked; exit code 1 means score or mechanical checks blocked.
Symptom: Ran /evaluate and finalized, committed, but expected to push without re-running evaluate.
Expected: gate_cleanup.py clears only precommit-passed on commit. Push-scoped flags (evaluate-passed, etc.) should still exist. If missing, re-run finalize for the skill.
Symptom: Push succeeded but next push requires fresh evaluate.
Expected: Push clears push-scoped flags. Re-finalize evaluate (and reviewer/assess per profile) before the next push.
Symptom: /debug or Skill(debug) fails with:
Skill debug cannot be used with Skill tool due to disable-model-invocation
Cause: Known Claude Code behavior — the Skill tool is invoked twice (slash command loads the skill, then the model calls Skill tool again). Toolkit skills set disable-model-invocation: false explicitly; the error can still appear on some Claude Code versions.
Fix (pick one):
- Use Read, not Skill tool — tell the agent:
Read skills/debug/SKILL.md and follow it step by step. Do not use the Skill tool. - Re-link skills — symlinks may point at a stale clone (
/tmp/...):cd /path/to/agent-toolkit && ./install.sh
- Start a new session after
./install.shso Claude picks up updated skill frontmatter.
Workaround for any skill: Natural language + Read the SKILL.md file always works; slash commands may still trigger the Skill tool error until Claude Code fixes the double-invocation bug.
Symptom: Wrapper exits instead of looping.
Check: HANDOFF.md must exist and NOT contain ## COMPLETE as a section header. The wrapper stops when it sees that marker or when HANDOFF.md is deleted.