mirror of
https://github.com/samvallad33/vestige.git
synced 2026-07-22 23:31:02 +02:00
* 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>
3 lines
15 KiB
JavaScript
3 lines
15 KiB
JavaScript
import"../chunks/Bzak7iHL.js";import{o as Re,a as Fe}from"../chunks/TZu9D97Z.js";import{p as Ae,c as Ne,f as De,g as e,a as u,b as Me,u as O,e as s,r,h as o,t as M,i as A,j as m,s as V,d as ye,n as xe}from"../chunks/wpu9U-D0.js";import{d as Ce,s as f,a as X}from"../chunks/D8mhvFt8.js";import{i as Y}from"../chunks/DKve45Wd.js";import{e as ce,i as Se,s as he,a as le,r as Pe}from"../chunks/60_R_Vbt.js";import{a as _e,r as Ze}from"../chunks/P1-U_Xsj.js";import{b as Ee}from"../chunks/CnZzd20v.js";import{s as de}from"../chunks/EqHb-9AZ.js";import{N as Ie}from"../chunks/CcUbQ_Wl.js";import{P as Be}from"../chunks/BHDZZvku.js";import{I as je}from"../chunks/D7A-gG4Z.js";import{A as we}from"../chunks/DcKTNC6e.js";import{s as He}from"../chunks/DPdYG9yN.js";function Le(n){return n>=.92?"near-identical":n>=.8?"strong":"weak"}function be(n){const a=Le(n);return a==="near-identical"?"var(--color-decay)":a==="strong"?"var(--color-warning)":"#fde047"}function Oe(n){const a=Le(n);return a==="near-identical"?"Near-identical":a==="strong"?"Strong match":"Weak match"}function ze(n){return n>.7?"#10b981":n>.4?"#f59e0b":"#ef4444"}function Ue(n){if(!n||n.length===0)return null;let a=n[0],d=Number.isFinite(a.retention)?a.retention:-1/0;for(let v=1;v<n.length;v++){const w=n[v],k=Number.isFinite(w.retention)?w.retention:-1/0;k>d&&(a=w,d=k)}return a}function We(n,a){return n.filter(d=>d.similarity>=a)}function ke(n){return n.map(a=>a.id).slice().sort().join("|")}function Ke(n,a=80){if(!n)return"";const d=n.trim().replace(/\s+/g," ");return d.length<=a?d:d.slice(0,a)+"…"}function Te(n){if(!n||typeof n!="string")return"";const a=new Date(n);return Number.isNaN(a.getTime())?"":a.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}function Ge(n,a=4){return Array.isArray(n)?n.slice(0,a):[]}var Ve=m('<span class="rounded bg-recall/15 px-1.5 py-0.5 text-[10px] font-medium text-recall">WINNER</span>'),Xe=m('<span class="rounded bg-white/[0.04] px-1.5 py-0.5 text-[10px] text-muted"> </span>'),Ye=m('<div class="text-[11px] text-muted"> </div>'),qe=m('<div><span class="mt-1.5 h-2 w-2 flex-shrink-0 rounded-full"></span> <div class="flex-1 min-w-0 space-y-1.5"><div class="flex flex-wrap items-center gap-1.5"><span class="text-xs text-dim"> </span> <!> <!></div> <p> </p> <!></div> <div class="flex flex-shrink-0 flex-col items-end gap-1"><div class="h-1.5 w-12 overflow-hidden rounded-full bg-deep"><div class="h-full rounded-full"></div></div> <span class="text-[11px] text-muted"> </span></div></div>'),Je=m('<div class="glass-panel rounded-2xl p-5 space-y-4 transition-all duration-300 hover:border-synapse/20"><div class="flex items-start justify-between gap-4"><div class="flex-1 min-w-0 space-y-1.5"><div class="flex items-center gap-3"><span class="text-sm font-semibold"> </span> <span class="text-xs text-dim"> </span> <span class="text-xs text-muted"> </span></div> <div class="h-2 w-full overflow-hidden rounded-full bg-deep/60" role="progressbar" aria-label="Cosine similarity" aria-valuemin="0" aria-valuemax="100"><div class="h-full rounded-full transition-all duration-500"></div></div></div> <span> </span></div> <div class="space-y-2"></div> <div class="flex flex-wrap items-center gap-2 pt-1"><button type="button" aria-label="Merge all memories into the highest-retention winner" class="rounded-lg bg-recall/20 px-3 py-1.5 text-xs font-medium text-recall transition hover:bg-recall/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-recall/60">Merge all → winner</button> <button type="button" class="rounded-lg bg-dream/20 px-3 py-1.5 text-xs font-medium text-dream-glow transition hover:bg-dream/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-dream-glow/60"> </button> <button type="button" aria-label="Dismiss cluster for this session" class="ml-auto rounded-lg bg-white/[0.04] px-3 py-1.5 text-xs text-dim transition hover:bg-white/[0.08] hover:text-text focus:outline-none focus-visible:ring-2 focus-visible:ring-synapse/60">Dismiss cluster</button></div></div>');function Qe(n,a){Ae(a,!0);let d=V(!1);const v=O(()=>Ue(a.memories)),w=O(()=>e(v)?a.memories.filter(y=>y.id!==e(v).id).map(y=>y.id):[]);function k(){a.onMerge&&e(v)&&a.onMerge(e(v).id,e(w))}var C=Ne(),q=De(C);{var ue=y=>{var J=Je(),z=s(J),Q=s(z),_=s(Q),P=s(_),ie=s(P);r(P);var U=o(P,2),ve=s(U,!0);r(U);var W=o(U,2),se=s(W);r(W),r(_);var Z=o(_,2),$=s(Z);r(Z),r(Q);var S=o(Q,2),ne=s(S);r(S),r(z);var ee=o(z,2);ce(ee,21,()=>a.memories,T=>T.id,(T,c)=>{var L=qe(),I=s(L),B=o(I,2),j=s(B),t=s(j),i=s(t,!0);r(t);var l=o(t,2);{var p=h=>{var D=Ve();u(h,D)};Y(l,h=>{e(c).id===e(v).id&&h(p)})}var b=o(l,2);ce(b,17,()=>Ge(e(c).tags,4),Se,(h,D)=>{var H=Xe(),fe=s(H,!0);r(H),M(()=>f(fe,e(D))),u(h,H)}),r(j);var g=o(j,2),x=s(g,!0);r(g);var ae=o(g,2);{var re=h=>{var D=Ye(),H=s(D,!0);r(D),M(fe=>f(H,fe),[()=>Te(e(c).createdAt)]),u(h,D)},oe=O(()=>Te(e(c).createdAt));Y(ae,h=>{e(oe)&&h(re)})}r(B);var R=o(B,2),G=s(R),ge=s(G);r(G);var F=o(G,2),N=s(F);r(F),r(R),r(L),M((h,D,H)=>{he(L,1,`group flex items-start gap-3 rounded-xl border border-synapse/5 bg-white/[0.02] p-3 transition-all duration-200 hover:border-synapse/20 hover:bg-white/[0.04] ${e(c).id===e(v).id?"ring-1 ring-recall/30":""}`),de(I,`background: ${(Ie[e(c).nodeType]||"#8B95A5")??""}`),le(I,"title",e(c).nodeType),f(i,e(c).nodeType),he(g,1,`text-sm text-text leading-relaxed ${e(d)?"whitespace-pre-wrap":""}`),f(x,h),de(ge,`width: ${e(c).retention*100}%; background: ${D??""}`),f(N,`${H??""}%`)},[()=>e(d)?e(c).content:Ke(e(c).content),()=>ze(e(c).retention),()=>(e(c).retention*100).toFixed(0)]),u(T,L)}),r(ee);var K=o(ee,2),te=s(K),E=o(te,2),me=s(E,!0);r(E);var pe=o(E,2);r(K),r(J),M((T,c,L,I,B,j,t,i)=>{de(P,`color: ${T??""}`),f(ie,`${c??""}%`),f(ve,L),f(se,`· ${a.memories.length??""} memories`),le(Z,"aria-valuenow",I),de($,`width: ${B??""}%; background: ${j??""}; box-shadow: 0 0 12px ${t??""}66`),he(S,1,`flex-shrink-0 rounded-full border px-3 py-1 text-xs font-medium ${a.suggestedAction==="merge"?"border-recall/40 bg-recall/10 text-recall":"border-dream-glow/40 bg-dream/10 text-dream-glow"}`),f(ne,`Suggested: ${a.suggestedAction==="merge"?"Merge":"Review"}`),le(te,"title",`Merge all into highest-retention memory (${i??""}%)`),le(E,"aria-expanded",e(d)),f(me,e(d)?"Collapse":"Review")},[()=>be(a.similarity),()=>(a.similarity*100).toFixed(1),()=>Oe(a.similarity),()=>Math.round(a.similarity*100),()=>(a.similarity*100).toFixed(1),()=>be(a.similarity),()=>be(a.similarity),()=>(e(v).retention*100).toFixed(0)]),X("click",te,k),X("click",E,()=>A(d,!e(d))),X("click",pe,function(...T){var c;(c=a.onDismiss)==null||c.apply(this,T)}),u(y,J)};Y(q,y=>{a.memories.length>0&&e(v)&&y(ue)})}u(n,C),Me()}Ce(["click"]);var $e=m('<span class="ping-host flex h-2 w-2 items-center justify-center text-synapse-glow" aria-hidden="true"><span class="breathe h-2 w-2 rounded-full bg-synapse-glow"></span></span> <span class="text-xs text-dim">Live</span>',1),et=m('<span class="breathe h-2 w-2 rounded-full bg-synapse-glow text-synapse-glow"></span> <span>Detecting…</span>',1),tt=m('<span class="h-2 w-2 rounded-full bg-decay"></span> <span class="text-decay">Error</span>',1),at=m('<span class="breathe h-2 w-2 rounded-full bg-synapse-glow text-synapse-glow"></span> <span class="tabular-nums"><!> <!> </span>',1),rt=m(`<div class="glass-panel flex flex-col items-center gap-3 rounded-2xl p-10 text-center"><div class="text-sm text-decay">Couldn't detect duplicates</div> <div class="max-w-md text-xs text-muted"> </div> <button type="button" class="mt-2 rounded-lg bg-synapse/20 px-4 py-2 text-xs font-medium text-synapse-glow transition hover:bg-synapse/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-synapse/60">Retry</button></div>`),it=m('<div class="glass-subtle shimmer h-40 rounded-2xl"></div>'),st=m('<div class="space-y-3"></div>'),nt=m('<div class="glass-panel enter flex flex-col items-center gap-3 rounded-2xl p-12 text-center"><div class="flex h-14 w-14 items-center justify-center rounded-2xl border border-recall/25 bg-recall/10 text-recall"><!></div> <div class="text-sm font-medium text-bright">No duplicates found — your memory is clean.</div> <div class="max-w-sm text-xs text-muted"> </div></div>'),ot=m('<div class="glass-subtle rounded-xl border border-warning/30 bg-warning/5 px-4 py-2 text-xs text-dim"> </div>'),lt=m('<div class="spotlight-surface lift rounded-2xl"><div class="relative z-[1]"><!></div></div>'),dt=m('<div class="space-y-4"><!> <!></div>'),ct=m('<div class="relative mx-auto max-w-5xl space-y-6 p-6"><!> <div class="glass-panel flex flex-wrap items-center gap-5 rounded-2xl p-4"><label class="flex flex-1 min-w-64 items-center gap-3 text-xs text-dim"><span class="whitespace-nowrap">Similarity threshold</span> <input type="range" min="0.70" max="0.95" step="0.01" class="flex-1 accent-synapse" aria-label="Similarity threshold"/> <span class="w-14 text-right font-mono text-sm text-bright"> </span></label> <div class="flex items-center gap-2 rounded-full border border-synapse/20 bg-synapse/10 px-3 py-1.5 text-xs text-text" role="status" aria-live="polite"><!></div> <button type="button" class="rounded-lg bg-white/[0.04] px-3 py-1.5 text-xs text-dim transition hover:bg-white/[0.08] hover:text-text disabled:opacity-40 focus:outline-none focus-visible:ring-2 focus-visible:ring-synapse/60">Rerun</button></div> <!></div>');function At(n,a){Ae(a,!0);let d=V(.8),v=V(ye([])),w=V(ye(new Set)),k=V(!0),C=V(null),q;async function ue(t){return await new Promise(l=>setTimeout(l,450)),{clusters:We([{similarity:.96,suggestedAction:"merge",memories:[{id:"m-001",content:"BUG FIX: Harmony parser dropped `final` channel tokens when tool call followed. Root cause: 5-layer fallback missed the final channel marker when channel switched mid-stream. Solution: added final-channel detector before tool-call pop. Files: src/parser/harmony.rs",nodeType:"fact",tags:["bug-fix","benchmark-suite","parser"],retention:.91,createdAt:"2026-04-12T14:22:00Z"},{id:"m-002",content:"Fixed Harmony parser final-channel bug — 5-layer fallback was missing the final channel marker when a tool call followed. Added detector before tool pop.",nodeType:"fact",tags:["bug-fix","benchmark-suite"],retention:.64,createdAt:"2026-04-13T09:15:00Z"},{id:"m-003",content:"Harmony parser: final channel dropped on tool-call. Patched the fallback stack.",nodeType:"note",tags:["parser"],retention:.38,createdAt:"2026-04-14T11:02:00Z"}]},{similarity:.88,suggestedAction:"merge",memories:[{id:"m-004",content:"DECISION: Use vLLM prefix caching at 0.35 gpu_memory_utilization for benchmark suite submissions. Alternatives considered: sglang (slower cold start), TensorRT-LLM (deployment friction).",nodeType:"decision",tags:["vllm","benchmark-suite","inference"],retention:.84,createdAt:"2026-04-05T18:44:00Z"},{id:"m-005",content:"Chose vLLM with prefix caching (0.35 mem util) over sglang and TensorRT-LLM for benchmark suite inference.",nodeType:"decision",tags:["vllm","benchmark-suite"],retention:.72,createdAt:"2026-04-06T10:30:00Z"}]},{similarity:.83,suggestedAction:"review",memories:[{id:"m-006",content:"Release process prefers one change per benchmark submission — stacking changes destroyed signal in a prior run.",nodeType:"pattern",tags:["methodology","benchmark-suite"],retention:.88,createdAt:"2026-04-04T22:10:00Z"},{id:"m-007",content:"One-variable-at-a-time rule: never stack multiple changes per submission. Paper 2603.27844 proves +/-2 points is noise.",nodeType:"pattern",tags:["kaggle","methodology"],retention:.67,createdAt:"2026-04-08T16:20:00Z"},{id:"m-008",content:"Lesson: stacking many changes in one benchmark run hid the causal signal. Always isolate variables.",nodeType:"note",tags:["methodology"],retention:.42,createdAt:"2026-04-15T08:55:00Z"}]},{similarity:.78,suggestedAction:"review",memories:[{id:"m-009",content:"Dimensional Illusion performance: 7-minute flow poi set, LED config Parthenos overcook preset, tempo 128 BPM.",nodeType:"event",tags:["dimensional-illusion","poi","performance"],retention:.76,createdAt:"2026-03-28T19:45:00Z"},{id:"m-010",content:"Dimensional Illusion set: 7 min, Parthenos LED overcook, 128 BPM.",nodeType:"event",tags:["dimensional-illusion","poi"],retention:.51,createdAt:"2026-04-02T12:12:00Z"}]},{similarity:.76,suggestedAction:"review",memories:[{id:"m-011",content:"Vestige v2.0.7 shipped active forgetting via Anderson 2025 top-down inhibition + Davis Rac1 cascade. Suppress compounds, reversible 24h.",nodeType:"fact",tags:["vestige","release","active-forgetting"],retention:.93,createdAt:"2026-04-17T03:22:00Z"},{id:"m-012",content:"Active Forgetting feature: compounds on each suppress, 24h reversible labile window, violet implosion animation in graph view.",nodeType:"concept",tags:["vestige","active-forgetting"],retention:.81,createdAt:"2026-04-18T09:07:00Z"}]}],t)}}async function y(){A(k,!0),A(C,null);try{const t=await ue(e(d));A(v,t.clusters,!0);const i=new Set(e(v).map(p=>ke(p.memories))),l=new Set;for(const p of e(w))i.has(p)&&l.add(p);A(w,l,!0)}catch(t){A(C,t instanceof Error?t.message:"Failed to detect duplicates",!0),A(v,[],!0)}finally{A(k,!1)}}function J(){clearTimeout(q),q=setTimeout(y,250)}function z(t){const i=new Set(e(w));i.add(t),A(w,i,!0)}function Q(t,i,l){console.log("Merge cluster",t,{winnerId:i,loserIds:l}),z(t)}const _=O(()=>e(v).map(t=>({c:t,key:ke(t.memories)})).filter(({key:t})=>!e(w).has(t))),P=O(()=>e(_).reduce((t,{c:i})=>t+i.memories.length,0)),ie=50,U=O(()=>e(_).length>ie),ve=O(()=>e(U)?e(_).slice(0,ie):e(_));Re(()=>y()),Fe(()=>clearTimeout(q));var W=ct(),se=s(W);Be(se,{icon:"duplicates",title:"Memory Hygiene — Duplicate Detection",subtitle:"Cosine-similarity clustering over embeddings. Merges reinforce the winner's FSRS state; losers inherit into the merged node. Dismissed clusters are hidden for this session only.",accent:"synapse",children:(t,i)=>{var l=$e();xe(2),u(t,l)},$$slots:{default:!0}});var Z=o(se,2),$=s(Z),S=o(s($),2);Pe(S);var ne=o(S,2),ee=s(ne);r(ne),r($);var K=o($,2),te=s(K);{var E=t=>{var i=et();xe(2),u(t,i)},me=t=>{var i=tt();xe(2),u(t,i)},pe=t=>{var i=at(),l=o(De(i),2),p=s(l);we(p,{get value(){return e(_).length}});var b=o(p),g=o(b);we(g,{get value(){return e(P)}});var x=o(g);r(l),M(()=>{f(b,` ${e(_).length===1?"cluster":"clusters"}, `),f(x,` potential duplicate${e(P)===1?"":"s"}`)}),u(t,i)};Y(te,t=>{e(k)?t(E):e(C)?t(me,1):t(pe,!1)})}r(K);var T=o(K,2);r(Z);var c=o(Z,2);{var L=t=>{var i=rt(),l=o(s(i),2),p=s(l,!0);r(l);var b=o(l,2);r(i),M(()=>f(p,e(C))),X("click",b,y),u(t,i)},I=t=>{var i=st();ce(i,20,()=>Array(3),Se,(l,p)=>{var b=it();u(l,b)}),r(i),u(t,i)},B=t=>{var i=nt(),l=s(i),p=s(l);je(p,{name:"sparkle",size:26,draw:!0}),r(l);var b=o(l,4),g=s(b);r(b),r(i),M(x=>f(g,`Nothing clusters above ${x??""}% similarity. Lower the threshold to
|
|
surface looser matches.`),[()=>(e(d)*100).toFixed(0)]),u(t,i)},j=t=>{var i=dt(),l=s(i);{var p=g=>{var x=ot(),ae=s(x);r(x),M(()=>f(ae,`Showing first 50 of ${e(_).length??""} clusters. Raise the
|
|
threshold to narrow results.`)),u(g,x)};Y(l,g=>{e(U)&&g(p)})}var b=o(l,2);ce(b,19,()=>e(ve),({c:g,key:x})=>x,(g,x,ae)=>{let re=()=>e(x).c,oe=()=>e(x).key;var R=lt(),G=s(R),ge=s(G);Qe(ge,{get similarity(){return re().similarity},get memories(){return re().memories},get suggestedAction(){return re().suggestedAction},onDismiss:()=>z(oe()),onMerge:(F,N)=>Q(oe(),F,N)}),r(G),r(R),_e(R,(F,N)=>{var h;return(h=Ze)==null?void 0:h(F,N)},()=>({delay:Math.min(e(ae)*40,400),y:14})),_e(R,F=>{var N;return(N=He)==null?void 0:N(F)}),u(g,R)}),r(i),u(t,i)};Y(c,t=>{e(C)?t(L):e(k)?t(I,1):e(_).length===0?t(B,2):t(j,!1)})}r(W),M(t=>{f(ee,`${t??""}%`),T.disabled=e(k)},[()=>(e(d)*100).toFixed(0)]),X("input",S,J),Ee(S,()=>e(d),t=>A(d,t)),X("click",T,y),u(n,W),Me()}Ce(["input","click"]);export{At as component};
|