Files
octopus-workflow/core/schemas/reviewer-output.schema.json
T

114 lines
5.8 KiB
JSON

{
"$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"
}
}
}