| name | release-review |
| description | Mandatory pre-release deep review for minor/major releases (X.Y.0 / X.0.0). Runs a multi-agent adversarial audit of the ENTIRE repository, produces a stable-ID findings report with user triage, drives the remediation PR, then runs a post-implementation verification round with fresh lenses. Point releases (X.Y.Z, bug fixes only) are exempt. Invoke when preparing a new minor/major release, or whenever the user asks for a full-repository audit/review. |
Release review — full-repository adversarial audit
Automated tests prove the code does what a test author thought to ask. They
do not prove that nobody overlooked a way the daemon can drop a healthy host
or miss a real outage. Before every minor/major release, the whole repository
at HEAD — not just the release diff — goes through this structured audit.
ELI5: every deep clean of a big house finds dirt; that never means the house
is filthy. The point is not "zero findings" (unreachable) — it's that new
findings stop being scary. Track the severity trend, not the count.
History (why this is mandatory): the v6.0.0 pass found ~100 issues, the
v6.1.6 pass 64, the v6.1.7 pass 65 + 28 more in verification — each round's
Criticals shrank in number and blast radius and migrated from the shutdown
core toward the periphery. See "Pre-release code review" in docs/testing.md.
When
- MANDATORY before tagging any
X.Y.0 or X.0.0 release. Do not tag
without a completed cycle (both rounds) for the release.
- NOT required for patch releases (
X.Y.Z) — those are bug-fix only and
inherit the minor's review. (If a "patch" has grown feature-sized, that's a
sign it should have been a minor — review it.)
- Also usable on demand when the user asks for a full-repo audit.
Round 1 — fan-out review (before any fixes)
- Spawn three specialist subagents IN PARALLEL (one message, three
Agent calls — sequential spawning defeats the purpose). These are task
roles, not assumed installed agent types: use
general-purpose agents for
the security and test roles. For the first role, use
agent-skills:code-reviewer when that skill is installed; otherwise give a
general-purpose agent the same fresh-context review prompt. In Codex, use
ordinary spawned agents with descriptive task names such as
code_review, security_audit, and test_quality:
- Code review — five-axis review (correctness, readability,
architecture, security, performance) of the whole tree. Priority:
production-readiness of the shutdown orchestration, state machine,
signal handling, subprocess/SSH execution, config validation, error
paths. Remind it of the uv-venv rule from
AGENTS.md.
- Security audit — threat model + vulnerability pass: OWASP for the
dashboard/API, command/argument injection, secrets in logs, YAML
safety, dependency CVEs, systemd/packaging hardening. Ask for an
explicit list of surfaces examined and found clean.
- Test quality — coverage AND quality: run the unit suite in a uv venv
for ground truth; find behavioral gaps (simulated-but-never-exercised
paths, races), not just uncovered lines.
- Orchestrator direct checks (main session, while agents run): docs
freshness, CI/workflow health, dashboard accessibility signals.
- Merge, dedupe, and write the report at the repo root
(
SHIP_REVIEW.md pattern — a working artifact, do NOT commit it):
- Ship decision (GO/NO-GO) + a rollback plan (trigger conditions,
per-install-path procedure, RTO).
- Master findings table —
ID | Sev | Axis (source) | file:line | Finding | Suggested remediation | Effort. IDs are stable F-NNN,
continuing the existing series across rounds and releases, never reused.
- Implementation guidance: findings sharing a root cause become one fix
group landed as one unit (the v6.1.7 config schema gate closed seven
findings at once); a suggested landing order; per-fix verification.
- The report must be self-contained for a fresh agent session: no
references to the review conversation.
- User triage (required before any fix). Present an ELI5 table — one
plain-language row per finding, concrete metaphor first, jargon second —
so the user can drop or downgrade findings. Record drops in the report
with the user's reason (strikethrough row + scope-rule entry). A dropped
finding is never implemented; reviewers never return empty, so triage is
part of the process, not an insult to it.
Remediation PR
- Track every in-scope finding with
/goals until closed — do not declare
done while any non-dropped finding is open (v6.1.7 shipped its PR with one
of 62 silently unaddressed; the tracker exists to make that impossible).
- One commit per category (fix group / silent-failures / security / perf /
CI / tests / docs-tail), all on a single branch, delivered as one PR.
- Then the standard
AGENTS.md flow: CI green → both upstream AI reviews →
address findings (max two rounds) → wait for the user's explicit
greenlight. Never self-merge.
Round 2 — verification (after implementation, before merge/tag)
Spawn IN PARALLEL:
- Compliance audit — every in-scope finding vs the actual diff:
fixed / fixed-differently (judge the deviation) / partial / missing.
Verify substance by reading the changed code, not commit messages.
Explicitly re-verify every user-mandated constraint from triage.
- Regression review of the diff itself — bugs the fixes introduced.
Crucially: verify each fix works in the exact scenario its finding
cites (three v6.1.7 fixes failed their own cited scenario).
- Fresh bug hunts with lenses earlier rounds did NOT use — rotate
among: cross-module interactions, real-world data edges (malformed/
extreme NUT variables, odd SSH targets), time & ordering (DST,
monotonic-vs-wall, rollover), resource lifecycle (leaks, unbounded
growth over weeks of uptime), newest-code-meets-oldest-code.
Rules for round-2 agents: read the round-1 report first — re-reporting a
known or user-dropped finding is a task failure; findings need a concrete,
traceable failure path (no hardening wishlists); an honest "found little"
beats padding.
Output: a separate round-2 report (SHIP_REVIEW_ROUND2.md pattern —
never fold into the round-1 report), continuing the F-ID series, with a
merge/tag gate section, already-fixed markers for anything closed in the
meantime, and a "verified sound — do not re-litigate" list so later passes
don't churn. New findings go through the same user triage, then loop back
into the remediation PR; re-verify only what changed.
Principles (learned over v6.0.0 → v6.1.7)
- Close bug classes, not instances. A declarative gate or a CI tripwire
beats N spot fixes; ask "what invariant was missing?" for every cluster.
- Finding count is not a health metric; the severity trend is. Expect a
long Minor/Low tail forever; reserve alarm for Criticals recurring in
previously-audited core code.
- A fix is not done until verified against its own cited scenario.
- New code carries new bugs at roughly constant density — a review after
a feature wave harvests that wave; that's the process working.
- Reports carry stable IDs and
file:line anchors so any harness (Claude,
Codex, a human) can execute them without the originating conversation.