Repository navigation
Make rules reliable: turn mechanical rules into hooks, check conversation rules at reply time #201
Description
What: Make AgentsMD rules hold in practice. Rules that are steps a script can do become hooks or scripts; worktree retirement moves to Chromeria (toolboxmd/chromeria#197). Rules that only the agent's judgment can meet are surfaced at the moment they apply, and the reply is checked against them.
Why: Agents read the rules and still skip them. Prose alone does not make an agent act, and right now nothing checks whether they did.
So what: An agent builds a first conversation check, measures compliance before and after, and reports here. The user reviews the rule classification and the wording.
Contribution to the Objective
"A reliable out-of-the-box system": right now the rules that govern ordinary work and conversation hold only when the agent remembers to follow them.
Evidence (2026-10-09)
Worktree retirement. finalization.md ("Retire at merge") and implementation.md (sweep merged worktrees at task start) landed in #140 on 2026-09-27.
~/dev/toolboxmd/chromeria: 18 of 28 worktrees belong to merged PRs, all created after the rule.dushows about 5.8 GB each, but pnpm's APFS clones share blocks, so all Chromeria checkouts together really use about 38 GB (measured by physical block offsets). The disk is 97 to 99% full.- Transcripts (Claude Code and Codex) after 2026-09-28 that mention
gh pr merge: 37. Of those, 31 mentionfinalization.md, and 13 of those 31 never ranworktree remove. This is a rough text match, not verified merges. The likely failure is acting on the rule, not loading it. - When the user merges on GitHub, no agent counts as "whoever merges", so the cleanup at merge never runs.
- Chromeria's own
storageCleanuponly scans~/.t3/worktrees(empty) and is off by default, so it never covers these worktrees.
Conversation rules. In the session that found the above (Claude Code, Opus 5.5), the agent:
- did not load
operationsat task start, despite the SessionStart hook telling it to; - wrote replies far over the three-sentence Communication default;
- recommended a process design without an Elon record (see Elon method is not applied in conversation: give it a visible output, concrete triggers and a brief rule #198).
The user's ask: "I would like the agents to use the prose instructions when we are talking and they are not doing that."
Proposed approach
- Classify every core and
operationsrule as one of:- mechanical: a script can do it;
- checkable: an agent decides, a script can verify;
- judgment: prose only.
- Mechanical rules become code. For worktree retirement the code lives in Chromeria: Agents get worktrees from Chromeria, and cleanup removes them at merge chromeria#197. The user runs all work through Chromeria (2026-10-09), so no AgentsMD hook. When docs: write already-decided direction changes and report the diff (#196) #197 ships, the prose it covers in
finalization.mdandimplementation.mdgets shortened to point at it. - Conversation rules apply at the moment they are needed and are checked.
- A short per-turn reminder of the conversation rules (Communication limits, Elon record before a recommendation). Candidates: UserPromptSubmit or an equivalent.
- A reply check for what is checkable: em dashes, length over the default without a reason, a recommendation without an Elon record. Candidates: a Stop hook or an equivalent that asks for a rewrite.
- Unknown: equivalent hook points on Codex, Grok and OpenCode.
- Measure compliance for each converted rule before and after, with Agent Observer or the Procedure trigger audit: measure which operations procedures fire, then fix the worst #164 harness.
Acceptance criteria
- The rule classification table is in this Issue, reviewed by the user.
- Worktree retirement is handled by Agents get worktrees from Chromeria, and cleanup removes them at merge chromeria#197, and the matching prose is trimmed here.
- A conversation reminder and reply check ship for Claude Code at minimum. Hosts without hook support are recorded.
- Before and after compliance numbers for the converted rules are posted here.
- Prose replaced by a mechanism is removed from the core or references.
Non-goals
- Re-measuring procedure triggers (Procedure trigger audit: measure which operations procedures fire, then fix the worst #164) or rewording the Elon method (Elon method is not applied in conversation: give it a visible output, concrete triggers and a brief rule #198). This Issue reuses their evidence.
- Shrinking pnpm installs in Chromeria (
supportedArchitecturesadds about 2.6 GB of Linux and x64 binaries per worktree). That belongs in the chromeria repo. - Deleting the existing merged worktrees. That is a separate, user-approved local cleanup.
Blockers
None known. Unknown: hook support on non-Claude hosts.
Elon record
Requirements and who asked: user (2026-10-09): instructions must work reliably, both actions like worktree cleanup and prose rules in conversation.
Deleted: an AgentsMD worktree hook (Chromeria's cleanup covers it, chromeria#197); adding more or stronger prose (already shown not to work); a separate compliance ledger; hooks for judgment-only rules.
Bottleneck: rules whose execution depends on the agent choosing to act, with nothing checking the outcome.
Checked myself: 18 merged worktrees and their sizes on disk; 37 transcripts mentioning a merge and their finalization.md and worktree remove mentions; Chromeria storageCleanup scope and defaults; my own replies in this session.
Activity
lukemaj commentedon Oct 18, 2026
Draft for user review: rule classification
What: every core (
global/AGENTS.md) andoperationsrule, classed as mechanical (a script can do it), checkable (the agent decides, a script can verify) or judgment (prose only), with today's mechanism.Why: criterion 1; it decides which rules get a hook and which prose can shrink later.
So what: you review the classes and the "Proposed" column; the draft PR builds only the three conversation checks marked #201 draft.
Granularity: one row per rule in the core; one row per enforceable rule in
operations(method-only procedures share a row). "Proposed" is a candidate, not scope of this PR.Core (
global/AGENTS.md)global/AGENTS.mdverified, reread on problembin/project-directionhook (SessionStart, UserPromptSubmit)PREFERENCES.mdin fullghcreate gate beside the Elon recorddelegate_taskgit add -A/git commit -agh issue/pr createbin/project-directionhookghgategh issue/gh pr, not the APIgh ... create)gh apiPOSTs to issues/pullsversionctlpre-commit + commit-msg hooks, Version check CIoperationsat task start and phase changebin/operations-routing), not checkedoperationsSKILL.md)implementation.md)finalization.md)implementation.md,delivery.md)versionctl, Version check CIwip:prefix (version-control)versionctlcommit-msg hookdelivery.md)delivery.md)verification.md)delivery.md,finalization.md)delivery.md)verification.md)verification.md)scoped-proof.md)bin/scoped-proofdelivery-profile)bin/delivery-profileorchestration.md)orchestration.md)orchestration.md)project-direction)writing-for-agents)domain-modeling)Summary
lukemaj commentedon Oct 18, 2026
Baseline: conversation-rule compliance before the check (criterion 4, before half)
What: in 254 real replies to the user since 8 October, no reply used an em dash, 73% ran over three sentences, and 9 of 15 recommending replies had no Elon record and no link to one.
Why: this is the "before" number for the three checks the #201 draft adds (C1, C8, C24 in the classification).
So what: the "after" half runs the same
conversation-check scanover sessions once the hook is installed, after your review.Results
Window: human prompts from 2026-10-08 15:23 to 2026-10-18 23:29 (Warsaw); Agent Observer 1.2.6 ledger after
sync.Recommendations: 15 Claude/Codex replies match the recommendation pattern; none carries all four Elon fields inline; 6 link an Issue or PR (not checked for a record there); 9 do neither.
Em dash, wider: across all 1,940 assistant messages in the Claude/Codex sessions (interim text included), 1 contains an em dash.
Method
agent-observer interventions --since 2026-10-04 --created-by all --kind promptlists prompts; a reply is the lastassistant_messageafter a prompt withcreated_by: userand before the next such prompt in the same session (the end of the user's turn, which the Stop hook sees). Every reply event came backokfromevent show; 1 Grok prompt had no reply.bin/conversation-check scanon the draft branch, the same functions the Stop hook runs:.!?in prose, after removing code, URLs, headings, table separators and abbreviations like "e.g."; each list item and table row counts at least once;#Nor a GitHub issue/pull URL).Limits
user(typed in T3 Code) count. 959 Claude and 17,653 Grok prompts ofunknownorigin are excluded, so plain terminal sessions may be missing; the Grok and OpenCode samples are small.wip: join soft-wrapped lines and treat an unclosed fence as code (#201)
wip: join soft-wrapped lines and treat an unclosed fence as code (#201)
wip: read only plain paragraphs, count list items once (#201)
lukemaj commentedon Oct 19, 2026
Corrected baseline (supersedes the counts in the baseline comment above)
What: the same 254 replies, rescored with the checker at
7cba1e5(PR #235), give 184 over three sentences (72%) instead of 185; the em-dash and recommendation counts are unchanged.Why: after two review rounds the counter reads only plain paragraph text, counts each list item as one sentence (quotes included), and skips code, quotes, tables and HTML.
So what: the "after" measurement will use this counter; nothing needs you here.
Same window, same reply selection and same limits as above; only the counting rules changed. Recommendation phrases are now read in paragraphs only, so one inside a list item is not counted.
lukemaj commentedon Oct 19, 2026
State (2026-10-19 04:40 Warsaw): waiting for the user. The classification, baseline (corrected: #201 (comment)) and draft PR #235 (head
7cba1e5) are ready for review. Luna round 3 found remaining Markdown edge shapes; parser rounds stopped (#235). Decisions for the user: approve the classification and wording; answer the PR's three questions; choose a real Markdown parser dependency if the check ships.lukemaj commentedon Oct 19, 2026
User decisions (2026-10-19), for draft PR #235:
Still open: rewrite-after-shown vs. naming findings in the next turn's reminder; whether to shorten the reminder to about 35 tokens (proposed: "Reply rules: result first, at most three sentences unless asked or a risk needs more. Give the Elon record (Requirements, Deleted, Bottleneck, Checked) before any design recommendation."); a real Markdown parser before shipping. Implementation must find a reliable way to tell a worker session from an interactive one.
feat: remind the agent of the reply rules every turn (#201)
lukemaj commentedon Oct 19, 2026
State (2026-10-19, Warsaw): PR #235 is ready for review at head
70a8e1b(17.4.0): the Stop-hook reply check andscanare deleted; one fixed reminder now rides the existing per-prompt loader on Claude Code, Codex, Muse and OpenCode, and Grok is recorded unsupported.Proof: full suite
Ran 447 tests ... OK, versionctl testsRan 7 tests ... OK,versionctl release-checkOK; the new reminder tests fail againstmain's loader (details in #235).Next: Luna reviews, then the user merges. This Issue stays open: the one-week after measurement reruns the baseline counter from
git show 7cba1e5:bin/conversation_check.py(command in the PR body), and the prose trimming remains.Merge pull request #235 from toolboxmd/feat/201-conversation-check