Skip to main content

Growth discipline and reverse ratchet

About the point in time this series describes

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:

DisciplineWhen it firesOwner
Usage-driven additionAt new-facet additionHuman (author) + AI
Size capWhen editing existing facets≤ cap per file
One file, one concernWhen designing any facetConcern boundary
Reverse ratchetMonthly /harness-pruneDetect 30-day-zero-refs etc., delete via inverted approval
Hooks-after-evidenceWhen considering a new hookOrphan 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 facetObserved patternAdopted?
hooks/check-git-commit-gate.shParallel sessions ran git commit without explicit instructionYes (exception: "essential Computational Sensors for loop-control / safety gates allowed at bootstrap")
rules/search-before-coding.md + hooks/check-pre-edit-search.shreplace_all overrode unintended locations twice; twice-requested "grep-first-before-writing" normYes (norm + log-only Computational Sensor pair)
rules/adversarial-review.md + agents/devil-advocate.mdTwice the main agent forgot to pre-critique before presentingYes (norm + agent pair)
knowledge/coding-accuracy-2026.md (Kuro's discretion)Twice assembled a reference pool for best practicesYes (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 typeCapException
CLAUDE.md≤100
rules/*.md (Policy)≤30
agents/*.md (Persona)≤40gating agents (plan-reviewer / auditor) ≤60
skills/*/SKILL.md (Instruction)≤80autodev ≤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/ or repos/<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:

  1. 30-day-zero-reference facets: rules / agents / skills / knowledge / output-contracts unreferenced for 30 days from other files or git history
  2. Size-cap overruns: CLAUDE.md > 100 / policy > 30 / persona > 40 (gating > 60) / skill > 80 (autodev > 100)
  3. Orphan hooks: hooks without a corresponding facet (enforcement target absent)
  4. 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:

  1. 1st failure: write to an Inferential Guide (rule) (read by main / subagent and self-honored)
  2. 2nd failure: if a same-type failure recurs, consider hook adoption
  3. Adoption gate: is there a corresponding Policy facet (norm body in a rule)?
  4. 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 commit is 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.sh exists
  • But no rules/*.md has a foo norm

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:

DisciplineEnforcementDetection path
Usage-driven addHuman approval (normative tier)Human judgment via AskUserQuestion
Size capAuto-detected/harness-prune item 2
One-file-one-concernHuman judgmentAt edit-review time (AI flags → human approves)
Reverse ratchetAuto-detected/harness-prune items 1, 4
Hooks-after-evidenceAuto-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

Key points
  • 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.