From 9fea88421d3d7189ff334923afe5a520646223a2 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Fri, 1 May 2026 17:13:31 +0200 Subject: [PATCH] =?UTF-8?q?docs(ultraplan-local):=20add=20Handover=206=20(?= =?UTF-8?q?review=20=E2=86=92=20plan)=20to=20HANDOVER-CONTRACTS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the iteration loop: review.md → plan via source_findings audit trail. Adds versioning row, validator-map entry, full Handover 6 section, and stability summary row mirroring the shape of Handovers 1-5. Co-Authored-By: Claude Opus 4.7 --- .../docs/HANDOVER-CONTRACTS.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/plugins/ultraplan-local/docs/HANDOVER-CONTRACTS.md b/plugins/ultraplan-local/docs/HANDOVER-CONTRACTS.md index dee975f..ef4de14 100644 --- a/plugins/ultraplan-local/docs/HANDOVER-CONTRACTS.md +++ b/plugins/ultraplan-local/docs/HANDOVER-CONTRACTS.md @@ -14,6 +14,7 @@ Each artifact carries an explicit version field. Schema bumps are coordinated: | `research/*.md` | (implicit; tracked via `type: ultraresearch-brief`) | unversioned | | `plan.md` | `plan_version` (frontmatter) | `1.7` | | `progress.json` | `schema_version` (top-level) | `"1"` | +| `review.md` | `review_version` (frontmatter) | `1.0` | ## Breaking-change protocol @@ -32,6 +33,7 @@ Each artifact carries an explicit version field. Schema bumps are coordinated: | 3. architecture → plan | `lib/validators/architecture-discovery.mjs` | | 4. plan → execute | `lib/validators/plan-validator.mjs` | | 5. progress.json (resume) | `lib/validators/progress-validator.mjs` | +| 6. review → plan | `lib/validators/review-validator.mjs` | Every validator exposes a CLI: `node lib/validators/.mjs --json ` returns `{valid, errors[], warnings[], parsed}`. Errors and warnings have stable `code` fields for downstream tooling. @@ -282,6 +284,72 @@ The strongest validation in the entire pipeline. Phase 5.5 (planning-orchestrato --- +## Handover 6 — `review.md` → plan + +**Handover 6 closes the iteration loop.** Where Handovers 1–4 flow forward (brief → research → plan → execute) and Handover 5 makes execute resumable, Handover 6 routes review findings *back* into planning so a remediation plan can be produced with full traceability via `source_findings`. + +**Producer:** `/ultrareview-local` Phase 7 (write `review.md` after coordinator dedup + verdict). + +**Consumer:** `/ultraplan-local` Phase 1 when `--brief review.md` is supplied and the consumer detects `type: ultrareview` in frontmatter. The plan command branches into a remediation-plan path: BLOCKER + MAJOR findings become plan goals, the produced `plan.md` carries a `source_findings: [, ...]` frontmatter list as the audit trail back to the consumed findings. MINOR + SUGGESTION are skipped for v1.0 plan-input. + +**Path conventions:** +- Project-dir mode (recommended): `{project_dir}/review.md` (one per review iteration; subsequent runs overwrite atomically). +- Multiple review iterations are allowed in the same project; each overwrites the canonical path. Audit trail lives in git history. + +**Frontmatter schema:** + +| Field | Type | Required | Allowed values | Notes | +|---|---|---|---|---| +| `type` | string | yes | `ultrareview` | Hard-coded discriminator | +| `review_version` | string | yes | `"1.0"` (current) | Bump on schema change | +| `task` | string | yes | one-line description | Mirrors brief task | +| `slug` | string | yes | URL-safe slug | Used in project_dir | +| `project_dir` | string | yes | `.claude/projects/{date}-{slug}/` | | +| `brief_path` | string | yes | path to consumed `brief.md` | Audit trail back to brief | +| `scope_sha_end` | string | yes | git sha of HEAD at review time | Defines "after" boundary | +| `reviewed_files_count` | number | yes | ≥ 0 | From triage gate Coverage | +| `findings` | list | yes | block-style YAML list of 40-char hex IDs | Flat array; full objects in body | +| `created` | date | optional | YYYY-MM-DD | | +| `scope_sha_start` | string | optional | git sha at review start | `null` if mtime fallback used | +| `verdict` | string | optional | `BLOCK \| WARN \| ALLOW` | Coordinator output | + +`findings:` is a flat array of finding-IDs (40-char hex from `lib/parsers/finding-id.mjs`). The full finding objects (severity, location, message, evidence, fix) live in the body as `### ` subsections under per-severity `## Findings (...)` headings — same pattern as brief-reviewer to avoid frontmatter-parser fragility on lists of dicts. + +**Body invariants:** required sections (validator runs in strict mode at write-time, soft mode at read-time): +- `## Executive Summary` +- `## Coverage` +- `## Remediation Summary` + +Optional but standard sections: `## Findings (BLOCKER)`, `## Findings (MAJOR)`, `## Findings (MINOR)`, `## Findings (SUGGESTION)`. The `## Coverage` section enumerates which files were deep-reviewed, summary-only, or skipped (with reason) — this is how the triage gate stays honest and avoids Copilot-style silent skips. + +**Validation strategy:** + +| Layer | When | What | +|---|---|---| +| Frontmatter parse | every read | YAML subset; reject nested dicts | +| Required fields | every read | All `REVIEW_REQUIRED_FRONTMATTER` present | +| Type discriminator | every read | `type === "ultrareview"` | +| Findings shape | every read | Array of strings, each matching `^[0-9a-f]{40}$` | +| Body sections | strict only | `Executive Summary`, `Coverage`, `Remediation Summary` | +| Version format | every read | `review_version` matches `N.M`; warning otherwise | + +The validator (`lib/validators/review-validator.mjs`) exposes the same CLI as the others: `node lib/validators/review-validator.mjs --json `. Strict mode is the default; `--soft` downgrades section-missing errors to warnings. `/ultrareview-local` Phase 8 runs `--strict`. `/ultraplan-local` Phase 1 (when consuming `--brief review.md`) runs `--soft` so a partially-valid review can still seed a plan. + +**Versioning:** current is `1.0`. There are no live `0.x` reviews. Future schema changes follow the breaking-change protocol above. + +**Failure modes:** +- `REVIEW_NOT_FOUND` → consumer halts with usage message +- `REVIEW_READ_ERROR` → I/O failure; halt +- `FM_MISSING` → file has no frontmatter; halt +- `REVIEW_WRONG_TYPE` → `type !== "ultrareview"`; halt +- `REVIEW_MISSING_FIELD` → strict halt; soft-mode warning +- `REVIEW_BAD_FINDINGS_TYPE` → `findings` is not an array; halt (covers the YAML flow-style trap) +- `REVIEW_BAD_FINDING_ID` → an ID is not 40-char hex; halt +- `REVIEW_MISSING_SECTION` → strict halt; soft-mode warning +- `REVIEW_VERSION_FORMAT` → warning only; review_version not in `N.M` form + +--- + ## Stability summary | Handover | Validation strength | Owner | Risk | @@ -291,5 +359,6 @@ The strongest validation in the entire pipeline. Phase 5.5 (planning-orchestrato | 3. architecture → plan | discovery-only, drift-WARN | **external** (ultra-cc-architect) | low — by design we tolerate drift | | 4. plan → execute | **strict, both ends** | this plugin | medium — Opus 4.7 narrative drift requires constant vigilance | | 5. progress.json | shape + resume readiness | this plugin | medium — drift during compaction handled by pre-compact-flush hook (CC v2.1.105+) | +| 6. review → plan | strict at write, soft at read | this plugin | low — additive feedback loop; consumer falls back gracefully when source_findings is absent | When extending the plugin or adding a new pipeline stage, follow the same pattern: produce an artifact with a versioned frontmatter (or `schema_version` for JSON), write a validator under `lib/validators/`, add fixtures under `tests/fixtures/`, and add an entry to this document.