ironic-mirror / docs /app.js
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/ironic-mirror
677e207 verified
Raw History Blame Contribute Delete
17.8 kB
import { CHECKPOINTS, EVENTS, HAZARDS, OBJECTIVES, TOOLS, deriveSnapshot } from './simulation.mjs';
import { createWasmBoundary } from './wasm-boundary.mjs';
const $ = selector => document.querySelector(selector);
const $$ = selector => [...document.querySelectorAll(selector)];
const esc = value => String(value)
.replaceAll('&', '&')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#039;');
const GRAPH_PHASES = ['OBSERVE', 'ANALYZE', 'PLAN', 'EXECUTE', 'VERIFY', 'COMMIT'];
let cursor = 0;
let playing = false;
let timer = null;
let selection = { kind: 'agent', id: 'primus' };
function eventPhase(event) {
if (event.type === 'OBSERVE' || event.type === 'SCAN' || event.type === 'DISCOVER') return 'OBSERVE';
if (event.type === 'REASON' || event.type === 'FAILURE' || event.type === 'RECOVERY' || event.type === 'HAZARD_DETECTED') return 'ANALYZE';
if (event.type === 'PLAN' || event.type === 'REROUTE') return 'PLAN';
if (event.type === 'MOVE' || event.type === 'TOOL_CALL' || event.type === 'ACTION') return 'EXECUTE';
if (event.type === 'VERIFICATION') return 'VERIFY';
if (event.type === 'CHECKPOINT' || event.type === 'COMPLETE') return 'COMMIT';
return 'OBSERVE';
}
function point([x, y]) {
return [x * 10, y * 5.6];
}
function pathFrom(points) {
return points.map((coord, index) => {
const [x, y] = point([coord.x, coord.y]);
return `${index === 0 ? 'M' : 'L'} ${x.toFixed(1)} ${y.toFixed(1)}`;
}).join(' ');
}
function staticWorld() {
$('#planned-route').setAttribute('d', pathFrom(EVENTS.map(item => item.position)));
$('#timeline').max = String(EVENTS.length - 1);
$('#timeline-ticks').innerHTML = EVENTS.map(() => '<i></i>').join('');
$('#hazard-layer').innerHTML = HAZARDS.map(hazard => {
const [x, y] = point([hazard.x, hazard.y]);
const typeClass = hazard.shortType.toLowerCase();
return `<g class="hazard-hit type-${typeClass}" data-select="hazard" data-id="${esc(hazard.id)}" role="button" tabindex="0" aria-label="Select ${esc(hazard.type)} hazard: ${esc(hazard.label)}" transform="translate(${x} ${y})">
<circle class="hazard-pulse" cx="0" cy="0" r="23"></circle>
<circle class="hazard-ring" cx="0" cy="0" r="16"></circle>
<text class="hazard-symbol" x="0" y="0">${esc(hazard.glyph)}</text>
<text class="hazard-name" x="0" y="31">${esc(hazard.shortType)}</text>
</g>`;
}).join('');
$('#checkpoint-layer').innerHTML = CHECKPOINTS.map(checkpoint => {
const [x, y] = point([checkpoint.x, checkpoint.y]);
return `<g class="checkpoint-hit" data-select="checkpoint" data-id="${esc(checkpoint.id)}" role="button" tabindex="0" aria-label="Select ${esc(checkpoint.label)}" transform="translate(${x} ${y})">
<circle cx="0" cy="0" r="13"></circle><circle class="checkpoint-core" cx="0" cy="0" r="4"></circle>
<text x="0" y="27">${esc(checkpoint.label.replace('CHECKPOINT ', 'CP '))}</text>
</g>`;
}).join('');
}
function renderInspector(snapshot) {
const current = snapshot.current;
const hazard = selection.kind === 'hazard' ? HAZARDS.find(item => item.id === selection.id) : null;
const checkpoint = selection.kind === 'checkpoint' ? CHECKPOINTS.find(item => item.id === selection.id) : null;
let heading = 'PRIMUS';
let subheading = 'DETERMINISTIC BROWSER AGENT';
let glyph = '✦';
let rows;
let foot;
if (hazard) {
heading = hazard.shortType;
subheading = hazard.label;
glyph = hazard.glyph;
const isActive = snapshot.activeHazards.some(item => item.id === hazard.id);
rows = [
['TYPE', hazard.type, 'acid'],
['SEVERITY', hazard.severity, hazard.severity === 'CRITICAL' ? 'red' : 'orange'],
['TRIGGER', hazard.trigger, ''],
['RESPONSE', hazard.response, 'cyan'],
['STATUS', isActive ? (current.hazardId === hazard.id ? 'ENCOUNTERED' : 'ACTIVE') : 'DORMANT', isActive ? 'orange' : ''],
];
foot = `This hazard is a simulated boundary. Select an event to inspect the exact state at detection.`;
$('#selection-chip').textContent = 'HAZARD';
} else if (checkpoint) {
heading = checkpoint.label;
subheading = 'VERIFIED STATE MARKER';
glyph = '◎';
const active = checkpoint.eventIndex <= snapshot.index;
rows = [
['EVENT', `#${String(checkpoint.eventIndex + 1).padStart(2, '0')}`, 'cyan'],
['POSITION', `${checkpoint.x} / ${checkpoint.y}`, ''],
['STATUS', active ? 'ACTIVE' : 'AHEAD', active ? 'acid' : ''],
['INVARIANT', active ? 'XREX-04 PASS' : 'PENDING', active ? 'acid' : 'orange'],
['SEALED BY', active ? 'REPLAY TRACE' : '—', ''],
];
foot = active ? 'The world remembers this verified transition and keeps it available during replay.' : 'This checkpoint has not been reached at the selected event.';
$('#selection-chip').textContent = 'CHECKPOINT';
} else if (selection.kind === 'event') {
heading = current.type;
subheading = `EVENT #${String(current.index + 1).padStart(2, '0')} / EXACT SNAPSHOT`;
glyph = current.verification === 'fail' ? '!' : current.verification === 'pass' ? '✓' : '·';
rows = [
['TIMESTAMP', current.timestamp, 'cyan'],
['ACTION', current.action, ''],
['TOOL', current.tool, 'cyan'],
['POSITION', `${current.position.x} / ${current.position.y}`, ''],
['STRAIN', `${current.strain}%`, current.strain > 70 ? 'red' : 'orange'],
];
foot = current.note;
$('#selection-chip').textContent = 'EVENT';
} else {
rows = [
['CURRENT STATE', current.state, 'acid'],
['CURRENT TOOL', current.tool, 'cyan'],
['POSITION', `${current.position.x} / ${current.position.y}`, ''],
['STRAIN', `${current.strain}%`, current.strain > 70 ? 'red' : 'orange'],
['RISK', current.risk, current.risk === 'CRITICAL' ? 'red' : current.risk === 'HIGH' ? 'orange' : 'acid'],
['INVARIANT', current.verification === 'pass' ? 'XREX-04 / VALID' : 'XREX-04 / GATED', current.verification === 'pass' ? 'acid' : 'orange'],
];
foot = 'PRIMUS is a simulated agent. Tools are allowlisted capabilities; the repository is not executed by this page.';
$('#selection-chip').textContent = 'AGENT';
}
$('#inspector-content').innerHTML = `<div class="inspector-entity"><div><h3>${esc(heading)}</h3><p>${esc(subheading)}</p></div><span class="entity-glyph">${esc(glyph)}</span></div>
<div class="inspector-rows">${rows.map(([label, value, color]) => `<div class="inspector-row"><span>${esc(label)}</span><strong class="${color}">${esc(value)}</strong></div>`).join('')}</div>
<div class="inspector-foot">${esc(foot)}</div>`;
}
function renderTrace(snapshot) {
$('#trace-count').textContent = `${String(snapshot.events.length).padStart(2, '0')} / ${EVENTS.length}`;
$('#trace-list').innerHTML = snapshot.events.map(item => {
const kind = item.type === 'FAILURE' || item.type === 'HAZARD_DETECTED' ? 'hazard' : item.type === 'VERIFICATION' || item.type === 'CHECKPOINT' ? 'verify' : '';
const status = item.verification === 'fail' ? '!' : item.type === 'REROUTE' ? '→' : item.type === 'CHECKPOINT' ? '◎' : item.verification === 'pass' || item.type === 'COMPLETE' ? '✓' : '·';
return `<button class="trace-item ${kind} ${item.index === snapshot.index ? 'is-current' : ''}" data-select="event" data-id="${item.index}" type="button" role="listitem" aria-label="Inspect event ${item.type}, ${item.timestamp}">
<span class="trace-time">${esc(item.timestamp)}</span><span class="trace-type">${esc(item.type)}</span><span class="trace-status">${status}</span><span class="trace-note">${esc(item.note)}</span>
</button>`;
}).join('');
}
function renderObjectives(snapshot) {
$('#objective-progress').textContent = `${snapshot.completedObjectives} / ${OBJECTIVES.length}`;
$('#objective-list').innerHTML = OBJECTIVES.map((objective, index) => {
const complete = index < snapshot.completedObjectives;
const current = index === snapshot.current.objective && !snapshot.isComplete;
return `<div class="objective ${complete ? 'is-complete' : ''} ${current ? 'is-current' : ''}"><span class="objective-marker">${complete ? '✓' : current ? '›' : ''}</span><span>${esc(objective)}</span><span class="objective-status">${complete ? 'DONE' : current ? 'NOW' : 'QUEUED'}</span></div>`;
}).join('');
}
function renderGraph(snapshot) {
const currentPhase = eventPhase(snapshot.current);
const phaseIndex = GRAPH_PHASES.indexOf(currentPhase);
$('#graph-track').innerHTML = GRAPH_PHASES.map((phase, index) => `<span class="graph-node ${index < phaseIndex ? 'is-complete' : ''} ${phase === currentPhase ? 'is-current' : ''} ${phase === 'ANALYZE' && snapshot.current.type === 'FAILURE' ? 'is-recovery' : ''}">${phase}</span>${index < GRAPH_PHASES.length - 1 ? '<i class="graph-arrow">→</i>' : ''}`).join('');
}
function renderTools(snapshot) {
const activeTool = snapshot.current.tool;
$('#tool-list').innerHTML = TOOLS.map(tool => {
let status = tool.status;
if (tool.name === activeTool) status = 'RUNNING';
else if (tool.status === 'RUNNING') status = snapshot.index >= 11 ? 'VERIFIED' : 'AVAILABLE';
const statusClass = status.toLowerCase();
return `<div class="tool-item status-${statusClass}"><span class="tool-light" aria-hidden="true"></span><span class="tool-name">${esc(tool.name)}</span><span class="tool-status">${esc(status)}</span></div>`;
}).join('');
const current = snapshot.current;
const toolState = current.type === 'TOOL_CALL' || current.type === 'ACTION' ? 'EXECUTED' : current.type === 'COMPLETE' ? 'SEALED' : 'IDLE';
const code = current.tool === 'IPython'
? `>>> analyze_state(world, tick=${snapshot.index})`
: `>>> ${current.tool.toLowerCase().replaceAll(' ', '_')}(snapshot)`;
const result = current.hazardId
? `constraint_detected = true\nrisk = ${current.risk.toLowerCase()}\nroute_candidates = ${Math.max(1, 4 - snapshot.mirror.collapsedRoutes)}`
: `state = "${current.state.toLowerCase()}"\nnetwork = false\ntransition = "${current.verification.toUpperCase()}"`;
$('#tool-call-state').textContent = toolState;
$('#tool-call-code').textContent = code;
$('#tool-call-result').textContent = result;
}
function renderGate(snapshot) {
const result = snapshot.current.verification;
const badge = $('#verification-badge');
const box = $('#gate-result-box');
const resultNode = $('#gate-result');
badge.className = `gate-badge ${result === 'pass' ? 'pass' : result === 'fail' ? 'fail' : 'pending'}`;
badge.textContent = result === 'pass' ? 'PASS' : result === 'fail' ? 'FAIL / BLOCKED' : 'PENDING';
box.className = `gate-result-box ${result === 'pass' ? 'pass' : result === 'fail' ? 'fail' : ''}`;
resultNode.className = `gate-node ${result === 'pass' ? 'pass' : result === 'fail' ? 'fail' : ''}`;
$('#gate-message').textContent = result === 'pass' ? 'XREX-04 holds. State transition: VALID.' : result === 'fail' ? 'Action blocked. Rerouting is required before the gate can pass.' : 'Awaiting a meaningful state transition.';
}
function renderWorld(snapshot) {
const current = snapshot.current;
const [x, y] = point([current.position.x, current.position.y]);
$('#trajectory-path').setAttribute('d', pathFrom(snapshot.path));
$('#agent').setAttribute('transform', `translate(${x} ${y})`);
$('#agent-hit-area').setAttribute('transform', `translate(${x} ${y})`);
$('#agent-action-label').textContent = current.action.toUpperCase();
$('#world-action').textContent = current.action;
$('#world-note').textContent = current.note;
$('#world-position').textContent = `${current.position.x} / ${current.position.y}`;
$('#world-risk').textContent = `RISK ${current.risk}`;
$('#world-state').textContent = current.state;
$('#event-counter').textContent = `EVENT ${String(snapshot.index + 1).padStart(2, '0')} / ${EVENTS.length}`;
$('#timeline-current').textContent = `${current.type} / T+${String(snapshot.index).padStart(2, '0')}`;
$('#timeline').value = String(snapshot.index);
$('#run-status').textContent = snapshot.isComplete ? 'MISSION COMPLETE' : playing ? 'PLAYING REPLAY' : `PAUSED / ${current.type}`;
$('#run-status').previousElementSibling.style.background = snapshot.isComplete ? 'var(--acid)' : playing ? 'var(--cyan)' : 'var(--orange)';
$('#world-svg-desc').textContent = `PRIMUS is ${current.state.toLowerCase()} at position ${current.position.x}, ${current.position.y}. Current action: ${current.action}. Strain ${current.strain} percent. ${snapshot.world.blockedPaths} route(s) blocked.`;
$$('#hazard-layer .hazard-hit').forEach(node => {
const hazardId = node.dataset.id;
const active = snapshot.activeHazards.some(item => item.id === hazardId);
node.classList.toggle('is-active', active);
node.classList.toggle('is-inactive', !active);
node.classList.toggle('is-selected', selection.kind === 'hazard' && selection.id === hazardId);
});
$$('#checkpoint-layer .checkpoint-hit').forEach(node => {
const active = snapshot.checkpoints.some(item => item.id === node.dataset.id);
node.classList.toggle('is-inactive', !active);
node.classList.toggle('is-selected', selection.kind === 'checkpoint' && selection.id === node.dataset.id);
});
}
function renderMetrics(snapshot) {
const current = snapshot.current;
$('#strain-value').textContent = `${current.strain}%`;
$('#strain-meter').style.width = `${current.strain}%`;
$('#confidence-value').textContent = `CONFIDENCE ${Math.round(current.confidence * 100)}%`;
$('#strain-caption').textContent = current.strain > 70 ? 'CRITICAL / PATH SENSITIVITY HIGH' : current.strain > 50 ? 'ELEVATED / SAFE ROUTES SHRINKING' : 'SAFE OPERATING ENVELOPE';
$('#probe-count').textContent = String(snapshot.mirror.probeCount);
$('#boundary-hardness').textContent = `${snapshot.mirror.boundaryHardness}%`;
$('#collapsed-routes').textContent = String(snapshot.mirror.collapsedRoutes);
$('#mirror-status').textContent = snapshot.mirror.status;
const counts = snapshot.world;
$('#world-safe').textContent = String(counts.safeZones);
$('#world-hazards').textContent = String(counts.hazards);
$('#world-checkpoints').textContent = String(counts.checkpoints);
$('#world-blocked').textContent = String(counts.blockedPaths);
$('#world-agent-count').textContent = String(counts.activeAgent);
}
function render(snapshot) {
renderWorld(snapshot);
renderInspector(snapshot);
renderTrace(snapshot);
renderObjectives(snapshot);
renderGraph(snapshot);
renderTools(snapshot);
renderGate(snapshot);
renderMetrics(snapshot);
}
function setCursor(next, announce = true) {
cursor = Math.min(EVENTS.length - 1, Math.max(0, Math.round(next)));
if (cursor >= EVENTS.length - 1) stop();
render(deriveSnapshot(cursor));
if (announce) $('#live-region').textContent = `PRIMUS ${EVENTS[cursor].type}. ${EVENTS[cursor].note}`;
}
function stop() {
playing = false;
if (timer !== null) {
window.clearInterval(timer);
timer = null;
}
$('#play-icon').textContent = '▶';
$('#play-label').textContent = 'PLAY';
}
function togglePlay() {
if (playing) {
stop();
render(deriveSnapshot(cursor));
return;
}
if (cursor >= EVENTS.length - 1) cursor = 0;
playing = true;
$('#play-icon').textContent = 'Ⅱ';
$('#play-label').textContent = 'PAUSE';
render(deriveSnapshot(cursor));
timer = window.setInterval(() => setCursor(cursor + 1), 850);
}
function select(kind, id) {
if (kind === 'event') {
selection = { kind, id: Number(id) };
setCursor(Number(id), false);
} else {
selection = { kind, id };
render(deriveSnapshot(cursor));
}
$('#live-region').textContent = `Selected ${kind} ${id}.`;
}
document.addEventListener('click', event => {
const target = event.target.closest('[data-select]');
if (target) select(target.dataset.select, target.dataset.id);
});
document.addEventListener('keydown', event => {
const target = event.target.closest('[data-select]');
if (target && (event.key === 'Enter' || event.key === ' ')) {
event.preventDefault();
select(target.dataset.select, target.dataset.id);
}
});
$('#agent-hit-area').addEventListener('click', () => select('agent', 'primus'));
$('#agent-hit-area').addEventListener('keydown', event => {
if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); select('agent', 'primus'); }
});
$('#play-toggle').addEventListener('click', togglePlay);
$('#step-back').addEventListener('click', () => { stop(); setCursor(cursor - 1); });
$('#step-forward').addEventListener('click', () => { stop(); setCursor(cursor + 1); });
$('#restart').addEventListener('click', () => { stop(); selection = { kind: 'agent', id: 'primus' }; setCursor(0); });
$('#timeline').addEventListener('input', event => { stop(); setCursor(event.target.value); });
document.addEventListener('keydown', event => {
if (event.target.matches('input, button')) return;
if (event.key === ' ') { event.preventDefault(); togglePlay(); }
if (event.key === 'ArrowLeft') { stop(); setCursor(cursor - 1); }
if (event.key === 'ArrowRight') { stop(); setCursor(cursor + 1); }
});
staticWorld();
render(deriveSnapshot(0));
createWasmBoundary().then(boundary => {
$('#wasm-status').textContent = boundary.status;
$('#wasm-status').title = `Deterministic gate implementation: ${boundary.implementation}`;
});