///|
/// Escape text for XML/HTML content and quoted attributes.
fn evidence_escape(text : String) -> String {
  text
  .replace(old="&", new="&")
  .replace(old="<", new="<")
  .replace(old=">", new=">")
  .replace(old="\"", new=""")
  .replace(old="'", new="'")
}

///|
/// Self-contained viewer. Target data lives in escaped inert text, never in a
/// script literal or innerHTML. No network, CDN, tracking, or active target IO.
pub fn evidence_html(report : Json) -> String {
  let page =
    #|
    #|
    #|
    #|MoonStateLens · Evidence Observatory
    #|
MODEL INFERENCE / FRESH REPLAY / AUDITABLE EVIDENCE

MoonStateLens Observatory

#|

Model predictions and actual observations have different scopes. An incomplete run is never an unconditional pass. Coverage refers to the learned model. Differing contexts are not independent bug counts.

#|

Inspect evidence

Case / contextStatusInputsEvidence
#|

Trace explorer

Select a row to inspect predicted and actual outputs step by step.

#|

Model transitions

#|
Full evidence JSON and reproducible configuration
#|
Offline report · no requests are sent to a component by this viewer.
#|
  let tail =
    #|
page + evidence_escape(report.stringify(indent=2)) + tail } ///| /// CI consumes one testcase per original assertion plus an explicit failure /// when evidence is incomplete. Unknown formats are rejected. pub fn regression_junit(report : Json) -> String raise LensError { guard report is { "format": "moonstatelens.regression-run", "cases": Array(cases), "execution_complete": complete, "suite_evidence": { "generation_complete": generated, .. }, .. } else { raise InvalidArgument("expected regression-run report") } let lines = [] let mut failures = 0 let mut skipped = 0 for entry in cases { guard entry is { "case": id, "status": String(status), .. } else { raise InvalidArgument("invalid regression testcase") } lines.push( "", ) match status { "passed" => () "failed" => { failures += 1 lines.push( "" + evidence_escape(entry.stringify()) + "", ) } "not-run" => { skipped += 1 lines.push("") } _ => raise InvalidArgument("unknown regression testcase status") } lines.push("") } let incomplete = complete != Json(true) || generated != Json(true) if incomplete { failures += 1 lines.push( "", ) } let total = cases.length() + (if incomplete { 1 } else { 0 }) "\n\n" + lines.join("\n") + "\n\n" }