Skip to content

Demo/cockpit sovereign hud#8

Merged
warheart1984-ctrl merged 6 commits into
mainfrom
demo/cockpit-sovereign-hud
Jul 20, 2026
Merged

Demo/cockpit sovereign hud#8
warheart1984-ctrl merged 6 commits into
mainfrom
demo/cockpit-sovereign-hud

Conversation

@warheart1984-ctrl

@warheart1984-ctrl warheart1984-ctrl commented Jul 20, 2026

Copy link
Copy Markdown
Owner

name: Pull Request
about: Contribute changes to the project
title: ''
labels: ''
assignees: ''

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Constitutional Impact

If this change affects constitutional governance:

  • No constitutional impact
  • Affects Law layer
  • Affects Execution layer
  • Affects Oversight layer
  • Affects Judicial layer

If constitutional impact, describe:

  • Which invariants are affected
  • New invariants introduced (if any)
  • Oversight mechanisms updated (if any)

Testing

Describe the tests you ran to verify your changes:

  • Unit tests pass
  • Integration tests pass
  • Manual testing completed
  • Added/updated tests for new functionality

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Open in Devin Review

warheart1984-ctrl and others added 4 commits July 19, 2026 19:02
Nest CRK-1 provenance into agent receipts, append .nova/ledger.wal.jsonl, return blocked receipts on generate failures, and POST observe ingest when NOVA_OBSERVE/spine env is set.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wire Sovereign X HUD and CRVS v1 evidence bindings for the cockpit demo, with CRVS contract tests and CI typecheck job. Backend stewardship/ISL emitters remain out of this commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
Deploy cockpit/dist on push to main and demo/cockpit-sovereign-hud.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Jul 20, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

View 2 additional findings in Devin Review.

Open in Devin Review

Comment on lines +41 to +59
: [
{ id: "1", label: "Understand Request", status: "done" as const, pct: 100 },
{ id: "2", label: "Bind Evidence", status: "done" as const, pct: 100 },
{ id: "3", label: "Await Authority", status: "running" as const, pct: 63 },
{ id: "4", label: "Execute & Verify", status: "pending" as const, pct: 0 },
];

const authStatus = String(authority?.authorityStatus ?? "awaiting evidence");
const authOk = authStatus === "Verified";
const phase =
Array.isArray(exec?.activeExecutions) && (exec!.activeExecutions as unknown[]).length
? "EXECUTION"
: unresolved.length
? "INTENT"
: authOk
? "ARCHITECTURE"
: "PLANNING";

const confidence = authOk ? 94 : 62;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Command panel shows made-up progress and confidence numbers with no supporting evidence

The central command view invents a fixed confidence figure (confidence = authOk ? 94 : 62 at cockpit/src/hud/CenterCommand.tsx:59) and a placeholder task checklist with hardcoded completion percentages when no live intent data exists, so the operator sees fabricated status instead of the honest "awaiting evidence" state used everywhere else.
Impact: The operator can be misled into believing work is progressing and trust a confidence level that was never computed from real system state.

Why this contradicts the panel's own evidence law

The rest of the HUD (cockpit/src/hud/HudRealityStrip.tsx, cockpit/src/crvs/ContractFields.tsx) deliberately renders "awaiting evidence" / "—" when a packet is missing, honoring the stated CRVS law ("Never fabricate evidence — bind to live state or show empty/pending provenance" in cockpit/src/crvs/README.md). In CenterCommand.tsx:41-46 the fallback checklist (Understand Request done 100%, Await Authority running 63%, etc.) and CenterCommand.tsx:59 confidence are static literals not derived from any evidence packet. Even the queue/unresolved branch assigns invented pct: 50 / pct: 0 values (CenterCommand.tsx:32,38). This is the exact fabrication the PR's anti-fabrication tests (tests/crvs.test.ts) were added to prevent.

Prompt for agents
CenterCommand.tsx fabricates constitutional/status facts, contradicting the CRVS 'never fabricate evidence' law that the rest of the HUD honors. Two problem spots: (1) the fallback checklist at lines 41-46 hardcodes task labels and completion percentages (e.g. 'Understand Request' done 100%, 'Await Authority' running 63%) when there is no live intent/queue data; (2) the confidence value at line 59 is a static literal (94 or 62) not derived from any evidence packet; the queue/unresolved mapping also assigns invented pct values (50/0). When no live evidence is available, the panel should show an 'awaiting evidence' / empty state and omit or blank the confidence figure, mirroring HudRealityStrip and ContractFields. Derive percentages only from real step statuses if present, otherwise render the pending/awaiting provenance state.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 144 to +147
for (const r of list) {
if (r?.id) store.actions.addReceipt(r);
}
if (list.length) requestEvidenceRefresh("rest:receipts");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Receipt list grows without bound and duplicates when the live event stream is unavailable

When the server-sent event stream is down, the fallback poller re-fetches the full receipt list every few seconds and re-inserts every receipt (store.actions.addReceipt(r) at cockpit/src/bridge/WebSocketBridge.ts:145) with no de-duplication, so the same receipts pile up indefinitely.
Impact: In fallback/offline mode the cockpit accumulates duplicate receipts without limit, inflating the evidence/receipt counts shown in the new panels and steadily consuming memory.

Mechanism and interaction with the new CRVS bindings

pollReceipts runs on the 5s interval whenever SSE is unavailable (WebSocketBridge.ts:158, soft=false). Each run pulls the complete /api/receipts list and loops for (const r of list) { if (r?.id) store.actions.addReceipt(r); } (WebSocketBridge.ts:144-146). addReceipt in cockpit/src/state/store.ts:151-170 unconditionally prepends [r, ...s.governance.receipts] with no id check, so every poll appends the entire ledger again. The new CRVS bindings compute evidence directly from this array — MemoryEvidenceBinding uses receipts.length and receipts.slice(0,8).map(r=>r.id), EvidenceChainBinding and RealityBinding count/verify receipts — so duplicates corrupt receiptCount, evidenceScore and produce repeated shard/packet ids. With the newly durable WAL (agent/governance/ledger.ts) the server-side list also grows across restarts, amplifying the effect.

Prompt for agents
The REST fallback poller in WebSocketBridge.ts (pollReceipts, lines 134-151) re-adds the entire receipt list on every poll, and store.ts addReceipt (lines 151-170) does not de-duplicate by id, causing unbounded duplication in fallback mode. This corrupts the new CRVS evidence bindings that count receipts and list receipt ids. Fix by making addReceipt idempotent (skip if a receipt with the same id already exists, or replace it), or by having pollReceipts only add receipts whose ids are not already present in the store. Consider the timeline array in addReceipt too, which likewise accumulates duplicates.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread backend/server.ts
Comment on lines +208 to +219
"/api/receipts/ingest": {
POST: async (req, res) => {
try {
const body = (await readBody(req)) as GovernanceReceipt;
if (!body?.id || !body?.hash) return error(res, 400, "Missing receipt id/hash");
ingestObservedReceipt(body);
json(res, 200, { ok: true, id: body.id });
} catch (err) {
error(res, 500, err instanceof Error ? err.message : String(err));
}
},
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟥 Unauthenticated receipt ingest endpoint lets anyone inject forged receipts into the live stream

The new /api/receipts/ingest route (backend/server.ts:208-219) accepts a POST body cast directly to GovernanceReceipt with no authentication and only a trivial body?.id/body?.hash presence check, then passes it to ingestObservedReceipt (backend/nova-spine.ts:44-46) which writes it into the CRK-2 observability ledger and broadcasts it to every connected cockpit via the SSE receipt event. Any network client that can reach the API (which also sets Access-Control-Allow-Origin: *) can fabricate arbitrary constitutional receipts — including forged authority, invariantsChecked, blocked, and crk1 provenance — that appear as genuine governed evidence in the cockpit.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread backend/server.ts
Comment on lines +208 to +219
"/api/receipts/ingest": {
POST: async (req, res) => {
try {
const body = (await readBody(req)) as GovernanceReceipt;
if (!body?.id || !body?.hash) return error(res, 400, "Missing receipt id/hash");
ingestObservedReceipt(body);
json(res, 200, { ok: true, id: body.id });
} catch (err) {
error(res, 500, err instanceof Error ? err.message : String(err));
}
},
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟥 Forged receipts from the open ingest endpoint can execute script in the cockpit (stored XSS)

Receipts injected through the unauthenticated /api/receipts/ingest endpoint are broadcast over SSE, ingested by the cockpit (cockpit/src/bridge/WebSocketBridge.ts:24-41 ingestReceiptPayload) and stored via addReceipt. When an operator opens the Receipt Viewer, the selected receipt is rendered with dangerouslySetInnerHTML={{ __html: highlightJSON(selected) }} (cockpit/src/panels/ReceiptViewer.tsx:80-83), and highlightJSON (ReceiptViewer.tsx:6-24) only wraps JSON tokens in spans without HTML-escaping string values. An attacker-controlled string field (e.g. blockReason or an action.payload value) containing markup such as <img src=x onerror=...> is therefore injected into the DOM and executed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

…auth, XSS

CenterCommand shows awaiting evidence instead of fake progress. Receipt store is idempotent. Ingest requires token in production. ReceiptViewer escapes JSON before highlight.
Wire /api/receipts/ingest to ingest-auth (token in production, localhost in dev) and allow X-Nova-Ingest-Token in CORS preflight.
@warheart1984-ctrl
warheart1984-ctrl merged commit bf940cc into main Jul 20, 2026
1 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant