Skip to content

Write rules that bind

A rule that reads well but never fires is wasted tokens — and worse, it pushes your other rules deeper into the weak-attention zone. This guide is the checklist for rules that fire.

A rule that reads nicely but never fires is just decoration — and it crowds out the rules that do work.

A real rule grabs the wheel at the right moment. It has two parts — a moment (“when this happens…”) and a move (“…do this”) — plus the why. “Be careful” is decoration. “When you’re about to hit send, check the address first” grabs the wheel.

❌ “Don’t bug me with needless questions.” ✅ “When the next step can’t be undone — send, delete, publish — stop and ask. Anything you can undo, just do it.”

❌ “Be honest about whether it’s finished.” ✅ “When you’re about to type ‘done,’ check it actually landed first. If you can’t, say ‘your turn to check’ — not ‘done.’”

Writing it well is half; proving it fired is the other half. A rule can read perfectly and still get ignored when the model is busy — so after you write it, recompile, watch the behavior actually change, and confirm it reverts when you remove the rule. Presence isn’t proof; a changed behavior that disappears when the rule is gone is.

Stop here and you’ve got it: a rule that binds = a moment + a move you can check. Write it so it can fire; prove it fired. The rest is decoration.


A rule needs a moment the model can detect and an action to take at that moment.

  • When the first sentence of a draft restates the question — delete it and lead with the answer.
  • Be concise and direct.

The model evaluates the when during generation. Aspirations have no activation point, so they lose to task pressure.

Rules that carry their reason adapt to cases they didn’t anticipate.

  • Never edit config.json by hand — the service validates its schema on startup and a malformed file crashes the process.
  • Don't edit config.json.

Decide where the rule should be enforced before you write it, and annotate it:

  • <!-- constraint: soft --> — tone/persona/reasoning → stays in CONTEXT.md
  • <!-- constraint: routing --> — skill triggers, action classification → ENFORCEMENT.md
  • <!-- constraint: verifiable --> — checkable output criteria → ENFORCEMENT.md

Routing/verifiable rules left in context are the #1 cause of “I added a rule and it still fails.” Background: Soft / routing / verifiable.

4. Write for the weakest model in the rotation

Section titled “4. Write for the weakest model in the rotation”

Your files may be read by any model. Stick to the universal baseline:

  • markdown structure (headings, bullets, tables) over prose or XML tags
  • direct, specific language; one idea per line
  • avoid “think step by step” scaffolding and few-shot examples in always-loaded files (they help some models, hurt others, and cost tokens every session)
  • skip “you are an expert in X” — it can degrade accuracy; use the domain’s vocabulary instead

Every line costs tokens every session and dilutes the others. Before adding, ask: has anything earned removal? When the compile report shows you over budget, remove before addingWhy context rots.

Terminal window
./scripts/compile-context.sh
grep -n "lead with the answer" CONTEXT.md

Presence in CONTEXT.md is the floor. The ceiling is proving the behavior changed and reverts when you remove the rule — Know it’s working.

  1. One idea per line?
  2. Would a different model read it the same way?
  3. Can any words come out without losing meaning?
  4. Does it have a trigger, or is it aspirational?
  5. Soft, routing, or verifiable — and is it in the right layer?
  6. Does adding it bust the budget? If so, remove first.