Commit graph

12 commits

Author SHA1 Message Date
Sam Valladares
30d92b5371 feat(graph): redesign node labels as dark glass pills
Some checks are pending
CI / Test (macos-latest) (push) Waiting to run
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Release Build (aarch64-apple-darwin) (push) Blocked by required conditions
CI / Release Build (x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Test Suite / Unit Tests (push) Waiting to run
Test Suite / MCP E2E Tests (push) Waiting to run
Test Suite / User Journey Tests (push) Blocked by required conditions
Test Suite / Dashboard Build (push) Waiting to run
Test Suite / Code Coverage (push) Waiting to run
Labels previously rendered as near-white text (#e2e8f0) on a transparent
canvas. UnrealBloomPass (threshold 0.2) amplified every bright pixel
into a huge white halo that made labels unreadable at normal camera
distances — reported by Sam 2026-04-19 with a screenshot of the LoRA
training label blown out into a luminous blob.

New design:

- Dark rounded pill (rgba(10,16,28,0.82)) sits below the text and
  hugs its measured width. That keeps the pill background well below
  bloom threshold so the halo can't spread past the label footprint.
- Text dimmed to mid-luminance slate (#94a3b8). Still legible at the
  standard camera distance but dim enough that bloom only adds a soft
  glow instead of a blast.
- Font trimmed to 22px / weight 600 (was bold 28px); sprite scale
  tightened from 12×1.5 to 9×1.2 so labels don't visually out-compete
  the node spheres they annotate.
- Hairline slate stroke (18% alpha) on the pill for definition when
  the camera gets close.

The canvas mock in the vitest setup grew beginPath / closePath /
moveTo / lineTo / quadraticCurveTo / arc / fill / stroke / strokeText
stubs so createTextSprite can exercise the full rounded-rect path in
unit tests without a real DOM. All 251 tests stay green.
2026-04-19 21:52:14 -05:00
Sam Valladares
d7f0fe03e0 test(graph): ruthless coverage for v2.0.8 memory-state colour mode
80 new vitest cases exhaustively exercising the v2.0.8 colour-mode
additions, taking total dashboard coverage to 251 tests.

Pure-function correctness:
- getMemoryState: 12 retention boundaries including exact thresholds,
  NaN, ±Infinity, negative, and >1 values + determinism across 10k
  random samples.
- getNodeColor: per-node-type mapping in type mode (all 8 types),
  per-bucket mapping in state mode, unknown-type fallback, and the
  invariants that type mode ignores retention + state mode ignores type.
- MEMORY_STATE_COLORS: valid 6-digit hex, all four buckets distinct,
  zero overlap with NODE_TYPE_COLORS.
- MEMORY_STATE_DESCRIPTIONS: threshold parentheticals match getMemoryState
  bucket boundaries (70 / 40 / 10), all four lines distinct.

NodeManager state machine:
- default mode 'type', field writable pre-createNodes.
- setColorMode is idempotent (early return verified via copy() spy counts).
- setColorMode calls color.copy + emissive.copy + glow.color.copy exactly
  once per node per transition, never replaces mesh / glow / material
  references, preserves userData.{nodeId,type,retention}.
- rapid 5× type <-> state toggle preserves all three maps.
- addNode during state mode inherits the mode; subsequent switch to
  type correctly retints the live-added node.
- suppressed-node interaction: setColorMode updates color + emissive but
  never touches opacity or emissiveIntensity (v2.0.5 SIF channel stays
  isolated from v2.0.8 colour channel).
- defensive paths: missing glow, missing userData.retention, missing
  userData.type — all degrade to sane defaults without throwing.

Also refreshes the embedded dashboard build so the Rust binary picks up
the new SvelteKit chunks with the memory-state-colors feature baked in.
2026-04-19 21:12:06 -05:00
Sam Valladares
4c2016596c feat(graph): FSRS memory-state colour mode + legend overlay
Closes Agent 1's audit gap #4: FSRS memory state (Active / Dormant /
Silent / Unavailable) was computed server-side per query but never
rendered in the 3D graph. Spheres always tinted by node type.

The new colour mode adds a second channel that users can toggle
between at runtime — Type (default, existing behaviour) and State
(new). The toggle is a radio-pair pill in the graph page's top-right
control bar next to the node-count selector + Dream button.

Buckets + palette:
- Active    ≥ 70%  emerald #10b981  easily retrievable
- Dormant  40-70%  amber   #f59e0b  retrievable with effort
- Silent   10-40%  violet  #8b5cf6  difficult, needs cues
- Unavail.  < 10%  slate   #6b7280  needs reinforcement

Thresholds match `execute_system_status` at the backend so the graph
colour bands line up exactly with what the Stats page reports in its
stateDistribution block. Using retention as the proxy for the full
accessibility formula (retention × 0.5 + retrieval × 0.3 + storage ×
0.2) is an approximation — retention is the dominant 0.5 weight and
it is the only FSRS channel the current GraphNode DTO carries. Swap
to the full formula in a future release if the DTO grows.

Implementation:
- `apps/dashboard/src/lib/graph/nodes.ts` — new `MemoryState` type,
  `getMemoryState(retention)`, `MEMORY_STATE_COLORS`,
  `MEMORY_STATE_DESCRIPTIONS`, `ColorMode`, `getNodeColor(node, mode)`.
- `NodeManager.colorMode` field (default `'type'`). `createNodeMeshes`
  now calls `getNodeColor(node, this.colorMode)` so newly-added nodes
  during the session follow the toggled mode.
- New `NodeManager.setColorMode(mode)` mutates every live mesh's
  material + glow sprite colour in place. Idempotent; cheap. Does NOT
  touch opacity/emissive-intensity so the v2.0.5 suppression dimming
  layer keeps working unchanged.
- New `MemoryStateLegend.svelte` floating overlay in the bottom-right
  when state mode is active (hidden in type mode so the legend doesn't
  compete with the node-type palette).
- `Graph3D.svelte` accepts a new `colorMode` prop (default `'type'`)
  and runs a `$effect` that calls `setColorMode` on every toggle.
- Dashboard rebuild picks up the new component + wiring.

Tests: 171 vitest, svelte-check 581 files / 0 errors. No backend
changes; this is pure dashboard code.
2026-04-19 20:45:08 -05:00
Sam Valladares
40b963e15b chore(release): v2.0.7 "Visible"
Hygiene release + two UI gap closures. Full CHANGELOG in CHANGELOG.md.

Version bumps:
- vestige-core: 2.0.6 -> 2.0.7
- vestige-mcp: 2.0.6 -> 2.0.7
- @vestige/dashboard: 2.0.6 -> 2.0.7
- @vestige/init: 2.0.6 -> 2.0.7
- vestige-mcp-server: 2.0.6 -> 2.0.7

Rebuild: pnpm --dir apps/dashboard run build regenerates apps/dashboard/build/**
with the v2.0.7 asset hashes.

Pre-release validation green:
- cargo check --workspace: clean
- cargo test -p vestige-core --lib: 366 passed
- cargo test -p vestige-mcp --lib: 425 passed
- pnpm run check (svelte-check): 580 files, 0 errors
- cargo clippy on touched crates: -D warnings clean
- 4-parallel-agent pre-merge audit passed (security, code quality,
  end-to-end flow, external verification). Two MEDIUM fixes landed
  in-branch before tag.

The 12 feature/fix commits on chore/v2.0.7-clean are preserved via
fast-forward merge so each logical change stays independently
revertible on main.
2026-04-19 20:37:11 -05:00
Sam Valladares
6c24a0ca69 chore(release): v2.0.6 "Composer" — rebuild + version bump + CHANGELOG
Some checks are pending
CI / Test (macos-latest) (push) Waiting to run
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Release Build (aarch64-apple-darwin) (push) Blocked by required conditions
CI / Release Build (x86_64-unknown-linux-gnu) (push) Blocked by required conditions
Test Suite / Unit Tests (push) Waiting to run
Test Suite / MCP E2E Tests (push) Waiting to run
Test Suite / User Journey Tests (push) Blocked by required conditions
Test Suite / Dashboard Build (push) Waiting to run
Test Suite / Code Coverage (push) Waiting to run
Bumps vestige-core + vestige-mcp + @vestige/dashboard +
vestige-mcp-server + @vestige/init from 2.0.5 → 2.0.6, regenerates the
Cargo.lock, rebuilds the dashboard with the new events.ts handlers +
intentions page fix baked in, and writes the v2.0.6 "Composer" entry
to CHANGELOG.md.

Release contents:
- fix(dashboard): intentions page priority + trigger rendering
  (commit 9df63de)
- feat(dashboard): wire 6 graph event handlers — suppress, unsuppress,
  Rac1 cascade, Connected, ConsolidationStarted, ImportanceScored
  (commit f085cfd)
- feat(mcp): opt-in VESTIGE_SYSTEM_PROMPT_MODE=full composition mandate
  (commit 7d7a7c2)
- docs(readme): v2.0.6 header + Intel Mac / Windows build-from-source
  honesty (commit ede0a02)

Pre-push gates green: cargo test --workspace --release, cargo clippy
--all-targets -D warnings, svelte-check (580 files 0 errors), vitest
(171/171). No regressions of merged PRs #18/20/22/24/26/28/29/30/32/33.
2026-04-18 18:33:31 -05:00
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
Alphaleonis
b05168ba9d fix: dashboard nav links now include /dashboard base path prefix
All sidebar links, mobile nav links, command palette navigation, logo link,
and the graph page "Explore Connections" link now correctly use SvelteKit's
base path. Also fixes favicon.svg and manifest.json paths in app.html.

Fixes: https://github.com/samvallad33/vestige/issues/17

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 23:41:50 +01:00
Sam Valladares
85fcaedcef fix: resolve CI failures — clippy lint + lockfile sync
- unwrap_or_else → unwrap_or for constant IpAddr (Rust 1.93 clippy)
- Update pnpm-lock.yaml with vitest/playwright dev deps
- Rebuild dashboard build/ artifacts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:20:37 -06:00
Sam Valladares
9bdcc69ce3 feat: live memory materialization — nodes spawn in 3D graph in real-time
When memories are created, promoted, deleted, or dreamed via MCP tools,
the 3D graph now shows spectacular live animations:

- Rainbow particle burst + elastic scale-up on MemoryCreated
- Ripple wave cascading to nearby nodes
- Green pulse + node growth on MemoryPromoted
- Implosion + dissolution on MemoryDeleted
- Edge growth animation on ConnectionDiscovered
- Purple cascade on DreamStarted/DreamProgress/DreamCompleted
- FIFO eviction at 50 live nodes to guard performance

Also: graph center defaults to most-connected node, legacy HTML
redirects to SvelteKit dashboard, CSS height chain fix in layout.

Testing: 150 unit tests (vitest), 11 e2e tests (Playwright with
MCP Streamable HTTP client), 22 proof screenshots.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:04:31 -06:00
Sam Valladares
d98cf6136a feat: dashboard v2.1 glassmorphism + graph decomposition + fix flaky macOS vector test
Dashboard v2.1 "Nuclear" upgrade:
- Dark glassmorphism UI system (4-tier glass utilities, ambient orbs, nav glow)
- Graph3D decomposed from 806-line monolith into 10 focused modules
- Custom GLSL shaders (nebula FBM background, chromatic aberration, film grain, vignette)
- Enhanced dream mode with smooth 2s lerped transitions and aurora cycling
- Cognitive pipeline visualizer (7-stage search cascade animation)
- Temporal playback slider (scrub through memory evolution over time)
- Bioluminescent color palette for node types and events

Fix flaky CI test on macOS:
- vector::tests::test_add_and_search used near-identical test vectors (additive phase shift)
- Changed to multiplicative frequency so each seed produces a distinct vector

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:24:10 -06:00
Sam Valladares
ec2af6e71b fix: comprehensive audit fixes for dashboard and backend
Backend:
- Emit WebSocket events from REST delete/promote/demote handlers
- Emit DreamStarted/ConsolidationStarted from MCP tool dispatch
- Add path validation in backup_to() for defense-in-depth

Dashboard:
- Fix ConnectionDiscovered field names (source_id/target_id)
- Fix $effect → onMount in settings (prevents infinite loop)
- Fix $derived → $derived.by in RetentionCurve
- Fix field name mismatches in settings (nodesProcessed, etc.)
- Fix nested <button> → <span role="button"> in memories
- Fix unhandled Promise rejection in stats consolidation
- Add missing EVENT_TYPE_COLORS entries
- Add Three.js resource disposal and event listener cleanup
- Eliminate duplicate root page, redirect to /graph
- Update nav links and keyboard shortcuts to /graph

All 734+ tests passing, 22MB binary, zero build warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:50:47 -06:00
Sam Valladares
c2d28f3433 feat: Vestige v2.0.0 "Cognitive Leap" — 3D dashboard, HyDE search, WebSocket events
The biggest release in Vestige history. Complete visual and cognitive overhaul.

Dashboard:
- SvelteKit 2 + Three.js 3D neural visualization at localhost:3927/dashboard
- 7 interactive pages: Graph, Memories, Timeline, Feed, Explore, Intentions, Stats
- WebSocket event bus with 16 event types, real-time 3D animations
- Bloom post-processing, GPU instanced rendering, force-directed layout
- Dream visualization mode, FSRS retention curves, command palette (Cmd+K)
- Keyboard shortcuts, responsive mobile layout, PWA installable
- Single binary deployment via include_dir! (22MB)

Engine:
- HyDE query expansion (intent classification + 3-5 semantic variants + centroid)
- fastembed 5.11 with optional Nomic v2 MoE + Qwen3 reranker + Metal GPU
- Emotional memory module (#29)
- Criterion benchmark suite

Backend:
- Axum WebSocket at /ws with heartbeat + event broadcast
- 7 new REST endpoints for cognitive operations
- Event emission from MCP tools via shared broadcast channel
- CORS for SvelteKit dev mode

Distribution:
- GitHub issue templates (bug report, feature request)
- CHANGELOG with comprehensive v2.0 release notes
- README updated with dashboard docs, architecture diagram, comparison table

734 tests passing, zero warnings, 22MB release binary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 03:07:25 -06:00