Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/rules/agents-tier-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Today's Tier-2 rules:

Pure intent-triggered. The skill description is detailed enough that Cursor surfaces it on relevant phrases. No always-on cost.

Skills stay rule-less when the work is **explicitly invoked** by the user, not pattern-triggered. Today: `audit-pr-architecture`, `codemap` (consumer pointer), `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `grill-me`, `improve-codebase-architecture`, `pr-comment-fact-check`, `write-a-skill`. (Skills like `gritql-codemods` and `ubiquitous-language` would also fit this tier if adopted.)
Skills stay rule-less when the work is **explicitly invoked** by the user, not pattern-triggered. Today: `audit-pr-architecture`, `codemap` (consumer pointer), `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `grill-me`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `write-a-skill`. (Skills like `gritql-codemods` and `ubiquitous-language` would also fit this tier if adopted.)

## Authoring guidelines

Expand Down
7 changes: 5 additions & 2 deletions .agents/rules/tracer-bullets.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ AI agents tend to produce complete solutions in one leap — all parsers, all sc

1. **Start with one vertical slice** that touches all relevant layers for the simplest case
2. **Commit and validate** that slice before expanding — the pre-commit hook will run format, lint, typecheck, and tests on staged files (when AI/agent env vars trigger it)
3. **Expand outward** from the working slice in subsequent commits
4. **Never build horizontal layers in isolation** (e.g. all DB helpers before any CLI wiring, or all docs before any working index path)
3. **Lite-harden the slice** — run [`harden-pr`](../skills/harden-pr/SKILL.md) in **lite** mode (parallel reviewers → fix in-bounds → up to 2 passes). When the user has asked for commits: one `harden: …` commit before the next slice. Does not change feature intent — production polish only.
4. **Expand outward** from the working slice in subsequent commits
5. **Never build horizontal layers in isolation** (e.g. all DB helpers before any CLI wiring, or all docs before any working index path)

## Feature layers in this project

Expand Down Expand Up @@ -65,3 +66,5 @@ Good — tracer bullet:
## Commit cadence

Each commit should represent a functional, describable milestone — not a placeholder. Every tracer bullet is a shippable slice that works end-to-end, even if the feature isn't complete yet. Small commits get validated by the pre-commit hook and are easier to review and revert.

Before opening a PR, run [`harden-pr`](../skills/harden-pr/SKILL.md) in **full** mode on `origin/main...HEAD` (or accept the offer when the plan checklist is complete).
144 changes: 144 additions & 0 deletions .agents/skills/harden-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
name: harden-pr
description: >-
Bring a branch to pristine, maximum production readiness without changing PR intent —
spawn parallel reviewer subagents, fix in-bounds findings, loop autonomously until
clean or pass cap, then report once. Use after a tracer-bullet commit (lite), before PR
is done (full), or on "harden", "harden-pr", "pristine", "review until clean",
"production-ready pass". Invoking this skill authorizes one harden commit at cycle end.
NEVER stop mid-loop to ask about commits, babysit, or the next pass. NEVER redesign the
feature or change observable runtime behavior.
---

# Harden PR

**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.

Local loop: parallel reviewer subagents → merge findings → fix in-bounds → re-verify → repeat until clean or cap → **one final report**.

**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.

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.

## Run-to-completion (read first)

**NEVER** stop between passes to ask:

- whether to commit
- whether to run babysit
- whether to continue to the next pass
- whether to spawn another reviewer

**ONLY** allowed mid-loop question: intent anchor step 3 when plan doc and commit range both fail to state what must not change.

Otherwise: resolve anchor → run all passes → fix → verify → next pass → finish → report.

| Phase | Behavior |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **During loop** | Autonomous. Spawn reviewers in parallel, merge findings, fix in-bounds, re-run checks, advance pass counter. |
| **After loop** | Single concise report: mode, passes run, production-bar status (met / gaps), fixes made, checks status, deferred nits (if any). |
| **Commit** | If there are uncommitted fixes: one `harden: …` commit **without asking** — skill invocation authorizes it. If no fixes: skip commit. |
| **Babysit** | Full mode only. One line at end of report: "For GitHub/CI, run `/babysit`." Do not ask. |

## Modes

| Mode | When | Scope | Max passes |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ---------- |
| **Lite** | After each tracer-bullet slice commit ([`tracer-bullets`](../../rules/tracer-bullets.md) cadence) | Files in the slice diff | 2 |
| **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 |

Default to **lite** when invoked immediately after a slice commit. Default to **full** when the user signals branch completion.

## Production bar (what "pristine" means)

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.

| Area | Pristine = |
| --------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Correctness** | No known bugs or unhandled edge cases in changed paths; behavior matches intent anchor |
| **Tests** | Changed behavior covered; affected tests pass |
| **Checks** | Format, lint, typecheck clean on touched files ([`verify-after-each-step`](../../rules/verify-after-each-step.md)) |
| **Docs** | User-visible changes reflected in docs, changesets, help text — no drift |
| **Surfaces** | No maintainer leaks into consumer surfaces ([`consumer-surfaces`](../../rules/consumer-surfaces.md)) |
| **Structure** | No boundary violations or barrel bypasses in the diff |
| **Hygiene** | No dead code, TODO slop, or sloppy naming in touched files; errors actionable |
| **Ship shape** | A reviewer could merge without "fix before ship" notes (except deferred out-of-scope nits) |

If a finding moves the bar toward pristine and stays in-bounds → **fix it**, including nits in touched files.

## Intent anchor (every reviewer prompt includes this)

Resolve in order; stop at the first hit:

1. **Plan doc** — in-flight `docs/plans/<topic>.md`: goal + non-goals
2. **Commit range** — `git log --oneline origin/main...HEAD` + `git diff --name-status origin/main...HEAD`
3. **User anchor** — ask once: "What must not change?" (1–2 sentences). **Only step that may interrupt the loop.**

Reviewers treat the anchor as contract. Findings that would violate it → **report, do not apply**.

## In-bounds vs out-of-bounds

**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).

**Report only:** redesign, new capabilities, semantic API changes, nits outside the diff, refactors unrelated to a flagged issue.

## Reviewer roster

Spawn applicable reviewers **in parallel** via subagents in **one batch per pass**. Each returns `{ finding, severity, file, fixable_in_bounds }`.

### Core (always)

1. **Correctness** — gaps vs production bar; bugs, edge cases, missing tests in changed paths
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
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)

### Extended (adaptive — spawn when diff triggers match)

| Reviewer | Trigger |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **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 |
| **Schema / migration** | `src/db.ts`, `SCHEMA_VERSION`, migration paths |
| **Consumer surface** | `templates/agent-content/**`, root `README.md`, CLI help/errors, `.changeset/*.md` bodies |
| **Security** | auth, secrets, env handling, user-input paths |
| **Performance** | hot paths, benchmarks, worker pools |

Re-derive layer globs from `docs/architecture.md` § Layering — don't hardcode module lists that drift.

## Loop

Execute **without pausing for user input** until exit condition:

```
resolve intent anchor
pass = 1
loop:
spawn reviewers (parallel, one batch)
merge + dedupe findings
if none actionable → goto done
fix in-bounds (pass 1: all; passes 2+: blockers first, then in-scope nits)
run project checks on touched files
if clean and no new findings → goto done
if pass >= max_passes → goto capped
pass += 1
goto loop
capped:
emit deferred-nits list
done:
if uncommitted fixes → git commit -m "harden: …"
emit final report (include babysit one-liner if full mode)
```

**Pass cap behavior:** after cap, stop auto-fixing; list deferred nits. Do not block the next tracer slice.

## Git

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.

## Quick invoke

| Intent | Say |
| ----------- | ------------------------------------------------------ |
| Post-slice | `/harden-pr lite` or `/harden-pr` after a slice commit |
| Branch done | `/harden-pr full` or "production-ready pass" |

Replaces the old copy-paste: _"spawn subagents → fix → loop until clean"_ — this skill **is** that loop.
5 changes: 5 additions & 0 deletions .changeset/cognitive-complexity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@stainless-code/codemap": minor
---

Add SonarSource cognitive complexity on `symbols` (same function-shaped coverage as cyclomatic, including class methods). New recipe `high-cognitive-complexity`; `high-complexity-untested` rows include `cognitive_complexity`.
1 change: 1 addition & 0 deletions .cursor/skills/harden-pr
Loading
Loading