{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://eightarms.net/octopus-workflow/schemas/reviewer-output.schema.json", "title": "Reviewer Output", "description": "Schema for a single reviewer's output for one review dimension. Also the Tier 1 review-findings schema ([org-internal #1988]): migrated skills (review-code) write each dimension's finding as a JSON file at runs/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json validated by this schema; the index.json row for that file carries type=review-findings, schema=this $id. When a dimension has multiple reviewers (dim_split > 1, e.g. D3 TOPO:2 / D4 TOPO:2), each writes its OWN slot file findings-{DIMENSION_CODE}-r{k}.json with reviewer_slot/reviewer_count set. See templates/runs-layout.md and rules/two-tier-artifacts.md.", "type": "object", "required": ["dimension", "dimension_label", "verdict", "quantitative_summary", "findings", "reviewed_files"], "properties": { "dimension": { "type": "string", "description": "Dimension code (e.g. COR, SEC, PERF, TRC)" }, "dimension_label": { "type": "string", "description": "Human-readable label" }, "reviewer_slot": { "type": "integer", "minimum": 1, "description": "1-based slot of this reviewer WITHIN its dimension, when dim_split assigns >1 reviewer to the dimension (e.g. review-dag D3 TOPO:2, D4 TOPO:2 — dim_split per `workflow-routing.yaml` dag.size_derivation.review_depth). Multi-reviewer dimensions write one file per slot: findings-{DIMENSION_CODE}-r{k}.json. Omitted for single-reviewer dimensions (file stays findings-{DIMENSION_CODE}.json). Preserves per-reviewer attribution for the retrospective overlap analysis ([org-internal #2996] step 1a)." }, "reviewer_count": { "type": "integer", "minimum": 2, "description": "Total reviewers assigned to this dimension in this round (set together with reviewer_slot)." }, "verdict": { "type": "string", "enum": ["PASS", "WARN", "FAIL", "UNRESOLVED"], "description": "PASS: pass_rate = 1.0 (no failed checks). WARN: pass_rate >= 0.7 and no BLOCKER findings. FAIL: any BLOCKER finding OR pass_rate < 0.7." }, "quantitative_summary": { "type": "object", "required": ["total_checks", "passed", "failed", "pass_rate"], "properties": { "total_checks": { "type": "integer", "minimum": 1 }, "passed": { "type": "integer", "minimum": 0 }, "failed": { "type": "integer", "minimum": 0 }, "pass_rate": { "type": "number", "minimum": 0, "maximum": 1 }, "na_count": { "type": "integer", "minimum": 0, "description": "Count of not-applicable items" }, "blocker_count": { "type": "integer", "minimum": 0, "description": "Count of BLOCKER findings (consumed by synthesis_task.md aggregation)" }, "major_count": { "type": "integer", "minimum": 0, "description": "Count of MAJOR findings (consumed by synthesis_task.md aggregation)" }, "minor_count": { "type": "integer", "minimum": 0, "description": "Count of MINOR findings (consumed by synthesis_task.md aggregation)" }, "info_count": { "type": "integer", "minimum": 0, "description": "Count of INFO findings (consumed by synthesis_task.md aggregation)" } } }, "findings": { "type": "array", "uniqueItems": true, "items": { "type": "object", "required": ["id", "severity", "checklist_ref", "location", "summary", "detail", "evidence", "suggestion"], "properties": { "id": { "type": "string", "pattern": "^[A-Z0-9]+-F\\d{3,}$", "description": "Unique finding ID within the dimension file, form {OWN_DIMENSION_CODE}-F{NNN}, e.g. COR-F001. In a grouped dispatch the id uses the finding's OWN dimension code (e.g. TST-F001 inside the COR+TST+DBT group), never the joined group code. NOTE: uniqueness of the id VALUE is NOT enforced by findings[] uniqueItems (JSON Schema uniqueItems compares whole objects by deep equality); the synthesizer MUST post-check that id values are unique across all findings-{DIM}*.json files of the round (wired as step 1b of _shared/synthesis_task.md). Multi-slot dimensions (reviewer_slot set): prefix the slot in the id, e.g. TOPOR1-F001 / TOPOR2-F001, so ids stay unique across a dimension's slot files while still matching this pattern." }, "severity": { "type": "string", "enum": ["BLOCKER", "MAJOR", "MINOR", "INFO"] }, "checklist_ref": { "type": "string", "pattern": "^[A-Z0-9]{2,6} \\d+(\\.\\d+)+(\\s*\\([^\\)]*\\))?(\\s*/\\s*[A-Z0-9]{2,6} \\d+(\\.\\d+)+(\\s*\\([^\\)]*\\))?)*$", "description": "Checklist item reference, e.g. COR 1.1, INV 1.3, SEC 3.7.1, STD 8.4 — dimension/section code followed by item number(s)." }, "location": { "type": "string", "description": "File:line or file:section where the issue occurs" }, "summary": { "type": "string", "description": "One-line description" }, "detail": { "type": "string", "description": "Full explanation of the finding" }, "evidence": { "type": "string", "description": "Quote or excerpt from the document that supports this finding" }, "suggestion": { "type": "string", "description": "Actionable recommendation to resolve the finding" } } } }, "reviewed_files": { "type": "array", "items": { "type": "string" }, "description": "List of files actually reviewed" } } }