# Maintainability Principles

These are non-negotiable. Every decision, at every layer, is measured
against them. When speed conflicts with maintainability, maintainability
wins — shortcuts compound into the worst kind of debt: the kind you
don't notice until it's already caused damage.

## Single Source of Truth

Every piece of logic, configuration, and state lives in exactly one
place. Everything else is a derived copy.

- **Templates are upstream, installed copies are downstream.** Edit
  `templates/`, never `.claude/skills/` or installed scripts.
- **Shared logic lives in one script, callers delegate.** If a function
  and a script do the same thing, delete one. The `worktree_health_check()`
  → `worktree-session-health.sh` consolidation is the pattern.
- **Schema defines shape, consumers read it.** Don't re-derive field
  names, validation rules, or defaults in multiple places.
- **State files are authoritative, summaries are projections.** If two
  files disagree, the source-of-truth file wins. Fix the projection.

When you're about to write logic, ask: *does this already exist
somewhere?* If yes, call it. If it exists but doesn't quite fit,
extend it — don't fork it.

## No Silent Failures

Systems that fail silently compound damage. By the time you notice,
the root cause is buried under layers of consequences.

- **Health checks report positive confirmation**, not just absence of
  warnings. Silence is ambiguous — it could mean "healthy" or "didn't
  run."
- **Automated checks run at the boundary** where problems enter (session
  start, worktree creation, install, commit), not on a schedule you'll
  forget about.
- **Hooks over hope.** If something must happen, enforce it with a hook
  or validation script. If it should happen, put it in a rule. If it's
  nice to have, document it. See `enforcement-pipeline.md` for the
  compliance stack.
- **Check the exit, not just the output.** A command that fails — `git
  show` on a bad ref, a glob that matched nothing — can still produce an
  empty-but-zero-looking stream that the next step consumes as if valid,
  yielding a confident wrong result with no error signal. Verify exit
  status or a non-empty result before piping a command's output into a
  decision or a diff.
- **Resolve merge conflicts by inspection, not preference.** Clearing a
  conflict with a blind `git checkout HEAD -- <file>` (or "keep ours")
  silently discards whatever the other side changed. Read the diff and
  merge intentionally; an unexamined "keep ours" is data loss disguised
  as conflict resolution.

## Fix Upstream, Not Downstream

When a problem surfaces in a derived copy (installed file, worktree,
consumer project), trace it to the source and fix it there.

- Don't patch installed copies — patch templates and reinstall.
- Don't add workarounds in consumers for bugs in the producer.
- Don't fix symptoms in hooks when the root cause is in the generator.

## One Concept, One Place

Related to single source of truth but broader — about cognitive load,
not just code duplication.

- If a concept (a slug algorithm, a path convention, a hook pattern)
  appears in multiple files, it should be *defined* in one and
  *referenced* from the others.
- When a convention changes, you should need to change one place. If
  you need to change three, the abstraction is wrong.
- Module manifests, template lists, and file registries are the index.
  The index must be complete — unindexed files are invisible files.

## Prefer Structural Prevention Over Detection

The best enforcement makes the wrong thing impossible, not just
detectable. In order of preference:

1. **Structural** — the system rejects invalid states (schema
   validation, type system, API contract)
2. **Mechanical** — a hook blocks the action (~100% compliance)
3. **Automated** — a check surfaces the problem (high compliance)
4. **Documented** — a rule describes the expectation (moderate
   compliance)

Move rules up this stack whenever the cost of violation justifies it.

## Automate the Human Out of the Maintenance Loop

If a human has to remember to do something for the system to stay
healthy, the system is fragile.

- Staleness checks should auto-fix, not just warn (when the fix is
  safe and deterministic).
- Cleanup should be automatic with safety checks, not manual with
  reminders.
- Validation should run on write, not on periodic audit.

The test: *if nobody touches this for six months, will it still work?*
If the answer depends on someone remembering a manual step, automate
that step.
