/gaia-harden
/gaia-harden is the human gate on the Policy-Memory Loop. When the same anti-pattern recurs across three or more distinct merged PRs at warning or error severity within a rolling 90-day window, the statusline nudges you with Run /gaia-harden (N recurring patterns). Calling /gaia-harden reads the live candidate queue, judges the lightest durable enforcement form for each finding, and presents a per-candidate approve / decline / defer choice. Nothing is authored or activated without your answer.
When to use it
Section titled “When to use it”The statusline tells you. When recurring code-review findings accumulate, you will see:
Run /gaia-harden (N recurring patterns)where N is the number of open candidates. Run /gaia-harden then to work through them.
You can also call /gaia-harden list at any time to see the current candidates without entering the interactive flow, or /gaia-harden why <finding_class> to inspect a specific one.
How to invoke
Section titled “How to invoke”Default (interactive review, same as what the statusline nudge points at):
/gaia-hardenList the live candidates and their recommended forms without prompting:
/gaia-harden listExplain one candidate: the PRs it recurred on, the recommended form, and the rationale:
/gaia-harden why rule/use-effect-derived-stateWhat triggers a candidate
Section titled “What triggers a candidate”The code-review-audit agent tags each eligible finding with a stable finding_class and a severity. A finding_class becomes a candidate when:
- it appears at
warningorerrorseverity (suggestionis ineligible), - across at least 3 distinct merged PRs,
- within a rolling 90-day window, and
- no promoted rule already covers it, and the decline ledger does not suppress it.
The tally is recomputed from GitHub PR data via gaia harden-tally each time you invoke /gaia-harden. It is an ephemeral projection: an unacted pattern decays by ageing out of the window.
Judge-the-form logic
Section titled “Judge-the-form logic”For each candidate, /gaia-harden judges two axes before recommending exactly one enforcement form. The bias is always to the lowest-context-weight form the pattern admits.
Edit vs new (checked first). Before recommending a new artifact, the command checks whether an existing rule, skill, or hook already covers the finding’s territory. If one does, the recommendation is to edit it, not create a new one.
Which form (lowest context weight that fits). The finding_class prefix and the pattern’s nature determine the form:
| Pattern type | Recommended form |
|---|---|
Oracle-class (react-doctor/, axe/, knip/, cve/) | Tighten the existing deterministic check: make it blocking or add it to the quality gate. Never a new prose rule. |
| Mechanizable pattern (catchable by a lint rule, hook, or test) | A deterministic check. v1 produces a hook+script sketch only; nothing is activated. |
| Correct procedure (a sequence of steps) | A skill via skill-creator. v1 produces a scaffold only; nothing is activated. |
| Judgment-based anti-pattern (no reliable mechanization) | A path-scoped prose rule. v1 owns this end to end. |
For each candidate, /gaia-harden presents the finding_class, its distinct-PR count and the PR numbers, the recommended form, and a one-line rationale. You then choose: approve, decline, defer, or redirect (override the form choice).
What gets drafted on approve
Section titled “What gets drafted on approve”Prose rule (v1: owned end to end)
Section titled “Prose rule (v1: owned end to end)”The rule is written to .claude/rules/<slug>.md. It is always path-scoped: a paths: frontmatter glob is derived from the candidate’s area_tags. The rule body uses present-tense prose naming the anti-pattern and the correct pattern. The first line after the frontmatter carries a provenance marker:
<!-- gaia-harden: promoted from recurring finding_class <class>; pruned by /gaia-audit on obsolescence/redundancy/supersession/duplication only, never for non-recurrence -->The marker documents the rule’s origin and instructs /gaia-audit not to treat non-recurrence as a staleness signal. A quiet pattern under a live rule means the rule is working.
Deterministic check (v1: scaffold only)
Section titled “Deterministic check (v1: scaffold only)”A hook+script sketch: a proposed hook entry and a script outline. The sketch is never wired into .claude/settings.json, never made executable, and no .claude/rules/ file is written for it. You finish and wire the check yourself.
Skill (v1: scaffold only)
Section titled “Skill (v1: scaffold only)”A skill-creator invocation with the captured intent (what the skill should enable, when it triggers, the expected output). Nothing is activated.
Oracle-class enforcement edit
Section titled “Oracle-class enforcement edit”An edit to the existing enforcement wiring: the tool’s rule file, the code-review-audit agent, the quality gate doc, or the CI workflow. A new prose rule is never drafted for an oracle-class finding.
All approved work lands in the working tree only. It ships through your normal PR review.
Decline and defer
Section titled “Decline and defer”Decline. The decline is written to the machine-local, gitignored ledger at .gaia/local/harden/declines.json. It is never shared: a teammate still sees the nudge and can approve the same candidate independently. The ledger is evidence-based: the declined class stays suppressed for you until at least 3 more distinct PRs carrying that finding_class merge after the decline. At that point it resurfaces.
Defer. Nothing is persisted. The candidate stays in the next tally pass and ages out naturally if the pattern stops recurring before anyone acts.
Guardrails
Section titled “Guardrails”/gaia-hardennever runsgit add,git commit, orgit push.- It never auto-activates a skill or wires a deterministic check.
- Every drafted prose rule has a mandatory
paths:glob: no always-loaded frontmatter-less rules are ever produced. - A decline is machine-local only: it never vetoes the candidate for a teammate.
- A defer persists nothing.
- The command never reads the privacy-sealed mentorship event store. The Policy-Memory Loop keys only on
finding_classrecurrence from the PR window.
Pruning promoted rules
Section titled “Pruning promoted rules”Promoted rules are not permanent in the “never touch” sense: /gaia-audit is the single pruner. It treats a provenance-marked rule as an ordinary rule and prunes it only on obsolescence, redundancy, supersession, or duplication. Non-recurrence is never a prune signal.
Related
Section titled “Related”code-review-auditagent: the source of thefinding_classemissions the loop counts./gaia-audit: the single pruner for promoted rules and all other knowledge-store hygiene.