AEGISLAYER/runtime-state-visualizer
0
1const datasetMap = {2 "policy-playground": {3 label: "Policy scenario",4 kind: "scenario",5 rows: [6 { name: "Low-risk allow", summary: "Identity, authority, policy, and connector checks align.", detail: { outcome: "allow", approval: "not_required", reason: "policy_and_authority_match" }, tags: ["allow", "low-risk", "deterministic"] },7 { name: "Unauthorized deny", summary: "Authority mismatch denies execution before connector use.", detail: { outcome: "deny", approval: "not_reached", reason: "authority_scope_mismatch" }, tags: ["deny", "fail-closed", "identity"] },8 { name: "High-impact approval required", summary: "Policy requires a bounded approval before execution.", detail: { outcome: "conditional", approval: "required", reason: "high_impact_requires_approval" }, tags: ["approval", "high-impact"] },9 { name: "Connector unavailable", summary: "A blocked connector halts execution.", detail: { outcome: "deny", approval: "not_reached", reason: "connector_not_ready" }, tags: ["connector", "deny"] },10 { name: "Capability expired", summary: "Capability expiry revokes execution authority mid-flight.", detail: { outcome: "revoke", approval: "granted_then_expired", reason: "capability_expired" }, tags: ["revocation", "continuous-verification"] },11 { name: "Containment triggered", summary: "Incident handling forces containment and review.", detail: { outcome: "contain", approval: "review_required", reason: "incident_containment_triggered" }, tags: ["containment", "incident"] }12 ]13 },14 "evidence-chain-explorer": {15 label: "Evidence event",16 kind: "evidence",17 rows: [18 { name: "request_created", summary: "Request id and intent recorded.", detail: { record_type: "request", correlation: "REQ-001" }, tags: ["request", "correlation"] },19 { name: "identity_validated", summary: "Identity and authority bindings recorded.", detail: { record_type: "identity", actor: "user-1" }, tags: ["identity", "authority"] },20 { name: "policy_evaluated", summary: "Policy decision and rationale appended.", detail: { record_type: "policy", decision: "conditional" }, tags: ["policy", "rationale"] },21 { name: "approval_recorded", summary: "Approver, scope, expiry, and outcome captured.", detail: { record_type: "approval", approved: true }, tags: ["approval", "scope"] },22 { name: "runtime_transition", summary: "Execution and connector context logged.", detail: { record_type: "runtime", state: "executing" }, tags: ["runtime", "connector"] },23 { name: "bundle_finalized", summary: "Bundle integrity and completeness summary generated.", detail: { record_type: "evidence", finalized: true }, tags: ["finalized", "integrity"] }24 ]25 },26 "threat-control-explorer": {27 label: "Threat family",28 kind: "threat",29 rows: [30 { name: "Unauthorized execution", summary: "Prevent action without explicit authority.", detail: { control: "Identity-first authorization", adr: "ADR-0002", residual_risk: "Stale authority data remains a timing risk." }, tags: ["authorization", "zero-trust"] },31 { name: "Approval bypass", summary: "High-impact execution requires accountable approval.", detail: { control: "Human approval for high-impact actions", adr: "ADR-0007", residual_risk: "Approver fatigue can still weaken review quality." }, tags: ["approval", "accountability"] },32 { name: "Connector abuse", summary: "Capability scoping narrows connector privileges.", detail: { control: "Capability-scoped connectors", adr: "ADR-0005", residual_risk: "Trusted connectors may still misbehave beyond visible state." }, tags: ["connector", "scope"] },33 { name: "Trust drift", summary: "Continuous verification revokes on degraded posture.", detail: { control: "Continuous verification", adr: "ADR-0006", residual_risk: "Signal quality determines detection speed." }, tags: ["runtime", "monitoring"] }34 ]35 },36 "connector-trust-simulator": {37 label: "Connector",38 kind: "connector",39 rows: [40 { name: "analytics", summary: "Ready connector with scoped report-read capability.", detail: { readiness: "ready", scope: "read_report", outcome: "allow" }, tags: ["ready", "allow"] },41 { name: "ops", summary: "Blocked readiness causes fail-closed denial.", detail: { readiness: "blocked", scope: "delete_resource", outcome: "deny" }, tags: ["blocked", "deny"] },42 { name: "content", summary: "Trust drift revokes a valid publishing capability.", detail: { readiness: "ready", scope: "publish_content", outcome: "revoke" }, tags: ["revoke", "trust-drift"] }43 ]44 },45 "runtime-state-visualizer": {46 label: "Runtime state",47 kind: "runtime",48 rows: [49 { name: "requested", summary: "Intent recorded with no execution authority granted.", detail: { next: ["identity_validated"] }, tags: ["requested"] },50 { name: "identity_validated", summary: "Identity and authority resolved before policy branch.", detail: { next: ["approval_pending", "executing", "denied"] }, tags: ["identity"] },51 { name: "approval_pending", summary: "Approval holds the request in a bounded waiting state.", detail: { next: ["executing", "denied"] }, tags: ["approval"] },52 { name: "executing", summary: "Connector trust and capability remain continuously verified.", detail: { next: ["completed", "revoked", "contained"] }, tags: ["executing"] },53 { name: "revoked", summary: "Execution authority removed due to expiry or drift.", detail: { next: ["contained", "closed"] }, tags: ["revoked"] },54 { name: "contained", summary: "Incident response isolates the request pending decision.", detail: { next: ["completed", "closed"] }, tags: ["contained"] },55 { name: "completed", summary: "Execution finished within bounds and evidence finalized.", detail: { next: [] }, tags: ["completed"] }56 ]57 },58 "governance-library": {59 label: "Library entry",60 kind: "library",61 rows: [62 { name: "ADR 0001", summary: "Separate AI reasoning from execution authority.", detail: { url: "https://vsdatta.github.io/aegislayer-architecture/adr/0001-separate-ai-reasoning-from-execution-authority/" }, tags: ["adr", "authority"] },63 { name: "ADR 0003", summary: "Evidence by design as a reviewability anchor.", detail: { url: "https://vsdatta.github.io/aegislayer-architecture/adr/0003-evidence-by-design/" }, tags: ["adr", "evidence"] },64 { name: "Pattern Library", summary: "Reference patterns and anti-patterns.", detail: { url: "https://vsdatta.github.io/aegislayer-architecture/PATTERN_LIBRARY/" }, tags: ["patterns"] },65 { name: "Glossary", summary: "Shared terminology and definitions.", detail: { url: "https://vsdatta.github.io/aegislayer-architecture/GLOSSARY/" }, tags: ["glossary"] }66 ]67 }68};69 70function renderTags(tags) {71 return `<div class="tag-row">${tags.map((tag) => `<span class="tag">${tag}</span>`).join("")}</div>`;72}73 74function renderDetail(detail) {75 return `<pre class="code-block">${JSON.stringify(detail, null, 2)}</pre>`;76}77 78function buildInteractiveRegion(spaceKey) {79 const region = document.getElementById("interactive-region");80 if (!region) {81 return;82 }83 84 const config = datasetMap[spaceKey];85 if (!config) {86 region.innerHTML = `87 <article class="interactive-card">88 <h3>Static Portfolio</h3>89 <p>This Space is intentionally static and uses cross-linked repository content rather than live interactions.</p>90 </article>91 `;92 return;93 }94 95 region.innerHTML = `96 <div class="interactive-card selector-row">97 <label for="record-select">Select ${config.label.toLowerCase()}</label>98 <select id="record-select"></select>99 </div>100 <article class="interactive-card">101 <h3 id="record-title"></h3>102 <p id="record-summary"></p>103 <div id="record-tags"></div>104 <div id="record-detail"></div>105 </article>106 `;107 108 const select = document.getElementById("record-select");109 const title = document.getElementById("record-title");110 const summary = document.getElementById("record-summary");111 const tags = document.getElementById("record-tags");112 const detail = document.getElementById("record-detail");113 114 config.rows.forEach((row, index) => {115 const option = document.createElement("option");116 option.value = String(index);117 option.textContent = row.name;118 select.appendChild(option);119 });120 121 function renderRow(index) {122 const row = config.rows[index];123 title.textContent = row.name;124 summary.textContent = row.summary;125 tags.innerHTML = renderTags(row.tags);126 detail.innerHTML = renderDetail(row.detail);127 }128 129 select.addEventListener("change", () => renderRow(Number(select.value)));130 renderRow(0);131}132 133buildInteractiveRegion(document.body.dataset.space);134 