The hero journey now flows through visible controls with cognitive context that
survives navigation (os-nav.ts gets its first real consumers):
- /dashboard/ redirects to /dashboard/palace (the home), base-safe (was a bare
goto('/graph') that escaped the base + landed on the wrong organ).
- ReceiptCard 'Open in Cinema' uses osGoto with {memory, focus, receipt, cinema}
— fixes the base-escape 404 AND carries the full evidence set.
- Graph consumes ?memory= (canonical; ?center= legacy alias), centers on it, and
a Graph-OWNED one-shot bridge auto-launches the PROTECTED Cinema by clicking its
own .cinema-launch control (MemoryCinema untouched).
- Graph 'Explore Connections' now carries the selected memory; Explore seeds the
walk from THAT memory instead of re-seeding from the newest.
Verified live: /→palace, graph?memory=X&cinema=1 centers + auto-opens Cinema (0
errors), explore?memory=X seeds a walk. check 0/0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Audit BLOCK: (1) DUPLICATE MOBILE NAV — removed the legacy MobileNav (mounted in
(app)/+layout); the registry-driven os-mobilebar is now the ONE mobile nav.
(2) CAPTURE LEAK — showShell now also hides on ?frame=N (was capture only), and
removing MobileNav kills its un-gated leak; ?frame=1 and ?capture=1 both show 0
chrome. (3) PALETTE A11Y — role=dialog + aria-modal + a paletteDialog action that
traps Tab focus, marks [data-app-root] inert while open, and restores focus to
the opener on close. (4) CINEMA KEYBOARD COLLISION (most serious) — the shell's
⌘K/Escape now no-op while a full-screen takeover owns the keyboard, detected via
a READ-ONLY .cinema-overlay DOM probe (Cinema stays protected/untouched) plus a
new shell.svelte store for non-DOM takeovers. Verified live: mobileBars=1,
frame/capture chrome=0, dialog role+inert set/cleared, palette blocked during
Cinema. check 0/0, 980 files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
THE nervous system (audit P0): one os-routes.ts registry (all 20 organs w/ group/
shortcut/icon/purpose) + base-aware os-nav.ts (osHref/osGoto + URL cognitive
context: memory/run/receipt/q/focus/cinema/days/filter). The root shell is now a
FLOATING dock + grouped ⌘K palette that overlays every full-bleed canvas organ,
so no page is a navigation island (Palace is in the nav for the first time).
Hideable via ?capture=1 for clean hero footage. Verified live: dock renders +
⌘K palette opens over the canvas, 0 console errors.
MUTATION SAFETY (audit dangerous-interactions, via M3 worker): a plain click now
SELECTS, never silently mutates. Feed no longer wipes on click (clearEvents gone);
Stats no longer runs consolidate() on a vital click (explicit button only);
Memories plain-click selects instead of promoting, with a visible affordance hint
for shift/alt. check 0/0, 979 files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Graph persists its renderer choice ('field'|'classic') in localStorage. In a
full-suite run a prior test could leave 'classic', so this test — which asserts
the WebGPU Field is the active/default renderer — intermittently failed. Clear
the pref via addInitScript before navigating so it deterministically gets the
field-mode default. Passes now even when ordered right after the graph-using
birth-ritual suite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Settings is a zero-DOM WebGPU console — '[ TRIGGER BIRTH ]' is an in-canvas MSDF
pick, not a DOM button. injectBirthViaSettings clicked getByRole('button', …)
which timed out. Click the canvas at the birth control's NDC (0.06, -0.5) instead
(with a small sweep for the MSDF hit box), and route the triple-birth test through
the same helper. All 3 birth-ritual visual-proof tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reasoning: replace the mount-time auto-run of a deep_reference (which violated
the honest-empty "ask a question to trace" contract) with a passive real
memory-pool substrate. The stage is alive at rest (55% fill) without claiming a
trace; a real query swaps the pool for the actual evidence galaxy. Align the ask
placeholder with the specs.
Specs: the Reasoning Theater is zero-DOM (sr-only input, everything in-canvas) as
of the living-field conversion, but organ-reasoning + reasoning-flow still drove
a visible input and asserted DOM response panels (Primary Source / Cognitive
Pipeline / EvidenceCards) that no longer exist. Rewrite them to fill the sr-only
input by id, wait on the real /api/deep_reference 200, and assert the canvas
re-lights (fill + non-black + animates) — proving the flow on pixels + the API
round-trip. organ-explore asserted a dead /memories/{id} navigation; the row
click is an in-place semantic walk (?q= re-centers), so assert that instead.
All three reasoning specs + explore now pass against the real brain.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The cross-project pattern set is recomputed and legitimately empty at times.
The spec hard-required patterns.length > 0 and 500+ lit row pixels, so it
false-failed whenever the brain had zero standing transfers. Branch on the
real count: assert the pattern rows when patterns exist, and assert the
memory-pool substrate still fills the field (fillPct > 20) when they don't —
matching the organ's real behavior. Also refresh the stale docstring
(LivingFieldPass galaxy + pool fallback, not just an MSDF text field).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Full multi-team audit of the living-field work (adversarial fleet + fresh-eyes
pass + foundation deep-dive). 11 real bugs found and fixed; 7 false positives
adversarially refuted. All re-verified live on the real brain.
Pick contract: field cells were unclickable in intentions/schedule/memory-prs/
importance — the click handlers read the old text-item id off a node payload.
Read the id from either shape; importance now also picks the field pass;
intentions gets a dedicated filter toggle instead of flipping the filter on every
click. RouteStage now picks passes top-down (front-rendered text before
back-rendered field) so a background cell can't steal a foreground control's
click. Proven live: cell clicks fire real promote/act with real memory ids.
Empty data: /patterns went black when the cross-project set is empty (it is
recomputed). Seeded a real memory-pool substrate it falls back to, like
contradictions — alive at zero patterns.
Correctness: memories unsuppress now honors UnsuppressResult.stillSuppressed
(compounded suppression stays scarred). LivingFieldPass no longer writes the
shared params[2] node_count lane (was corrupting the co-resident scene renderer
on graph/observatory/memories). Finite-guard every value reaching the GPU buffer
so a bad mapper can't NaN-out the field. blackbox selected-cell highlight tracks
selectedRunId. graph nulls its field handle when leaving field mode.
Accessibility: /memories and /importance (direct ObservatoryCanvas mounts) now
honor prefers-reduced-motion via engine.setPaused — the field freezes for
reduce-motion users. Gate pins reducedMotion:'no-preference' so the motion
assertion is stable.
Gates green: check 0/0, build ok, palace-launch-gate 22/22 + curated tour,
all-routes-smoke 20/20, ChangelogResponse gains totalEvents.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turn all 17 sparse organs from text-on-black voids into full-bleed, moving,
bioluminescent WebGPU fields. Each cell maps to a real backend fact; verified
live on the real brain with a decoded fill% + motion + zero-error probe.
Foundation: one reusable LivingFieldPass (src/lib/observatory/field/) does
splat -> separable-blur (render passes) -> membrane base coat -> HDR cells with
orbital drift and a CPU pick-mirror. Each organ writes a ~20-line data->cells
mapper (cell-layout.ts: layoutGalaxy / layoutRings / FIELD_HUE).
Organs brought alive (fill% before -> after, all zero WebGPU errors):
stats 0.8->80.9, observatory 10.8->81.4, graph 12.3->82.4, memories ->78.4,
blackbox 18.2->83.3, contradictions 1.6->69.6, dreams 0.3->64.5,
settings 2.7->76.4, reasoning 2.7->39.2, patterns 7.1->45.6,
activation 10->64.9, feed ->89, explore ->83.3, intentions ->66.6,
importance ->73.7, memory-prs ->74.4, schedule ->37.1.
Backend surfaces: add api.memoryChangelog() + ChangelogResponse; surface
suppress/unsuppress on the memories field (shift/alt-click -> scar).
Tests: palace-launch-gate now asserts fillPct>30 + isAnimating (not just
non-black), with a longer settle for reasoning's deep_reference and a raised
timeout for the curated tour. all-routes-smoke treats settings as the WebGPU
field it now is. Gates green: check 0/0, build ok, palace-launch-gate 22/22 +
tour, all-routes-smoke 20/20.
Protected work untouched: MemoryCinema, graph/cinema, observatory scene
shaders, node-renderer, palace-map.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every line is a REAL memory from api.memories.list, rendered as glowing MSDF:
content snippet | id[:8] | retention%. Depth=retrievalStrength, stroke
weight=retentionStrength — a memory near the forgetting horizon renders
dimmer and thinner. Cursor-reactive (inherits the Parallax field). ASCII-
sanitized (real content has em-dashes/curly quotes the atlas can't draw).
Zero DOM, zero hardcoded text. check 0 errors.
Verified live: renders real memory ids (8bf0bb5a, 9070cece, 6d54f085) and
real retention (100%, 100%, 89% — the 89% line visibly dimmer).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v1 magnitudes were imperceptible (verified live: cursor reached the shader but
R=0.45/lift=0.20/glow=0.6 gave ~16% influence at the text = invisible). Cranked
for the signature 'alive' read: influence radius 0.45→0.75 (reacts when the
cursor is anywhere near, not dead-on), z-lift 0.20→0.42, glow 0.6→1.4, added a
per-glyph scale-up (×1.55 near cursor) so glyphs visibly swell toward the
pointer, lean 0.015→0.04, warp tuned to 0.007 (liquid ripple, still readable).
Verified live on the real dashboard: glyphs near the cursor swell, flare bright,
and ripple like liquid mercury. check 0 errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The dashboard text is now a volumetric field: each glyph floats at a depth
set by its trust, stroke weight set by FSRS retention, blur by confidence,
glow by salience. Move the cursor and nearby glyphs lift toward the camera,
lean, and ripple (SDF domain-warp); the field parallaxes like a diorama.
Every motion is a real memory fact — Math.random would visibly break it.
v1: PARAMS 16→20 cursor uniform (pre-divide NDC + velocity + off-canvas
sentinel), depth/weight packed into the free info.zw glyph lanes, vertex
depth→clip.z + Gaussian cursor lift + lean + pulse parallax, fragment SDF
warp + retention weight bias + depth-of-field + depth glow. Zero new render
passes. Deterministic (params.time/frame, never wall clock).
Built by GPT-5.5 against a source-verified scour spec (8-agent frontier
research combining W-perspective depth, cursor Gaussian fields, SDF warp,
and weight-as-data-gauge). Conductor live-GPU audit caught + fixed two
visual bugs: z clamped positive so cursor-lift never clips glyphs behind the
near plane; resting depth-of-field and glow floor raised so the field is
readable and lit at rest, sharpening toward the cursor. Verified live: text
glows at rest, brightens and lifts toward the pointer. check 0 errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
RouteStage.svelte rebuilt: no slot chrome, no pause button, no telemetry/
loading/error/empty divs. One transparent pointer host + the canvas. Pause,
telemetry, and all lifecycle states now render as MSDF glyphs via TextLayerPass;
the sidebar nav is now an in-canvas WebGPU rail (nav-layer.ts) with all 19
routes, active route glowing cyan, hover ignition, click-to-navigate.
check 0 errors 0 warnings (the slot-deprecation warning is gone), build green.
The 5 organ routes still compile. Their own page DOM headers convert in Day-2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every dashboard route except marketing/waitlist now renders bare children:
no sidebar nav, no websocket toasts, no ambient orbs, no command palette.
Extends the existing /observatory immersive bypass to the whole app.
Verified live: the MSDF test route drops from ~304 DOM elements to 3 empty
structural divs, no <nav>, just the WebGPU canvas. The nav itself will be
rebuilt as an in-canvas WebGPU layer. check green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Day-1 linchpin of the zero-DOM Cognitive OS. Every label, receipt id, and
number in the dashboard now renders as glowing in-canvas MSDF glyphs instead
of DOM text. Checked-in JetBrains Mono mtsdf atlas (512x512, 95 glyphs) +
loader + pure layout helper + FramePass + trap-checked WGSL.
Built by a GPT-5.5 swarm against an adversarially-verified spec (5 verifiers
+ 3 skeptics caught 6 silent-fail traps before a line was written: V-flip,
release-binary atlas embed, base-path fetch, linear rgba8unorm, premultiplied
blend, ASCII-only charset). Conductor live-GPU audit on the real dashboard
found one more at runtime: the aspect transform pushed text off-screen in
portrait; fixed to keep glyphs square in both orientations.
Renders cyan, crisp, upright, glowing, glyph-by-glyph, landscape + portrait.
check 0 errors, build green, golden V-flip test 2/2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Built by GPT-5.5 swarm worker, audited + fixed live by Opus 4.8. An agent
run rendered as a living nervous system: tool calls / retrievals / writes /
suppressions / vetoes as impulses, receipts as beads, real TraceEvent order.
- blackbox/blackbox-scene.ts + blackbox-pass.ts (metaball nerve field, all
render passes, no storage textures) + wired route.
- Live-GPU audit caught a WGSL 'meta' reserved-keyword struct field
(invalid module, 600 pipeline errors/frame, gates green) — renamed to
'beat'. Added meta to the brief's reserved-word list.
Verified live vs the real brain: real agent runs list, real event log
(Tool Call smart_ingest, Wrote <memory-id>), real event producers
(mcp.call/memory.write/retrieve/suppress), honest empty states (no
contradiction/dream/veto this run), 115fps. check+build+1043 tests green.
Cinema + Graph field untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The second Cognitive OS flagship, built by GPT-5.5 in the council,
audited + verified live by Opus 4.8.
- contradictions/contradictions-scene.ts: /api/contradictions →
RouteSceneModel. Real backend {stronger:{id},weaker:{id},topic_overlap}
shape + DeepReferenceCompleted.contradiction_pairs. Provenance enforced.
- contradictions/contradictions-pass.ts: dual-channel signed metaball
field — side A (stronger) splats red, side B (weaker) green; the seam
(min(r,g) + opposing gradient) renders as a scarlet immune synapse.
Trust thickens the membrane. Unresolved pairs spark scarlet arcs.
All render passes (splat→render-pass blur→membrane), no storage
textures, scarlet not magenta (magenta stays RSB-only).
- contradictions/+page.svelte: RouteStage full-bleed, replaced the
AmbientField base coat. Seam-pick → DOM receipt drawer. Honest
"CALM IMMUNE FIELD" empty state.
A WGSL struct-field mismatch (PairCell.meta vs p.signals) made the splat
pipeline invalid at runtime — caught by the live-GPU audit (invisible to
check/build), root-caused with getCompilationInfo + a web-verified spec
research pass, fixed by renaming the field.
Verified live vs the real 1241-memory brain: 104fps, valid pipelines,
zero GPU errors, honest empty state (brain has 0 standing contradictions).
check + build + 1043 tests green. Cinema + Graph field untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first full-bleed WebGPU organ of the Cognitive Bioluminescent Cortex,
built by GPT-5.5 in the design council, audited + fixed live by Opus 4.8.
- RouteStage.svelte: reusable organ shell (engine/canvas lifecycle, WebGPU
fallback, reduced-motion auto-pause, persistent pause control) — the
lifecycle-only reuse of ObservatoryStage, NOT its Graph data path.
- reasoning/reasoning-scene.ts: /deep_reference → RouteSceneModel adapter.
Honest 8-stage derivation from real fields (label unexposed internals),
real backend contradiction {stronger/weaker} + superseded {superseded_by}
shapes, provenance enforced.
- reasoning/reasoning-theater-pass.ts: the 8-chamber organ. Metaball field
(additive splat -> render-pass separable blur -> membrane, all render
passes, no storage textures), compute Bezier spline packet advection,
labeled deterministic replay of the one-shot receipt. Palette-driven;
magenta stays RSB-only; contradictions scarlet.
- reasoning/+page.svelte: query -> /deep_reference -> scene -> full-bleed
organ behind the DOM answer/evidence panels.
Three WebGPU runtime traps caught by the live-GPU audit (invisible to
check/build) and fixed: (T6) no read_write storage in a shared compute+
render module; (T3) no rgba16float write-storage blur -> use render-pass
blur; and the 'active' reserved-keyword WGSL parse error.
Verified LIVE vs the real 1241-memory brain: query "How does FSRS-6 trust
scoring work?" lit the chambers with a REAL memory (trust 51%), 84%
confidence, 26 analyzed, contradiction stage correctly dark (none real),
120fps. check + build + 1043 tests green. Cinema + Graph field untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The two-model design council (Opus 4.8 x GPT-5.5) converged. This captures
the full record: Round 1 vision (Causal Bioluminescent Cortex), Round 2
pushbacks+acceptance+WGSL research, Round 3 final plan + GPT-5.5's repo
sign-off with 5 verified corrections (deep_reference stage-derivation,
real contradiction shapes, rgba16float portability, RouteStage lifecycle-
only copy, magenta-is-RSB-only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Shared foundation for the Cognitive OS dashboard (design council Opus 4.8
× GPT-5.5). Both locked, zero-risk, no engine changes yet.
- cognitive-palette.ts: the invented "Causal Bioluminescent Cortex" color
language. Blackwater base (never purple), retention oxygen ramp
(sediment→amber→green→luciferin), magenta reserved ONLY for RSB
retrograde causality, indigo ONLY for bitemporal parallax, scarlet for
the immune system. Event→impulse map, trust→membrane width, retention
→color. One source of truth to prevent per-route accent drift.
- route-scene.ts: RouteSceneModel — the adapter↔RouteStage contract with
the discipline test enforced in the type system (every primitive carries
real Provenance: memory/event/receipt/pair/trace/pr/pattern/scalar).
assertProvenance() trips a screensaver primitive in dev before it ships.
check green. Foundation only — RouteStage waits on the council's
buffer-layout decision.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Closes the launch guardrail: the field's ambient orbit + force-sim drift
run >5s, so WCAG needs a persistent pause control and prefers-reduced-
motion must be honored.
- engine.setPaused(): freezes the deterministic clock so the orbit + sim
drift hold still, while the frame still renders and the live preFrameHook
still runs — discrete event pulses (firewall, decay, dream) are
information, not decoration, so they land even when motion is reduced.
- ObservatoryStage: a persistent ❚❚ PAUSE / ▶ RESUME control on the live
field; auto-pauses under prefers-reduced-motion (user can override).
Verified live: the pause button toggles engine.isPaused (frozen drift,
pulses still land); check 0 err, 1043 tests, build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The dead routes were flat purple. This adds ONE cheap WebGPU substrate
behind them whose drive is REAL backend metrics, so it legibly READS the
data instead of being decoration — a store with 129 endangered memories
storms; 0 contradictions is a calm field (the discipline test still holds).
- AmbientField.svelte + ambient-field.wgsl: a metric-bound mote field.
Each mote's vertical drift IS its retention (low sinks to the forgetting
floor, high floats up); the real endangered fraction storms turbulence +
the sink split; contradiction fraction tears rifts; due-for-review
pulses it. Deterministic per mote (no Math.random in the loop).
- Guardrails: no WebGPU / null adapter / context throw -> renders nothing
(page background shows, never a black canvas). prefers-reduced-motion
freezes drift but keeps the metric snapshot. Page-Visibility +
IntersectionObserver gate the rAF loop. DPR clamped, mobile-first budget.
- Wired to the two highest-signal routes: /stats (endangered + due) and
/contradictions (fracture). Reusable — any remaining route adopts it with
one import + real metric props.
Verified live: /stats renders the field reading the retention distribution
(dense healthy top, endangered embers); /contradictions shows a calm
crimson field at 0 contradictions (fracture=0). check 0 err, 1043 tests,
build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A real recall lights the backward CAUSE chain through the graph — every
hop after the origin follows a real ConnectionType::Causal edge, not mere
co-occurrence. This is the conjunction no competitor has: RSB's directed
causation + the causal edge type + per-memory FSRS + the raw-WebGPU engine.
- pathfinder: isCausalEdge() + a preferCausal walk option (defaults false,
so Memory Cinema is byte-identical). When set, the greedy walk prefers
real causal edges every step, tracing true causation.
- path-builder: buildRecallPath gains preferCausal + centerId; causal hops
(detected on viaEdge.type, keeping the shared Cinema beat-kind union and
the protected narrator untouched) map to PATH_KIND.backwardCause — the
magenta backward rim in render-path.wgsl.
- live-bridge: a real DeepReferenceCompleted (or BackfillFired) whose
primary is in-field rebuilds the PathStep buffer centered on the real
recalled memory, preferring causal edges, and rides the proven recall
wavefront machinery. Honest scope: only lights when the recalled memory
is actually on screen (never invents a path).
- 2 new tests: the pathfinder picks the real cause over the strongest
co-occurrence; a live DeepReferenceCompleted arms the causal wavefront.
Verified live: injected a real in-field DeepReferenceCompleted → the
bridge armed causalRecall for the real primary + set an 8-step path whose
7 post-origin hops are ALL kind-1 (backward-cause) following real causal
edges. 1043 tests, check + build green. Cinema untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When the real dream pipeline runs, the field enters a metabolic storm:
damping loosens, the newly-discovered edges are appended live, and their
springs pull the clusters into their new shape.
- node-renderer: setEdges() — a setPathSteps clone that regrows the edge
index buffer, updates the CPU graph, bumps edge_count, rebuilds the sim
pipeline so new springs act immediately.
- simulate.wgsl: while live_kind==dreamStorm, damping loosens with
live_energy + a deterministic turbulence rides the envelope (pure of
node index + live_frame, so no wall clock).
- live-bridge: real ConnectionDiscovered pairs append to a deduped edge
accumulator, coalesced to ONE setEdges per frame (a 1000-edge burst is
one regrow, not a thousand). Storm fires on DreamStarted OR
DreamCompleted (a real dream floods the 200-event ring and evicts
DreamStarted, so Completed must also arm it), holds ~6s, settles.
- ingest rewrite: timestamp watermark instead of object-identity dedup —
robust to ring eviction AND browser/backend clock skew (seeds from the
backend clock, never the browser wall clock). This fixed a real bug
where a 36s clock skew silently dropped every event.
- 8 new LiveBridge unit tests machine-prove decay/firewall/storm/edges
(the multi-second storm can't be screenshotted in a frozen-rAF preview).
Verified: firewall re-fired live post-rewrite naming the real memory;
1041 tests (8 new), check + build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The crimson quarantine firewall was hard-locked to the deterministic demo
clock. Now it fires on real cognitive events — a MemorySuppressed or a
DeepReferenceCompleted contradiction pair — targeting the REAL memory and
its REAL graph neighbors, on camera.
- firewall-plan: buildLiveFirewallPlan(graph, seed, intruderIndex) reuses
all the deterministic machinery (real-layout shock delays, real severed
neighbors, spine, verdict) but takes the intruder from the live event.
- firewall.wgsl + render-nodes.wgsl: dual-gate on demo_id==4 OR
live_kind==1, driven by live_frame (frames since the event) so the
720-frame beat map plays once from the event, not the loop clock.
- firewall-renderer: rearm(plan) rebuilds the fire buffer for a live
target; compute() gates on demo OR live.
- live-bridge: lazily builds + rearms a live FirewallRenderer on a
firewall event; onFirewall callback surfaces the verdict.
- ObservatoryStage: crimson "threat quarantined" verdict card naming the
real memory, auto-clears after the choreography.
- live lane [13] repurposed liveStartFrame -> liveFrame (event-relative).
Verified live: fired 3 real suppressions on the 1241-memory brain — each
raised the crimson verdict naming the real memory ("ProtocolGate Lane 4
design decision", cascade ~54), the field ran the quarantine, the forget
counter incremented 129->132, then all 3 reversed cleanly. check 0 err,
1033 tests, build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The raw-WebGPU field was inert — it ran the deterministic DemoClock and
never heard the backend. This wires it to the real event stream and makes
every memory visibly forget on its true FSRS curve.
- LiveBridge (new): lock-free per-frame drain via engine.preFrameHook,
ingests $eventFeed oldest-first, decodes real events into live lanes.
- fsrs.ts (new): exact TS port of retrievability_with_decay (w20=0.1542).
- params 12→16 floats (capture_mode + 4 live lanes); all 8 WGSL Params
structs updated in lockstep. _pad renamed to its real meaning.
- node-renderer: live-retention GPU buffer (binding 4); simulate.wgsl
overwrites vel_retention.w so render-nodes dims on the real curve.
- ObservatoryStage: `live` prop, $eventFeed subscription, persistent
FORGETTING HORIZON scrubber (project the curve forward N days, honest).
- backend: get_graph node json now carries stability + lastAccessed.
Verified live vs the real 1241-memory brain: +300d scrub visibly decays
low-stability nodes while high-stability survive; per-node FSRS math
confirmed. svelte-check 0 err, 1033 tests, build, cargo check all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The living field is now interactive, killing Classic's main reason to
exist. Clicking a node in the WebGPU field opens the same Memory Detail
inspector (content, FSRS bars, retention forecast, promote/demote,
explore) that Classic's Three.js picking drove.
How: NodeRenderer.pickAt(ndcX, ndcY) — the one sanctioned GPU readback,
input-driven and click-frequency only, so the render loop's determinism
contract (spec §6) holds. It copies the live NodeState buffer (post
force-sim positions) to a MAP_READ staging buffer, reprojects every node
on the CPU through the SAME deterministic orbit camera the frame used
(engine params phase + canvas aspect, column-major viewProj), and picks
the nearest node whose projected disc (r·f/w with a floor for faint
nodes, 1.6x halo slop) contains the click. NodeState gains COPY_SRC for
the copy; a fresh staging buffer per click is created and destroyed.
ObservatoryStage gains an onpick prop wired to the canvas layer
(crosshair cursor when interactive); the graph page passes onNodeSelect
so field picks open the existing panel.
Verified live: click at field center hit a real memory, panel opened
with real FSRS data (retention 65.4%, forecast 65%->37% @30d), zero
console errors. svelte-check 940 files 0/0; 96 observatory tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The main graph page defaults to the Observatory engine — GPU force sim,
HDR bloom, and the recall wavefront sweeping the REAL memory graph on a
12s loop — instead of the flat Three.js view. Visuals to the max, per
the locked ALIVE-field direction.
- ObservatoryStage gains embedded (fills parent, not viewport) and
chrome ('full' | 'none') props; chrome='none' is a pure living canvas
plus loading/error text, so the page's own DOM chrome stays in charge.
- New Field | Classic renderer toggle in the control bar. Field is the
default wherever WebGPU exists; no WebGPU forces classic. Choice
persists in localStorage.
- Classic (Three.js) remains one click away and untouched: node picking,
colour modes, node count, brightness, temporal scrubbing and legends
are classic-renderer features and now only render there. Dream,
Observatory takeover, Memory Cinema (protected) and Reload work in
both modes.
Verified live: fresh load defaults to Field (148 real nodes, 2865 real
edges, recall ribbon igniting on camera, zero console errors); Classic
toggle restores search/colour/brightness with a single canvas; the
choice round-trips through localStorage. svelte-check 940 files 0
errors 0 warnings.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Observatory is no longer a separate URL you have to know about. It
is now a first-class part of the main graph page, following the proven
Memory Cinema pattern (which remains untouched per the protected-block
rule):
- The full experience is factored into a reusable ObservatoryStage
component (engine, plans, overlays moved verbatim from the route).
- The graph control bar gains an Observatory button beside Dream and
Memory Cinema; clicking it takes over the screen full-bleed (z-50).
- Inside the stage: an on-screen switcher for the 5 cognitive moments
(RECALL / BIRTH / RESCUE / HORIZON / FIREWALL) and an EXIT control
(Esc works too) that returns to the graph exactly as it was. Both are
hidden in capture mode so recordings stay chrome-free.
- {#key demo} remounts the stage per moment: fresh engine, plans, and
clock, deterministic from frame 0.
- The /observatory route stays as a thin wrapper so deep links and the
?frame=N / ?capture=1 recording contract are unchanged; switching a
moment there rewrites the URL so links stay shareable.
Verified live in the running dashboard: button renders between Dream
and Cinema, click boots the WebGPU takeover (148 real nodes, 2865
edges), RESCUE chip switches the moment (telemetry: SALIENCE-RESCUE),
EXIT unmounts cleanly back to the graph (canvas count 2 -> 1).
svelte-check 940 files 0 errors 0 warnings; 96 observatory tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Gate the auto-dedup consolidation pass behind VESTIGE_AUTO_CONSOLIDATE_MERGE (default on) and exclude protected (pinned) nodes so they are never absorbed or deleted by the unattended cycle.
Reviewed and verified green locally before merge:
- 8 new #142 tests pass; regression guards proven to bite pre-fix (5 protection tests fail when the pin filter is removed)
- full vestige-core lib suite: 541 passed / 0 failed
- clippy --workspace --all-targets -D warnings: 0 warnings
Fixes#142.
Co-authored-by: Michael Kurras <michael.kurras@wuestpartner.com>
Two demo-readiness fixes so the Observatory reads as a living brain
doing real work, not a sparse placeholder:
1. Graph query switched from sort=recent to sort=connected (max_nodes
200). 'recent' centered on the newest memory, a lonely node whose
depth-3 neighborhood is only ~12 nodes, so the field looked empty.
'connected' surfaces the populous hotspot: ~148 real memories and
~2865 real edges, laid out as two dense clusters. Verified live on
recall-path and salience-rescue: 148 nodes / 2865 edges at 110-119fps.
2. Verdict card now holds. The 'root cause found' card faded fully out
by frame 660 in a 720-frame (12s) loop, so it flashed for ~1s then
vanished. Widened the default fade window to [600,620,705,719]: it
fades in, holds fully readable through the field's decay to rest, and
only fades out just before the seamless loop wrap. ~1.75s of readable
verdict instead of a blink. GPU envelopes and the seam-zero loop test
are unaffected (DOM overlay window is independent of the sim).
Verified live against the real brain: 96 observatory tests green, zero
console errors, verdict readable at frames 660 and 695 (both blank before).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Observatory is a full-bleed, zero-library WebGPU surface that renders
the memory graph as a living cognitive field. Five deterministic demo
moments driven by a URL contract (?demo=<name>&seed=...&frame=N):
recall-path, engram-birth, salience-rescue, forgetting-horizon, firewall.
Capture mode (?frame=N) freezes the sim deterministically so the same URL
produces identical pixels, the viral-clip primitive.
Architecture: bare-metal WebGPU engine (no Three.js), seeded demo clock,
per-demo plan + renderer modules, WGSL shaders (simulate, nodes, edges,
path, birth particles, rescue, forgetting, firewall) plus a post-processing
chain (tone mapping, MIP). DOM is instrument overlays only (telemetry strip,
timeline spine, rescue verdict); the layout gives /observatory the same
full-bleed bypass as marketing routes so recordings stay clean.
Reads the real memory graph. Verified live: svelte-check 939 files 0 errors,
96 observatory unit tests green, all 5 demos load at 108-119fps with zero
console errors against the live brain.
Known follow-up: engram-birth capture-mode particle cluster needs a render
fix pass before it is camera-ready; the other 4 demos are camera-ready.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The background consolidation cycle's auto_dedup_consolidation pass silently
concat-merged near-duplicate memories (cosine >= 0.85) into [MERGED] blocks and
hard-deleted the originals, with no opt-out and while ignoring `dedup protect`
pins — so a pinned memory could be absorbed/deleted unattended.
- Gate the pass behind VESTIGE_AUTO_CONSOLIDATE_MERGE (default on; set
0/false/off/no to disable), parsed like the sibling VESTIGE_BACKFILL_AUTOFIRE,
at the function top so every consolidation caller is covered consistently.
- Exclude protected (pinned) nodes from merge clusters at both loops, so a
protected node is never an anchor nor a member — never absorbed, never deleted.
protected_node_ids() is fetched once before the reader-lock window (lock-safe).
- Tests: default-unchanged regression, flag-off suppression, full protection
matrix, liveness, and an explicit #142 regression guard.
- Docs: CONFIGURATION.md env-var row + CHANGELOG entry.
Default behavior is unchanged. TOCTOU: the protected set is snapshotted once per
pass (consistent with the function's existing point-in-time idiom). Out of scope
(follow-up): a reversible audit trail for merges that still happen when enabled,
and the [MERGED] concat-bloat itself.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A second adversarial audit of shipped main (post the 29+3 earlier fixes) found
10 more real bugs in areas the first pass under-covered (FTS sanitizer,
protocol/HTTP, connectors, frontend). None regressions — all pre-existing, and
several are "twin sites" of a class fixed elsewhere but missed here.
Majors:
- FTS5: sanitize_fts5_terms leaked bare operators on doubled input ("foo AND AND
AND"), aborting MATCH with a syntax error or silently flipping AND->OR. Now
filters operator tokens (repetition-proof).
- Server crash (DoS): unbounded MCP `hours_back`/`hours_forward` panicked via
Duration::minutes in CaptureWindow; unclamped `limit` in match_context
panicked via negative Vec::with_capacity / limit*2 overflow. Both now
bounded/checked.
- Connectors: the source idempotency key omitted source_project, so two repos
(or two Redmine instances) with overlapping ids clobbered each other's memory.
Key + unique index (migration V19) now include source_project.
Minors/nits:
- list_memories now honors node_type/tag on the search path (were dropped).
- HTTP Accept honors */* and type wildcards (was hard 406 for curl et al.).
- Bearer scheme matched case-insensitively (RFC 7235).
- Dream insight time-span no longer seeds from now/-365d sentinels (fabricated a
TemporalTrend for old clusters).
- WebSocket disconnect() detaches onclose before close() so it can't resurrect
the socket via scheduleReconnect.
- Redmine thread truncation keeps the NEWEST journals (was keeping oldest, so
new activity never re-indexed).
Tests: FTS operator-leak regression added. Full workspace green (1559 tests,
clippy -D warnings clean); dashboard check + 937 tests green.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The /duplicates, /contradictions, and /patterns routes shipped hardcoded mock
data — and /duplicates rendered a "Live" badge over it. That is a launch
credibility risk: a visitor who spots the canned data distrusts every real
claim (including the CauseBench benchmark).
Replaces the three mocks (mockFetchDuplicates, MOCK_CONTRADICTIONS,
mockFetchCrossProject) with real dashboard HTTP endpoints backed by the existing
core capabilities:
- GET /api/duplicates -> dedup cluster detection
- GET /api/contradictions -> trust-weighted contradiction analysis
- GET /api/patterns/cross-project-> cross-project pattern transfer
Adds the handlers (dashboard/handlers.rs), route registrations (dashboard/mod.rs),
frontend api client methods + response types, and rewrites the three routes to
fetch live. The "Live" badge is now truthful.
Verified this session:
- cargo build -p vestige-mcp: compiles
- pnpm --filter @vestige/dashboard check: 905 files, 0 errors, 0 warnings
- live backend on a 1073-memory DB returns real rows from all three endpoints
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- #117 Agent Black Box: the trace recorder had zero production callers, so
agent_traces/receipts/memory_prs never populated. handle_tools_call now
records the opening mcp.call event (record_call) before dispatch and the
downstream memory events (record_result) after a successful call, under a
shared run_id. Also fixed the args capture so tracing works in pure stdio
mode (was gated on event_tx, which is None without a dashboard socket).
- #124 Recurring intentions now re-arm: mark_triggered advances a recurring
trigger's next_occurrence and returns the intention to Active (was firing
once and staying Triggered forever). Added Trigger::re_arm (recurses into
Compound).
- #137 Co-access prediction channel is now live: search_unified feeds the
retrieved set to speculative_retriever.record_usage, so co-access patterns
populate (were permanently empty). The temporal channel was already fixed
(#136); the file-context channel stays dormant by design (search has no file
context to supply).
Tests: Black Box trace population, recurring re-arm. Full workspace green
(1558 tests, clippy -D warnings clean).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A backend-wide audit (18 feature areas, adversarially verified) surfaced 31
real bugs. This fixes 29 of them; each was re-verified by an independent
adversarial pass and the whole workspace stays green (1556 tests, clippy -D
warnings clean).
Data integrity & storage:
- Migrations no longer brick the DB on a mid-migration failure: each runs in a
transaction (atomic schema change + version bump); V7 repages under WAL.
- decide_memory_pr rejects re-deciding a finalized PR (audit ledger + no
resurrection of a rejected memory).
- suppress reverse is now a true inverse (was leaving stability permanently
halved).
- update_node_content flips has_embedding=0 when the embedder isn't ready, so
the stale embedding is regenerated instead of matching old content forever.
- plan_merge validates survivor_id is a member (was an unchecked-unwrap panic).
- Redmine detail-fetch failure aborts the page (retry) instead of storing a
journal-less record and skipping it forever.
- ContentStore cache counter accounts for replaced entries; changelog no longer
loads the whole connections table; source_sync clamps max_pages.
Cognitive correctness:
- Contradiction heuristic requires a real polarity flip (was demoting correct
memories on benign "do not"/"cannot" notes).
- Hybrid search relevance is the RRF fused score, min-max normalized, so the
best match ranks first (was capped and outranked by recency/importance).
- Sentiment-boosted stability is clamped to MAX_STABILITY.
- Chain confidence uses the correct geometric-mean root; looks_like_failure no
longer over-fires on "$500"; contains_marker_word is UTF-8-boundary-safe.
- Prediction merge can't cross min_confidence from below; temporal prediction
wraps around midnight; match_context tag overlap is clamped to 1.0.
MCP / CLI:
- UTF-8 panic in the " at " intention parser fixed (boundary-safe match).
- vestige backup no longer fails on encrypted DBs (best-effort raw checkpoint).
- --ago-days uses checked Duration + subtraction (no overflow panic).
- smart_ingest honors an explicit forceCreate:false (was silently inverted).
- append_trace_event propagates the seq query error (no duplicate seq=0).
- RewardPattern::matches requires real overlap (was matching everything).
Deferred: the dead trace-recorder wiring (Black Box/Receipts/Memory-PR) is a
feature-completion task for its own change; two dormant speculative-prediction
channels with no production caller are left as-is (fixing dead code adds risk
without user benefit).
Regression tests added for the migration brick, suppress inverse, backfill
bound, contradiction false-positive, and forceCreate handling.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Surface the contributor credit as its own subsection rather than a
trailing sentence: @Vrakoss for the Windows repro (#101), @randomnimbus
(Peter Lauzon) for the backfill report + fix (#103), whose commit is
already co-authored in the shipped v2.2.1 release (f7530af).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* patch(backfill-safety): VESTIGE_BACKFILL_AUTOFIRE gate (default OFF) + bounded promote_memory_backfill
Off-by-default env gate around step-8.5 auto-fire in run_consolidation (decouples
backfill from consolidation cadence). New promote_memory_backfill caps stability at
MIN(stability*1.5, stability+365.0) (the bound retroactive_backfill.rs:300 already
computes but discarded); both backfill entry points use it. Fixes the false 'capped'
comment. Cloud-sync excluded at build (--no-default-features). Pending upstream PR to
samvallad33/vestige. omega-backfill-safety-v2.2.0 off tag v2.2.0 (3bcd4667).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* release: v2.2.1 — Windows embeddings fix + backfill safety + first-run guide
Board-clearing patch release.
Fixes:
- #101 Windows embeddings: release.yml already restores vector-search on the
x86_64-pc-windows-msvc target (merged in #102); this release rebuilds the
Windows binary so users actually get working embeddings.
- #103 Retroactive Salience Backfill safety (from community PR #104, adjusted):
* promote_memory_backfill bounds the stability multiply to
MIN(stability*1.5, stability+365.0) on both auto-fire and manual paths.
* VESTIGE_BACKFILL_AUTOFIRE gate — default ON (preserves the shipped/documented
v2.2.0 behavior), disable with 0/false/off/no. Env value is trimmed.
* Corrected the false "capped" comment and the promote_memory_backfill doc.
* Added 3 tests: +365 cap binds, *1.5 multiply below crossover, gate parsing.
Docs:
- #83 First-Run: new docs/GETTING-STARTED.md + README pointer.
- Consolidated roadmap issues #82,#84-#92 into docs/ROADMAP.md (Tracked Issues).
- Documented VESTIGE_BACKFILL_AUTOFIRE in docs/CONFIGURATION.md.
- CHANGELOG v2.2.1 entry.
Version bumped to 2.2.1 across all manifests + Cargo.lock + dashboard build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Peter Lauzon <inbijiburu@protonmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Windows x86_64-pc-windows-msvc release binary was built with
`--no-default-features --features embeddings,ort-download`, dropping
`vector-search` (the usearch HNSW index). Without that feature the
storage layer's `#[cfg(feature = "vector-search")]` paths compile out,
so embeddings are never persisted or queried. On Windows the binary
reports "Embedding Service: Not Ready", 0% coverage, `consolidate`
generates 0 embeddings, and no model download is ever attempted. The
same machine and model cache work on v2.1.23, which predates the flag.
`vector-search` was likely dropped to sidestep the usearch MSVC build
failure (C1021 from a bare-fp16 `#warning`), but that was already fixed
properly by pinning usearch with `features=["fp16lib"]`, so omitting
the feature is both unnecessary and the cause of the regression.
Verified locally: building vestige-mcp with
`embeddings,ort-download,vector-search` compiles and links cleanly, and
the reporter's repro (ingest -> consolidate -> stats) downloads the
nomic model and reaches 100% embedding coverage.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Vestige is the MCP memory layer underneath every agent, not an add-on for one
tool. Quick start leads with the universal mcp.json config (works with any
agent), then per-agent shortcuts (Cursor first). 'Works in every editor' ->
'Works with every AI agent' with Cursor/Windsurf/VS Code/Cline/Continue/Zed/
Goose leading and Claude Code as one option among many. Added a confirm-it-worked
step and surfaced the flagship backfill command.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The real cause was not a flaky runner image: the macOS Test job restored a
cached `target/` built against a previous runner Xcode, and that stale build
dir carried a clang compiler-rt search path (.../clang/<N>/lib/darwin) that no
longer exists on the current image, so the linker failed with
'ld: library clang_rt.osx not found' on every commit.
Fix: stop caching `target/` on the test job (cache only the download-heavy
registry/git dirs) and bump the cache key to v2 to discard the poisoned
caches. Also deleted the existing poisoned macOS caches. Reverted the macos-14
pin (it didn't help and that image is deprecating) back to macos-latest, which
is fine now that target/ is always built clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The MCP Registry rejects descriptions over 100 chars (422). Tightened to the
backward-reach hook so server.json matches the published v2.2.0 registry entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Updates the official MCP Registry manifest (server.json) and the Claude
Desktop .mcpb bundle manifest to 2.2.0, and refreshes their descriptions to
lead with the v2.2.0 flagship (Retroactive Salience Backfill).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The rolling macos-latest image intermittently ships a broken compiler-rt
path, causing 'ld: library clang_rt.osx not found' on the Rust link step of
an otherwise-green commit (a README-only change failed CI this way). Pinning
all five macOS jobs (CI test + CI release-build + Release) to macos-14 gives a
stable Xcode/clang toolchain so the linker step is deterministic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces 44 em-dashes with commas, colons, periods, and parentheses so the
prose reads naturally without them. No content changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>