/* PivotWire dashboard. Synthetic demos and authenticated live controls stay separate. */
"use strict";
const $ = (id) => document.getElementById(id);
const state = {run: null, source: null, receipt: null, busy: false, stories: [], trace: new Map()};
const live = {token:"", readiness:null, busy:false, poll:null, epoch:0, runId:null, attempts:0, deadline:0, polling:false, controller:null, publicStatus:"UNAVAILABLE"};
function runKind(run) {
if (run.demonstration === true || /synthetic/i.test(run.provenance || "")) return "synthetic";
if (run.mode === "replay" || /recorded/i.test(run.provenance || "")) return "recorded";
return run.demonstration === false && run.mode === "live" ? "live" : "unknown";
}
function provenanceLabel(run) {
const kind = runKind(run);
if (kind === "synthetic") return "SYNTHETIC OFFLINE DEMO";
if (kind === "recorded") return "RECORDED REPLAY";
if (kind !== "live") return "SOURCE PROVENANCE UNCONFIRMED";
return run.after?.source === "youcom_contents" ? "LIVE YOU.COM COMPARISON" : "LIVE COMPARISON · REVIEW SOURCE";
}
function deliveryLabel(run) {
if (runKind(run) === "synthetic") return {title:run.local_alert ? "Recorded locally" : "No local alert", note:"Synthetic alert · no Slack delivery"};
if (runKind(run) !== "live") return {title:"Recorded result", note:"No fresh Slack delivery claimed"};
if (run.slack_status === 200) return {title:"Slack accepted", note:"Delivery endpoint returned HTTP 200"};
return {title:"Not sent", note:run.slack_status ? `Slack returned HTTP ${run.slack_status} · review required` : "No successful Slack delivery recorded"};
}
const esc = (value) => String(value ?? "").replace(/[&<>"']/g, (c) => ({"&":"&","<":"<",">":">",'"':""","'":"'"}[c]));
const label = (value) => String(value ?? "").replace(/_/g, " ");
const time = (value) => { if (!value) return "Not recorded"; const d = new Date(value); return Number.isNaN(d.valueOf()) ? String(value) : d.toLocaleString("en-US", {timeZone:"America/New_York",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"short"}); };
function safeLink(url, text) {
try { const parsed = new URL(url, location.origin); if (!["https:", "http:"].includes(parsed.protocol)) return esc(text || url); return `${esc(text || parsed.hostname)} ↗ `; }
catch { return esc(text || url); }
}
async function api(path, options = {}) {
const response = await fetch(path, {credentials:"same-origin", ...options, headers:{"Content-Type":"application/json", ...options.headers}});
const data = await response.json().catch(() => ({}));
if (!response.ok) {
const detail = data.detail ?? data.message ?? `Request failed (${response.status})`;
const message = typeof detail === "string" ? detail : Array.isArray(detail) ? detail.map(item => item.msg || String(item)).join("; ") : detail.message || detail.status || JSON.stringify(detail);
const error = new Error(message); error.status = response.status; throw error;
}
return data;
}
function notice(message, isError = false) {
$("notice").textContent = message;
$("notice").classList.toggle("error", isError);
$("notice").hidden = !message;
}
function busy(value) {
state.busy = value;
$("run-demo").disabled = value || live.busy || Boolean(live.runId);
$("pro-price").disabled = value;
$("scenario").disabled = value;
renderLiveControls();
$("run-demo").classList.toggle("loading", value);
$("run-demo").innerHTML = value ? '◌ Verifying the change…' : '▶ Run price-change demo';
}
function showMetric(id, numerator, denominator) {
$(id).innerHTML = `${esc(numerator ?? 0)} of ${esc(denominator ?? 0)} `;
}
async function runDemo(event) {
event.preventDefault();
if (state.busy || live.busy || live.runId || !$("demo-form").reportValidity()) return;
const price = Number($("pro-price").value);
const scenario = $("scenario").value;
if (!Number.isInteger(price) || price < 13 || price > 99) { notice("Choose a whole-dollar Pro price from $13 to $99.", true); return; }
if (!("EventSource" in window)) { notice("This browser needs EventSource support to stream the synthetic demo.", true); return; }
busy(true);
clearRunForPending("Synthetic verification is running. Trace rows arrive as each step completes.", true);
notice("Running a synthetic comparison · no provider requests or Slack delivery.");
try {
const result = await api("/api/demo/start", {method:"POST", body:JSON.stringify({pro_price:price, scenario})});
if (!result.run_id) throw new Error("The demo did not return a run ID.");
$("run-reference").textContent = `Synthetic run ${result.run_id}`;
await followDemoTrace(result.run_id);
await loadRun(result.run_id, () => true, false);
history.replaceState(null, "", `#run=${encodeURIComponent(result.run_id)}`);
notice("Synthetic demonstration complete. Open either value to inspect its receipt. The alert is recorded locally.");
} catch (error) { notice(error.message, true); }
finally { busy(false); }
}
async function loadRun(id, current = () => true, replayTrace = true) {
if (state.busy && replayTrace) {
notice("A synthetic comparison is running. Open the saved run after it finishes.");
return false;
}
if (state.source) { state.source.close(); state.source = null; }
const run = await api(`/api/runs/${encodeURIComponent(id)}`);
if (!current()) return false;
state.run = run;
renderRun(run);
await loadAlerts();
if (!current()) return false;
if (replayTrace) connectTrace(id);
return true;
}
function renderRun(run) {
const priceChange = (run.events || []).find(e => e.showable && e.plan === "Pro" && e.type === "price_increase");
if (priceChange) { $("price-art").textContent = priceChange.after; $("pro-price").value = priceChange.after; }
const shown = (run.events || []).filter(e => e.showable).length;
const trust = run.trust || {};
showMetric("metric-receipts", trust.quotes_verified, trust.quotes_proposed);
showMetric("metric-events", shown, (run.events || []).length);
showMetric("metric-claims", trust.claims_quote_verified, (trust.claims_quote_verified || 0) + (trust.claims_source_linked || 0));
const kind = runKind(run);
const delivery = deliveryLabel(run);
$("metric-alert").textContent = delivery.title;
$("metric-alert-note").textContent = delivery.note;
$("mode-label").textContent = provenanceLabel(run);
$("mode-detail").textContent = kind === "synthetic" ? "Fictional pages. Real verification code." : kind === "live" ? "Stored baseline and fetched source · inspect receipts." : "Recorded evidence · no fresh comparison claimed.";
$("event-count").textContent = `${shown} verified ${shown === 1 ? "change" : "changes"}`;
$("events-empty").hidden = true;
$("events-container").hidden = false;
$("run-banner").hidden = false;
const fixtureResearch = (run.research || []).length > 0 || ["announced","not_found"].includes(run.announcement?.status);
$("run-banner").textContent = kind === "synthetic" ? (fixtureResearch ? "Synthetic research replay · fictional sources · not a fresh You.com investigation" : "Synthetic offline comparison · hand-authored pricing facts · deterministic verification") : `${provenanceLabel(run)} · before: ${run.before?.source || "unknown"} · after: ${run.after?.source || "unknown"} · ${run.provenance || "provenance not recorded"}`;
$("run-reference").textContent = `Run ${run.id}`;
$("diff-summary").textContent = `${run.diff?.cosmetic_ignored || 0} cosmetic changes ignored · ${trust.events_suppressed_noise || 0} events suppressed as noise · ${trust.events_unverified || 0} unverified`;
const rows = (run.events || []).map(event => {
const delta = event.pct_change == null ? (event.direction ? event.direction === "up" ? "↑" : "↓" : "—") : `${event.pct_change > 0 ? "+" : ""}${Number(event.pct_change.toFixed(1))}%`;
return `
${esc(event.plan || event.field || "Add-on")} ${esc(label(event.type))} ${event.showable ? "" : `${esc(event.suppressed_reason || "Not verified")}
`}${receiptCell(event, "before")} ${receiptCell(event, "after")} ${esc(delta)} `;
}).join("");
$("events-container").innerHTML = rows ? `` : 'No verified material change The evidence and noise checks did not produce a showable event.
';
state.trace.clear();
(run.trace || []).forEach(addTrace);
if (!state.trace.size) $("trace-list").innerHTML = 'No pipeline trace recorded for this run. ';
document.querySelector(".trace-light").classList.add("active");
renderBattlecard(run);
renderInvestigation(run);
renderDiff(run.diff);
}
function receiptCell(event, side) {
const evidence = event[`${side}_evidence`];
const value = event[side] ?? "—";
if (!evidence?.quote) return `${esc(value)} `;
const isVerified = evidence.status === "verified";
return `${esc(value)}${isVerified ? "✓" : "⚠"} `;
}
function addTrace(row) {
const key = row.seq ?? `${row.step}:${row.detail}`;
state.trace.set(key, row);
$("trace-list").innerHTML = [...state.trace.values()].sort((a,b) => (a.seq || 0) - (b.seq || 0)).map(item => `${esc(label(item.step))} ${esc(item.api || "local")}
${esc(item.detail)}
${item.why ? `${esc(item.why)}
` : ""} `).join("");
}
function followDemoTrace(id) {
return new Promise((resolve, reject) => {
const source = new EventSource(`/api/runs/${encodeURIComponent(id)}/events`);
state.source = source;
let settled = false;
const finish = error => {
if (settled) return;
settled = true; clearTimeout(timeout); source.close();
if (state.source === source) state.source = null;
if (error) reject(error); else resolve();
};
const timeout = setTimeout(() => finish(new Error("Synthetic trace timed out. No completed result is claimed.")), 45000);
source.onmessage = event => {
try { const row = JSON.parse(event.data); if (row.step) addTrace(row); }
catch { finish(new Error("The synthetic trace was invalid. No completed result is claimed.")); }
};
source.addEventListener("done", event => {
try {
const result = JSON.parse(event.data);
finish(result.status === "ok" ? null : new Error("Synthetic comparison did not complete. Review the trace and try again."));
} catch { finish(new Error("The synthetic completion response was invalid.")); }
});
source.onerror = () => finish(new Error("Synthetic trace disconnected. No completed result is claimed; try again."));
});
}
function connectTrace(id) {
if (!("EventSource" in window)) return;
const source = new EventSource(`/api/runs/${encodeURIComponent(id)}/events`);
state.source = source;
source.onmessage = event => { try { const row = JSON.parse(event.data); if (row.step) addTrace(row); } catch { /* Keep valid stored trace if a malformed row arrives. */ } };
source.addEventListener("done", event => {
try { const result = JSON.parse(event.data); if (result.status === "error") notice("The run ended with an error. Review the trace before using its results.", true); } catch { /* The displayed stored trace remains available. */ }
source.close(); if (state.source === source) state.source = null;
});
source.onerror = () => { source.close(); if (state.source === source) state.source = null; };
}
function renderBattlecard(run) {
const card = run.battlecard;
$("copy-battlecard").disabled = !card;
if (!card) { $("battlecard-content").innerHTML = 'No battlecard is available for this run. Verified change receipts remain available above.
'; return; }
const story = state.stories.find(item => item.slug === run.story_slug);
const seller = (story?.our_company_name || "PivotWire seller").replace(/\s*\(fictional seller\)\s*$/i, "");
let html = `Prepared for ${esc(seller)}${run.story_slug === "sandbox" || runKind(run) === "synthetic" ? " (fictional seller)" : ""} · ${esc(provenanceLabel(run))}
${esc(card.headline)} ${esc(card.tl_dr)}
`;
if (run.announcement === null) html += 'Investigation unavailable ';
else if (run.announcement?.complete === false && run.announcement?.domains?.length) html += 'Investigation incomplete · no absence conclusion ';
if (card.what_changed?.length) html += `What changed ${card.what_changed.map(item => `${esc(item.summary)} `).join("")} `;
if (card.why_it_matters?.length) html += `Possible implications · inference ${card.why_it_matters.map(item => `
${esc(item.claim)} ${(item.urls || []).map(url => safeLink(url)).join(" ")}
`).join("")}
`;
if (card.talk_tracks?.length) html += `Conversation starter ${card.talk_tracks.map(item => `
${esc(item.situation)} “${esc(item.say_this)}”
`).join("")}
`;
if (card.objection_handlers?.length) html += `Objection responses ${card.objection_handlers.map(item => `${esc(item.objection)} ${esc(item.response)}
`).join("")} `;
if (card.landmine_questions?.length) html += `Questions to explore ${card.landmine_questions.map(item => `${esc(item)} `).join("")} `;
if (run.validator_notes?.length) html += `Validation notes ${run.validator_notes.map(item => `${esc(item)} `).join("")} `;
$("battlecard-content").innerHTML = html;
}
function renderInvestigation(run) {
const announcement = run.announcement;
const research = run.research || [];
const display = research.length > 0 || (announcement && (announcement.status !== "skipped" || announcement.domains?.length));
$("investigation-panel").hidden = !display;
if (!display) return;
const synthetic = runKind(run) === "synthetic";
$("investigation-kind").textContent = synthetic ? "SYNTHETIC RESEARCH REPLAY" : "RECORDED INVESTIGATION EVIDENCE";
$("investigation-mode").textContent = synthetic ? "Not live research" : runKind(run) === "live" ? "Source checks recorded" : "Replay";
let html = `${synthetic ? "Recorded synthetic fixture, not fresh research. " : "Review the recorded search scope and source timestamps. "}A quote match establishes text presence only; it does not establish that a claim is accurate or that an inferred motive is true.
`;
if (announcement?.status === "announced") {
html += `ANNOUNCED${synthetic ? " · SYNTHETIC SCENARIO" : " · WITHIN RECORDED SCOPE"}
${esc(announcement.quote)}
${safeLink(announcement.url, synthetic ? "Fictional announcement source" : "Announcement source")}${esc(announcement.page_date || "Date not recorded")}
`;
} else if (announcement?.status === "not_found") {
html += `NO ANNOUNCEMENT FOUND · ${synthetic ? "WITHIN THIS FIXTURE’S SCOPE" : "WITHIN RECORDED SEARCH SCOPE"}
This is a scoped search result, not proof that no announcement exists.
`;
} else html += 'INVESTIGATION UNAVAILABLE
';
if (announcement) html += `Domains ${esc((announcement.domains || []).join(", ") || "Not recorded")} Window ${esc(announcement.window || "Not recorded")} Searches ${(announcement.queries || []).map(q => `${esc(q.q)}${q.why ? ` — ${esc(q.why)}` : ""} `).join("") || "None recorded "} Stop reason ${esc(announcement.stop_reason || "Not recorded")} `;
if (announcement?.limitations?.length) html += `Coverage limits ${announcement.limitations.map(item => `${esc(item)} `).join("")} `;
for (const finding of research) {
html += `Possible intent · ${esc(finding.status)} ${esc(finding.summary)}
`;
for (const claim of finding.claims || []) html += `${claim.label === "quote-verified" ? (synthetic ? "Quote present in synthetic source" : "Quote present in source") : "Source linked · quote not verified"} ${esc(claim.claim)}
${claim.quote ? `
${esc(claim.quote)} ` : ""}${(claim.urls || []).map(url => safeLink(url, synthetic ? "Synthetic source" : "Cited source")).join(" ")}
`;
}
$("investigation-content").innerHTML = html;
}
function renderDiff(diff) {
const substantive = diff?.substantive || [];
$("raw-diff-panel").hidden = !substantive.length;
$("raw-diff-count").textContent = `${substantive.length} blocks`;
$("raw-diff-content").innerHTML = substantive.map(item => `${esc(item.before || "[absent before]")} ${esc(item.after || "[absent after]")} `).join("");
}
async function loadAlerts() {
let alerts = [];
try { const response = await api("/api/demo/alerts"); alerts = Array.isArray(response) ? response : response.alerts || response.items || []; }
catch { if (state.run?.local_alert) alerts = [state.run.local_alert]; }
if (!alerts.length && state.run?.local_alert) alerts = [state.run.local_alert];
if (!alerts.length) { $("alerts-content").innerHTML = 'No local alert has been recorded. Check the run trace for its gate or delivery result.
'; return; }
const ordered = [...alerts].sort((a,b) => String(b.created_at || b.ts || "").localeCompare(String(a.created_at || a.ts || ""))).slice(0,5);
$("alerts-content").innerHTML = ordered.map(item => {
const changes = Array.isArray(item.changes) ? item.changes.map(change => `${change.plan || "Add-on"}: ${label(change.type)} (${change.before ?? "not listed"} → ${change.after ?? "not listed"})`).join("\n") : "";
const text = item.message || item.text || item.body || item.summary || changes || (typeof item === "string" ? item : "Verified change recorded in the local alert ledger.");
return `✓ RECORDED LOCALLY · SYNTHETIC ${esc(item.title || "Acme pricing change")} ${esc(text)}
${esc(time(item.created_at || item.ts))}${item.run_id ? ` · ${esc(item.run_id)}` : ""}
`;
}).join("");
}
async function openReceipt(eventId, side) {
const event = state.run?.events?.find(item => item.id === eventId);
const evidence = event?.[`${side}_evidence`];
const snapshotRef = state.run?.[side];
if (!evidence || !snapshotRef) return;
try {
const snapshot = await api(`/api/snapshots/${encodeURIComponent(snapshotRef.id)}`);
state.receipt = {eventId, side, snapshot, evidence};
$("receipt-title").textContent = `${event.plan || "Add-on"} · ${label(event.type)}`;
const synthetic = runKind(state.run) === "synthetic";
$("receipt-side").textContent = `${side.toUpperCase()} RECEIPT · ${synthetic ? "SYNTHETIC SOURCE" : label(snapshot.source).toUpperCase()}`;
$("receipt-meta").innerHTML = `Status ${esc(evidence.status)}${evidence.reason ? ` · ${esc(evidence.reason)}` : ""} Source ${esc(snapshot.source)}${synthetic ? " · synthetic fixture" : ""} Fetched ${esc(time(snapshot.fetched_at))}${synthetic ? " · fixture metadata" : ""} Page ${safeLink(snapshot.url, snapshot.url)} SHA-256 ${esc(snapshot.sha256)} Span ${evidence.span ? `${esc(evidence.span[0])}–${esc(evidence.span[1])}` : "No verified span"} `;
$("receipt-quote").textContent = evidence.quote;
const text = snapshot.text || "";
const [start, end] = evidence.span || [-1,-1];
$("receipt-text").innerHTML = start >= 0 && end <= text.length && end > start ? `${esc(text.slice(0,start))}${esc(text.slice(start,end))} ${esc(text.slice(end))}` : esc(text);
$("tamper-result").hidden = true;
$("tamper-result").innerHTML = "";
$("tamper-button").hidden = !/\d/.test(evidence.quote || "") || evidence.status !== "verified";
$("tamper-button").disabled = false;
$("tamper-button").textContent = "Run tamper test";
$("receipt-dialog").showModal();
requestAnimationFrame(() => {
const mark = $("receipt-highlight");
if (mark) { const box = $("receipt-text"); box.scrollTop = mark.offsetTop - box.offsetTop - box.clientHeight / 3; }
});
} catch (error) { notice(`Receipt unavailable: ${error.message}`, true); }
}
async function tamperTest() {
if (!state.receipt || !state.run) return;
$("tamper-button").disabled = true;
$("tamper-button").textContent = "Checking…";
try {
const result = await api(`/api/runs/${encodeURIComponent(state.run.id)}/tamper`, {method:"POST", body:JSON.stringify({event_id:state.receipt.eventId, side:state.receipt.side})});
const rejected = result.verdict === "rejected";
$("tamper-result").hidden = false;
$("tamper-result").innerHTML = `ORIGINAL · ${result.original?.found ? "FOUND" : "NOT FOUND"} ${esc(result.original?.quote)}
Checked against the stored snapshot. TAMPERED · ${rejected ? "REJECTED" : "ACCEPTED — REVIEW REQUIRED"} ${esc(result.tampered?.quote)}
${rejected ? "Not on the page. This quote would be dropped." : "Unexpected result: the corrupted quote was accepted."} `;
$("tamper-result").scrollIntoView({behavior:"smooth", block:"nearest"});
} catch (error) {
if (error.status === 409) $("tamper-button").hidden = true;
$("tamper-result").hidden = false;
$("tamper-result").innerHTML = ``;
} finally { $("tamper-button").disabled = false; $("tamper-button").textContent = "Run tamper test again"; }
}
async function copyBattlecard() {
const card = state.run?.battlecard;
if (!card) return;
const content = [provenanceLabel(state.run) + (state.run.story_slug === "sandbox" || runKind(state.run) === "synthetic" ? " — fictional sandbox competitor and seller" : ""), card.headline, card.tl_dr, "", ...(card.what_changed || []).map(item => `• ${item.summary}`), "", ...(card.talk_tracks || []).map(item => `${item.situation}: ${item.say_this}`), "", `Receipts: ${location.origin}/#run=${state.run.id}`, (runKind(state.run) === "synthetic" ? "Research in this demonstration is a synthetic replay, not a live investigation." : "Review source timestamps and recorded scope. Quote presence does not establish claim accuracy."), `Alert: ${deliveryLabel(state.run).title}. ${deliveryLabel(state.run).note}`].join("\n");
try { await navigator.clipboard.writeText(content); $("copy-battlecard").textContent = "Copied"; setTimeout(() => { $("copy-battlecard").textContent = "Copy brief"; }, 1800); }
catch { notice("Clipboard access is unavailable in this browser. Select the brief text to copy it.", true); }
}
function liveMessage(message, error = false) {
$("live-message").textContent = message;
$("live-message").classList.toggle("error", error);
}
function renderLiveControls() {
const ready = live.readiness;
const sandbox = ready?.sandbox || {};
const connected = Boolean(live.token && ready);
const occupied = Boolean(sandbox.warming || sandbox.in_flight_run_id || live.runId);
const disabled = !connected || !ready.can_run || live.busy || occupied || state.busy;
$("live-gate").textContent = ready?.live_status || live.publicStatus;
$("live-status").textContent = `You.com: ${ready?.live_status || live.publicStatus}${ready?.reasoning_mode === "research" ? " · Research reasoning" : ready?.reasoning_mode === "router" ? " · Router reasoning" : ""}`;
$("live-connect").disabled = live.busy || state.busy;
$("live-forget").disabled = !live.token;
$("live-refresh").disabled = !live.token || live.busy || live.polling || state.busy;
$("live-selftest").disabled = disabled;
$("live-warm").disabled = disabled;
for (const id of ["live-reset", "live-price", "live-publish", "live-check"]) $(id).disabled = disabled || !ready?.baseline_ready;
$("run-demo").disabled = state.busy || live.busy || Boolean(live.runId);
$("live-blockers").innerHTML = (ready?.blockers || []).map(reason => `${esc(reason)} `).join("");
$("live-state").textContent = connected ? `Baseline: ${ready.baseline_ready ? "ready" : "not warmed"} · Page: ${sandbox.version || "unknown"} · Pro: $${sandbox.pro_price ?? "?"} · ${sandbox.warming ? "Warming" : sandbox.in_flight_run_id ? "Running " + sandbox.in_flight_run_id : "Idle"}${sandbox.error ? " · Last error: " + sandbox.error : ""}` : "No live workflow connected.";
}
function stopLivePoll() {
if (live.poll !== null) clearTimeout(live.poll);
live.poll = null;
}
function forgetLive(message = "Token forgotten. Any server operation already started may still be running.", error = false) {
live.epoch += 1;
live.controller?.abort();
live.controller = null;
stopLivePoll();
if (live.runId) { state.source?.close(); state.source = null; }
live.token = ""; live.readiness = null; live.busy = false; live.polling = false; live.runId = null;
$("admin-token").value = "";
liveMessage(message, error);
renderLiveControls();
}
async function liveApi(path, options = {}) {
if (!live.token) throw new Error("Connect with the admin token first.");
const controller = new AbortController();
live.controller = controller;
const timeout = setTimeout(() => controller.abort(), options.method === "POST" ? 120000 : 15000);
try {
return await api(path, {...options, signal:controller.signal, headers:{"X-Admin-Token":live.token}});
} catch (error) {
if (error.name === "AbortError") throw new Error("Request timed out or was disconnected. Refresh status before retrying; the server may still be working.");
throw error;
} finally {
clearTimeout(timeout);
if (live.controller === controller) live.controller = null;
}
}
async function readReadiness(epoch) {
const readiness = await liveApi("/api/live/readiness");
if (epoch !== live.epoch) return null;
live.readiness = readiness;
live.publicStatus = readiness.live_status;
renderLiveControls();
return readiness;
}
async function connectLive(event) {
event.preventDefault();
if (live.busy || state.busy || !$("live-auth-form").reportValidity()) return;
const token = $("admin-token").value.trim();
if (!token) return;
forgetLive("Checking configuration; no provider request is being made.");
live.token = token;
await refreshLive();
}
async function refreshLive() {
if (!live.token || live.busy || live.polling || state.busy) return;
stopLivePoll();
const epoch = live.epoch;
live.busy = true; renderLiveControls();
try {
const ready = await readReadiness(epoch);
if (!ready) return;
liveMessage(ready.can_run ? "Connected. Review readiness below before starting a live action." : `Connected · ${ready.live_status}. Resolve the listed prerequisites before live requests.`);
if (ready.sandbox?.error) liveMessage(`Last live attempt failed: ${ready.sandbox.error}. The last good baseline is retained.`, true);
if (ready.sandbox?.in_flight_run_id) { live.attempts = 60; live.deadline = Date.now() + 120000; watchLiveRun(ready.sandbox.in_flight_run_id); }
else if (live.runId) await finishLiveRun(ready, epoch);
} catch (error) {
if (epoch !== live.epoch) return;
if (error.status === 401) forgetLive("Authentication failed. Enter the server’s valid admin token to reconnect.", true);
else { live.readiness = null; liveMessage(error.message, true); }
} finally {
if (epoch === live.epoch) { live.busy = false; renderLiveControls(); }
}
}
function clearRunForLive(message) { clearRunForPending(message); }
function clearRunForPending(message, synthetic = false) {
state.source?.close(); state.source = null; state.run = null; state.receipt = null; state.trace.clear();
$("receipt-dialog").close();
$("mode-label").textContent = synthetic ? "SYNTHETIC OFFLINE DEMO · RUNNING" : "LIVE WORKFLOW · NO RESULT YET";
$("mode-detail").textContent = synthetic ? "Fictional pages. Real verification code. No provider calls." : "Previous results cleared. Waiting for this operation.";
$("events-container").hidden = true;
$("events-empty").hidden = false;
$("events-empty").innerHTML = `${synthetic ? "Synthetic comparison in progress" : "No live result yet"} ${esc(message)}
`;
$("run-banner").hidden = true;
$("event-count").textContent = synthetic ? "Awaiting synthetic result" : "Awaiting live result";
$("diff-summary").textContent = "Only a completed run can supply comparison results.";
for (const id of ["metric-receipts", "metric-events", "metric-claims"]) $(id).textContent = "—";
$("metric-alert").textContent = "Not recorded";
$("metric-alert-note").textContent = synthetic ? "Synthetic alert only · no Slack delivery" : "No delivery result for this operation";
$("copy-battlecard").disabled = true;
$("battlecard-content").innerHTML = 'No brief for this operation yet.
';
$("investigation-panel").hidden = true;
$("raw-diff-panel").hidden = true;
$("trace-list").innerHTML = `Waiting for ${synthetic ? "synthetic verification" : "a live comparison run"}. `;
document.querySelector(".trace-light").classList.remove("active");
$("run-reference").textContent = synthetic ? "No completed synthetic run" : "No completed live run";
history.replaceState(null, "", location.pathname + location.search);
notice("");
}
function watchLiveRun(id) {
stopLivePoll();
if (live.runId !== id) {
clearRunForLive("Following the live sandbox comparison. A failure will not reuse demonstration results.");
live.runId = id;
live.attempts = 60;
live.deadline = Date.now() + 120000;
connectTrace(id);
}
liveMessage(`Live comparison running: ${id}`);
renderLiveControls();
const epoch = live.epoch;
live.poll = setTimeout(() => pollLiveRun(epoch), 2000);
}
async function finishLiveRun(ready, epoch) {
const id = live.runId;
if (!id) return;
const sandbox = ready.sandbox || {};
stopLivePoll();
live.runId = null;
state.source?.close(); state.source = null;
if (sandbox.error) {
liveMessage(`Live comparison failed: ${sandbox.error}. No new result is shown; the last good baseline is retained.`, true);
notice("Live comparison failed. Review the trace and refresh status before retrying.", true);
} else if (sandbox.last_run_id === id) {
if (!await loadRun(id, () => epoch === live.epoch)) return;
if (epoch !== live.epoch) return;
history.replaceState(null, "", `#run=${encodeURIComponent(id)}`);
liveMessage(`Live comparison completed. ${deliveryLabel(state.run).title}: ${deliveryLabel(state.run).note}.`);
notice("Live sandbox result loaded. Inspect source receipts and the recorded delivery outcome.");
} else {
liveMessage("The operation is no longer in flight, but no completed result was found. The server may have restarted; refresh before retrying.", true);
}
renderLiveControls();
}
async function pollLiveRun(epoch) {
live.poll = null;
if (epoch !== live.epoch || !live.token || !live.runId || live.polling) return;
live.polling = true;
renderLiveControls();
try {
const ready = await readReadiness(epoch);
if (!ready) return;
if (!ready.sandbox?.in_flight_run_id) { await finishLiveRun(ready, epoch); return; }
if (ready.sandbox.in_flight_run_id !== live.runId) throw new Error("Another run is now active. Refresh status to follow it.");
if (--live.attempts <= 0 || Date.now() >= live.deadline) {
liveMessage("Automatic status checks stopped at the polling limit. The server may still be running; use Refresh status to continue.", true);
return;
}
live.poll = setTimeout(() => pollLiveRun(epoch), 2000);
} catch (error) {
if (epoch !== live.epoch) return;
if (error.status === 401) forgetLive("Authentication expired. Reconnect to follow the server operation.", true);
else { live.readiness = null; liveMessage(`Status unavailable: ${error.message} Refresh before retrying.`, true); renderLiveControls(); }
} finally {
if (epoch === live.epoch) { live.polling = false; renderLiveControls(); }
}
}
async function liveAction(action) {
if ($("live-" + action).disabled) return;
const price = Number($("live-price").value);
if (action === "publish" && (!Number.isInteger(price) || price < 13 || price > 99)) { liveMessage("Choose a whole-dollar Pro price from $13 to $99.", true); return; }
const epoch = live.epoch;
stopLivePoll();
live.busy = true;
clearRunForLive("Waiting for the requested live operation.");
liveMessage(`Running ${action === "selftest" ? "freshness check" : action}…`);
renderLiveControls();
let result;
try {
const path = action === "selftest" ? "/api/selftest" : `/api/sandbox/${action === "publish" ? "version" : action}`;
result = await liveApi(path, {method:"POST", ...(action === "publish" ? {body:JSON.stringify({version:"v2", pro_price:price})} : {})});
if (epoch !== live.epoch) return;
if (action === "selftest") {
const passed = result.contents_freshness === "PASS";
liveMessage(passed ? "Freshness passed. Reasoning remains a separate funded probe; no comparison run was created." : "Freshness check failed. Do not treat this as a live validation pass.", !passed);
} else if (action === "warm") {
if (result.status !== "PASS") throw new Error("Warm-up did not confirm a validated baseline.");
liveMessage(`Live baseline warmed with ${result.events} verified event types. Choose a new price to compare.`);
} else if (action === "reset") liveMessage("Sandbox reset to its warmed v1 baseline. No new comparison or alert was produced.");
else if (!result.run_id) liveMessage("This page version was already processed. No new run or alert was created; reset before repeating the same change.");
const ready = await readReadiness(epoch);
if (ready && result.run_id) watchLiveRun(result.run_id);
} catch (error) {
if (epoch !== live.epoch) return;
live.readiness = null;
if (error.status === 401) forgetLive("Authentication failed. Reconnect before live actions.", true);
else liveMessage(`${error.message} No successful result is claimed. Refresh status before retrying.`, true);
} finally {
if (epoch === live.epoch) { live.busy = false; renderLiveControls(); }
}
}
async function initialize() {
$("live-auth-form").addEventListener("submit", connectLive);
$("live-forget").addEventListener("click", () => forgetLive());
$("live-refresh").addEventListener("click", () => refreshLive());
for (const action of ["selftest", "warm", "reset", "publish", "check"]) $("live-" + action).addEventListener("click", () => liveAction(action));
$("demo-form").addEventListener("submit", runDemo);
$("pro-price").addEventListener("input", () => { $("price-art").textContent = $("pro-price").value || "?"; });
$("events-container").addEventListener("click", event => { const button = event.target.closest("[data-event]"); if (button) openReceipt(button.dataset.event, button.dataset.side); });
$("close-receipt").addEventListener("click", () => $("receipt-dialog").close());
$("receipt-dialog").addEventListener("click", event => { if (event.target !== $("receipt-dialog")) return; const rect = event.target.getBoundingClientRect(); if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) event.target.close(); });
$("tamper-button").addEventListener("click", tamperTest);
$("copy-battlecard").addEventListener("click", copyBattlecard);
const [status, health, stories] = await Promise.allSettled([api("/api/status"), api("/healthz"), api("/api/stories")]);
if (status.status === "fulfilled") live.publicStatus = status.value.live_status || "UNAVAILABLE";
renderLiveControls();
if (health.status === "fulfilled") $("commit").textContent = String(health.value.commit || "local").slice(0,8);
if (stories.status === "fulfilled") state.stories = Array.isArray(stories.value) ? stories.value : stories.value.stories || [];
const match = location.hash.match(/^#run=(.+)$/);
if (match) { try { await loadRun(decodeURIComponent(match[1])); } catch(error) { notice(`Could not open this run: ${error.message}`, true); } }
else await loadAlerts();
window.addEventListener("hashchange", async () => { const m = location.hash.match(/^#run=(.+)$/); if (m && decodeURIComponent(m[1]) !== state.run?.id) { try { await loadRun(decodeURIComponent(m[1])); } catch(error) { notice(error.message, true); } } });
window.addEventListener("pagehide", () => { forgetLive(); state.source?.close(); });
}
initialize().catch(error => notice(`Dashboard could not initialize: ${error.message}`, true));