vestige/apps/dashboard/build/_app/immutable/nodes/10.CuqTW1-V.js
Sam Valladares 8178beb961 feat(v2.0.5): Intentional Amnesia — active forgetting via top-down inhibitory control
First AI memory system to model forgetting as a neuroscience-grounded
PROCESS rather than passive decay. Adds the `suppress` MCP tool (#24),
Rac1 cascade worker, migration V10, and dashboard forgetting indicators.

Based on:
- Anderson, Hanslmayr & Quaegebeur (2025), Nat Rev Neurosci — right
  lateral PFC as the domain-general inhibitory controller; SIF
  compounds with each stopping attempt.
- Cervantes-Sandoval et al. (2020), Front Cell Neurosci PMC7477079 —
  Rac1 GTPase as the active synaptic destabilization mechanism.

What's new:
* `suppress` MCP tool — each call compounds `suppression_count` and
  subtracts a `0.15 × count` penalty (saturating at 80%) from
  retrieval scores during hybrid search. Distinct from delete
  (removes) and demote (one-shot).
* Rac1 cascade worker — background sweep piggybacks the 6h
  consolidation loop, walks `memory_connections` edges from
  recently-suppressed seeds, applies attenuated FSRS decay to
  co-activated neighbors. You don't just forget Jake — you fade
  the café, the roommate, the birthday.
* 24h labile window — reversible via `suppress({id, reverse: true})`
  within 24 hours. Matches Nader reconsolidation semantics.
* Migration V10 — additive-only (`suppression_count`, `suppressed_at`
  + partial indices). All v2.0.x DBs upgrade seamlessly on first launch.
* Dashboard: `ForgettingIndicator.svelte` pulses when suppressions
  are active. 3D graph nodes dim to 20% opacity when suppressed.
  New WebSocket events: `MemorySuppressed`, `MemoryUnsuppressed`,
  `Rac1CascadeSwept`. Heartbeat carries `suppressed_count`.
* Search pipeline: SIF penalty inserted into the accessibility stage
  so it stacks on top of passive FSRS decay.
* Tool count bumped 23 → 24. Cognitive modules 29 → 30.

Memories persist — they are INHIBITED, not erased. `memory.get(id)`
returns full content through any number of suppressions. The 24h
labile window is a grace period for regret.

Also fixes issue #31 (dashboard graph view buggy) as a companion UI
bug discovered during the v2.0.5 audit cycle:

* Root cause: node glow `SpriteMaterial` had no `map`, so
  `THREE.Sprite` rendered as a solid-coloured 1×1 plane. Additive
  blending + `UnrealBloomPass(0.8, 0.4, 0.85)` amplified the square
  edges into hard-edged glowing cubes.
* Fix: shared 128×128 radial-gradient `CanvasTexture` singleton used
  as the sprite map. Retuned bloom to `(0.55, 0.6, 0.2)`. Halved fog
  density (0.008 → 0.0035). Edges bumped from dark navy `0x4a4a7a`
  to brand violet `0x8b5cf6` with higher opacity. Added explicit
  `scene.background` and a 2000-point starfield for depth.
* 21 regression tests added in `ui-fixes.test.ts` locking every
  invariant in (shared texture singleton, depthWrite:false, scale
  ×6, bloom magic numbers via source regex, starfield presence).

Tests: 1,284 Rust (+47) + 171 Vitest (+21) = 1,455 total, 0 failed
Clippy: clean across all targets, zero warnings
Release binary: 22.6MB, `cargo build --release -p vestige-mcp` green
Versions: workspace aligned at 2.0.5 across all 6 crates/packages

Closes #31
2026-04-14 17:30:30 -05:00

1 line
5.6 KiB
JavaScript

import"../chunks/Bzak7iHL.js";import{o as Ft}from"../chunks/DeTA_5mp.js";import{p as $t,a as Ct,d as s,e,j as W,h as y,g as t,r as a,s as E,f as dt,O,t as B,u as P}from"../chunks/nyjtQ1Ok.js";import{d as Rt,s as i,a as At}from"../chunks/C4L78yoI.js";import{i as X}from"../chunks/B17metm1.js";import{e as U,i as q}from"../chunks/BilMa3tw.js";import{a as p,f as u}from"../chunks/B0IenmM-.js";import{s as A}from"../chunks/D2QmVWrb.js";import{a as w}from"../chunks/BcuCGYSa.js";var Dt=u('<div class="h-24 glass-subtle rounded-xl animate-pulse"></div>'),Mt=u('<div class="grid grid-cols-2 lg:grid-cols-4 gap-4"></div>'),kt=u('<div class="flex-1 flex flex-col items-center gap-1"><span class="text-xs text-dim"> </span> <div class="w-full rounded-t transition-all duration-500"></div> <span class="text-xs text-muted"> </span></div>'),Bt=u('<div class="flex items-center gap-2 text-sm"><div class="w-3 h-3 rounded-full"></div> <span class="text-dim"> </span> <span class="text-muted ml-auto"> </span></div>'),St=u('<div class="flex items-center gap-3 text-sm"><span class="text-xs text-decay"> </span> <span class="text-dim truncate"> </span></div>'),Tt=u('<div class="p-6 glass rounded-xl !border-decay/20"><h2 class="text-sm text-decay font-semibold mb-3"> </h2> <div class="space-y-2 max-h-48 overflow-y-auto"></div></div>'),jt=u('<div class="p-6 glass rounded-xl"><h2 class="text-sm text-bright font-semibold mb-4">Retention Distribution</h2> <div class="flex items-end gap-1 h-40"></div></div> <div class="p-6 glass-subtle rounded-xl"><h2 class="text-sm text-bright font-semibold mb-4">Memory Types</h2> <div class="grid grid-cols-2 lg:grid-cols-4 gap-3"></div></div> <!>',1),Et=u('<div class="flex items-center gap-3 p-4 glass rounded-xl"><div class="w-3 h-3 rounded-full animate-pulse-glow"></div> <span class="text-sm font-medium"> </span> <span class="text-xs text-dim"> </span></div> <div class="grid grid-cols-2 lg:grid-cols-4 gap-4"><div class="p-4 glass rounded-xl"><div class="text-2xl text-bright font-bold"> </div> <div class="text-xs text-dim mt-1">Total Memories</div></div> <div class="p-4 glass rounded-xl"><div class="text-2xl font-bold"> </div> <div class="text-xs text-dim mt-1">Avg Retention</div></div> <div class="p-4 glass rounded-xl"><div class="text-2xl text-bright font-bold"> </div> <div class="text-xs text-dim mt-1">Due for Review</div></div> <div class="p-4 glass rounded-xl"><div class="text-2xl text-bright font-bold"> </div> <div class="text-xs text-dim mt-1">Embedding Coverage</div></div></div> <!> <div class="flex gap-3"><button class="px-4 py-2 bg-warning/20 border border-warning/40 text-warning text-sm rounded-xl hover:bg-warning/30 transition">Run Consolidation</button></div>',1),Ot=u('<div class="p-6 max-w-5xl mx-auto space-y-6"><h1 class="text-xl text-bright font-semibold">System Stats</h1> <!></div>');function Lt(ot,vt){$t(vt,!0);let n=E(null),m=E(null),l=E(null),Y=E(!0);Ft(async()=>{try{await(async d=>{var r=W(d,3);y(n,r[0],!0),y(m,r[1],!0),y(l,r[2],!0)})(await Promise.all([w.stats(),w.health(),w.retentionDistribution()]))}catch{}finally{y(Y,!1)}});function z(d){return{healthy:"#10b981",degraded:"#f59e0b",critical:"#ef4444",empty:"#6b7280"}[d]||"#6b7280"}async function nt(){try{await w.consolidate(),await(async d=>{var r=W(d,3);y(n,r[0],!0),y(m,r[1],!0),y(l,r[2],!0)})(await Promise.all([w.stats(),w.health(),w.retentionDistribution()]))}catch{}}var G=Ot(),lt=s(e(G),2);{var ct=d=>{var r=Mt();U(r,20,()=>Array(8),q,(F,H)=>{var $=Dt();p(F,$)}),a(r),p(d,r)},xt=d=>{var r=Et(),F=dt(r),H=e(F),$=s(H,2),pt=e($,!0);a($);var Z=s($,2),ut=e(Z);a(Z),a(F);var I=s(F,2),J=e(I),tt=e(J),mt=e(tt,!0);a(tt),O(2),a(J);var K=s(J,2),L=e(K),gt=e(L);a(L),O(2),a(K);var N=s(K,2),at=e(N),_t=e(at,!0);a(at),O(2),a(N);var et=s(N,2),st=e(et),ft=e(st);a(st),O(2),a(et),a(I);var rt=s(I,2);{var bt=D=>{var S=jt(),M=dt(S),T=s(e(M),2);U(T,21,()=>t(l).distribution,q,(g,c,v)=>{const C=P(()=>Math.max(...t(l).distribution.map(V=>V.count),1)),R=P(()=>t(c).count/t(C)*100),_=P(()=>v<3?"#ef4444":v<5?"#f59e0b":v<7?"#10b981":"#6366f1");var x=kt(),o=e(x),f=e(o,!0);a(o);var b=s(o,2),h=s(b,2),Q=e(h,!0);a(h),a(x),B(()=>{i(f,t(c).count),A(b,`height: ${t(R)??""}%; background: ${t(_)??""}; opacity: 0.7; min-height: 2px`),i(Q,t(c).range)}),p(g,x)}),a(T),a(M);var k=s(M,2),j=s(e(k),2);U(j,21,()=>Object.entries(t(l).byType),q,(g,c)=>{var v=P(()=>W(t(c),2));let C=()=>t(v)[0],R=()=>t(v)[1];var _=Bt(),x=e(_),o=s(x,2),f=e(o,!0);a(o);var b=s(o,2),h=e(b,!0);a(b),a(_),B(()=>{A(x,`background: ${({fact:"#00A8FF",concept:"#9D00FF",event:"#FFB800",person:"#00FFD1",note:"#8B95A5",pattern:"#FF3CAC",decision:"#FF4757"}[C()]||"#8B95A5")??""}`),i(f,C()),i(h,R())}),p(g,_)}),a(j),a(k);var yt=s(k,2);{var wt=g=>{var c=Tt(),v=e(c),C=e(v);a(v);var R=s(v,2);U(R,21,()=>t(l).endangered.slice(0,20),q,(_,x)=>{var o=St(),f=e(o),b=e(f);a(f);var h=s(f,2),Q=e(h,!0);a(h),a(o),B(V=>{i(b,`${V??""}%`),i(Q,t(x).content)},[()=>(t(x).retentionStrength*100).toFixed(0)]),p(_,o)}),a(R),a(c),B(()=>i(C,`Endangered Memories (${t(l).endangered.length??""})`)),p(g,c)};X(yt,g=>{t(l).endangered.length>0&&g(wt)})}p(D,S)};X(rt,D=>{t(l)&&D(bt)})}var it=s(rt,2),ht=e(it);a(it),B((D,S,M,T,k,j)=>{A(F,`border-color: ${D??""}30`),A(H,`background: ${S??""}`),A($,`color: ${M??""}`),i(pt,T),i(ut,`v${t(m).version??""}`),i(mt,t(n).totalMemories),A(L,`color: ${t(n).averageRetention>.7?"#10b981":t(n).averageRetention>.4?"#f59e0b":"#ef4444"}`),i(gt,`${k??""}%`),i(_t,t(n).dueForReview),i(ft,`${j??""}%`)},[()=>z(t(m).status),()=>z(t(m).status),()=>z(t(m).status),()=>t(m).status.toUpperCase(),()=>(t(n).averageRetention*100).toFixed(1),()=>t(n).embeddingCoverage.toFixed(0)]),At("click",ht,nt),p(d,r)};X(lt,d=>{t(Y)?d(ct):t(n)&&t(m)&&d(xt,1)})}a(G),p(ot,G),Ct()}Rt(["click"]);export{Lt as component};