|
| 1 | +--- |
| 2 | +name: harden-pr |
| 3 | +description: >- |
| 4 | + Bring a branch to pristine, maximum production readiness without changing PR intent — |
| 5 | + spawn parallel reviewer subagents, fix in-bounds findings, loop autonomously until |
| 6 | + clean or pass cap, then report once. Use after a tracer-bullet commit (lite), before PR |
| 7 | + is done (full), or on "harden", "harden-pr", "pristine", "review until clean", |
| 8 | + "production-ready pass". Invoking this skill authorizes one harden commit at cycle end. |
| 9 | + NEVER stop mid-loop to ask about commits, babysit, or the next pass. NEVER redesign the |
| 10 | + feature or change observable runtime behavior. |
| 11 | +--- |
| 12 | + |
| 13 | +# Harden PR |
| 14 | + |
| 15 | +**Goal:** leave the PR / feature in **pristine, maximum production state** — every changed path shippable, verified, documented, and hygienic. Polish and harden what the PR already does; **never** change its intent or runtime behavior. |
| 16 | + |
| 17 | +Local loop: parallel reviewer subagents → merge findings → fix in-bounds → re-verify → repeat until clean or cap → **one final report**. |
| 18 | + |
| 19 | +**Invoking this skill (`/harden-pr`, `harden-pr lite`, `harden-pr full`) is a run-to-completion command.** The agent executes the full loop before ending the turn. |
| 20 | + |
| 21 | +Sister skills: [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) (extended structural reviewer). Mention **`babysit`** only in the final report (full mode) — never mid-loop. |
| 22 | + |
| 23 | +## Run-to-completion (read first) |
| 24 | + |
| 25 | +**NEVER** stop between passes to ask: |
| 26 | + |
| 27 | +- whether to commit |
| 28 | +- whether to run babysit |
| 29 | +- whether to continue to the next pass |
| 30 | +- whether to spawn another reviewer |
| 31 | + |
| 32 | +**ONLY** allowed mid-loop question: intent anchor step 3 when plan doc and commit range both fail to state what must not change. |
| 33 | + |
| 34 | +Otherwise: resolve anchor → run all passes → fix → verify → next pass → finish → report. |
| 35 | + |
| 36 | +| Phase | Behavior | |
| 37 | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- | |
| 38 | +| **During loop** | Autonomous. Spawn reviewers in parallel, merge findings, fix in-bounds, re-run checks, advance pass counter. | |
| 39 | +| **After loop** | Single concise report: mode, passes run, production-bar status (met / gaps), fixes made, checks status, deferred nits (if any). | |
| 40 | +| **Commit** | If there are uncommitted fixes: one `harden: …` commit **without asking** — skill invocation authorizes it. If no fixes: skip commit. | |
| 41 | +| **Babysit** | Full mode only. One line at end of report: "For GitHub/CI, run `/babysit`." Do not ask. | |
| 42 | + |
| 43 | +## Modes |
| 44 | + |
| 45 | +| Mode | When | Scope | Max passes | |
| 46 | +| -------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ---------- | |
| 47 | +| **Lite** | After each tracer-bullet slice commit ([`tracer-bullets`](../../rules/tracer-bullets.md) cadence) | Files in the slice diff | 2 | |
| 48 | +| **Full** | User intent ("full harden", "PR done", "production-ready pass") **or** offer when an in-flight `docs/plans/<topic>.md` checklist is complete | `origin/main...HEAD` | 3 | |
| 49 | + |
| 50 | +Default to **lite** when invoked immediately after a slice commit. Default to **full** when the user signals branch completion. |
| 51 | + |
| 52 | +## Production bar (what "pristine" means) |
| 53 | + |
| 54 | +Reviewers optimize for this bar on in-scope files. **Full** mode applies it to the entire `origin/main...HEAD` diff; **lite** to the slice diff. |
| 55 | + |
| 56 | +| Area | Pristine = | |
| 57 | +| --------------- | ------------------------------------------------------------------------------------------------------------------ | |
| 58 | +| **Correctness** | No known bugs or unhandled edge cases in changed paths; behavior matches intent anchor | |
| 59 | +| **Tests** | Changed behavior covered; affected tests pass | |
| 60 | +| **Checks** | Format, lint, typecheck clean on touched files ([`verify-after-each-step`](../../rules/verify-after-each-step.md)) | |
| 61 | +| **Docs** | User-visible changes reflected in docs, changesets, help text — no drift | |
| 62 | +| **Surfaces** | No maintainer leaks into consumer surfaces ([`consumer-surfaces`](../../rules/consumer-surfaces.md)) | |
| 63 | +| **Structure** | No boundary violations or barrel bypasses in the diff | |
| 64 | +| **Hygiene** | No dead code, TODO slop, or sloppy naming in touched files; errors actionable | |
| 65 | +| **Ship shape** | A reviewer could merge without "fix before ship" notes (except deferred out-of-scope nits) | |
| 66 | + |
| 67 | +If a finding moves the bar toward pristine and stays in-bounds → **fix it**, including nits in touched files. |
| 68 | + |
| 69 | +## Intent anchor (every reviewer prompt includes this) |
| 70 | + |
| 71 | +Resolve in order; stop at the first hit: |
| 72 | + |
| 73 | +1. **Plan doc** — in-flight `docs/plans/<topic>.md`: goal + non-goals |
| 74 | +2. **Commit range** — `git log --oneline origin/main...HEAD` + `git diff --name-status origin/main...HEAD` |
| 75 | +3. **User anchor** — ask once: "What must not change?" (1–2 sentences). **Only step that may interrupt the loop.** |
| 76 | + |
| 77 | +Reviewers treat the anchor as contract. Findings that would violate it → **report, do not apply**. |
| 78 | + |
| 79 | +## In-bounds vs out-of-bounds |
| 80 | + |
| 81 | +**Fix:** bugs, missing tests, docs/changeset drift, lint/type/format, error-handling gaps, edge cases, **behavior-preserving refactors in touched files**, in-scope nits (naming, comment hygiene, cheap lint fixes). |
| 82 | + |
| 83 | +**Report only:** redesign, new capabilities, semantic API changes, nits outside the diff, refactors unrelated to a flagged issue. |
| 84 | + |
| 85 | +## Reviewer roster |
| 86 | + |
| 87 | +Spawn applicable reviewers **in parallel** via subagents in **one batch per pass**. Each returns `{ finding, severity, file, fixable_in_bounds }`. |
| 88 | + |
| 89 | +### Core (always) |
| 90 | + |
| 91 | +1. **Correctness** — gaps vs production bar; bugs, edge cases, missing tests in changed paths |
| 92 | +2. **Ship-readiness** — gaps vs production bar; docs, changesets, consumer-surface leaks, error messages; run [`verify-after-each-step`](../../rules/verify-after-each-step.md) checks on touched files |
| 93 | +3. **Structure (lite)** — gaps vs production bar; boundary smells on the diff (imports across declared layers, barrel bypasses); query codemap per [`codemap`](../codemap/SKILL.md) |
| 94 | + |
| 95 | +### Extended (adaptive — spawn when diff triggers match) |
| 96 | + |
| 97 | +| Reviewer | Trigger | |
| 98 | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
| 99 | +| **Structure (full)** | ≥5 files moved between top-level `src/` modules, new `src/<X>/` folder, or user asked for structural review → run [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) read-only; apply only fixable in-bounds items, not audit-doc recommendations that change design | |
| 100 | +| **Schema / migration** | `src/db.ts`, `SCHEMA_VERSION`, migration paths | |
| 101 | +| **Consumer surface** | `templates/agent-content/**`, root `README.md`, CLI help/errors, `.changeset/*.md` bodies | |
| 102 | +| **Security** | auth, secrets, env handling, user-input paths | |
| 103 | +| **Performance** | hot paths, benchmarks, worker pools | |
| 104 | + |
| 105 | +Re-derive layer globs from `docs/architecture.md` § Layering — don't hardcode module lists that drift. |
| 106 | + |
| 107 | +## Loop |
| 108 | + |
| 109 | +Execute **without pausing for user input** until exit condition: |
| 110 | + |
| 111 | +``` |
| 112 | +resolve intent anchor |
| 113 | +pass = 1 |
| 114 | +loop: |
| 115 | + spawn reviewers (parallel, one batch) |
| 116 | + merge + dedupe findings |
| 117 | + if none actionable → goto done |
| 118 | + fix in-bounds (pass 1: all; passes 2+: blockers first, then in-scope nits) |
| 119 | + run project checks on touched files |
| 120 | + if clean and no new findings → goto done |
| 121 | + if pass >= max_passes → goto capped |
| 122 | + pass += 1 |
| 123 | + goto loop |
| 124 | +capped: |
| 125 | + emit deferred-nits list |
| 126 | +done: |
| 127 | + if uncommitted fixes → git commit -m "harden: …" |
| 128 | + emit final report (include babysit one-liner if full mode) |
| 129 | +``` |
| 130 | + |
| 131 | +**Pass cap behavior:** after cap, stop auto-fixing; list deferred nits. Do not block the next tracer slice. |
| 132 | + |
| 133 | +## Git |
| 134 | + |
| 135 | +Skill invocation **is** the commit authorization. After the loop: if fixes exist, create one `harden: …` commit immediately — do not ask first. If the working tree is clean, skip. |
| 136 | + |
| 137 | +## Quick invoke |
| 138 | + |
| 139 | +| Intent | Say | |
| 140 | +| ----------- | ------------------------------------------------------ | |
| 141 | +| Post-slice | `/harden-pr lite` or `/harden-pr` after a slice commit | |
| 142 | +| Branch done | `/harden-pr full` or "production-ready pass" | |
| 143 | + |
| 144 | +Replaces the old copy-paste: _"spawn subagents → fix → loop until clean"_ — this skill **is** that loop. |
0 commit comments