(() => {
"use strict";
const params = new URLSearchParams(location.search);
const suppliedToken = params.get("token");
if (suppliedToken) sessionStorage.setItem("casan_viewer_token", suppliedToken);
const token = suppliedToken || sessionStorage.getItem("casan_viewer_token") || "";
params.delete("token");
history.replaceState({}, "", `${location.pathname}${params.size ? `?${params}` : ""}${location.hash}`);
const state = {
view: params.get("view") || (params.get("trace") ? "runs" : "overview"),
trace: params.get("trace") || "",
project: null,
registry: null,
h6: null,
run: null,
selectedGate: "H1-context",
};
const $ = (selector) => document.querySelector(selector);
const esc = (value) => String(value ?? "")
.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">")
.replaceAll('"', """).replaceAll("'", "'");
const slug = (value) => String(value || "unknown").toLowerCase().replaceAll("_", "-").replace(/[^a-z0-9-]/g, "");
const text = (value, fallback = "Unavailable") => value === null || value === undefined || value === "" ? fallback : String(value);
const number = (value) => value === null || value === undefined || !Number.isFinite(Number(value))
? "Unavailable" : new Intl.NumberFormat("en-US").format(Number(value));
const time = (value) => value ? String(value).replace("T", " ").replace("Z", " UTC") : "No timestamp";
const money = (value) => value === null || value === undefined ? "Unavailable" : `$${Number(value).toFixed(6)}`;
const pill = (value) => `${esc(String(value || "unknown").replaceAll("_", " "))} `;
async function api(path) {
const response = await fetch(path, {
headers: { "X-CASAN-Viewer-Token": token },
cache: "no-store",
});
const payload = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(payload.error || `HTTP ${response.status}`);
return payload;
}
function downloadUrl(path, query = {}) {
const next = new URLSearchParams({ ...query, token });
return `${path}?${next}`;
}
function hero({ eyebrow, title, description, verdict, meta = [], actions = "" }) {
return `
${esc(eyebrow)}
${esc(title)}
${esc(description)}
${meta.map((item) => `${esc(item)} `).join("")}
${verdict ? pill(verdict) : ""}${actions}
`;
}
function metric(label, value, detail) {
return `${esc(label)}
${esc(text(value))}
${esc(detail)}
`;
}
function panel(eyebrow, title, description, body, right = "") {
return `${esc(eyebrow)}
${esc(title)} ${esc(description)}
${right}
${body}
`;
}
function disclosure(summary, description, body, badge = "") {
return `${esc(summary)} ${esc(description)}
${badge}+ ${body}
`;
}
function distribution(label, rows) {
const maximum = Math.max(...rows.map((row) => Number(row.value) || 0), 1);
return `
${rows.map((row) => {
const value = Math.max(Number(row.value) || 0, 0);
const width = value === 0 ? 0 : Math.max((value / maximum) * 100, 3);
return `${esc(row.label)} ${esc(row.detail || "")} ${esc(number(value))}
`;
}).join("")} `;
}
function empty(title, detail) {
return `∅
${esc(title)} ${esc(detail)}
`;
}
function setView(view, push = true) {
state.view = ["overview", "runs", "h6"].includes(view) ? view : "overview";
document.querySelectorAll(".nav-item").forEach((item) => {
const active = item.dataset.view === state.view;
item.classList.toggle("active", active);
if (active) item.setAttribute("aria-current", "page");
else item.removeAttribute("aria-current");
});
document.querySelectorAll(".view").forEach((item) => item.classList.add("hidden"));
$(`#${state.view}-view`).classList.remove("hidden");
$("#page-title").textContent = {
overview: "Assurance overview", runs: "Run assurance registry", h6: "H6 AgentOps dossier",
}[state.view];
if (push) {
const next = new URL(location.href);
next.searchParams.set("view", state.view);
if (state.trace) next.searchParams.set("trace", state.trace);
else next.searchParams.delete("trace");
history.pushState({}, "", `${next.pathname}?${next.searchParams}`);
}
if (state.view === "runs") renderRuns();
if (state.view === "h6") renderH6();
closeNav();
}
function renderOverview() {
const profile = state.project;
const registry = state.registry;
const latest = registry.latest || {};
const recent = registry.runs || [];
const failures = recent.filter((row) => row.status === "failed").length;
const certified = latest.certified === true;
const latestTrace = latest.trace_id || recent[0]?.trace_id;
const maturity = profile.maturity || {};
const actions = latestTrace
? `Inspect latest run
Open H6 `
: `View registry `;
$("#overview-view").innerHTML =
hero({
eyebrow: "CASAN Core · Local assurance",
title: latestTrace ? "One prompt. One evidence trail." : "Ready for the first governed run.",
description: "A read-only, offline-capable assurance workspace reconstructed from canonical project evidence. No Platform service or HTML generation on the prompt hot path.",
verdict: latestTrace ? (certified ? "certified" : "review required") : "ready",
meta: [
`${profile.project_name} · ${profile.edition}`,
latestTrace ? `Trace ${latestTrace}` : "No finalized trace yet",
`Maturity ${maturity.level == null ? "not assessed" : `L${maturity.level}`} · ${maturity.status}`,
],
actions,
}) +
`
${metric("Governed records", number(registry.count), `${recent.length} recent records loaded`)}
${metric("Latest H6 quality", latest.telemetry_quality || "Unavailable", "Missing values are disclosed, never coerced to zero")}
${metric("Observed failures", number(failures), `${recent.length ? Math.round((failures / recent.length) * 100) : 0}% of loaded records`)}
${metric("Evidence gates", latestTrace ? "H1 → H7" : "Waiting", latestTrace ? "Control-by-control reconstruction available" : "Evidence appears after a prompt finalizes")}
` +
disclosure(
"About this local report",
"Edition boundaries and implementation notes are hidden until needed.",
`
Included in Core Latest run, history, interactive H1–H7 evidence, H6 AgentOps, and on-demand JSON/HTML export.
Platform boundary Multi-project fleet views, centralized RBAC, shared approvals, ingestion and organization-wide retention.
`
) +
recentRunsPanel(recent.slice(0, 6), "Latest governed evidence");
bindActions();
}
function recentRunsPanel(rows, title = "Recent governed runs") {
const body = rows.length ? `` : empty("No governed run yet", "Complete a prompt in a configured client, then refresh this viewer.");
return panel("Evidence index", title, "Operational values are shown only when present in canonical telemetry.", body);
}
function renderRuns() {
const rows = state.registry.runs || [];
const selected = state.run;
const body = hero({
eyebrow: "Run assurance registry",
title: "Every governed run, one evidence trail.",
description: "Select a lifecycle record to reconstruct H1–H7 decisions, inspect sanitized evidence and export an independent dossier.",
verdict: rows.some((row) => row.status === "failed") ? "attention" : "operational",
meta: [`${state.registry.count} records`, `${rows.filter((row) => row.status === "failed").length} failures`, "Local canonical evidence"],
actions: `Open H6 dossier `,
}) + (selected ? renderTrace(selected) : "") + recentRunsPanel(rows);
$("#runs-view").innerHTML = body;
bindActions();
bindGates();
}
function renderTrace(report) {
const gates = report.gates || [];
let selected = gates.find((gate) => gate.id === state.selectedGate) || gates[0];
if (!selected) return "";
const rail = gates.map((gate, index) => `
0${index + 1} ${esc(gate.title)}
${esc(gate.status)} `).join("");
const events = (selected.events || []).slice(-4).reverse();
const timeline = events.length ? `${events.map((event) => `
${esc(event.status)} ${esc(time(event.timestamp))} ${esc(event.reason)}
`).join("")}
` : `No individual event was emitted for this control.
`;
const entries = Object.entries(selected.evidence || {});
const manifest = entries.length ? `${entries.map(([key, value]) => `
${esc(key)} ${esc(typeof value === "string" ? value : JSON.stringify(value))} `).join("")} `
: empty("No safe evidence fields", "This control has not emitted a sanitized evidence manifest.");
const actions = `JSON evidence
Export dossier `;
return panel(
"Run assurance",
"Governed execution dossier",
"A control-by-control reconstruction backed by sanitized lifecycle evidence.",
`
Trace provenance
${esc(report.trace_id)}
${report.summary.gates_observed}/7 controls observed ${report.project.edition} edition
${pill(report.verdict)}
Selected control
${esc(selected.title)} ${esc(selected.description)}
Latest decision · ${esc(time(selected.updated_at))} ${esc(selected.reason)}
${disclosure("Event history", `${events.length} recent lifecycle events · hidden by default`, timeline)}
${disclosure("Safe evidence manifest", "Sanitized fields persisted by the harness · hidden by default", manifest, pill(`${entries.length} fields`))}
`,
actions,
);
}
function renderH6() {
const data = state.h6;
if (!data) return;
const query = data.scope || {};
const queryObject = Object.fromEntries(Object.entries(query).filter(([, value]) => value));
const actions = `JSON evidence
Export dossier `;
const findings = data.findings.length ? `${data.findings.map((item, index) => `
${String(index + 1).padStart(2, "0")} ${esc(item.code)}${esc(item.message)}
`).join("")}
`
: `No threshold breach was detected in the selected evidence boundary.
`;
const sources = data.evidence_sources.map((source) => {
const status = !source.present ? "missing" : source.stale ? "stale" : "fresh";
return `${esc(source.source)} ${source.records} records · ${source.age_s == null ? "no timestamp" : `${number(source.age_s)}s old`}
${pill(status)}
${esc(source.path)}
`;
}).join("");
const breakdown = (rows, subject) => ``;
const outcomes = distribution("Governed run outcome distribution", data.details.by_status.map((row) => ({
label: String(row.status).replaceAll("_", " "),
value: row.count,
detail: `${data.summary.runs ? Math.round((row.count / data.summary.runs) * 100) : 0}% of selected runs`,
tone: row.status === "failed" ? "danger" : row.status === "degraded" ? "warning" : "success",
})));
$("#h6-view").innerHTML =
hero({
eyebrow: "H6 · AgentOps assurance",
title: "Operational evidence, ready for a decision.",
description: "Runtime health, reliability, cost provenance and telemetry integrity—designed to answer what happened, why it matters and where the evidence lives.",
verdict: data.verdict,
meta: [data.report_id, `Generated ${time(data.generated_at)}`, `Freshness ${data.freshness.status}`],
actions,
}) +
disclosure("Filter the evidence boundary", "Project, date and trace filters stay out of the executive view until needed.", h6Filters(data)) +
`
${metric("Governed runs", number(data.summary.runs), `${data.summary.success} successful · ${data.summary.degraded} degraded`)}
${metric("Failure rate", `${data.summary.failure_rate_pct}%`, `${data.summary.failed} failed · ${data.summary.alerts} alerts`)}
${metric("P95 latency", `${number(data.summary.latency_ms.p95)} ms`, `P50 ${number(data.summary.latency_ms.p50)} ms`)}
${metric("Telemetry integrity", data.data_quality.status.replaceAll("_", " "), `${data.summary.coverage.token_pct}% token · ${data.summary.coverage.cost_pct}% cost`)}
` +
`
${panel("Decision brief", "What requires attention", "Threshold findings are review signals, not maturity claims.", findings, pill(data.verdict))}
${panel("Outcome mix", "Run distribution", "Canonical runtime status values, normalized against the largest observed group.", outcomes, `${number(data.summary.runs)} total `)}
` +
panel("Evidence quality", "Coverage and disclosure", "Unavailable telemetry remains null. Coverage gaps stay visible.", `
${coverage("Token attribution", data.summary.coverage.token_pct, `${data.summary.coverage.token_records}/${data.summary.coverage.runtime_records} records`)}
${coverage("Cost attribution", data.summary.coverage.cost_pct, `${data.summary.coverage.cost_records}/${data.summary.coverage.runtime_records} records`)}
Disclosure notes ${data.data_quality.warnings.length ? `
${data.data_quality.warnings.map((warning) => `${esc(warning)} `).join("")} ` : `
All required sources are present with no estimation warning.
`}
`, pill(data.data_quality.status)) +
disclosure(
"Technical evidence and breakdowns",
"Provider counters, canonical paths and raw tables are preserved for audit without crowding the decision view.",
`
${metric("Provider tokens", data.summary.coverage.token_records > 0 ? number(data.summary.tokens.provider_total ?? data.summary.tokens.total) : "Unavailable", `${data.summary.coverage.token_pct}% record coverage`)}
${metric("Actual cost", money(data.summary.cost_usd.provider_actual), `${data.summary.coverage.cost_pct}% record coverage`)}
${metric("Provider calls", number(data.summary.provider_calls), "Provider-attributed requests")}
${metric("Retries", number(data.summary.retries), "Observed reroute attempts")}
Source integrity
Evidence provenance ${sources}
${panel("Runtime", "Execution profile by step", "Latency, failure and attribution by governed lifecycle step.", breakdown(data.details.by_step, "Step"))}
${panel("Provider", "Model usage and provenance", "Only provider-reported token and actual cost values are shown.", breakdown(data.details.by_provider, "Provider · model"))}
`,
pill(data.freshness.status),
);
bindH6Filters();
}
function coverage(label, value, detail) {
const width = Math.round(Math.max(0, Math.min(100, Number(value) || 0)) / 5) * 5;
return `${esc(label)} ${esc(value)}%
${esc(detail)}
`;
}
function h6Filters(data) {
const scope = data.scope || {};
const options = data.available_filters || { projects: [], runs: [] };
const date = (value) => value ? value.slice(0, 10) : "";
return ``;
}
async function loadTrace(traceId) {
if (!traceId) return;
state.trace = traceId;
state.selectedGate = "H1-context";
$("#loading").classList.remove("hidden");
try {
state.run = await api(`/api/v1/reports/run/${encodeURIComponent(traceId)}`);
setView("runs");
} catch (error) {
showError(`Run report could not be reconstructed: ${error.message}`);
} finally {
$("#loading").classList.add("hidden");
}
}
async function loadH6(query = {}) {
const next = new URLSearchParams(Object.fromEntries(Object.entries(query).filter(([, value]) => value)));
$("#loading").classList.remove("hidden");
try {
state.h6 = await api(`/api/v1/reports/h6${next.size ? `?${next}` : ""}`);
renderH6();
} catch (error) {
showError(`H6 report could not be generated: ${error.message}`);
} finally {
$("#loading").classList.add("hidden");
}
}
function bindActions() {
document.querySelectorAll("[data-view-target]").forEach((button) => button.addEventListener("click", () => setView(button.dataset.viewTarget)));
document.querySelectorAll("[data-open-trace]").forEach((button) => button.addEventListener("click", () => loadTrace(button.dataset.openTrace)));
document.querySelectorAll("[data-open-h6]").forEach((button) => button.addEventListener("click", async () => {
await loadH6({ run: button.dataset.openH6 });
setView("h6");
}));
}
function bindGates() {
document.querySelectorAll("[data-gate]").forEach((button) => button.addEventListener("click", () => {
state.selectedGate = button.dataset.gate;
renderRuns();
}));
}
function bindH6Filters() {
$("#h6-filters")?.addEventListener("submit", async (event) => {
event.preventDefault();
const values = Object.fromEntries(new FormData(event.currentTarget));
await loadH6(values);
});
$("#clear-h6")?.addEventListener("click", () => loadH6());
}
function showError(message) {
$("#error").textContent = message;
$("#error").classList.remove("hidden");
}
function closeNav() {
$(".sidebar").classList.remove("open");
$("#nav-scrim").classList.add("hidden");
$("#menu-button").setAttribute("aria-expanded", "false");
}
async function loadAll() {
$("#error").classList.add("hidden");
$("#loading").classList.remove("hidden");
try {
[state.project, state.registry, state.h6] = await Promise.all([
api("/api/v1/project"),
api("/api/v1/runs?limit=100"),
api("/api/v1/reports/h6?limit=50"),
]);
$("#freshness-pill").textContent = `${state.h6.freshness.status} evidence`;
$("#freshness-pill").className = `pill ${slug(state.h6.freshness.status)}`;
renderOverview();
renderH6();
if (state.trace) {
await loadTrace(state.trace);
} else {
setView(state.view, false);
}
} catch (error) {
showError(`Local evidence could not be loaded: ${error.message}`);
} finally {
$("#loading").classList.add("hidden");
}
}
document.querySelectorAll(".nav-item").forEach((button) => button.addEventListener("click", () => setView(button.dataset.view)));
$("#refresh-button").addEventListener("click", loadAll);
$("#menu-button").addEventListener("click", () => {
const open = !$(".sidebar").classList.contains("open");
$(".sidebar").classList.toggle("open", open);
$("#nav-scrim").classList.toggle("hidden", !open);
$("#menu-button").setAttribute("aria-expanded", String(open));
});
$("#nav-scrim").addEventListener("click", closeNav);
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") closeNav();
});
window.addEventListener("popstate", () => setView(new URLSearchParams(location.search).get("view") || "overview", false));
loadAll();
})();