from __future__ import annotations import json from pathlib import Path from .engagement import AuthorizationError from .model import RunReport def write_report(report: RunReport, output: str | Path) -> None: path = Path(output) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(report.as_dict(), indent=2, sort_keys=True) + "\n", encoding="utf-8") def risk_nexus_message(report: RunReport) -> str: lines = [ f"Whitehat run `{report.run_id}`: **{report.outcome}**", "", f"- evidence class: `{report.evidence_class}`", f"- target: `{report.target}` at `{report.target_revision}`", f"- posture/model: `{report.posture_claim}` / `{report.attacker_model}`", f"- engagement/authorization: `{report.engagement_id}` / `{report.authorization_id}`", f"- attempted operations: {report.attempted_operations}", f"- interval: {report.started_at} to {report.ended_at}", "", report.assurance_statement, ] if report.outcome == "finding": lines.extend(["", "Reporter supplies facts only; risk-nexus owns severity and disclosure."]) if report.evidence_class == "abort": lines.extend(["", "This is an abort record, not target assurance."]) return "\n".join(lines) + "\n" def conformance_message( report: RunReport, *, specification: str, test_id: str, component: str | None = None, invariant_ids: list[str] | None = None, ) -> str: """Render a value-safe Gate House conformance envelope. Does not send it.""" target = component or report.target subject = ( f"[GH-CONFORMANCE] {test_id} {report.outcome} " f"{target}@{report.target_revision}" ) lines = [ f"Subject: {subject}", "", f"- specification: `{specification}` test `{test_id}`", f"- report/run: `{report.run_id}`", f"- engagement/authorization: `{report.engagement_id}` / `{report.authorization_id}`", f"- target: `{target}` at `{report.target_revision}`", f"- environment/class: `{report.evidence_class}`", f"- outcome: `{report.outcome}`", f"- attempted operations: {report.attempted_operations}", f"- interval: {report.started_at} to {report.ended_at}", ] if invariant_ids: lines.append("- invariants: " + ", ".join(f"`{item}`" for item in invariant_ids)) lines.extend([ "", report.assurance_statement, "", "Implementation findings route to risk-nexus. This envelope is the " "doctrine-return copy only. It contains no credential, response body, " "or severity.", ]) if report.evidence_class == "fixture": lines.extend(["", "Fixture calibration is not target assurance."]) return "\n".join(lines) + "\n" def queue_risk_nexus(report: RunReport, outbox: str | Path) -> Path: """Persist a delivery artifact. Fixture calibration is not target assurance.""" if report.evidence_class == "fixture": raise AuthorizationError("fixture evidence is not delivered as target assurance") if report.evidence_class not in {"target", "abort"}: raise AuthorizationError("unsupported evidence class for delivery") directory = Path(outbox) directory.mkdir(parents=True, exist_ok=True) path = directory / f"{report.run_id}.md" path.write_text(risk_nexus_message(report), encoding="utf-8") return path