Growth discipline and reverse ratchet
This series is a record based on the harness environment as it existed at the time of writing (file contents, run logs, file counts). The harness has kept evolving since this series was written, so quoted file contents, counts, and procedures may differ from the current state. The focus of this series is the design ideas (five-facet separation, verification gates, growth discipline) rather than the specific values.
This chapter covers the growth discipline that prevents the harness from re-bloating and keeps its growth within discipline, however much it grows.
As covered in Chapter 1, the pre-rebuild harness ballooned to a few-hundred-file scale via the asymmetry "easy add, hard delete." The disciplines here flip that asymmetry the other way.
Five disciplines operate in the new harness:
| Discipline | When it fires | Owner |
|---|---|---|
| Usage-driven addition | At new-facet addition | Human (author) + AI |
| Size cap | When editing existing facets | ≤ cap per file |
| One file, one concern | When designing any facet | Concern boundary |
| Reverse ratchet | Monthly /harness-prune | Detect 30-day-zero-refs etc., delete via inverted approval |
| Hooks-after-evidence | When considering a new hook | Orphan hooks forbidden |
Each in detail, with operational examples.
7.1. Discipline 1: usage-driven addition
Rule: consider faceting only after the same instruction has been given by hand twice. Preemptive addition is forbidden.
The pre-rebuild process was "facet on observed failure." That caused:
- Each failure adds a file → cumulative growth
- "Might come in handy someday" preemptive additions go unblocked
- Even when realized post-add as unnecessary, there's no motivation to delete
In the new harness, addition is gated by the two-occurrence rule:
- 1st instance: the author writes it directly / the AI handles it ad hoc (no faceting)
- 2nd instance: on a repeat of the same type, consider faceting
- Decision: "is there reason to expect a 3rd? can another facet absorb this?"
This caps cumulative growth structurally. As examples, here are a few of the facets added by triggering the 2-occurrence rule (not an exhaustive list — a representative sample that conveys the variety of addition patterns):
| Added facet | Observed pattern | Adopted? |
|---|---|---|
hooks/check-git-commit-gate.sh | Parallel sessions ran git commit without explicit instruction | Yes (exception: "essential Computational Sensors for loop-control / safety gates allowed at bootstrap") |
rules/search-before-coding.md + hooks/check-pre-edit-search.sh | replace_all overrode unintended locations twice; twice-requested "grep-first-before-writing" norm | Yes (norm + log-only Computational Sensor pair) |
rules/adversarial-review.md + agents/devil-advocate.md | Twice the main agent forgot to pre-critique before presenting | Yes (norm + agent pair) |
knowledge/coding-accuracy-2026.md (Kuro's discretion) | Twice assembled a reference pool for best practices | Yes (Knowledge = AI discretion; re-verified via context7 before promotion) |
What matters is that these are retrospective, not preemptive, additions. Even a norm that in hindsight feels like "should have been there from the start" wasn't added at bootstrap — it was faceted only after the same type of case was observed twice. Adding norms preemptively re-enters the same bloat.
Preemptive addition (writing for hypothetical future failures) is forbidden: facets without an observed failure model an imagined risk, not real harm.
Normative tier vs Knowledge approval boundary
There's also an approval boundary:
- Normative tier (CLAUDE.md / rules / agents): the author's approval required
- Knowledge: AI's discretion
This is because normative-tier additions have the destructive power to change runtime behavior (silent behavior changes are unverifiable for the human). Knowledge is descriptive and behavior-neutral, so AI can add at its own discretion.
Example: adding a new term to ~/.claude/repos/<repo>/CONTEXT.md is fine at AI discretion. Adding rules/<new Policy>.md, on the other hand, requires AskUserQuestion approval from the human.
7.2. Discipline 2: size cap
Rule: assign size caps per file type; on overrun, reduce, don't split.
Caps in lines:
| File type | Cap | Exception |
|---|---|---|
CLAUDE.md | ≤100 | — |
rules/*.md (Policy) | ≤30 | — |
agents/*.md (Persona) | ≤40 | gating agents (plan-reviewer / auditor) ≤60 |
skills/*/SKILL.md (Instruction) | ≤80 | autodev ≤100 |
output-contracts/*.md | ≤30 | — |
In practice, files under rules/, agents/, and skills/ have all kept staying within these caps. usage-driven addition has grown the number of rules, but because each facet stays narrowly scoped to "1 file, 1 concern," every new addition has also stayed within cap. The coupling of "more Policy = each file bloating" being broken is what lets the size cap and usage-driven addition coexist.
Reduce, don't split, on overrun
When the size cap is exceeded, splitting (cutting into 2 files) feels intuitive. But the new harness picks reduction (cut content) for these reasons:
- Splitting increases file count, contradicting Discipline 1 (usage-driven addition)
- Splitting fragments references, raising the risk that subagents read only one half
- "Doesn't fit in 30 lines" implies either multiple concerns mixed in (violation of 1-concern) or verbose content (reducible)
Example: the pre-rebuild rules/git-workflow.md had a fair amount of content. During the rebuild:
- Commit discipline + worktree discipline + branch discipline were mixed (1-concern violation)
- Since all are git-related, instead of splitting they were integrated (= consolidated into
rules/git.md) - Each section was split internally by section header, and "obvious notes" (already in other Policies) were removed
- Result: compressed to less than half its original length
7.3. Discipline 3: one file, one concern
Rule: don't write procedures in Policy; don't write norms in Instruction; Knowledge stays descriptive.
This is the runtime version of the concern boundary from Chapter 2 (Faceted Prompting).
Operational guidance applied at each edit:
- Editing a Policy file (
rules/*.md): if you're about to write a procedure, it's an Instruction (skills/) - Editing an Instruction file (
skills/*/SKILL.md): if you're about to write a norm, it's a Policy (rules/) - Editing a Knowledge file (
knowledge/orrepos/<repo>/): if procedure or norm slips in, move it elsewhere
Example from editing rules/git.md during this series: "git add <file> individually" is a norm (purpose: prevent accidental inclusion), and "for Bash-direct commit, end the HEREDOC with 🤖 Generated with [Claude Code]" is somewhere between a norm and a procedure. After thought:
- "individual add," "no personal names," "explicit trigger word" → norms (Policy)
- "end HEREDOC with the marker" → a hybrid: norm (because attribution.commit doesn't work on the Bash route, so this is a substitute) + procedure (HEREDOC instruction)
Hybrid cases got placed in git.md with the rationale included (why HEREDOC is needed). One-file-one-concern is strict, but hybrids stay on the Policy side with rationale.
7.4. Discipline 4: reverse ratchet (inverted approval)
Rule: monthly /harness-prune detects 30-day-zero-references / size-cap overruns / orphan hooks / dangling references, and processes deletions via inverted approval (ask why to keep).
The usual deletion check asks "OK to delete this?" — making "keep just in case" the default and reproducing the same bloat as before the rebuild.
Inverted approval flips the question:
- Usual: "OK to delete A?" → default: keep
- Inverted: "What's the reason to keep A?" → default: delete
The burden of proof moves to the keeper. "Might come in handy" can't keep things; empirical evidence ("referenced X times in the last 30 days," "without it Y breaks") is required.
The 4 detection items in /harness-prune
/harness-prune detects:
- 30-day-zero-reference facets: rules / agents / skills / knowledge / output-contracts unreferenced for 30 days from other files or git history
- Size-cap overruns: CLAUDE.md > 100 / policy > 30 / persona > 40 (gating > 60) / skill > 80 (autodev > 100)
- Orphan hooks: hooks without a corresponding facet (enforcement target absent)
- Dangling references:
~/.claude/<path>mentions in rules / skills / agents that don't resolve (excluding globs / trailing-slash directory refs)
The discipline is itself constrained:
## Discipline
- This skill is itself ≤80 lines, with detection fixed at the 4 items above
(don't bundle metrics aggregation; prevent self-bloat)
- Launch is staged: for now the AI promotes "time since last prune" awareness
- When restoring a deletion candidate, rewrite to the new size cap before
re-placement (no verbatim restore)
The key is that /harness-prune itself doesn't bloat. Detection is deliberately kept small (4 items at the time of writing); adding "90-day trends," "per-facet aggregates," etc. would create a new bloat source.
Reminder strategy
/harness-prune is easy for a human to forget. Temporary mitigation:
- The AI promotes "it's been a while since the last prune" by half-automatic awareness
- If forgotten launches reach 2 times, add a SessionStart hook (promotes when 30 days since last prune have passed)
"Forgotten launches twice" aligns with Discipline 1's 2-occurrence rule.
7.5. Discipline 5: hooks-after-evidence
Rule: adding a hook requires two observations of the same failure type + an existing corresponding facet. Orphan hooks (hooks without a corresponding facet) are forbidden.
The pre-rebuild era was "hook on observed failure." That caused:
- Hooks grow per failure → cumulative count
- False positives discovered post-add don't motivate deletion
- "Just block it with a hook" becomes a habit, and Inferential Guides (rules) don't mature
The new harness:
- 1st failure: write to an Inferential Guide (rule) (read by main / subagent and self-honored)
- 2nd failure: if a same-type failure recurs, consider hook adoption
- Adoption gate: is there a corresponding Policy facet (norm body in a rule)?
- Decision: if yes, hook-adopt + add a hook reference to the Policy
Exception clause
Exception: Computational Sensors essential for loop-control / safety gates may be allowed at bootstrap.
Example: check-git-commit-gate.sh was added at bootstrap of the new harness. Reasons:
git commitis destructive with high blast radius (mixing other sessions' staged changes risk)- Inferential Guides alone can't prevent probabilistic violations across parallel sessions
- Essential to safety → exception clause applies
The exception is also processed by inverted approval: "what's the reason to keep this exception?" If the safety gate's role is still demonstrated, it stays.
Orphan-hook detection
/harness-prune's detection item #3 ("orphan hook") covers hooks with no corresponding Policy facet. For example:
hooks/check-foo.shexists- But no
rules/*.mdhas afoonorm
This implies the hook is enforcing behavior without a norm body. The author can no longer reconstruct "why this hook exists" later. Orphan hooks are deletion candidates.
Concretely, hooks/check-fact-source-nullresult.sh is not orphan because its norm body is in rules/fact-check.md's "don't fill null-results from primary sources via memory" section. If that section were removed from rules/fact-check.md, the hook would become orphan and /harness-prune would catch it.
7.6. Entrance friction × exit pull
Bundling the 5 disciplines: friction at the entrance, pull at the exit:
Pre-rebuild, the asymmetry was "pull at the entrance (add = default) / friction at the exit (hard to delete)," growing to a few-hundred-file scale. Post-rebuild, it flipped to "friction at the entrance (2-occurrence rule / size cap / one-file-one-concern / no orphans) / pull at the exit (inverted approval)," and although the file count has kept growing via usage-driven addition even after bootstrap, each facet has stayed within its size cap (= quantitative growth and qualitative bloat are separated).
The structural novelty is flipping the asymmetry. This isn't one discipline but the composition of all 5.
7.7. How discipline violations are detected
Mechanical enforcement is the ideal, but for now it's half-automatic:
| Discipline | Enforcement | Detection path |
|---|---|---|
| Usage-driven add | Human approval (normative tier) | Human judgment via AskUserQuestion |
| Size cap | Auto-detected | /harness-prune item 2 |
| One-file-one-concern | Human judgment | At edit-review time (AI flags → human approves) |
| Reverse ratchet | Auto-detected | /harness-prune items 1, 4 |
| Hooks-after-evidence | Auto-detected (orphan) | /harness-prune item 3 |
Size cap, orphan hook, and dangling reference are mechanically detected; one-file-one-concern judgment and reduce-vs-split decisions are human (AI proposes + human approves).
In the future, mechanical sensing of "verb/noun distribution in a facet" or "string commonality between files" could detect one-file-one-concern violations, but at present human judgment is sufficient.
7.8. Summary of this chapter
- The 5 disciplines structurally create entrance friction × exit pull: usage-driven addition / size cap / one-file-one-concern / reverse ratchet / hooks-after-evidence
- "2-occurrence rule": consider faceting only after the same instruction has been issued twice manually; preemptive addition forbidden
- On size-cap overrun, reduce, don't split (splitting raises file count and conflicts with Discipline 1)
- Reverse ratchet uses inverted approval ("what's the reason to keep?")
- Hooks require a corresponding Policy facet under
rules/(no orphan hooks) - Detection is half-auto: size cap / orphan hook / dangling reference / 30-day-zero reference are auto via
/harness-prune; one-file-one-concern and split-vs-reduce are human gates
The next chapter walks through post-bootstrap iteration cycles (silent drop / doubled worktrees / wording drift, and more) as problem-finding → analysis → fix → verification.