Skip to content

Commit 073ed21

Browse files
committed
Implement System B Consensus Engine core, register API routes, and add Developer Mode toggle with honest indicators
1 parent 42995be commit 073ed21

5 files changed

Lines changed: 205 additions & 38 deletions

File tree

dashboard/dashboard.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,3 +746,48 @@ document.getElementById("btn-run-simulation").addEventListener("click", async ()
746746
loadData();
747747
loadContinuityRecords();
748748
loadGovernanceData();
749+
750+
// Developer Mode Toggle initialization
751+
const devModeCheckbox = document.getElementById("dev-mode-checkbox");
752+
if (devModeCheckbox) {
753+
// Default to off (add dev-mode-off class to body)
754+
document.body.classList.add("dev-mode-off");
755+
devModeCheckbox.addEventListener("change", () => {
756+
if (devModeCheckbox.checked) {
757+
document.body.classList.remove("dev-mode-off");
758+
} else {
759+
document.body.classList.add("dev-mode-off");
760+
}
761+
});
762+
}
763+
764+
// Download Audit Report listener
765+
const downloadBtn = document.getElementById("btn-download-audit-report");
766+
if (downloadBtn) {
767+
downloadBtn.addEventListener("click", async () => {
768+
try {
769+
const data = await fetchJson("/api/dashboard-data");
770+
const consensus = await fetchJson("/api/operator/consensus-map");
771+
const report = {
772+
disclaimer: "WARNING: THIS REPORT IS A BEST-EFFORT RECONSTRUCTION AND IS NOT TAMPER-PROOF OR CRYPTOGRAPHICALLY SECURE.",
773+
generated_at: new Date().toISOString(),
774+
projection: data.projection,
775+
prompt_sources: data.prompt_sources,
776+
docs: data.docs,
777+
consensus_state: consensus
778+
};
779+
780+
const blob = new Blob([JSON.stringify(report, null, 2)], { type: "application/json" });
781+
const url = URL.createObjectURL(blob);
782+
const a = document.createElement("a");
783+
a.href = url;
784+
a.download = `dizzy-audit-report-${new Date().toISOString().slice(0, 10)}.json`;
785+
document.body.appendChild(a);
786+
a.click();
787+
document.body.removeChild(a);
788+
URL.revokeObjectURL(url);
789+
} catch (error) {
790+
alert("Failed to download audit report: " + error.message);
791+
}
792+
});
793+
}

dashboard/index.html

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,10 @@
745745
stroke-dashoffset: -1000;
746746
}
747747
}
748+
749+
body.dev-mode-off .dev-only {
750+
display: none !important;
751+
}
748752
</style>
749753
</head>
750754
<body>
@@ -756,7 +760,16 @@ <h2>Dizzy Calibration Playground</h2>
756760
<div class="title-sub">Drift & Epistemic Memory Dashboard</div>
757761
</div>
758762
</div>
759-
<span class="badge badge-emerald">Online</span>
763+
<div style="display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;">
764+
<button class="btn btn-secondary btn-small" id="btn-download-audit-report" style="padding: 0.35rem 0.6rem; font-size: 0.8rem;">
765+
📥 Download Audit Report
766+
</button>
767+
<label style="display: flex; align-items: center; gap: 0.4rem; font-size: 0.85rem; cursor: pointer; user-select: none; color: var(--text-muted);">
768+
<input type="checkbox" id="dev-mode-checkbox" style="accent-color: var(--primary);">
769+
Developer Mode
770+
</label>
771+
<span class="badge badge-emerald">Online</span>
772+
</div>
760773
</header>
761774

762775
<div class="grid">
@@ -899,7 +912,7 @@ <h3>Receipt</h3>
899912
<h3>Bounded Inference &amp; Routing Monitor</h3>
900913
<div id="routing-warning-banner"></div>
901914
<div class="field-stack" style="margin-top: 1rem;">
902-
<div class="metric-row">
915+
<div class="metric-row dev-only">
903916
<span class="metric-label">System Memory / VRAM:</span>
904917
<div class="progress-wrap">
905918
<div class="bar-container" style="width: 150px; height: 16px; border-radius: 8px;">
@@ -914,12 +927,12 @@ <h3>Bounded Inference &amp; Routing Monitor</h3>
914927
<span id="active-model-route" class="badge badge-primary" style="font-size: 0.85rem; padding: 0.35rem 0.75rem;">Loading...</span>
915928
</div>
916929

917-
<div class="metric-row">
930+
<div class="metric-row dev-only">
918931
<span class="metric-label">Routing Logic Basis:</span>
919932
<span id="active-routing-basis" style="color: var(--text-muted); font-size: 0.875rem;">Loading...</span>
920933
</div>
921934

922-
<div class="metric-row">
935+
<div class="metric-row dev-only">
923936
<span class="metric-label">Context Compression Ratio:</span>
924937
<div class="progress-wrap">
925938
<div class="bar-container" style="width: 150px; height: 16px; border-radius: 8px;">
@@ -983,7 +996,7 @@ <h3>Pluralistic Consensus &amp; Governance</h3>
983996
</div>
984997

985998
<!-- Sandbox Simulation Terminal (System C) -->
986-
<div class="console-panel console-panel-receipt">
999+
<div class="console-panel console-panel-receipt dev-only">
9871000
<h3>Sandbox Simulation Terminal</h3>
9881001
<div class="field-stack" style="margin-top: 1rem;">
9891002
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">

lib/consensus.mjs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import fs from "fs";
2+
import path from "path";
3+
4+
const STATE_FILE = path.resolve(process.cwd(), "runtime", "consensus_state.json");
5+
6+
const DEFAULT_OPTIONS = [
7+
{ option_id: "opt-1", description: "Local speculative serving path (preferred)", friction: "low" },
8+
{ option_id: "opt-2", description: "Quantized fall-back path", friction: "medium" },
9+
];
10+
11+
function ensureDir(dir) {
12+
if (!fs.existsSync(dir)) {
13+
fs.mkdirSync(dir, { recursive: true });
14+
}
15+
}
16+
17+
export function getConsensusState() {
18+
try {
19+
if (fs.existsSync(STATE_FILE)) {
20+
const content = fs.readFileSync(STATE_FILE, "utf8");
21+
return JSON.parse(content);
22+
}
23+
} catch (error) {
24+
console.error("Failed to read consensus state, resetting to default:", error.message);
25+
}
26+
27+
// Default state initialization
28+
const defaultState = {
29+
ok: true,
30+
signing_chain: {
31+
codex: "SIGNED",
32+
openclaude: "SIGNED",
33+
antigravity: "PENDING",
34+
},
35+
consensus_status: "Awaiting Operator",
36+
options: DEFAULT_OPTIONS,
37+
};
38+
saveConsensusState(defaultState);
39+
return defaultState;
40+
}
41+
42+
export function saveConsensusState(state) {
43+
try {
44+
ensureDir(path.dirname(STATE_FILE));
45+
// Write atomically using a temporary file to prevent torn-writes
46+
const tmpFile = `${STATE_FILE}.tmp`;
47+
fs.writeFileSync(tmpFile, JSON.stringify(state, null, 2), "utf8");
48+
fs.renameSync(tmpFile, STATE_FILE);
49+
return true;
50+
} catch (error) {
51+
console.error("Failed to save consensus state:", error);
52+
return false;
53+
}
54+
}
55+
56+
export function signOffOperator() {
57+
const state = getConsensusState();
58+
state.signing_chain.antigravity = "SIGNED";
59+
state.consensus_status = "Consensus Reached";
60+
saveConsensusState(state);
61+
return {
62+
ok: true,
63+
message: "Operator signed off successfully. Consensus reached.",
64+
signing_chain: state.signing_chain,
65+
consensus_status: state.consensus_status,
66+
};
67+
}
68+
69+
export function vetoOperator() {
70+
const state = getConsensusState();
71+
state.signing_chain.codex = "VETOED";
72+
state.signing_chain.openclaude = "VETOED";
73+
state.signing_chain.antigravity = "VETOED";
74+
state.consensus_status = "Vetoed";
75+
saveConsensusState(state);
76+
return {
77+
ok: true,
78+
message: "Operator veto override initiated. Reverting state commit...",
79+
signing_chain: state.signing_chain,
80+
consensus_status: state.consensus_status,
81+
};
82+
}
83+
84+
export function initializeNewProposal(options = DEFAULT_OPTIONS) {
85+
const newState = {
86+
ok: true,
87+
signing_chain: {
88+
codex: "SIGNED",
89+
openclaude: "SIGNED",
90+
antigravity: "PENDING",
91+
},
92+
consensus_status: "Awaiting Operator",
93+
options: options,
94+
};
95+
saveConsensusState(newState);
96+
return newState;
97+
}

lib/dashboard.mjs

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { fileURLToPath } from "url";
55
import { buildContinuityAudit, buildContinuityReport, deleteClientContinuity, exportClientContinuity } from "./client_continuity.mjs";
66
import { getIndex, getRelevantMarkdownSnippets } from "./md_retriever.mjs";
77
import { getPromptSources } from "./prompt_bundle.mjs";
8+
import { getConsensusState, signOffOperator, vetoOperator } from "./consensus.mjs";
89

910
const DEFAULT_DASHBOARD_ASSET = fileURLToPath(new URL("../dashboard/index.html", import.meta.url));
1011
const DEFAULT_DASHBOARD_SCRIPT_ASSET = fileURLToPath(new URL("../dashboard/dashboard.js", import.meta.url));
@@ -243,19 +244,7 @@ export function registerDashboardRoutes(app, options) {
243244

244245
app.get("/api/operator/consensus-map", guard, (req, res) => {
245246
res.setHeader("Cache-Control", "no-store");
246-
return res.json({
247-
ok: true,
248-
signing_chain: {
249-
codex: "SIGNED",
250-
openclaude: "SIGNED",
251-
antigravity: "PENDING",
252-
},
253-
consensus_status: "Awaiting Operator",
254-
options: [
255-
{ option_id: "opt-1", description: "Local speculative serving path (preferred)", friction: "low" },
256-
{ option_id: "opt-2", description: "Quantized fall-back path", friction: "medium" },
257-
],
258-
});
247+
return res.json(getConsensusState());
259248
});
260249

261250
app.get("/api/operator/sandbox-preflight", guard, (req, res) => {
@@ -268,30 +257,12 @@ export function registerDashboardRoutes(app, options) {
268257

269258
app.post("/api/operator/signoff", guard, (req, res) => {
270259
res.setHeader("Cache-Control", "no-store");
271-
return res.json({
272-
ok: true,
273-
message: "Operator signed off successfully. Consensus reached.",
274-
signing_chain: {
275-
codex: "SIGNED",
276-
openclaude: "SIGNED",
277-
antigravity: "SIGNED",
278-
},
279-
consensus_status: "Consensus Reached",
280-
});
260+
return res.json(signOffOperator());
281261
});
282262

283263
app.post("/api/operator/veto", guard, (req, res) => {
284264
res.setHeader("Cache-Control", "no-store");
285-
return res.json({
286-
ok: true,
287-
message: "Operator veto override initiated. Reverting state commit...",
288-
signing_chain: {
289-
codex: "VETOED",
290-
openclaude: "VETOED",
291-
antigravity: "VETOED",
292-
},
293-
consensus_status: "Vetoed",
294-
});
265+
return res.json(vetoOperator());
295266
});
296267

297268
app.post("/api/operator/run-simulation", guard, (req, res) => {

scripts/safety_checks.mjs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4854,11 +4854,52 @@ async function testQueueIdempotency() {
48544854
console.log("-> Queue enqueuing idempotency checks passed");
48554855
}
48564856

4857+
async function testConsensusStateTransitions() {
4858+
const { getConsensusState, signOffOperator, vetoOperator, initializeNewProposal } = await import("../lib/consensus.mjs");
4859+
const statePath = path.resolve(process.cwd(), "runtime", "consensus_state.json");
4860+
4861+
fs.rmSync(statePath, { force: true });
4862+
fs.rmSync(`${statePath}.lock`, { force: true });
4863+
4864+
const defaultState = getConsensusState();
4865+
assert.equal(defaultState.consensus_status, "Awaiting Operator");
4866+
assert.equal(defaultState.signing_chain.antigravity, "PENDING");
4867+
assert.equal(defaultState.signing_chain.codex, "SIGNED");
4868+
assert.equal(defaultState.signing_chain.openclaude, "SIGNED");
4869+
4870+
const signoffRes = signOffOperator();
4871+
assert.equal(signoffRes.consensus_status, "Consensus Reached");
4872+
assert.equal(signoffRes.signing_chain.antigravity, "SIGNED");
4873+
4874+
const persistedState = JSON.parse(fs.readFileSync(statePath, "utf8"));
4875+
assert.equal(persistedState.consensus_status, "Consensus Reached");
4876+
assert.equal(persistedState.signing_chain.antigravity, "SIGNED");
4877+
4878+
const vetoRes = vetoOperator();
4879+
assert.equal(vetoRes.consensus_status, "Vetoed");
4880+
assert.equal(vetoRes.signing_chain.codex, "VETOED");
4881+
assert.equal(vetoRes.signing_chain.openclaude, "VETOED");
4882+
assert.equal(vetoRes.signing_chain.antigravity, "VETOED");
4883+
4884+
const persistedVeto = JSON.parse(fs.readFileSync(statePath, "utf8"));
4885+
assert.equal(persistedVeto.consensus_status, "Vetoed");
4886+
assert.equal(persistedVeto.signing_chain.codex, "VETOED");
4887+
4888+
const newProposal = initializeNewProposal();
4889+
assert.equal(newProposal.consensus_status, "Awaiting Operator");
4890+
assert.equal(newProposal.signing_chain.antigravity, "PENDING");
4891+
4892+
fs.rmSync(statePath, { force: true });
4893+
fs.rmSync(`${statePath}.lock`, { force: true });
4894+
console.log("-> Consensus state transitions checks passed");
4895+
}
4896+
48574897
await testRateLimiting();
48584898
await testLoopbackBrowserOriginGuard();
48594899
await testAdversarialTrustZoneBypass();
48604900
await testReadContractTool();
48614901
await testNewHardeningFeatures();
48624902
await testQueueIdempotency();
4903+
await testConsensusStateTransitions();
48634904

48644905
console.log("SAFETY_CHECKS_OK");

0 commit comments

Comments
 (0)