Structured Output
Phase 5 turns each surviving finding into machine-readable JSON, conforming to report-schema.json and checked by a zero-dependency Node validator.
The schema is a oneOf: a finding is either confirmed (full trace, execution and remediation) or rejected (investigated and found factually wrong). additionalProperties:false is enforced everywhere.
// Confirmed finding — required fields
verdictconst "confirmed"Marks this as a validated vulnerability.
titlestringConcise, standard vulnerability title.
descriptionstringFull explanation incl. proof-of-concept and observed output.
root_causestringOne sentence: "[function] in [file] does not [action], allowing [consequence]".
intended_behaviorstringWhat the developer was trying to build.
tracearray (≥2)Sequential steps entrypoint → … → sink; each {kind,file,line,scope,description}. First must be entrypoint, last must be sink.
conditionsarrayFactual prerequisites (auth level, role, config, timing…). Empty if exploitable by default.
executionobject{attacker_perspective, payloads[], instructions[], expected_result}.
remediationobject{strategy, code_changes[]} — the fix.
severityobject{likelihood{score,reason}, impact{score,reason}, overall_severity}.
confidenceobject{score, reason} — note any missing files or ambiguous data flows.
// Rejected finding
verdictconst "rejected"The described behavior is factually incorrect or the code path doesn't exist.
reasonstringWhich specific claims are wrong, with code evidence.
// A confirmed finding (excerpt)
{
"verdict": "confirmed",
"title": "Stored XSS in comment rendering",
"root_cause": "renderComment in views/comment.js does not escape body, allowing script injection",
"trace": [
{ "kind": "entrypoint", "file": "routes/comment.js", "line": 42,
"scope": "createComment", "description": "req.body.text stored unsanitized" },
{ "kind": "sink", "file": "views/comment.js", "line": 17,
"scope": "renderComment", "description": "body interpolated into innerHTML" }
],
"severity": {
"likelihood": { "score": "high", "reason": "any authenticated user can post" },
"impact": { "score": "high", "reason": "fires for every viewer" },
"overall_severity": "high"
},
"confidence": { "score": "high", "reason": "trace verified against source" }
}validate-findings.cjs
A zero-dependency Node validator. It reads report-schema.json directly and checks required fields, enum values, structural constraints, additionalProperties, and that the trace runs entrypoint → sink. It is a structural check only — it confirms the JSON conforms to the schema, not that the findings are correct. Factual verification is Phase 6's job.
node validate-findings.cjs findings.json