Repository navigation
v0.327.0 - A lesson on record can be shown at the call it is about
2026-10-16. On the dogfood project, 86 of 96 corrections over a month repeated a lesson already
written down, and the corrections file was opened in 12 of 71 sessions. Four builders outside the project
describe the same thing in their own posts. A replay of the 86 repeats, against rules frozen before it
read them, found that showing the matching lesson at the moment of the call reached the most of them: 31,
against 14 for the checks that already existed. This release ships that, off by default, so the
maintainer can test it in his own sessions first.
What changed
hooks/lesson-triggers.shandscripts/lesson_triggers.pyare wired on Bash, Write/Edit/MultiEdit
and the web tools.- Off unless
MYCELIUM_LESSON_TRIGGERS=on. The person sets it; the agent cannot, since aMYCELIUM_*
switch in a settings file is the person's to write. - When on, it reads
.claude/memory/lesson-triggers.ymlin the project. Each entry is a lesson as one rule
line with amatchon the call:commandfor Bash,pathandcontentfor file writes, andurlfor
web calls (the query for WebSearch). These are regular expressions; every key that applies to the tool
must match. - It shows the matching rule lines, at most three, and the call runs. An entry with
refuse: truerefuses
the call with its rule line as the reason. - It fails open and is listed
continue; refusals go in the denial ledger. A triggers file that exists and cannot
be parsed is said out loud at every call, since silence would read as nothing matching, and--checkexits 2
naming the error.
- Off unless
- Privacy. Only the rule line is shown, and it reaches the runtime's vendor without the agent choosing to
read the file, which PRIVACY.md now says.lesson_triggers.py --check FILElists any rule line that
carries a handle or an address. - Measured on the maintainer's own project before release (the success criteria were declared before any
code):- 15 of the 15 replay reaches it covers fire as the replay said.
- Over 16,994 recorded Bash calls it shows a line on 2.9% and refuses 4. Over 2,206 file and web calls it
shows on 3.0% and refuses 18, each of them a real instance by hand count. - p95 is 63 ms per call for the real hook.
tests/python/test_lesson_triggers.py: 16 tests, each test that it fires paired with one that it stays
quiet.
Considered and not done
- Ten triggers that did not survive the noise replay. Four were shapes the shell guard already refuses or
warns on. One fired on every push, because a hook cannot see that the battery ran in an earlier command.
One keyed on output that does not exist before the call. One relied on the shell guard's rule-4 detector,
which was wrong in 9 of 20 sampled refusals. Making that detector precise is cycle-074's work. - Writing a trigger when a lesson is logged, and triggers for every lesson. They come after the real-use
test shows whether a lesson shown at the call stops anything. - On by default. That is for every adopter, and it waits on the maintainer's 31-day test.
Not covered, and what that costs
- The agent can edit the triggers file and drop a refusal it meets. Named, not mitigated in this release.
- It reads Claude Code's tool names only, so on Codex and Cursor it is registered and stays silent.
- MCP tool calls are not read.