Release 0.12 - xsyetopz/claudetto GitHub Wiki
This page records the notes of the 0.12 release.
Released 2026-09-29.
This release adds many guards and checks, a reverse-engineer agent with Ghidra setup, and a more compact status line.
The guards close gaps that usage data showed.
The gaps were unchecked edits, repeated reads, and commands that never end.
A version in parentheses marks a later patch of this line.
An entry with no version comes from 0.12.0.
Note: After updating, restart Claude Code and run
/dotclaude:apply-settings-profileagain. The profile now allows 5 agents at once and adds compact instructions to the globalCLAUDE.mdsection. It keeps the values that the user set. An agent cap of3becomes5, because 0.11.1 wrote that value.
-
Stopgate, task check: the gate also runs when Claude marks a task completed. After a code edit with no check run after it, the gate keeps the task open once. It tells Claude to run the tests, build, or lint. Thestop_gateoption turns this off too. -
Stopgate, announced work: the gate sends Claude back once when the last paragraph of its reply announces the next step or offers work. Examples: "Next I'll ..." or "Should I ...?".- Claude then does the work, or ends the turn again when only the user can decide.
- A step that is public or hard to reverse, such as a push or a release, passes.
A turn that
AskUserQuestionended also passes. - Each
TaskCompletedcall adds ataskline toverdicts.jsonlwith the names of its input fields. The hooks docs do not pin that input yet.
- Verdict log: the
Bashguard and the edit guard write each deny and ask toverdicts.jsonlin the plugin data directory. Each entry is one JSON line, with the target cut to 200 characters. The log shows which rules fire too often. It moves toverdicts.1.jsonlabove about 1 MB. - Approval memory: when the user approves an ask and the tool runs, the guards do not ask again in that session. This applies to the same command, or the same edit, with the same reason. The guard then makes no decision, so the permission rules of the user still apply. A deny is never remembered.
-
Bashguard, re-reads: denies a full re-read of a file that the same agent already read in full, when the file did not change.- This covers a plain
cat, aReadafter acat, and acatafter aRead. - Claude Code already skips a
Readafter aRead. - A partial
Read, a pipedcat, and a read after compaction pass.
- This covers a plain
-
Bashguard, long commands: denies a foreground command that does not end by itself or runs for a long time. Examples are adev,serve, orwatchscript,--watch,tail -f, and GhidraanalyzeHeadless. The reason says to run the same command withrun_in_background. A shell&or atimeoutwrapper passes. -
Bashguard, binaries: asks beforegit addstages a file with an ELF, Mach-O, or PE header. A committed binary stays in the history. - Usage notes (
usage_notesturns them off):- On the third correction in a row, a note suggests a rewind to before the failed attempts, or a handoff and
/clear. - After a reply that stopped with a refusal, a note says to start a new session. The refusal stays in the context.
- On the third identical
Bashcommand in a row with identical output in one agent, a note says to change the approach. It also says to wait withMonitor.
- On the third correction in a row, a note suggests a rewind to before the failed attempts, or a handoff and
- Agent limits (
subagent_guidanceturns this off):- A subagent that
SendMessageresumes gets no second copy of the working conventions. Claude Code firesSubagentStartagain on a resume (#80489). The agent already has the text. - With 5 subagents running, the guard denies an
Agentcall before Claude Code refuses it. The reason tells Claude to wait for a report and then send the next wave. - The count comes from
SubagentStartandSubagentStop. An agent with no activity for 10 minutes no longer counts. An interrupted agent can end withoutSubagentStop.
- A subagent that
- Compact instructions: the global
CLAUDE.mdsection of the settings profile has a# Compact instructionssection. It tells the compaction summary to keep the requests of the user in their own words. It tells the summary to keep decisions with their reasons, and exact paths, commands, and errors. - Ghidra setup:
/dotclaude:setup-integrationsregisters the MCP serverpyghidra-mcpin the reverse-engineering project only. It also installs theghidra-bridgeCLI as the fallback. The status reportsuvx, Python 3.10 or newer,GHIDRA_INSTALL_DIRwithanalyzeHeadless, Java 21, theghidraMCP entry, and the CLI. -
reverse-engineeragent (Opus 5.5, efforthigh): analyzes a binary, protocol, or file format with Ghidra.- It uses the
ghidraMCP tools first. It uses theghidra-bridgeCLI only when they are missing or fail. Its report names the path. - For matching work, it pins the SHA-256 of the input, compares bytes and relocations, and keeps an iteration log.
- It does not analyze the Claude Code binary.
- It uses the
-
scripts/usage-report.mjs:- It counts the main sessions by entrypoint (
cli,claude-vscode,sdk-cli,sdk-py). It also counts the usage-limit hits, theSkillcalls by skill, and the guard verdicts per rule fromverdicts.jsonl.--verdicts FILEreads a different verdict log. - It reports the cache write on the first call after a prompt while the cache is warm (
firstCallAfterPrompt). It reports this with and without hook context in the history. On one week of sessions, the write was 2.2% of the context with hook context and 1.6% without. So hook context did not rewrite the cached prefix (#83913). - It counts the dotclaude agent runs that reached their turn-limit reserve.
For each agent type, it gives the median files and list items in the brief of those runs and of the other runs.
On one week, most capped briefs named one behavior.
Long runs passed the 100k context bound near turn 20.
So the
implementerlimit stays 80.
- It counts the main sessions by entrypoint (
- Status line pace: the 5-hour and weekly limits show their pace, as CodexBar does.
▲12%→12:46is a deficit. Usage runs 12 points ahead of an even rate, and at this rate the limit is used up at 12:46.▼30%is a reserve. The pace shows after 3% of the window is gone.
- Compact status line (0.12.0, 0.12.1): one-column glyphs replace words.
-
⎇is the branch,⊞the worktree,◷and◌a warm and cold cache,✗cache misses, and▲and▼a limit deficit and reserve. - A space follows the branch, worktree, and cache glyphs. So the glyph and the text after it do not run together.
- The warm cache shows the minutes until it expires, not the clock time.
- The context bar has 5 cells, not 8.
-
- Cache misses: the status line does not count a miss after a model switch.
A new model starts a new cache.
Claude Code already keeps the first call and the call after a compaction out of its miss count.
scripts/usage-report.mjscounts full cache rewrites on the first call, after a compaction, and after a model switch as expected. The rewrites that nothing explains stay counted. - Agent cap: the settings profile and the usage bounds allow 5 agents at once, not 3.
Five is the community figure.
A cap of 3 caused 50 of 77 measured
Agenterrors. When the user applies the profile, a value of3that 0.11.1 wrote becomes5. Any other value stays. 0.12.0 removes and renames no profile value. A test applies the profile to a real 0.11.1 output.
-
Bashfile writes: files that aBashcommand writes now get the same checks as theEditandWritetools.- Before,
cat > tests/a.test.mjs <<'EOF'could remove every assertion. A heredoc could write broken YAML frontmatter. Neither case asked. - The checks cover redirects,
tee,sed -i,sd,cp,mv, and file writes in inline interpreter code. - A new file under a build directory does not get the generated-file warning.
- The
edit_guardoption turns these checks off.
- Before,
- Snapshot updates: the
Bashguard asks before a snapshot update through a package script, such asnpm test -- -uorpnpm test -u. Before, only direct runner calls asked. The reason tells Claude to find the cause of a failing test before it updates the snapshots. - Python writes: the
Stopgate counts a write through aPathvariable as an edit. An example isp = pathlib.Path("src/a.cs")and thenp.write_text(s). Before, Claude could edit code this way and stop with no check run. - Globs in search paths: the
Bashguard expands them as the shell does before it looks for ignored directories. Before,grep -rn x docs/*.mdwas denied becausedocs/has ignored directories. The glob names only files, so this deny was wrong.grep -r x *is still denied when*matches an ignored directory. -
cd ~/dir: theBashguard resolves paths after it against the home directory. Before,cd ~/.claude/projects && find .was checked as if it ran in the project. So the guard denied it for the ignored directories of the project. Aftercd $DIR, the guard treats the directory as unknown. It does not guess the project root. - Backticks in code: the
Bashguard no longer treats a backtick in Python, Node, Bun, or Deno code as a shell command. Before, a Python heredoc that wrote Markdown with code spans could be denied. An example is a CHANGELOG entry. Backticks still count in Perl, Ruby, and PHP, where they run a shell.
- Previous: Release 0.11
- Next: Release 0.13
- Archive: the index of the archived pages.