--- type: trekbrief brief_version: "2.1" slug: nw1-reviewer-output-schema task: Codify the /trekreview Phase 5 reviewer-output JSON as a validated schema contract research_topics: 0 research_status: complete brief_quality: ready created: 2026-06-18 --- # NW1 — reviewer-output schema contract ## Intent `/trekreview` Phase 5 launches two reviewer agents (`brief-conformance-reviewer`, `code-correctness-reviewer`) that each emit a trailing fenced `json` block of findings. The main context used to "collect the last fenced json block and `JSON.parse()` it; on parse error, ask the agent to re-emit" — a fragile contract (`trekreview.md:202–204`) that catches *parse* failure but not *schema* failure: a reviewer can emit valid JSON with a missing `rule_key`, a bad `severity`, or a non-numeric `line`, and it flows unchecked into the coordinator's dedup-by-`(file,line,rule_key)` triplet. ## Goal Codify the reviewer-output JSON as a validated schema. Main validates each reviewer's output against the schema (not merely parses it) and re-asks on schema failure as well as parse failure, with bounded retries. The load-bearing fields the downstream dedup triplet + verdict depend on — `file`, `rule_key`, `severity`, `line` — are hard errors; descriptive fields and unknown keys are tolerated (forward-compatible). No Workflow dependency — the substrate stays prose (this is the ungated, ship-regardless win). ## Success Criteria - **SC1** — A findings-schema validator accepts a well-formed findings array and rejects each malformation (missing `rule_key`, unknown `rule_key`, bad `severity` enum, non-numeric `line`, missing `file`) with a stable error code. - **SC2** — `lib/review/findings-schema.mjs` implements the schema + validator, reusing the `lib/util/result.mjs` issue/result shape and the `lib/review/rule-catalogue.mjs` `RULE_KEYS` / `SEVERITY_VALUES`. - **SC3** — `commands/trekreview.md` Phase 5 prose replaces the `JSON.parse`-only contract with "validate each reviewer's JSON against the findings schema; on schema failure re-ask for conforming JSON (bounded retries N=2); never feed unvalidated findings to the coordinator." - **SC4** — `node --test tests/lib/findings-schema.test.mjs` is green; the full `node --test` suite still passes; `claude plugin validate` is clean (modulo the pre-existing root-CLAUDE.md warning). ## Non-Goals - **NG1** — Do NOT introduce a Workflow-tool dependency. NW1 is the prose-only tier; the substrate stays prose. - **NG2** — Do NOT change the `review.md` output schema or `lib/validators/review-validator.mjs`. This is the *reviewer-output* contract (Phase 5 input), not the review.md artifact contract (Phase 7 output). - **NG3** — Do NOT touch NW2 (Workflow port) or NW3 (synthesis-agent) scope. ## Constraints - Zero runtime dependencies — Node stdlib only (project invariant). - 3-layer module pattern (Content → Raw-text → CLI shim) mirroring the other `lib/` validators. - TDD (Iron Law): failing tests first, then minimal code to pass. ## Assumptions - Reviewers continue to emit the documented JSON shape (`{reviewer, findings:[…]}`) with the per-finding fields shown in the agent specs. - The 12-key rule catalogue and 4-tier severity enum are the contract surface for `rule_key` / `severity` validation. ## NFRs - The schema validator adds no measurable latency to Phase 5 (pure in-process validation). - Error codes are stable strings so a bounded re-ask can quote them.