How to turn a rule the user just stated into doctrine this repo will still follow next session. Activate the moment the user writes NEVER or ALWAYS in capitals, and on the same shapes without the capitals — "don't ever", "from now on", "every time", "stop doing X". Also activate, unprompted, when the user faults HOW the session ran — "fatal flaw", "why only N", "too small", "you should have", or asks whether the work was complete — "did we fix all of it", "is there a guard", "why didn't CI catch this" — since that complaint names a rule the tree failed to carry. Also activate, unprompted, when YOU notice a defect class — a duplicate definition, a rule a sub-agent or open PR broke — before you record it. The load-bearing rule is that the capture happens in the session that heard it, on a PR that session already has open, never as a promise or an issue.
Install
npx skillscat add alexandermattturner/agent-glovebox/doctrine-capture Install via the SkillsCat registry.
Capturing a NEVER or an ALWAYS
The doctrine
A capitalised NEVER or ALWAYS from the user is a standing rule, and you are the only one who will ever hear it. The conversation ends and the next session starts from the committed tree, so a rule you merely obey this turn is a rule you deleted. Obey it now AND write it down, in the same turn.
A doctrine change needs no approval. Root CLAUDE.md § Guard budget asks only that it be LOUDLY ANNOUNCED in the PR description. Write a standing rule the user just stated without asking, and quote their sentence in the PR body. Apply the § What is NOT doctrine test below first, and write nothing when the test does not pass.
Fix the instance first, then the rule. The user says NEVER about something you just did, so the artifact holding the mistake is still open. Correct it, then capture. A capture with the broken artifact still standing answers the complaint with a promise.
A complaint about the session's process is a capture too
When the user faults how this session ran, fix the instance, then capture the rule in the same turn without waiting to be asked. Find the doctrine sentence or tool that let it happen and change THAT. Prefer the tool: a rule the session must obey under momentum belongs on the tool-use loop (`prompt-authoring.md`). Worked case: a session babysitting "even PRs" saved its set --bounded, so it sat with zero agents while seven even PRs went unwatched. The capture gave babysit-next.py a --parity rule that refills at every run.
A defect class you notice is a capture too
Do not wait for the user to complain. When you notice a defect CLASS — a third copy of a helper, a rule a sub-agent broke, a finding you are about to write under ## Also noticed — fix the instance, then find the rule that should have stopped it. No rule: write one. A rule that exists but did not fire: move it to where it fires — the sub-agent brief, the skill the activity loads, a hook. Worked case: an open PR added a third "is the process gone" helper, and the session only recorded it. The capture widened code-style.md's one-reader rule from grammars to every job, and made every implementation brief report the definitions it added.
Which surface takes it
Root CLAUDE.md § Where the rest of the guidance lives already gives the narrowest-surface rule. Apply it to the three surfaces this workflow chooses between:
- A path gets a
.claude/rules/file whosepaths:glob matches it. A rule about shell goes inshell-style.md, not in a skill nobody invoked. - An activity gets the skill that owns it. A rule about how a PR body reads goes in
pr-creation; a rule about copyable markdown goes inmarkdown-block. - Root
CLAUDE.mdtakes it only when it must fire BEFORE any file is opened, or must override the system prompt. That is a small set, and everything else that lands there taxes every unrelated session.
What is NOT doctrine
A rule binds future sessions; an instruction binds this one. The test: would this be right for a session that never saw this conversation?
- "ALWAYS push to the probe branch" during one task is scheduling, not doctrine. Follow it, do not write it down.
- "NEVER merge without asking me" is doctrine, and root
CLAUDE.md§ Autonomy already carries it. Confirm it is there and say so instead of adding a second copy. - A rule whose steady state is unbounded growth needs a budget or a removal clause in the same edit, per root
CLAUDE.md§ Guard budget's 500-session question — answer it in one sentence in the PR body.
Where it lands
The capture rides the PR THIS SESSION already has open, MARKED LOUDLY. Never open a separate doctrine PR, and never search for one to fold into. Searching for another session's doctrine PR made every capture wait on a branch this session did not control, and two sessions editing the same prose on it conflicted before either landed. Your own branch has neither problem.
The mark is how the owner sees that a rule moved, so write both halves:
- Its own commit, holding the doctrine files alone —
docs(rules):,docs(claude):ordocs(skill):. - A sentence in the PR lead saying the PR carries a doctrine change, which rule it moves, and what that rule now asks for. It sits in the lead, never in a later section.
## What & why then names the wrong behaviour, quotes the user's sentence that authorised it, and answers the 500-session question. A reviewer must be able to read the lead alone and know a rule moved.
Open a second PR only for SIZE, when the branch already trips the `pr-creation` skill's file-count bound — never as a deferral, and never to keep the doctrine diff separate. A session with no PR of its own opens one for the capture, marked the same way. Never file an issue for a rule the § What is NOT doctrine test already passed, and never leave the capture for a session with more context.
Examples
The user writes: "NEVER fold text, put it all on one line and update the skill."
The session had just pasted a hard-wrapped report inside a fenced block. It rewrote the report unwrapped, then found the two surfaces: root CLAUDE.md § Writing owns the never-wrap rule and exempted fenced blocks wholesale, and the markdown-block skill owns copyable fenced content. It narrowed the exemption to code and captured output in the first, added the paragraph-per-line rule to the second, and carried both on the branch already open.
The user writes: "always run the linter before you push."
No capitals, same shape. .claude/rules/development-workflow.md already says to run bash scripts/background-lint.sh on its own, only to clear a pre-push refusal. Nothing is written; the session says which sentence already carries it and gets back to work.