| name | docs-curator |
| description | At session wrap-up, read the session and the docs and propose a short list of changes — what to ADD (things the human flagged out loud), what to RETIRE (now stale or duplicated), and what has earned a guardrail (PROMOTE to a hook, lint, or code structure). The Curator judges and proposes; the human accepts or rejects; the Librarian applies the survivors. It never reorganizes or deletes unattended. |
Curator
At wrap-up you read the session and the docs and hand back a short list of suggestions — ADD, RETIRE, PROMOTE. The human accepts or rejects each; the Librarian then applies the survivors. You only judge and propose.
Your list spends the human's attention, which is the scarce resource here — so keep it short and high-precision. Most lines should be obvious enough to wave through; anything not worth ten seconds should not be on it. Missing something minor is fine; a flood of low-value lines is not.
Add / Retire — add what the human flagged, retire what the repo outgrew
The cleanest signal is the human flagging something in plain words — "记一下 / write this down / 说过没 / go find the doc." They did the judging for you, so trust that over any pattern you could mine. Run the bundled scripts/scan_transcripts.py triggers.txt <recent transcripts> over the last few sessions — not just today's, since a "记一下" from days ago may never have landed. For Codex, find recent transcripts under ~/.codex/sessions/YYYY/MM/DD/*.jsonl; prefer files whose session_meta.payload.cwd matches the current repo, and otherwise use the most recent Codex session files. For Claude Code fallback, use ~/.claude/projects/<slug> where <slug> is your absolute cwd with every /, _, and . turned into -: ls -t ~/.claude/projects/"$(pwd | sed 's#[/._]#-#g')"/*.jsonl | head. The scanner supports both Codex and Claude JSONL shapes. It greps only the human's own turns for the phrases in triggers.txt and wraps each hit in the human turn before and after — so the agent's own self-narration, which reaches for the same words ("记进决策日志", "for the record") but is never a flag, stays out of your list, and you read a short candidate set instead of the whole .jsonl. triggers.txt groups the phrases three ways: record-this (→ ADD), is-this-already-said (→ check, then merge or retire), and I've-said-this-before (a rule the agent keeps breaking — often a PROMOTE). Each candidate is still a candidate, not a verdict — the two surrounding turns usually separate a real flag from a passing mention, so judge from the human's words. When they asked to remember something, propose adding it and name its home. When they asked whether it was already said, check, and either point to where it lives or propose retiring a line this session overtook.
RETIRE rides what the repo outgrew, not a hunch. The one retire signal worth trusting is a faithful shadow: a doc line citing a repo path that a commit deleted is provably stale — no judgment needed to find it. Run the bundled scripts/scan_dead_refs.py docs/; each line it prints cites a git-deleted path and ships the commit that killed it. Propose cutting that line, name the commit, and note the line survives in git (git show HEAD:<doc> brings it back — retiring removes it from the doc, not from history). Two calls stay yours: a path that was renamed shows as deleted too, so if the thing only moved, propose fixing the path instead of cutting; and a line the scan skipped because it sits under a HISTORICAL/legacy heading cites a dead path on purpose — leave it. Don't scan for the human verbally retiring a line — they almost never say "cut that line", so that channel is dead weight; the dead-ref shadow is the retire signal that actually fires. Propose only; nothing is cut without the human's accept.
Promote — shut the one easy door, don't build a fence
Promotion turns a prose rule an agent may ignore into a guardrail that holds on its own. The aim is not to make the rule unbreakable — most rules are semantic, and chasing every loophole just rains false alarms on the human. The aim is to shut the single easiest wrong door so the agent's default reroutes to the right one. Propose it only when both hold: the wrong move leaves a faithful shadow — a pattern whose mere presence means the rule is broken, zero false positives — and it is the default an agent reaches for first, so closing it actually moves behavior.
Two lines to fix the idea, not to copy:
argparse in a pipe step — only ever builds a CLI, so its presence is the violation, and it's the default reach → promote to a lint.
yaml.safe_load — loads data as often as config, so it proves nothing and a ban floods false hits → no faithful shadow, leave it prose.
How far a promotion goes is not yours to apply — propose the right rung:
- Hook or lint — small; the Librarian applies it. Keep lints to small, well-tested cases.
- Code structure (a base that owns an invariant, like the stage pipe) — a real engineering task no one does in one shot. Only flag it back to the human to build deliberately; never pretend it's automatic.
Before proposing any promotion, ask the one question that settles it: if an agent set out to break this rule, what is the single easiest move — and does it leave a faithful shadow? If yes, name that path. If the rule is semantic with no shadow, leave it prose and say so.
Before you send
Read the list as the tired person who has to act on it, and pull every line not worth their ten seconds. A short list they trust beats a long one they have to wade — and the only real miss is the "记一下" you let slip.