mirror of
https://github.com/samvallad33/vestige.git
synced 2026-06-16 21:05:15 +02:00
Compare commits
36 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16903f3ab4 | ||
|
|
31890278d3 | ||
|
|
47de61f2d2 | ||
|
|
51f08264f7 | ||
|
|
c23d7a309c | ||
|
|
b01269db22 | ||
|
|
5aa261398d | ||
|
|
241dfdd6cb | ||
|
|
603efdcb2c | ||
|
|
a355da99a6 | ||
|
|
6a37586c5f | ||
|
|
67f9550e6c | ||
|
|
00511948ff | ||
|
|
d8de7daf11 | ||
|
|
c9f457dd94 | ||
|
|
cd496e562c | ||
|
|
8c18231a20 | ||
|
|
3df930ca7e | ||
|
|
14b061f124 | ||
|
|
21f0b29bae | ||
|
|
fc0681ed0f | ||
|
|
9ef8afdb20 | ||
|
|
697ade5b02 | ||
|
|
c584ec8afe | ||
|
|
a8550410b0 | ||
|
|
1399329810 | ||
|
|
c4e90f7f4a | ||
|
|
3c913f9942 | ||
|
|
7eba0b1e97 | ||
|
|
9936928be9 | ||
|
|
c3c54d4e97 | ||
|
|
c77b05078c | ||
|
|
fb250207a3 | ||
|
|
4e9e11ac0b | ||
|
|
9c633c172b | ||
|
|
0d273c5641 |
425 changed files with 33173 additions and 3462 deletions
94
.github/workflows/release.yml
vendored
94
.github/workflows/release.yml
vendored
|
|
@ -50,14 +50,93 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.tag || github.ref }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Validate release version
|
||||
shell: bash
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.inputs.tag || github.ref_name }}
|
||||
run: |
|
||||
node <<'NODE'
|
||||
const { execFileSync } = require('node:child_process');
|
||||
const tag = process.env.RELEASE_TAG || '';
|
||||
const expected = tag.replace(/^refs\/tags\//, '').replace(/^v/, '');
|
||||
if (!expected) {
|
||||
throw new Error('Release tag is empty');
|
||||
}
|
||||
|
||||
const packageFiles = [
|
||||
'package.json',
|
||||
'apps/dashboard/package.json',
|
||||
'packages/vestige-init/package.json',
|
||||
'packages/vestige-mcp-npm/package.json'
|
||||
];
|
||||
for (const file of packageFiles) {
|
||||
const actual = require(`./${file}`).version;
|
||||
if (actual !== expected) {
|
||||
throw new Error(`${file} version ${actual} does not match ${tag}`);
|
||||
}
|
||||
}
|
||||
|
||||
const metadata = JSON.parse(execFileSync('cargo', [
|
||||
'metadata',
|
||||
'--format-version',
|
||||
'1',
|
||||
'--locked',
|
||||
'--no-deps'
|
||||
], { encoding: 'utf8' }));
|
||||
for (const name of ['vestige-core', 'vestige-mcp']) {
|
||||
const pkg = metadata.packages.find((candidate) => candidate.name === name);
|
||||
if (!pkg) throw new Error(`Missing Cargo package ${name}`);
|
||||
if (pkg.version !== expected) {
|
||||
throw new Error(`${name} version ${pkg.version} does not match ${tag}`);
|
||||
}
|
||||
}
|
||||
NODE
|
||||
|
||||
- name: Build embedded dashboard
|
||||
shell: bash
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.inputs.tag || github.ref_name }}
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm --filter @vestige/dashboard check
|
||||
pnpm --filter @vestige/dashboard test
|
||||
pnpm --filter @vestige/dashboard build
|
||||
node <<'NODE'
|
||||
const fs = require('node:fs');
|
||||
const tag = process.env.RELEASE_TAG || '';
|
||||
const expected = tag.replace(/^refs\/tags\//, '').replace(/^v/, '');
|
||||
const versionFile = 'apps/dashboard/build/_app/version.json';
|
||||
const version = JSON.parse(fs.readFileSync(versionFile, 'utf8')).version;
|
||||
if (version !== expected) {
|
||||
throw new Error(`${versionFile} version ${version} does not match ${tag}`);
|
||||
}
|
||||
for (const file of ['apps/dashboard/build/index.html', versionFile]) {
|
||||
if (!fs.existsSync(file)) {
|
||||
throw new Error(`Dashboard build did not produce ${file}`);
|
||||
}
|
||||
}
|
||||
NODE
|
||||
|
||||
- name: Build
|
||||
run: cargo build --package vestige-mcp --release --target ${{ matrix.target }} ${{ matrix.cargo_flags }}
|
||||
run: cargo build --locked --package vestige-mcp --release --target ${{ matrix.target }} ${{ matrix.cargo_flags }}
|
||||
|
||||
- name: Package (Unix)
|
||||
if: matrix.os != 'windows-latest'
|
||||
|
|
@ -77,10 +156,21 @@ jobs:
|
|||
cd target/${{ matrix.target }}/release
|
||||
Compress-Archive -Path vestige-mcp.exe,vestige.exe,vestige-restore.exe -DestinationPath ../../../vestige-mcp-${{ matrix.target }}.zip
|
||||
|
||||
- name: Generate checksum
|
||||
shell: bash
|
||||
run: |
|
||||
if command -v shasum >/dev/null 2>&1; then
|
||||
shasum -a 256 vestige-mcp-${{ matrix.target }}.${{ matrix.archive }} > vestige-mcp-${{ matrix.target }}.${{ matrix.archive }}.sha256
|
||||
else
|
||||
sha256sum vestige-mcp-${{ matrix.target }}.${{ matrix.archive }} > vestige-mcp-${{ matrix.target }}.${{ matrix.archive }}.sha256
|
||||
fi
|
||||
|
||||
- name: Upload to Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.event.inputs.tag || github.ref_name }}
|
||||
files: vestige-mcp-${{ matrix.target }}.${{ matrix.archive }}
|
||||
files: |
|
||||
vestige-mcp-${{ matrix.target }}.${{ matrix.archive }}
|
||||
vestige-mcp-${{ matrix.target }}.${{ matrix.archive }}.sha256
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
13
.github/workflows/test.yml
vendored
13
.github/workflows/test.yml
vendored
|
|
@ -12,6 +12,19 @@ env:
|
|||
VESTIGE_TEST_MOCK_EMBEDDINGS: "1"
|
||||
|
||||
jobs:
|
||||
hook-tests:
|
||||
name: Hook Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.9"
|
||||
- run: python3 -m unittest discover -s tests/hooks -p 'test_*.py'
|
||||
- run: python3 -m py_compile hooks/sanhedrin-local.py tests/hooks/test_sanhedrin_claim_mode.py
|
||||
- run: bash -n hooks/sanhedrin.sh scripts/install-sandwich.sh scripts/check-sandwich-prereqs.sh
|
||||
|
||||
unit-tests:
|
||||
name: Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -139,3 +139,6 @@ apps/dashboard/node_modules/
|
|||
# =============================================================================
|
||||
fastembed-rs/
|
||||
.mcp.json
|
||||
|
||||
.claude/
|
||||
.codebase-memory/
|
||||
|
|
|
|||
251
CHANGELOG.md
251
CHANGELOG.md
|
|
@ -5,6 +5,257 @@ All notable changes to Vestige will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.1.26] - 2026-06-15 — "Configurable Output"
|
||||
|
||||
Roadmap **Phase 2: Configurable Output**. Users can now control the default
|
||||
shape and size of high-traffic MCP responses with an optional, local-first
|
||||
config file — without recompiling and without a cloud service. The default
|
||||
behavior is unchanged: a fresh install with no `vestige.toml` behaves exactly
|
||||
as before.
|
||||
|
||||
### Added
|
||||
|
||||
- **`vestige.toml` config file**, loaded from the active Vestige data directory
|
||||
(`<data_dir>/vestige.toml`, alongside `vestige.db`). A missing or malformed
|
||||
file falls back to built-in defaults, so existing installs are unaffected.
|
||||
- **`[defaults]` table** with three keys: `detail_level`
|
||||
(`brief` | `summary` | `full`), `limit` (default result count for
|
||||
high-traffic tools), and `profile`.
|
||||
- **Output profiles** — `lean`, `default`, `audit`, `research` — each presetting
|
||||
a coherent bundle of detail level, result limit, and whether scores and
|
||||
timestamps are included:
|
||||
- `lean`: `brief` detail, limit 5, scores and timestamps dropped (smallest
|
||||
context cost).
|
||||
- `default`: historical behavior — `summary` detail, tool's own default
|
||||
limit, scores and timestamps present. **Unchanged.**
|
||||
- `audit`: `full` detail with every field, score, and timestamp.
|
||||
- `research`: `full` detail with a larger default limit (25).
|
||||
- **Three-layer precedence**, applied per call: an explicit MCP parameter wins
|
||||
over the config file, which wins over the built-in default.
|
||||
- **`profile` field** echoed in `search`, `memory_timeline`, `codebase`
|
||||
(`get_context`), and `session_context` responses so the active profile is
|
||||
observable.
|
||||
|
||||
### Changed
|
||||
|
||||
- `search`, `memory_timeline`, `codebase` (`get_context`), and
|
||||
`session_context` now resolve their default detail level and result limit
|
||||
through the config file when no explicit parameter is supplied. With no
|
||||
`vestige.toml` present, their output is byte-for-byte identical to v2.1.25.
|
||||
|
||||
### Documentation
|
||||
|
||||
- `docs/CONFIGURATION.md` gains a **Output Configuration (`vestige.toml`)**
|
||||
section documenting the file location, `[defaults]` keys, profile presets,
|
||||
and precedence rules.
|
||||
|
||||
## [2.1.25] - 2026-06-12 — "Merge / Supersede Controls"
|
||||
|
||||
v2.1.25 ships Phase 3: diff-previewed, confidence-gated, reversible,
|
||||
self-explaining combine/dedupe/supersede on a never-delete (bitemporal) store.
|
||||
The default is always preview/review — these tools never silently mutate memory.
|
||||
The differentiator is the reversible operation log: every merge/supersede/undo is
|
||||
an auditable, reversible event with provenance ("why did these combine?") — a git
|
||||
reflog for your agent's memory.
|
||||
|
||||
### Added
|
||||
|
||||
- **Seven new MCP tools** for merge/supersede control:
|
||||
- `merge_candidates` — surface likely duplicate/overlapping clusters with
|
||||
confidence scores and the signals behind each (Fellegi-Sunter
|
||||
match/possible/non-match). Read-only.
|
||||
- `plan_merge` — produce a previewable merge PLAN (a diff of combined
|
||||
content/tags/provenance) without applying it.
|
||||
- `plan_supersede` — preview superseding A with B (bitemporal invalidation,
|
||||
audit-preserving) without applying.
|
||||
- `apply_plan` — execute a previously-generated plan id; recorded as a
|
||||
reversible operation.
|
||||
- `merge_undo` — reverse a prior merge/supersede operation, or list the
|
||||
reversible operation log (the "memory reflog").
|
||||
- `protect` — pin a memory so it can never be auto-merged, superseded, or
|
||||
garbage-collected.
|
||||
- `merge_policy` — get/set the per-project Fellegi-Sunter two thresholds
|
||||
(`match_threshold`, `possible_threshold`) and `auto_apply`.
|
||||
- **Bitemporal "invalidate, don't delete" supersede** (Graphiti-style): a
|
||||
superseded memory is kept and stays queryable for audit. It is stamped with
|
||||
`valid_until = now` and a new `superseded_by` lineage pointer, instead of being
|
||||
deleted or merely demoted.
|
||||
- **Reversible operation log** (`merge_operations` table) — every applied
|
||||
merge/supersede records an undo payload and provenance signals so any operation
|
||||
can be reversed, including restoring survivor content/tags and clearing the
|
||||
bitemporal invalidation.
|
||||
- **Fellegi-Sunter two-threshold scoring** for dedup/merge candidates, combining
|
||||
embedding cosine similarity with tag and content-token overlap. Borderline
|
||||
"possible" matches are surfaced for review instead of force-merged.
|
||||
- **Memory protection / pinning** — `protected` column on `knowledge_nodes`;
|
||||
protected memories are excluded from auto-merge/supersede/GC paths.
|
||||
- **Migration V14** adding the `merge_plans` and `merge_operations` tables, the
|
||||
`protected` and `superseded_by` columns on `knowledge_nodes`, and their
|
||||
indexes. Idempotent on replay.
|
||||
- **Docs**: `docs/MERGE_SUPERSEDE.md` describing the design, the bitemporal
|
||||
model, the two-threshold policy, the reversible operation log, and the tool
|
||||
surface.
|
||||
|
||||
### Notes
|
||||
|
||||
- All merge/supersede operations are **opt-in and preview-first**. `apply_plan`
|
||||
requires `confirm=true` for `possible`/`non_match` plans, and only applies
|
||||
`match` plans without confirmation when `merge_policy.auto_apply` is enabled
|
||||
(default off). This deliberately avoids the silent-merge / auto-delete /
|
||||
audit-trail-loss anti-patterns reported against other memory systems.
|
||||
- The merge policy persists per-project and is also overridable via
|
||||
`VESTIGE_MERGE_MATCH_THRESHOLD`, `VESTIGE_MERGE_POSSIBLE_THRESHOLD`, and
|
||||
`VESTIGE_MERGE_AUTO_APPLY` environment variables.
|
||||
|
||||
## [2.1.23] - 2026-05-27 — "Receipt Lock Hardening"
|
||||
|
||||
v2.1.23 hardens the Sanhedrin launch path so Receipt Lock is portable,
|
||||
observable, and precise enough for broader use.
|
||||
|
||||
### Added
|
||||
|
||||
- **Model-agnostic Sanhedrin backend presets** for custom OpenAI-compatible
|
||||
servers, small laptops, Ollama, MLX, vLLM, llama.cpp, hosted APIs, and
|
||||
Anthropic via LiteLLM. Sanhedrin no longer guesses a large default verifier.
|
||||
- **Fail-open telemetry** in `fail-open.jsonl`, plus a dashboard telemetry API
|
||||
and 7-day ambient dashboard counters for vetoes, appeals, and fail-open runs.
|
||||
- **Receipt schema documentation** covering receipt artifacts, appeals, command
|
||||
ledgers, fail-open logs, compatibility rules, and staged-evidence trust
|
||||
boundaries.
|
||||
- **Opt-in CUDA feature flags** for Qwen3 embedding builds on NVIDIA hardware.
|
||||
|
||||
### Changed
|
||||
|
||||
- Receipt Lock strips code fences, inline code, blockquotes, quoted regions, and
|
||||
scoped epistemic hedges before matching verification claims.
|
||||
- Structured transcript tool-use receipts are the default evidence path; loose
|
||||
JSON command scanning now requires `VESTIGE_SANHEDRIN_ALLOW_LOOSE_LEDGER=1`.
|
||||
- Claim-mode sampling now prioritizes higher-severity claims instead of taking
|
||||
the first eight source-order claims.
|
||||
- Hosted Sanhedrin credentials now require `VESTIGE_SANHEDRIN_API_KEY` and are
|
||||
only sent to the configured Sanhedrin endpoint, never to Vestige retrieval.
|
||||
- `smart_ingest` batch mode now defaults to `batchMergePolicy: "force_create"`
|
||||
so caller-separated items stay separate unless callers opt into smart merging.
|
||||
- CUDA-enabled Qwen3 builds now try `Device::new_cuda(0)` before falling back to
|
||||
Metal or CPU.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Standalone dashboard mode now hydrates the cognitive engine for Dream and
|
||||
Deep Reference instead of returning 503s.
|
||||
- `--data-dir` now rejects existing non-directory paths with a clear error.
|
||||
- `vestige-restore` now handles `--help` and `--version` instead of treating
|
||||
them as backup file paths.
|
||||
- Smart ingest merge/update responses now include `previousContent`,
|
||||
`mergedFrom`, and `mergePreview` so callers can inspect mutated memories.
|
||||
- Daily Sanhedrin telemetry now preserves NOTE and CAUTION buckets instead of
|
||||
folding both into PASS.
|
||||
|
||||
## [2.1.22] - 2026-05-25 — "Sanhedrin Receipts"
|
||||
|
||||
v2.1.22 makes the optional Sanhedrin hook quieter and more accountable by
|
||||
turning draft judgment into local, appealable receipts instead of opaque vetoes.
|
||||
|
||||
### Added
|
||||
|
||||
- **Receipt Lock** blocks unsupported verification claims such as "tests passed"
|
||||
unless the current transcript contains a matching successful test, build,
|
||||
lint, or typecheck command receipt.
|
||||
- **Veto receipts** are written to `~/.vestige/sanhedrin/latest.json` and
|
||||
`latest.html` with Claim -> Verdict -> Precedent -> Fix -> Appeal fields.
|
||||
- **Dashboard Verdict Bar** surfaces the latest PASS, NOTE, CAUTION, VETO, or
|
||||
APPEALED state and lets users appeal stale, wrong, or too-strict vetoes.
|
||||
- **Appeal training** records feedback in `appeals.jsonl` and suppresses future
|
||||
vetoes for the same claim fingerprint.
|
||||
|
||||
### Changed
|
||||
|
||||
- Sanhedrin claim-mode output now feeds a per-claim receipt ledger while keeping
|
||||
the existing one-line Stop-hook contract for Claude Code.
|
||||
|
||||
## [2.1.21] - 2026-05-24 — "Agent-Neutral Hardening"
|
||||
|
||||
v2.1.21 is a release-hardening pass for normal MCP usage across agents. It keeps
|
||||
Claude Code Cognitive Sandwich companion files optional while making the MCP
|
||||
server, package installer, release workflow, and portable sync path safer.
|
||||
|
||||
### Added
|
||||
|
||||
- **Agent-neutral memory protocol** — new `docs/AGENT-MEMORY-PROTOCOL.md` gives
|
||||
any MCP-compatible client the same practical memory loop: initialize context,
|
||||
search/deep-reference when needed, save durable facts with `smart_ingest`, and
|
||||
promote/demote/purge with `memory`.
|
||||
- **HTTP transport opt-in** — `vestige-mcp` now requires `--http`,
|
||||
`--http-port`, or `VESTIGE_HTTP_ENABLED=1` before starting MCP-over-HTTP.
|
||||
- **Release checksums** — release assets now publish `.sha256` files beside each
|
||||
archive.
|
||||
|
||||
### Changed
|
||||
|
||||
- **`vestige update` is binary-only by default** — Claude Code Cognitive
|
||||
Sandwich companion files refresh only with `vestige update --sandwich-companion`
|
||||
or `vestige sandwich install`.
|
||||
- **MCP tool results include structured content** while keeping text content for
|
||||
clients that only consume the classic MCP response shape.
|
||||
- **NPM install messaging is agent-neutral** and unsupported release targets
|
||||
fail fast instead of trying to download assets that do not exist.
|
||||
- **Portable merge uses UPSERT instead of `INSERT OR REPLACE`** for keyed tables,
|
||||
preserving related rows instead of causing delete-and-insert side effects.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Destructive delete confirmation** — `memory(action="delete")` now requires
|
||||
`confirm=true`, matching `purge`; the deprecated `delete_knowledge` shim no
|
||||
longer bypasses confirmation.
|
||||
- **Portable purge tombstone sync** — merge imports now carry
|
||||
`deletion_tombstones` and apply purges without retaining deleted memory text.
|
||||
Hard purge tombstones win over newer local edits during portable sync, while
|
||||
tombstone merges keep the newest deletion timestamp.
|
||||
- **Vector index reload staleness** — loading persisted embeddings rebuilds the
|
||||
in-memory index from an empty index before adding current embeddings.
|
||||
- **HTTP transport hardening** — origin, Accept, session, and protocol-version
|
||||
validation now reject incompatible or cross-origin browser requests earlier.
|
||||
- **Init config safety** — `@vestige/init` backs up existing config files, writes
|
||||
atomically, accepts JSONC-style comments/trailing commas, and no longer writes
|
||||
Xcode trust-accepted flags.
|
||||
- **Release tag checkout** — manual release builds now checkout the requested tag
|
||||
or ref before packaging.
|
||||
|
||||
### Verified
|
||||
|
||||
- `cargo test -p vestige-mcp --lib --no-fail-fast`
|
||||
- `cargo test -p vestige-mcp --bin vestige-mcp --no-fail-fast`
|
||||
- `cargo test -p vestige-core portable_merge_import --no-fail-fast`
|
||||
- `cargo test -p vestige-mcp --bin vestige --no-fail-fast`
|
||||
- `cargo test -p vestige-e2e-tests --test mcp_protocol --no-fail-fast`
|
||||
- `cargo check --workspace`
|
||||
- `cargo metadata --format-version 1 --locked --no-deps`
|
||||
- `pnpm --filter @vestige/dashboard check`
|
||||
- `pnpm --filter @vestige/dashboard test`
|
||||
- `pnpm --filter @vestige/dashboard build`
|
||||
- `node --check packages/vestige-init/bin/init.js`
|
||||
- `node --check packages/vestige-mcp-npm/scripts/postinstall.js`
|
||||
- `node --check packages/vestige-mcp-npm/bin/vestige-restore.js`
|
||||
|
||||
## [2.1.2] - 2026-05-01 — "Honest Memory"
|
||||
|
||||
v2.1.2 focuses on operational trust: exact search stays exact, purge really removes content, contradictions are directly inspectable, and the update flow no longer depends on copied curl commands.
|
||||
|
||||
### Added
|
||||
|
||||
- **Concrete search mode** — `search` now auto-detects literal queries such as quoted strings, env vars, UUIDs, paths, and code identifiers. Those queries take a keyword/literal path that skips HyDE, semantic fusion, FSRS reweighting, retrieval competition, and spreading activation so exact matches land first.
|
||||
- **Irreversible purge** — `memory(action="purge", confirm=true)` permanently removes memory content and embeddings, scrubs `insights.source_memories`, detaches temporal-summary children, prunes graph edges, and writes only a non-content `deletion_tombstones` row for sync/audit.
|
||||
- **First-class contradictions tool** — new `contradictions` MCP tool scans a topic or recent memories for trust-weighted disagreements using the same local contradiction logic as `deep_reference`.
|
||||
- **Simple update flow** — `vestige update` refreshes the installed binary and companion Sandwich files without requiring users to paste a curl installer.
|
||||
- **Pro waitlist preview** — `/dashboard/waitlist` adds a local-only marketing surface for Solo Pro and Team Pro early-access signups. `VITE_WAITLIST_ENDPOINT` and `VITE_SUPPORT_BOT_ENDPOINT` are opt-in dashboard env vars, so no signup data is captured unless endpoints are configured.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Dream connection persistence cap** — dense single-domain dreams now persist every connection discovered in that run instead of losing everything beyond the old 1,000-entry live buffer. The live dreamer buffer now keeps up to 200,000 high-scoring recent connections, and the MCP `dream` tool exposes `min_similarity` for corpus-specific tuning.
|
||||
- **Embedding-model upgrade repair** — `vestige consolidate` now re-embeds every missing or active-model-mismatched memory in one pass, so v1/v2 mixed stores are no longer left partially unreachable after only the first 100 legacy embeddings are regenerated.
|
||||
|
||||
## [2.1.1] - 2026-05-01 — "Portable Sync"
|
||||
|
||||
v2.1.1 focuses on user-controlled portability: exact storage archives, merge-safe file sync, pluggable sync backends, and explicit hook opt-ins.
|
||||
|
|
|
|||
390
CLAUDE.md
390
CLAUDE.md
|
|
@ -1,362 +1,62 @@
|
|||
# 🚫 READ FIRST EVERY PROMPT — NO HEDGING
|
||||
# Vestige Agent Guidance
|
||||
|
||||
Sam's April 20 2026 correction: *"you NEVER LISTEN TO YOUR RULES, WHY ARE YOU ALWAYS BREAKING THE HEDGING/PESSIMISTIC RULE."*
|
||||
This file is intentionally safe for the public repository. It gives coding
|
||||
agents project-specific context without relying on private local files,
|
||||
personal operating notes, or mandatory background hooks.
|
||||
|
||||
When Sam commits to an execution path (content cadence, shipping velocity, outreach, launch), COMPUTE THE FORECAST AS IF THAT COMMITMENT IS MET. Do not discount by execution probability. Sam has earned the benefit of the doubt across 139 commits and 1,292 passing tests in 3 months.
|
||||
## Project Shape
|
||||
|
||||
**Forbidden in any response**: "has to be true", "has to convert", "realistic forecast" used to shrink, "contingent on" Sam's own execution, "not guaranteed", "may or may not", "aspiration not forecast", "temper your expectations", floors framed as reality vs. ceilings framed as fantasy.
|
||||
Vestige is a local-first MCP memory server written in Rust, with a SvelteKit
|
||||
dashboard embedded into the release binary. The core product promise is:
|
||||
|
||||
**Required format for forecasts**: `Target X. Floor Y. Ceiling Z. Math: [line items]. Risks: [separate section]. Let's go.`
|
||||
- user-owned memory stored locally by default
|
||||
- MCP-native integration with coding agents
|
||||
- retrieval and memory lifecycle behavior informed by cognitive science
|
||||
- explicit tools for search, review, suppression, purge, graph exploration,
|
||||
contradiction inspection, and maintenance
|
||||
|
||||
Full rule: `/Users/entity002/CLAUDE.md` (top banner) + `/Users/entity002/.claude/projects/-Users-entity002/memory/feedback_always_positive_energy.md`. Stop-hook enforcement: `/Users/entity002/.claude/hooks/synthesis-stop-validator.sh`.
|
||||
## Working Rules
|
||||
|
||||
---
|
||||
- Prefer source evidence over memory. Use `rg`, tests, and nearby code before
|
||||
making claims about behavior.
|
||||
- Keep release changes scoped. Do not rewrite unrelated modules during a
|
||||
version/tag cleanup unless the release gate requires it.
|
||||
- Preserve local-first behavior. Heavy models, Sanhedrin-style verifier hooks,
|
||||
and preflight automation must remain optional.
|
||||
- Treat deletion semantics carefully. `purge` must remove content and
|
||||
embeddings, while retaining only content-free audit tombstones.
|
||||
- Treat exact lookup semantics carefully. Env vars, paths, UUIDs, quoted
|
||||
strings, and code identifiers should not be distorted by semantic expansion.
|
||||
|
||||
# Vestige v2.0.4 — Cognitive Memory & Reasoning System
|
||||
## Common Checks
|
||||
|
||||
Vestige is your long-term memory AND reasoning engine. 29 stateful cognitive modules implement real neuroscience: FSRS-6 spaced repetition, synaptic tagging, prediction error gating, hippocampal indexing, spreading activation, reconsolidation, and dual-strength memory theory. **Use it automatically. Use it aggressively.**
|
||||
Run the narrowest check that covers the change, then run the release gates
|
||||
before tagging:
|
||||
|
||||
**NEW: `deep_reference` — call this for ALL factual questions.** It doesn't just retrieve — it REASONS across memories with FSRS-6 trust scoring, intent classification, contradiction analysis, and generates a pre-built reasoning chain. Read the `reasoning` field FIRST.
|
||||
|
||||
---
|
||||
|
||||
## Session Start Protocol
|
||||
|
||||
Every conversation, before responding to the user:
|
||||
|
||||
```
|
||||
session_context({
|
||||
queries: ["user preferences", "[current project] context"],
|
||||
context: { codebase: "[project]", topics: ["[current topics]"] },
|
||||
token_budget: 2000
|
||||
})
|
||||
```sh
|
||||
cargo test --workspace --no-fail-fast
|
||||
cargo clippy --workspace -- -D warnings
|
||||
pnpm --filter @vestige/dashboard check
|
||||
pnpm --filter @vestige/dashboard build
|
||||
```
|
||||
|
||||
Then check `automationTriggers` from response:
|
||||
- `needsDream` → call `dream` (consolidates memories, discovers hidden connections)
|
||||
- `needsBackup` → call `backup`
|
||||
- `needsGc` → call `gc(dry_run: true)` then review
|
||||
- totalMemories > 700 → call `find_duplicates`
|
||||
For documentation-only changes, at minimum run:
|
||||
|
||||
Say "Remembering..." then retrieve context before answering.
|
||||
|
||||
> **Fallback:** If `session_context` unavailable: `search` × 2 → `intention` check → `system_status` → `predict`.
|
||||
|
||||
---
|
||||
|
||||
## Complete Tool Reference (23 Tools)
|
||||
|
||||
### session_context — One-Call Initialization
|
||||
```
|
||||
session_context({
|
||||
queries: ["user preferences", "project context"], // search queries
|
||||
context: { codebase: "project-name", topics: ["svelte", "rust"], file: "src/main.rs" },
|
||||
token_budget: 2000, // 100-100000, controls response size
|
||||
include_status: true, // system health
|
||||
include_intentions: true, // triggered reminders
|
||||
include_predictions: true // proactive memory predictions
|
||||
})
|
||||
```
|
||||
Returns: markdown context + `automationTriggers` + `expandable` IDs for on-demand retrieval.
|
||||
|
||||
### smart_ingest — Save Anything
|
||||
**Single mode** — auto-decides CREATE/UPDATE/SUPERSEDE via Prediction Error Gating:
|
||||
```
|
||||
smart_ingest({
|
||||
content: "What to remember",
|
||||
tags: ["tag1", "tag2"],
|
||||
node_type: "fact", // fact|concept|event|person|place|note|pattern|decision
|
||||
source: "optional reference",
|
||||
forceCreate: false // bypass dedup when needed
|
||||
})
|
||||
```
|
||||
**Batch mode** — save up to 20 items in one call (session end, pre-compaction):
|
||||
```
|
||||
smart_ingest({
|
||||
items: [
|
||||
{ content: "Item 1", tags: ["session-end"], node_type: "fact" },
|
||||
{ content: "Item 2", tags: ["bug-fix"], node_type: "fact" }
|
||||
]
|
||||
})
|
||||
```
|
||||
Each item runs the full cognitive pipeline: importance scoring → intent detection → synaptic tagging → hippocampal indexing → PE gating → cross-project recording.
|
||||
|
||||
### search — 7-Stage Cognitive Search
|
||||
```
|
||||
search({
|
||||
query: "search query",
|
||||
limit: 10, // 1-100
|
||||
min_retention: 0.0, // filter by retention strength
|
||||
min_similarity: 0.5, // minimum cosine similarity
|
||||
detail_level: "summary", // brief|summary|full
|
||||
context_topics: ["rust", "debugging"], // boost topic-matching memories
|
||||
token_budget: 3000, // 100-100000, truncate to fit
|
||||
retrieval_mode: "balanced" // precise|balanced|exhaustive (v2.1)
|
||||
})
|
||||
```
|
||||
Retrieval modes: `precise` (fast, no activation/competition), `balanced` (default 7-stage pipeline), `exhaustive` (5x overfetch, deep graph traversal, no competition suppression).
|
||||
|
||||
Pipeline: Overfetch → Rerank (cross-encoder) → Temporal boost → Accessibility filter (FSRS-6) → Context match (Tulving 1973) → Competition (Anderson 1994) → Spreading activation. **Every search strengthens the memories it finds (Testing Effect).**
|
||||
|
||||
### memory — Read, Edit, Delete, Promote, Demote
|
||||
```
|
||||
memory({ action: "get", id: "uuid" }) // full node with all FSRS state
|
||||
memory({ action: "edit", id: "uuid", content: "updated text" }) // preserves FSRS state, regenerates embedding
|
||||
memory({ action: "delete", id: "uuid" })
|
||||
memory({ action: "promote", id: "uuid", reason: "was helpful" }) // +0.20 retrieval, +0.10 retention, 1.5x stability
|
||||
memory({ action: "demote", id: "uuid", reason: "was wrong" }) // -0.30 retrieval, -0.15 retention, 0.5x stability
|
||||
memory({ action: "state", id: "uuid" }) // Active/Dormant/Silent/Unavailable + accessibility score
|
||||
memory({ action: "get_batch", ids: ["uuid1", "uuid2", "uuid3"] }) // retrieve up to 20 full memories at once (v2.1)
|
||||
```
|
||||
Promote/demote does NOT delete — it adjusts ranking. Demoted memories rank lower; alternatives surface instead.
|
||||
`get_batch` is designed for batch retrieval of expandable overflow IDs from search/session_context.
|
||||
|
||||
### codebase — Code Patterns & Architectural Decisions
|
||||
```
|
||||
codebase({ action: "remember_pattern", name: "Pattern Name",
|
||||
description: "How it works and when to use it",
|
||||
files: ["src/file.rs"], codebase: "project-name" })
|
||||
|
||||
codebase({ action: "remember_decision", decision: "What was decided",
|
||||
rationale: "Why", alternatives: ["Option A", "Option B"],
|
||||
files: ["src/file.rs"], codebase: "project-name" })
|
||||
|
||||
codebase({ action: "get_context", codebase: "project-name", limit: 10 })
|
||||
// Returns: patterns, decisions, cross-project insights
|
||||
```sh
|
||||
git diff --check
|
||||
```
|
||||
|
||||
### intention — Prospective Memory (Reminders)
|
||||
```
|
||||
intention({ action: "set", description: "What to do",
|
||||
trigger: { type: "context", topic: "authentication" }, // fires when discussing auth
|
||||
priority: "high" })
|
||||
## Documentation
|
||||
|
||||
intention({ action: "set", description: "Deploy by Friday",
|
||||
trigger: { type: "time", at: "2026-03-07T17:00:00Z" },
|
||||
deadline: "2026-03-07T17:00:00Z" })
|
||||
- User setup: `README.md`
|
||||
- Claude-specific templates: `docs/CLAUDE-SETUP.md`
|
||||
- Storage and sync behavior: `docs/STORAGE.md`
|
||||
- Cognitive Sandwich and optional verifier hooks: `docs/COGNITIVE_SANDWICH.md`
|
||||
- Release history: `CHANGELOG.md`
|
||||
|
||||
intention({ action: "set", description: "Check test coverage",
|
||||
trigger: { type: "context", codebase: "vestige", file_pattern: "*.test.*" } })
|
||||
## Public-Repo Hygiene
|
||||
|
||||
intention({ action: "check", context: { codebase: "vestige", topics: ["testing"] } })
|
||||
intention({ action: "update", id: "uuid", status: "complete" })
|
||||
intention({ action: "list", filter_status: "active" })
|
||||
```
|
||||
|
||||
### dream — Memory Consolidation
|
||||
```
|
||||
dream({ memory_count: 50 })
|
||||
```
|
||||
5-stage cycle: Replay → Cross-reference → Strengthen → Prune → Transfer. Uses Waking SWR tagging (70% tagged + 30% random for diversity). Discovers hidden connections, generates insights, persists new edges to the activation network.
|
||||
|
||||
### explore_connections — Graph Traversal
|
||||
```
|
||||
explore_connections({ action: "associations", from: "uuid", limit: 10 })
|
||||
// Spreading activation from a memory — find related memories via graph traversal
|
||||
|
||||
explore_connections({ action: "chain", from: "uuid-A", to: "uuid-B" })
|
||||
// Build reasoning path between two memories (A*-like pathfinding)
|
||||
|
||||
explore_connections({ action: "bridges", from: "uuid-A", to: "uuid-B" })
|
||||
// Find connecting memories that bridge two concepts
|
||||
```
|
||||
|
||||
### predict — Proactive Retrieval
|
||||
```
|
||||
predict({ context: { codebase: "vestige", current_file: "src/main.rs",
|
||||
current_topics: ["error handling", "rust"] } })
|
||||
```
|
||||
Returns: predictions with confidence, suggestions, speculative retrievals, top interests. Uses SpeculativeRetriever's learned patterns from access history.
|
||||
|
||||
### importance_score — Should I Save This?
|
||||
```
|
||||
importance_score({ content: "Content to evaluate",
|
||||
context_topics: ["debugging"], project: "vestige" })
|
||||
```
|
||||
4-channel model: novelty (0.25), arousal (0.30), reward (0.25), attention (0.20). Composite > 0.6 = save it.
|
||||
|
||||
### find_duplicates — Dedup Memory
|
||||
```
|
||||
find_duplicates({ similarity_threshold: 0.80, limit: 20, tags: ["bug-fix"] })
|
||||
```
|
||||
Cosine similarity clustering. Returns merge/review suggestions.
|
||||
|
||||
### memory_timeline — Chronological Browse
|
||||
```
|
||||
memory_timeline({ start: "2026-02-01", end: "2026-03-01",
|
||||
node_type: "decision", tags: ["vestige"], limit: 50, detail_level: "summary" })
|
||||
```
|
||||
|
||||
### memory_changelog — Audit Trail
|
||||
```
|
||||
memory_changelog({ memory_id: "uuid", limit: 20 }) // per-memory history
|
||||
memory_changelog({ start: "2026-03-01", limit: 20 }) // system-wide
|
||||
```
|
||||
|
||||
### memory_health — Retention Dashboard
|
||||
```
|
||||
memory_health()
|
||||
```
|
||||
Returns: avg retention, distribution buckets (0-20%, 20-40%, etc.), trend (improving/declining/stable), recommendation.
|
||||
|
||||
### memory_graph — Visualization Export
|
||||
```
|
||||
memory_graph({ query: "search term", depth: 2, max_nodes: 50 })
|
||||
memory_graph({ center_id: "uuid", depth: 3, max_nodes: 100 })
|
||||
```
|
||||
Returns nodes with force-directed positions + edges with weights.
|
||||
|
||||
### deep_reference — Cognitive Reasoning Engine (v2.0.4) ★ USE THIS FOR ALL FACTUAL QUESTIONS
|
||||
```
|
||||
deep_reference({ query: "What port does the dev server use?" })
|
||||
deep_reference({ query: "Should I use prefix caching with vLLM?", depth: 30 })
|
||||
```
|
||||
**THE killer tool.** 8-stage cognitive reasoning pipeline:
|
||||
1. Broad retrieval + cross-encoder reranking
|
||||
2. Spreading activation expansion (finds connected memories search misses)
|
||||
3. FSRS-6 trust scoring (retention × stability × reps ÷ lapses)
|
||||
4. Intent classification (FactCheck / Timeline / RootCause / Comparison / Synthesis)
|
||||
5. Temporal supersession (newer high-trust replaces older)
|
||||
6. Trust-weighted contradiction analysis (only flags conflicts between strong memories)
|
||||
7. Relation assessment (Supports / Contradicts / Supersedes / Irrelevant per pair)
|
||||
8. **Template reasoning chain** — pre-built natural language reasoning the AI validates
|
||||
|
||||
Parameters: `query` (required), `depth` (5-50, default 20).
|
||||
|
||||
Returns: `intent`, `reasoning` (THE KEY FIELD — read this first), `recommended` (highest-trust answer), `evidence` (trust-sorted), `contradictions`, `superseded`, `evolution`, `related_insights`, `confidence`.
|
||||
|
||||
`cross_reference` is a backward-compatible alias that calls `deep_reference`.
|
||||
|
||||
### Maintenance Tools
|
||||
```
|
||||
system_status() // health + stats + warnings + recommendations
|
||||
consolidate() // FSRS-6 decay cycle + embedding generation
|
||||
backup() // SQLite backup → ~/.vestige/backups/
|
||||
export({ format: "json", tags: ["bug-fix"], since: "2026-01-01" })
|
||||
gc({ min_retention: 0.1, dry_run: true }) // garbage collect (dry_run first!)
|
||||
restore({ path: "/path/to/backup.json" })
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mandatory Save Gates
|
||||
|
||||
**You MUST NOT proceed past a save gate without executing the save.**
|
||||
|
||||
| Gate | Trigger | Action |
|
||||
|------|---------|--------|
|
||||
| **BUG_FIX** | After any error is resolved | `smart_ingest({ content: "BUG FIX: [error]\nRoot cause: [why]\nSolution: [fix]\nFiles: [paths]", tags: ["bug-fix", "project"], node_type: "fact" })` |
|
||||
| **DECISION** | After any architectural/design choice | `codebase({ action: "remember_decision", decision, rationale, alternatives, files, codebase })` |
|
||||
| **CODE_CHANGE** | After >20 lines or new pattern | `codebase({ action: "remember_pattern", name, description, files, codebase })` |
|
||||
| **SESSION_END** | Before stopping or compaction | `smart_ingest({ items: [{ content: "SESSION: [summary]", tags: ["session-end"] }] })` |
|
||||
|
||||
---
|
||||
|
||||
## Trigger Words — Auto-Save
|
||||
|
||||
| User Says | Action |
|
||||
|-----------|--------|
|
||||
| "Remember this" / "Don't forget" | `smart_ingest` immediately |
|
||||
| "I always..." / "I never..." / "I prefer..." | Save as preference |
|
||||
| "This is important" | `smart_ingest` + `memory(action="promote")` |
|
||||
| "Remind me..." / "Next time..." | `intention({ action: "set" })` |
|
||||
|
||||
---
|
||||
|
||||
## Cognitive Architecture
|
||||
|
||||
### Search Pipeline (7 stages)
|
||||
1. **Overfetch** — 3x results from hybrid search (0.3 BM25 + 0.7 semantic, nomic-embed-text-v1.5 768D)
|
||||
2. **Rerank** — Cross-encoder rescoring (Jina Reranker v1 Turbo, 38M params)
|
||||
3. **Temporal** — Recency + validity window boosting (85% relevance + 15% temporal)
|
||||
4. **Accessibility** — FSRS-6 retention filter (Active ≥0.7, Dormant ≥0.4, Silent ≥0.1)
|
||||
5. **Context** — Tulving 1973 encoding specificity (topic overlap → +30% boost)
|
||||
6. **Competition** — Anderson 1994 retrieval-induced forgetting (winners strengthen, competitors weaken)
|
||||
7. **Activation** — Spreading activation side effects + predictive model + reconsolidation marking
|
||||
|
||||
### Ingest Pipeline
|
||||
**Pre:** 4-channel importance scoring (novelty/arousal/reward/attention) + intent detection → auto-tag
|
||||
**Store:** Prediction Error Gating: similarity >0.92 → UPDATE, 0.75-0.92 → UPDATE/SUPERSEDE, <0.75 → CREATE
|
||||
**Post:** Synaptic tagging (Frey & Morris 1997, 9h backward + 2h forward) + hippocampal indexing + cross-project recording
|
||||
|
||||
### FSRS-6 (State-of-the-Art Spaced Repetition)
|
||||
- Retrievability: `R = (1 + factor × t / S)^(-w20)` — 21 trained parameters
|
||||
- Dual-strength model (Bjork & Bjork 1992): storage strength (grows) + retrieval strength (decays)
|
||||
- Accessibility = retention×0.5 + retrieval×0.3 + storage×0.2
|
||||
- 20-30% more efficient than SM-2 (Anki)
|
||||
|
||||
### 29 Cognitive Modules (stateful, persist across calls)
|
||||
|
||||
**Neuroscience (16):**
|
||||
ActivationNetwork (Collins & Loftus 1975), SynapticTaggingSystem (Frey & Morris 1997), HippocampalIndex (Teyler & Rudy 2007), ContextMatcher (Tulving 1973), AccessibilityCalculator, CompetitionManager (Anderson 1994), StateUpdateService, ImportanceSignals, NoveltySignal, ArousalSignal, RewardSignal, AttentionSignal, EmotionalMemory (Brown & Kulik 1977), PredictiveMemory, ProspectiveMemory, IntentionParser
|
||||
|
||||
**Advanced (11):**
|
||||
ImportanceTracker, ReconsolidationManager (Nader — 5min labile window), IntentDetector (9 intent types), ActivityTracker, MemoryDreamer (5-stage consolidation), MemoryChainBuilder (A*-like), MemoryCompressor (30-day min age), CrossProjectLearner (6 pattern types), AdaptiveEmbedder, SpeculativeRetriever (6 trigger types), ConsolidationScheduler
|
||||
|
||||
**Search (2):** Reranker, TemporalSearcher
|
||||
|
||||
### Memory States
|
||||
- **Active** (retention ≥ 0.7) — easily retrievable
|
||||
- **Dormant** (≥ 0.4) — retrievable with effort
|
||||
- **Silent** (≥ 0.1) — difficult, needs cues
|
||||
- **Unavailable** (< 0.1) — needs reinforcement
|
||||
|
||||
### Connection Types
|
||||
semantic, temporal, causal, spatial, part_of, user_defined — each with strength (0-1), activation_count, timestamps
|
||||
|
||||
---
|
||||
|
||||
## Advanced Techniques
|
||||
|
||||
### Cross-Project Intelligence
|
||||
The CrossProjectLearner tracks patterns across ALL projects (ErrorHandling, AsyncConcurrency, Testing, Architecture, Performance, Security). When you learn a pattern in one project that works, it becomes available in all projects. Use `codebase({ action: "get_context" })` without a codebase filter to get universal patterns.
|
||||
|
||||
### Reconsolidation Window
|
||||
After any memory is accessed (via search, get, or promote), it enters a 5-minute "labile" state where modifications are enhanced. This is the optimal time to edit memories with new context. The system handles this automatically.
|
||||
|
||||
### Synaptic Tagging (Retroactive Importance)
|
||||
Memories encoded in the last 9 hours can be retroactively promoted when something important happens. If you fix a critical bug, not only does the fix get saved — related memories from the past 9 hours also get importance boosts. The SynapticTaggingSystem handles this automatically.
|
||||
|
||||
### Dream Insights
|
||||
Dreams don't just consolidate — they generate new insights by cross-referencing recent memories with older knowledge. The insights can reveal: contradictions between memories, previously unseen patterns, connections across different projects. Always check dream results for `insights_generated`.
|
||||
|
||||
### Token Budget Strategy
|
||||
Use `token_budget` on search and session_context to control response size. For quick lookups: 500. For deep context: 3000-5000. Results that don't fit go to `expandable` — retrieve them with `memory({ action: "get", id: "..." })`.
|
||||
|
||||
### Detail Levels
|
||||
- `brief` — id/type/tags/score only (1-2 tokens per result, good for scanning)
|
||||
- `summary` — 8 fields including content preview (default, balanced)
|
||||
- `full` — all FSRS state, timestamps, embedding info (for debugging/analysis)
|
||||
|
||||
---
|
||||
|
||||
## Memory Hygiene
|
||||
|
||||
**Promote** when user confirms helpful, solution worked, info was accurate.
|
||||
**Demote** when user corrects mistake, info was wrong, led to bad outcome.
|
||||
**Never save:** secrets, API keys, passwords, temporary debugging state, trivial info.
|
||||
|
||||
---
|
||||
|
||||
## The One Rule
|
||||
|
||||
**When in doubt, save. The cost of a duplicate is near zero (Prediction Error Gating handles dedup). The cost of lost knowledge is permanent.**
|
||||
|
||||
Memory is retrieval. Searching strengthens memory. Search liberally, save aggressively.
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
- **Crate:** `vestige-mcp` v2.0.4, Rust 2024 edition, MSRV 1.91
|
||||
- **Tests:** 758 (406 mcp + 352 core), zero warnings
|
||||
- **Build:** `cargo build --release -p vestige-mcp` (features: `embeddings` + `vector-search`)
|
||||
- **Build (no embeddings):** `cargo build --release -p vestige-mcp --no-default-features`
|
||||
- **Bench:** `cargo bench -p vestige-core`
|
||||
- **Architecture:** `McpServer` → `Arc<Storage>` + `Arc<Mutex<CognitiveEngine>>`
|
||||
- **Storage:** SQLite WAL mode, `Mutex<Connection>` reader/writer split, FTS5 full-text search
|
||||
- **Embeddings:** nomic-embed-text-v1.5 (768D, 8K context) via fastembed (local ONNX, no API)
|
||||
- **Vector index:** USearch HNSW (20x faster than FAISS)
|
||||
- **Binaries:** `vestige-mcp` (MCP server), `vestige` (CLI), `vestige-restore`
|
||||
- **Dashboard:** SvelteKit 2 + Svelte 5 + Three.js + Tailwind 4, embedded at `/dashboard`
|
||||
- **Env vars:** `VESTIGE_DASHBOARD_PORT` (default 3927), `VESTIGE_HTTP_PORT` (default 3928), `VESTIGE_HTTP_BIND` (default 127.0.0.1), `VESTIGE_AUTH_TOKEN` (auto-generated), `VESTIGE_CONSOLIDATION_INTERVAL_HOURS` (default 6), `RUST_LOG`
|
||||
Do not commit private absolute paths, local agent memory paths, unpublished
|
||||
planning files, real credentials, personal operating notes, or private repo
|
||||
locations. Example environment variables in docs must be empty placeholders or
|
||||
obviously fake examples.
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ Tags: ["decision", "topic-name"]
|
|||
| "Don't forget" | `smart_ingest` with tags: ["important"] |
|
||||
| "I always..." / "I never..." | Save as preference |
|
||||
| "I prefer..." / "I like..." | Save as preference |
|
||||
| "This is important" | `smart_ingest` + `promote_memory` |
|
||||
| "This is important" | `smart_ingest` + `memory(action="promote")` |
|
||||
| "Remind me..." | Create `intention` with trigger |
|
||||
| "Next time we..." | Create `intention` with context trigger |
|
||||
| "When I'm working on X..." | Create `intention` with codebase trigger |
|
||||
|
|
@ -115,7 +115,7 @@ Act on feedback immediately — don't ask permission to promote/demote.
|
|||
|
||||
### Proactive Health Checks
|
||||
If you notice degraded recall or a user mentions memory issues:
|
||||
1. Run `health_check` — check overall system status
|
||||
1. Run `system_status` — check overall system status
|
||||
2. If `averageRetention < 0.5` → suggest running `consolidate`
|
||||
3. If `dueForReview > 50` → mention that some memories need review
|
||||
|
||||
|
|
|
|||
120
Cargo.lock
generated
120
Cargo.lock
generated
|
|
@ -392,8 +392,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6bd9895436c1ba5dc1037a19935d084b838db066ff4e15ef7dded020b7c12a4a"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"candle-kernels",
|
||||
"candle-metal-kernels",
|
||||
"candle-ug",
|
||||
"cudarc 0.19.7",
|
||||
"float8",
|
||||
"gemm 0.19.0",
|
||||
"half",
|
||||
|
|
@ -413,6 +415,15 @@ dependencies = [
|
|||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "candle-kernels"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "742e2ac226b777134436e9e692f44e77c278b8a7abb1554dc10e44dc911b349f"
|
||||
dependencies = [
|
||||
"cudaforge",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "candle-metal-kernels"
|
||||
version = "0.10.2"
|
||||
|
|
@ -453,6 +464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ca0fc3167cbc99c8ec1be618cb620aa21dca95038f118c3579a79370e3dc5f77"
|
||||
dependencies = [
|
||||
"ug",
|
||||
"ug-cuda",
|
||||
"ug-metal",
|
||||
]
|
||||
|
||||
|
|
@ -771,6 +783,46 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cudaforge"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f7a0d45b139b5beeeb1c34188717e12241c44a0120afb498815ce7f5373c691"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"fs2",
|
||||
"glob",
|
||||
"num_cpus",
|
||||
"rayon",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"thiserror 2.0.18",
|
||||
"walkdir",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cudarc"
|
||||
version = "0.17.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf99ab37ee7072d64d906aa2dada9a3422f1d975cdf8c8055a573bc84897ed8"
|
||||
dependencies = [
|
||||
"half",
|
||||
"libloading 0.8.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cudarc"
|
||||
version = "0.19.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cea5f10a99e025c1b44ae2354c2d8326b25ddbd0baf76bde8e55cfd4018a2cc"
|
||||
dependencies = [
|
||||
"float8",
|
||||
"half",
|
||||
"libloading 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.194"
|
||||
|
|
@ -1034,6 +1086,12 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_home"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
|
||||
|
||||
[[package]]
|
||||
name = "equator"
|
||||
version = "0.4.2"
|
||||
|
|
@ -1254,6 +1312,16 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
|
|
@ -1632,6 +1700,12 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.13"
|
||||
|
|
@ -3752,6 +3826,17 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
|
|
@ -4327,6 +4412,19 @@ dependencies = [
|
|||
"yoke 0.7.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ug-cuda"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f0a1fa748f26166778c33b8498255ebb7c6bffb472bcc0a72839e07ebb1d9b5"
|
||||
dependencies = [
|
||||
"cudarc 0.17.8",
|
||||
"half",
|
||||
"serde",
|
||||
"thiserror 1.0.69",
|
||||
"ug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ug-metal"
|
||||
version = "0.5.0"
|
||||
|
|
@ -4531,7 +4629,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|||
|
||||
[[package]]
|
||||
name = "vestige-core"
|
||||
version = "2.1.1"
|
||||
version = "2.1.26"
|
||||
dependencies = [
|
||||
"candle-core",
|
||||
"chrono",
|
||||
|
|
@ -4567,7 +4665,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "vestige-mcp"
|
||||
version = "2.1.1"
|
||||
version = "2.1.26"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
|
|
@ -4792,6 +4890,18 @@ version = "0.1.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "7.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762"
|
||||
dependencies = [
|
||||
"either",
|
||||
"env_home",
|
||||
"rustix",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
@ -5058,6 +5168,12 @@ version = "0.53.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||
|
||||
[[package]]
|
||||
name = "winsafe"
|
||||
version = "0.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ exclude = [
|
|||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "2.1.1"
|
||||
version = "2.1.26"
|
||||
edition = "2024"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/samvallad33/vestige"
|
||||
|
|
|
|||
205
README.md
205
README.md
|
|
@ -2,116 +2,51 @@
|
|||
|
||||
# Vestige
|
||||
|
||||
### The cognitive engine that gives AI agents a brain.
|
||||
### Local cognitive memory for MCP-compatible AI agents.
|
||||
|
||||
[](https://github.com/samvallad33/vestige)
|
||||
[](https://github.com/samvallad33/vestige/releases/latest)
|
||||
[](https://github.com/samvallad33/vestige/actions)
|
||||
[](https://github.com/samvallad33/vestige/actions)
|
||||
[](LICENSE)
|
||||
[](https://modelcontextprotocol.io)
|
||||
|
||||
**Your Agent forgets everything between sessions. Vestige fixes that.**
|
||||
**Your agent forgets project decisions between sessions. Vestige gives it local, inspectable memory.**
|
||||
|
||||
Built on 130 years of memory research — FSRS-6 spaced repetition, prediction error gating, synaptic tagging, spreading activation, memory dreaming — all running in a single Rust binary with a 3D neural visualization dashboard. 100% local. Zero cloud.
|
||||
Built on proven memory and retrieval ideas — FSRS-6 spaced repetition, prediction error gating, synaptic tagging, spreading activation, and memory consolidation — all running in a single Rust binary with a local dashboard. 100% local. Zero cloud.
|
||||
|
||||
[Quick Start](#quick-start) | [Dashboard](#-3d-memory-dashboard) | [How It Works](#-the-cognitive-science-stack) | [Tools](#-24-mcp-tools) | [Docs](docs/)
|
||||
[Quick Start](#quick-start) | [Dashboard](#-3d-memory-dashboard) | [How It Works](#-the-cognitive-science-stack) | [Tools](#-25-mcp-tools) | [Docs](docs/)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## What's New in v2.1.1 "Portable Sync"
|
||||
## What's New in v2.1.23 "Receipt Lock Hardening"
|
||||
|
||||
v2.1.1 focuses on the biggest post-launch ask: move memories between machines without losing cognitive state. It also adds opt-in Qwen3 embeddings for higher-recall local retrieval.
|
||||
v2.1.23 turns the Sanhedrin Receipt Lock launch into something more portable,
|
||||
observable, and harder to spoof.
|
||||
|
||||
- **Exact portable archives.** `vestige portable-export` / `vestige portable-import` preserve IDs, FSRS state, graph edges, suppression state, audit rows, and embedding blobs for Vestige-to-Vestige device transfer.
|
||||
- **Sync-safe merge storage.** `vestige portable-import --merge` and `vestige sync <archive>` merge non-empty databases, apply delete tombstones, keep newer local memories, rebuild FTS, and push through a pluggable portable-sync backend. v2.1.1 ships the file backend for Dropbox, iCloud, Syncthing, Git, and shared folders.
|
||||
- **Qwen3 embeddings.** Build with `qwen3-embeddings`, set `VESTIGE_EMBEDDING_MODEL=qwen3-0.6b`, and run `vestige consolidate` to re-embed existing memories.
|
||||
- **Model-aware retrieval.** Vestige now avoids comparing Qwen and Nomic vectors in the same search/dedup path.
|
||||
|
||||
## What's New in v2.1.0 "Cognitive Sandwich Goes Local"
|
||||
|
||||
v2.1.0 adds an opt-in Claude Code hook harness around the existing Vestige MCP server. The MCP tool surface and database schema stay backward compatible, while preflight hooks can inject trusted memory context before Claude answers. The heavyweight Sanhedrin verifier is optional and can be enabled separately.
|
||||
|
||||
- **Optional Sanhedrin Executioner.** The post-response verifier is off by default. Users can enable it with an OpenAI-compatible endpoint on x86/Linux/Intel Mac, or add `--with-launchd` on Apple Silicon to run the local MLX Qwen backend.
|
||||
- **One-command Cognitive Sandwich installer.** `scripts/install-sandwich.sh` stages hook files and agents by default, removes old Vestige hook wiring, and leaves all Claude Code hook layers plus the 19 GB model path opt-in.
|
||||
- **Pulse hook backed by `/api/changelog`.** Fresh dream and connection events can be injected into the next Claude Code prompt context without blocking the prompt.
|
||||
- **`VESTIGE_DATA_DIR` support.** `--data-dir` now has an env-var fallback, tilde expansion, secure directory creation, and clear precedence docs.
|
||||
- **NPM release wrapper fixed.** `vestige-mcp-server@2.1.0` now downloads binaries from the matching `v2.1.0` GitHub release tag instead of an old hardcoded release.
|
||||
|
||||
## What's New in v2.0.9 "Autopilot"
|
||||
|
||||
Autopilot flips Vestige from passive memory library to **self-managing cognitive surface**. Same 24 MCP tools, zero schema changes — but the moment you upgrade, 14 previously dormant cognitive primitives start firing on live events without any tool call from your client.
|
||||
|
||||
- **One supervised backend task subscribes to the 20-event WebSocket bus** and routes six event classes into the cognitive engine: `MemoryCreated` triggers synaptic-tagging PRP + predictive-access records, `SearchPerformed` warms the speculative-retrieval model, `MemoryPromoted` fires activation spread, `MemorySuppressed` emits the Rac1 cascade wave, high-importance `ImportanceScored` (>0.85) auto-promotes, and `Heartbeat` rate-limit-fires `find_duplicates` on large DBs. **The engine mutex is never held across `.await`, so MCP dispatch is never starved.**
|
||||
- **Panic-resilient supervisors.** Both background tasks run inside an outer supervisor loop — if one handler panics on a bad memory, the supervisor respawns it in 5 s instead of losing every future event.
|
||||
- **Fully backward compatible.** No new MCP tools. No schema migration. Existing v2.0.8 databases open without a single step. Opt out with `VESTIGE_AUTOPILOT_ENABLED=0` if you want the passive-library contract back.
|
||||
- **3,091 LOC of orphan v1.0 tool code removed** — nine superseded modules (`checkpoint`, `codebase`, `consolidate`, `ingest`, `intentions`, `knowledge`, `recall`, plus helpers) verified zero non-test callers before deletion. Tool surface unchanged.
|
||||
|
||||
## What's New in v2.0.8 "Pulse"
|
||||
|
||||
v2.0.8 wires the dashboard through to the cognitive engine. Eight new surfaces expose the reasoning stack visually — every one was MCP-only before.
|
||||
|
||||
- **Reasoning Theater (`/reasoning`)** — `Cmd+K` Ask palette over the 8-stage `deep_reference` pipeline (hybrid retrieval → cross-encoder rerank → spreading activation → FSRS-6 trust → temporal supersession → contradiction analysis → relation assessment → template reasoning chain). Evidence cards, confidence meter, contradiction geodesic arcs, superseded-memory lineage, evolution timeline. **Zero LLM calls, 100% local.**
|
||||
- **Pulse InsightToast** — real-time toasts for `DreamCompleted`, `ConsolidationCompleted`, `ConnectionDiscovered`, promote/demote/suppress/unsuppress, `Rac1CascadeSwept`. Rate-limited, auto-dismiss, click-to-dismiss.
|
||||
- **Memory Birth Ritual (Terrarium)** — new memories materialize in the 3D graph on every `MemoryCreated`: elastic scale-in, quadratic Bezier flight path, glow sprite fade-in, Newton's Cradle docking recoil. 60-frame sequence, zero-alloc math.
|
||||
- **7 more dashboard surfaces** — `/duplicates`, `/dreams`, `/schedule`, `/importance`, `/activation`, `/contradictions`, `/patterns`. Left nav expanded 8 → 16 with single-key shortcuts.
|
||||
- **Intel Mac (`x86_64-apple-darwin`) support restored** via the `ort-dynamic` Cargo feature + Homebrew `onnxruntime`. Microsoft deprecated x86_64 macOS prebuilts; the dynamic-link path sidesteps that permanently. **Closes #41.**
|
||||
- **Contradiction-detection false positives eliminated** — four thresholds tightened so adjacent-domain memories no longer flag as conflicts. On an FSRS-6 query this collapses false contradictions 12 → 0 without regressing legitimate test cases.
|
||||
|
||||
## What's New in v2.0.7 "Visible"
|
||||
|
||||
Hygiene release closing two UI gaps and finishing schema cleanup. No breaking changes, no user-data migrations.
|
||||
|
||||
- **`POST /api/memories/{id}/suppress` + `/unsuppress` HTTP endpoints** — dashboard can trigger Anderson 2025 SIF + Rac1 cascade without dropping to raw MCP. `suppressionCount`, `retrievalPenalty`, `reversibleUntil`, `labileWindowHours` all in response. Suppress button joins Promote / Demote / Delete on the Memories page.
|
||||
- **Uptime in the sidebar footer** — the `Heartbeat` event has carried `uptime_secs` since v2.0.5 but was never rendered. Now shows as `up 3d 4h` / `up 18m` / `up 47s`.
|
||||
- **`execute_export` panic fix** — unreachable match arm replaced with a clean "unsupported export format" error instead of unwinding through the MCP dispatcher.
|
||||
- **`predict` surfaces `predict_degraded: true`** on lock poisoning instead of silently returning empty vecs. `memory_changelog` honors `start` / `end` bounds. `intention` check honors `include_snoozed`.
|
||||
- **Migration V11** — drops dead `knowledge_edges` + `compressed_memories` tables (added speculatively in V4, never used).
|
||||
|
||||
## What's New in v2.0.6 "Composer"
|
||||
|
||||
v2.0.6 is a polish release that makes the existing cognitive stack finally *feel* alive in the dashboard and stays out of your way on the prompt side.
|
||||
|
||||
- **Six live graph reactions, not one** — `MemorySuppressed`, `MemoryUnsuppressed`, `Rac1CascadeSwept`, `Connected`, `ConsolidationStarted`, and `ImportanceScored` now light the 3D graph in real time. v2.0.5 shipped `suppress` but the graph was silent when you called it; consolidation and importance scoring have been silent since v2.0.0. No longer.
|
||||
- **Intentions page actually works** — fixes a long-standing bug where every intention rendered as "normal priority" (type/schema drift between backend and frontend) and context/time triggers surfaced as raw JSON.
|
||||
- **Opt-in composition mandate** — the new MCP `instructions` string stays minimal by default. Opt in to the full Composing / Never-composed / Recommendation composition protocol with `VESTIGE_SYSTEM_PROMPT_MODE=full` when you want it, and nothing is imposed on your sessions when you don't.
|
||||
|
||||
## What's New in v2.0.5 "Intentional Amnesia"
|
||||
|
||||
**The first shipped AI memory system with top-down inhibitory control over retrieval.** Other systems implement passive decay — memories fade if you don't touch them. Vestige v2.0.5 also implements *active* suppression: the new **`suppress`** tool compounds a retrieval penalty on every call (up to 80%), a background Rac1 worker fades co-activated neighbors over 72 hours, and the whole thing is reversible within a 24-hour labile window. **Never deletes.** The memory is inhibited, not erased.
|
||||
|
||||
Ebbinghaus 1885 models what happens to memories you don't touch. Anderson 2025 models what happens when you actively want to stop thinking about one. Every other AI memory system implements the first. Vestige is the first to ship the second.
|
||||
|
||||
Based on [Anderson et al. 2025](https://www.nature.com/articles/s41583-025-00929-y) (Suppression-Induced Forgetting, *Nat Rev Neurosci*) and [Cervantes-Sandoval et al. 2020](https://pmc.ncbi.nlm.nih.gov/articles/PMC7477079/) (Rac1 synaptic cascade). **24 tools · 30 cognitive modules · 1,223 tests.**
|
||||
|
||||
<details>
|
||||
<summary>Earlier releases (v2.0 "Cognitive Leap" → v2.0.4 "Deep Reference")</summary>
|
||||
|
||||
- **v2.0.4 — `deep_reference` Tool** — 8-stage cognitive reasoning pipeline with FSRS-6 trust scoring, intent classification, spreading activation, contradiction analysis, and pre-built reasoning chains. Token budgets raised 10K → 100K. CORS tightened.
|
||||
- **v2.0 — 3D Memory Dashboard** — SvelteKit + Three.js neural visualization with real-time WebSocket events, bloom post-processing, force-directed graph layout.
|
||||
- **v2.0 — WebSocket Event Bus** — Every cognitive operation broadcasts events: memory creation, search, dreaming, consolidation, retention decay.
|
||||
- **v2.0 — HyDE Query Expansion** — Template-based Hypothetical Document Embeddings for dramatically improved search quality on conceptual queries.
|
||||
- **v2.0 — Nomic v2 MoE (experimental)** — fastembed 5.11 with optional Nomic Embed Text v2 MoE (475M params, 8 experts) + Metal GPU acceleration.
|
||||
- **v2.0 — Command Palette** — `Cmd+K` navigation, keyboard shortcuts, responsive mobile layout, PWA installable.
|
||||
- **v2.0 — FSRS Decay Visualization** — SVG retention curves with predicted decay at 1d/7d/30d.
|
||||
|
||||
</details>
|
||||
- **Model-agnostic Sanhedrin presets.** Sanhedrin no longer guesses a large default verifier. Users choose any OpenAI-compatible endpoint/model, or start from custom, small laptop, Ollama, MLX, vLLM, llama.cpp, hosted API, or LiteLLM presets.
|
||||
- **Sharper Receipt Lock.** Verification claims inside code fences, quotes, blockquotes, or explicitly hedged "let me verify" language no longer trigger false vetoes, while actual "tests passed" claims still require command receipts.
|
||||
- **Safer command receipts.** Transcript command evidence now prefers structured tool-use receipts; loose JSON scanning is opt-in only.
|
||||
- **Visible fail-open telemetry.** Timeouts, unavailable model endpoints, and malformed verdicts are logged locally and surfaced in the dashboard's 7-day Sanhedrin stats.
|
||||
- **Durable evidence boundary.** Staged evidence remains useful context, but it cannot satisfy durable support or contradiction requirements by itself.
|
||||
- **Safer batch writes.** `smart_ingest` batch mode now keeps caller-separated items separate by default and returns merge previews when an existing memory is mutated.
|
||||
- **Opt-in NVIDIA acceleration path.** Qwen3 embedding builds expose CUDA/cuDNN feature flags for contributors and users with CUDA-capable hosts.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Install (macOS Apple Silicon)
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
# 1. Install
|
||||
npm install -g vestige-mcp-server@latest
|
||||
|
||||
# 2. Connect to Claude Code
|
||||
# 2. Connect to any MCP-compatible agent
|
||||
# Claude Code
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
|
||||
# Or connect to Codex
|
||||
codex mcp add vestige -- /usr/local/bin/vestige-mcp
|
||||
# Codex
|
||||
codex mcp add vestige -- vestige-mcp
|
||||
|
||||
# 3. Test it
|
||||
# "Remember that I prefer TypeScript over JavaScript"
|
||||
|
|
@ -123,18 +58,25 @@ codex mcp add vestige -- /usr/local/bin/vestige-mcp
|
|||
<details>
|
||||
<summary>Other platforms & install methods</summary>
|
||||
|
||||
**Linux (x86_64):**
|
||||
**Updating an existing install:**
|
||||
```bash
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-x86_64-unknown-linux-gnu.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
vestige update
|
||||
```
|
||||
|
||||
`vestige update` updates only the Vestige binaries by default. Use
|
||||
`vestige update --sandwich-companion` if you also want to refresh optional Claude
|
||||
Code Cognitive Sandwich companion files.
|
||||
|
||||
**macOS/Linux manual binary install:**
|
||||
```bash
|
||||
vestige update --install-dir /usr/local/bin
|
||||
```
|
||||
|
||||
**macOS (Intel):** Microsoft is discontinuing x86_64 macOS prebuilts after ONNX Runtime v1.23.0, so Vestige's Intel Mac build links dynamically against a Homebrew-installed ONNX Runtime via the `ort-dynamic` feature. Install with:
|
||||
|
||||
```bash
|
||||
brew install onnxruntime
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-x86_64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
npm install -g vestige-mcp-server@latest
|
||||
echo 'export ORT_DYLIB_PATH="'"$(brew --prefix onnxruntime)"'/lib/libonnxruntime.dylib"' >> ~/.zshrc
|
||||
source ~/.zshrc
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
|
|
@ -163,7 +105,7 @@ Open `%APPDATA%\Claude\claude_desktop_config.json` and point Claude Desktop at t
|
|||
}
|
||||
```
|
||||
|
||||
If Claude Desktop cannot find `vestige-mcp`, run `where vestige-mcp` in PowerShell and use the exact `.cmd` path it prints as `command`. Example: `"C:\\Users\\you\\AppData\\Roaming\\npm\\vestige-mcp.cmd"`. Reopen Claude Desktop after saving. Once v2.1.0 is installed, future binary updates can run with `vestige update`.
|
||||
If Claude Desktop cannot find `vestige-mcp`, run `where vestige-mcp` in PowerShell and use the exact `.cmd` path it prints as `command`. Example: `"C:\\Users\\you\\AppData\\Roaming\\npm\\vestige-mcp.cmd"`. Reopen Claude Desktop after saving. Future binary updates use `vestige update`; optional Claude Code companion files require `vestige update --sandwich-companion`.
|
||||
|
||||
**Windows source build:** Prebuilt binaries ship but `usearch 2.24.0` hit an MSVC compile break ([usearch#746](https://github.com/unum-cloud/usearch/issues/746)); we've pinned `=2.23.0` until upstream fixes it. Source builds work with:
|
||||
|
||||
|
|
@ -190,7 +132,7 @@ cargo build --release -p vestige-mcp --features metal
|
|||
|
||||
## Works Everywhere
|
||||
|
||||
Vestige speaks MCP — the universal protocol for AI tools. One brain, every IDE.
|
||||
Vestige speaks MCP, so any client that can register a stdio MCP server can use it.
|
||||
|
||||
| IDE | Setup |
|
||||
|-----|-------|
|
||||
|
|
@ -235,7 +177,7 @@ Run `vestige dashboard` to open `http://localhost:3927/dashboard`, or set `VESTI
|
|||
│ 15 REST endpoints · WS event broadcast │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ MCP Server (stdio JSON-RPC) │
|
||||
│ 24 tools · 30 cognitive modules │
|
||||
│ 25 tools · 30 cognitive modules │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Cognitive Engine │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
||||
|
|
@ -302,7 +244,7 @@ This isn't a key-value store with an embedding model bolted on. Vestige implemen
|
|||
|
||||
---
|
||||
|
||||
## 🛠 24 MCP Tools
|
||||
## 🛠 25 MCP Tools
|
||||
|
||||
### Context Packets
|
||||
| Tool | What It Does |
|
||||
|
|
@ -312,9 +254,9 @@ This isn't a key-value store with an embedding model bolted on. Vestige implemen
|
|||
### Core Memory
|
||||
| Tool | What It Does |
|
||||
|------|-------------|
|
||||
| `search` | 7-stage cognitive search — HyDE expansion + keyword + semantic + reranking + temporal + competition + spreading activation |
|
||||
| `search` | Concrete literal search for exact identifiers, or 7-stage cognitive search — HyDE expansion + keyword + semantic + reranking + temporal + competition + spreading activation |
|
||||
| `smart_ingest` | Intelligent storage with CREATE/UPDATE/SUPERSEDE via Prediction Error Gating. Batch mode for session-end saves |
|
||||
| `memory` | Get, delete, check state, promote (thumbs up), demote (thumbs down) |
|
||||
| `memory` | Get, purge content/embeddings, check state, promote (thumbs up), demote (thumbs down), edit |
|
||||
| `codebase` | Remember code patterns and architectural decisions per-project |
|
||||
| `intention` | Prospective memory — "remind me to X when Y happens" |
|
||||
|
||||
|
|
@ -352,26 +294,20 @@ This isn't a key-value store with an embedding model bolted on. Vestige implemen
|
|||
|------|-------------|
|
||||
| `deep_reference` | **Cognitive reasoning across memories.** 8-stage pipeline: FSRS-6 trust scoring, intent classification, spreading activation, temporal supersession, contradiction analysis, relation assessment, dream insight integration, and algorithmic reasoning chain generation. Returns trust-scored evidence with a pre-built reasoning scaffold. |
|
||||
| `cross_reference` | Backward-compatible alias for `deep_reference`. |
|
||||
| `contradictions` | **Honest memory inspection.** Scans a topic or recent memories for trust-weighted disagreements using the same local contradiction logic as `deep_reference`. |
|
||||
|
||||
### Active Forgetting (v2.0.5)
|
||||
| Tool | What It Does |
|
||||
|------|-------------|
|
||||
| `suppress` | **Top-down active forgetting** — neuroscience-grounded inhibitory control over retrieval. Distinct from `memory.delete` (destroys the row) and `memory.demote` (one-shot ranking hit). Each call **compounds** a retrieval-score penalty (Anderson 2025 SIF), and a background Rac1 cascade worker fades co-activated neighbors over 72h (Davis 2020). Reversible within a 24-hour labile window via `reverse: true`. **The memory persists** — it is inhibited, not erased. |
|
||||
| `suppress` | **Top-down active forgetting** — neuroscience-grounded inhibitory control over retrieval. Distinct from `memory(action="purge")`, which permanently removes content/embeddings. Each suppression compounds a retrieval-score penalty (Anderson 2025 SIF), and a background Rac1 cascade worker fades co-activated neighbors over 72h (Davis 2020). Reversible within a 24-hour labile window via `reverse: true`. **The memory persists** — it is inhibited, not erased. |
|
||||
|
||||
---
|
||||
|
||||
## Make Your AI Use Vestige Automatically
|
||||
|
||||
Add this to your `CLAUDE.md`:
|
||||
|
||||
```markdown
|
||||
## Memory
|
||||
|
||||
At the start of every session:
|
||||
1. Search Vestige for user preferences and project context
|
||||
2. Save bug fixes, decisions, and patterns without being asked
|
||||
3. Create reminders when the user mentions deadlines
|
||||
```
|
||||
Registering the MCP server exposes tools; the agent still needs an instruction
|
||||
that tells it when to call memory. Use the agent-neutral protocol, then adapt it
|
||||
to your client-specific instruction file.
|
||||
|
||||
| You Say | AI Does |
|
||||
|---------|---------|
|
||||
|
|
@ -380,7 +316,7 @@ At the start of every session:
|
|||
| "Remind me..." | Creates a future trigger |
|
||||
| "This is important" | Saves + promotes |
|
||||
|
||||
[Full CLAUDE.md templates ->](docs/CLAUDE-SETUP.md)
|
||||
[Agent memory protocol ->](docs/AGENT-MEMORY-PROTOCOL.md) · [Claude Code template ->](docs/CLAUDE-SETUP.md)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -389,7 +325,7 @@ At the start of every session:
|
|||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| **Language** | Rust 2024 edition (MSRV 1.91) |
|
||||
| **Codebase** | 80,000+ lines, 1,292 tests (366 core + 425 mcp + 497 e2e + 4 doctests) |
|
||||
| **Codebase** | 80,000+ lines with Rust core/MCP/e2e, dashboard, and hook coverage |
|
||||
| **Binary size** | ~20MB |
|
||||
| **Embeddings** | Nomic Embed Text v1.5 by default (768d -> 256d Matryoshka, 8192 context); Qwen3 0.6B optional |
|
||||
| **Vector search** | USearch HNSW (20x faster than FAISS) |
|
||||
|
|
@ -409,6 +345,53 @@ cargo build --release -p vestige-mcp --features qwen3-embeddings,metal
|
|||
VESTIGE_EMBEDDING_MODEL=qwen3-0.6b vestige consolidate
|
||||
```
|
||||
|
||||
### Building with CUDA support (NVIDIA hosts - Windows / Linux)
|
||||
|
||||
The `cuda` feature routes Qwen3 embedding through NVIDIA GPUs via
|
||||
`candle-core/cuda`. On a host with the CUDA toolkit installed and a supported
|
||||
NVIDIA runtime, this drops Qwen3-Embedding inference from CPU-bound to GPU-bound
|
||||
for batched workloads.
|
||||
|
||||
```bash
|
||||
# Linux / Windows + CUDA toolkit (12.x or 13.x)
|
||||
cargo build --release -p vestige-mcp --features qwen3-embeddings,cuda
|
||||
|
||||
# Optional cuDNN acceleration on top of CUDA
|
||||
cargo build --release -p vestige-mcp --features qwen3-embeddings,cudnn
|
||||
|
||||
VESTIGE_EMBEDDING_MODEL=qwen3-0.6b vestige consolidate
|
||||
```
|
||||
|
||||
**Prerequisites:**
|
||||
|
||||
- NVIDIA driver + CUDA toolkit (12.x or 13.x). Verify with `nvcc --version`.
|
||||
- A C++ host compiler that `nvcc` can drive (Linux: `gcc`; Windows: MSVC /
|
||||
`cl.exe` from a recent Visual Studio Build Tools install).
|
||||
|
||||
**Windows + MSVC + CUDA 13.x build note.** Recent CCCL headers shipped with
|
||||
CUDA 13.x require the modern preprocessor. Without it, the `candle-kernels`
|
||||
`.cu` compile pass can fail at `cuda/include/cuda/std/__cccl/compiler.h`. Set
|
||||
this env var before `cargo build` to pass `/Zc:preprocessor` through `nvcc`:
|
||||
|
||||
```powershell
|
||||
# PowerShell
|
||||
$env:NVCC_PREPEND_FLAGS = '-Xcompiler="/Zc:preprocessor"'
|
||||
cargo build --release -p vestige-mcp --features qwen3-embeddings,cuda
|
||||
```
|
||||
|
||||
```cmd
|
||||
:: cmd.exe
|
||||
set NVCC_PREPEND_FLAGS=-Xcompiler="/Zc:preprocessor"
|
||||
cargo build --release -p vestige-mcp --features qwen3-embeddings,cuda
|
||||
```
|
||||
|
||||
Linux + CUDA 13.x builds with `gcc` do not need the equivalent flag.
|
||||
|
||||
**Verifying GPU is actually used.** With CUDA-enabled builds, run
|
||||
`VESTIGE_EMBEDDING_MODEL=qwen3-0.6b vestige consolidate` on a corpus of 1000+
|
||||
memories and watch `nvidia-smi`; embedding passes should pin a single GPU while
|
||||
the run is active.
|
||||
|
||||
---
|
||||
|
||||
## CLI
|
||||
|
|
@ -464,7 +447,7 @@ First run downloads ~130MB from Hugging Face. If behind a proxy:
|
|||
export HTTPS_PROXY=your-proxy:port
|
||||
```
|
||||
|
||||
Cache: macOS `~/Library/Caches/com.vestige.core/fastembed` | Linux `~/.cache/vestige/fastembed`
|
||||
Cache: platform user cache directory first, then `./.fastembed_cache` as a fallback. Override with `FASTEMBED_CACHE_PATH`.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.0.x | :white_check_mark: |
|
||||
| 2.1.x | :white_check_mark: |
|
||||
| 2.0.x | Critical fixes only |
|
||||
| 1.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
|
@ -27,13 +28,13 @@ You can expect a response within 48 hours.
|
|||
|
||||
Vestige is a **local MCP server** designed to run on your machine with your user permissions:
|
||||
|
||||
- **Trusted**: The MCP client (Claude Code/Desktop) that connects via stdio
|
||||
- **Trusted**: The MCP client or local agent that connects via stdio
|
||||
- **Untrusted**: Content passed through MCP tool arguments (validated before use)
|
||||
|
||||
### What Vestige Does NOT Do
|
||||
|
||||
- ❌ Make network requests (except first-run model download from Hugging Face)
|
||||
- ❌ Execute shell commands
|
||||
- ❌ Make network requests during normal memory use, except first-run model download from Hugging Face
|
||||
- ❌ Require telemetry, hosted memory storage, or a cloud account
|
||||
- ❌ Access files outside its data directory
|
||||
- ❌ Send telemetry or analytics
|
||||
- ❌ Phone home to any server
|
||||
|
|
|
|||
|
|
@ -1,95 +1,62 @@
|
|||
---
|
||||
name: executioner
|
||||
description: "[LEGACY/FALLBACK as of 2026-04-25] The Sanhedrin post-cognitive judge. Originally invoked by sanhedrin.sh Stop hook as a Haiku 4.5 subagent. PRIMARY EXECUTION PATH NOW: ~/.claude/hooks/sanhedrin-local.py (local Qwen3.6-35B-A3B via mlx_lm.server, zero API cost, fully offline). This Haiku-backed agent runs only as manual fallback if mlx-server is unavailable or invoked explicitly via Task(subagent_type='executioner'). Same protocol: decomposes draft into atomic claims across 10 classes, verifies via Vestige deep_reference, returns 'yes' or 'no - reason' on one line."
|
||||
description: Optional Sanhedrin fallback verifier. Decomposes a draft into check-worthy claims, checks high-trust durable Vestige evidence, and returns a pass/veto verdict.
|
||||
tools: mcp__vestige__deep_reference, mcp__vestige__memory, mcp__vestige__search
|
||||
model: claude-haiku-4-5-20251001
|
||||
---
|
||||
|
||||
# Identity
|
||||
# Role
|
||||
|
||||
You are the Sanhedrin Executioner. A fresh amnesiac judge with access to the Vestige cognitive memory graph. You exist for one turn only. You do not converse. You do not explain. You return exactly one line.
|
||||
You are a one-turn verifier. You do not converse. You return exactly one line.
|
||||
|
||||
# Your Only Job
|
||||
# Job
|
||||
|
||||
Decompose the DRAFT RESPONSE into ATOMIC CLAIMS across 10 exhaustive classes, verify each against high-trust Vestige memory, and VETO the draft if any claim contradicts memory or is factual-shaped but unverifiable.
|
||||
Decompose the draft response into check-worthy claims, verify each claim against
|
||||
high-trust durable Vestige memory when available, and veto only when the draft
|
||||
contradicts memory or makes a sensitive user-specific assertion without durable
|
||||
supporting evidence.
|
||||
|
||||
You are a fail-closed judge. If a claim is factual-shaped and has zero evidence in Vestige either way, that is suspicious — VETO it.
|
||||
# Claim Classes
|
||||
|
||||
# The Ten Claim Classes (Exhaustive)
|
||||
Check all relevant classes:
|
||||
|
||||
You MUST scan the draft for all ten classes. Do not skip a class because it is "not your usual job." Sam's Nightvision verification lesson (memory `efbec834`): *"Handlers must validate ALL possible enum values, not just known cases."* The same rule applies here. Enumerate exhaustively.
|
||||
1. `TECHNICAL` — APIs, commands, versions, files, configs, endpoints.
|
||||
2. `BIOGRAPHICAL` — identity, role, location, employment, education.
|
||||
3. `FINANCIAL` — costs, revenue, pricing, funding, prizes.
|
||||
4. `ACHIEVEMENT` — releases, rankings, completions, scores, milestones.
|
||||
5. `TIMELINE` — dates, durations, ordering, deadlines.
|
||||
6. `QUANTITATIVE` — counts, percentages, metrics, measurements.
|
||||
7. `ATTRIBUTION` — who said, decided, agreed, shipped, or committed.
|
||||
8. `CAUSAL` — claimed causes and effects.
|
||||
9. `COMPARATIVE` — better, most, fastest, more than, fewer than.
|
||||
10. `EXISTENTIAL` — whether a file, feature, repo, or artifact exists.
|
||||
11. `VAGUE-QUANTIFIER` — vague positive claims like "a few wins" or "some prize money".
|
||||
|
||||
1. **TECHNICAL** — API names, version numbers, architectural patterns, configuration recommendations, file paths, command flags, library methods, crate names, endpoint URLs.
|
||||
2. **BIOGRAPHICAL** — claims about the user's identity, age, role, location, employment status, education, family, background.
|
||||
3. **FINANCIAL** — revenue figures, prize money amounts, costs, valuations, pricing, pay, MRR/ARR claims, funding received.
|
||||
4. **ACHIEVEMENT** — competition results, rankings ("won", "tied #1", "scored X/50"), project completions ("we shipped X", "released v2.3"), leaderboard claims, records set, deadlines met.
|
||||
5. **TEMPORAL** — specific dates, durations, sequences ("before X", "after Y"), deadlines, "tonight", "yesterday", "last week".
|
||||
6. **QUANTITATIVE** — counts, percentages, metrics, measurements, star counts, test pass rates, line counts.
|
||||
7. **ATTRIBUTION** — "user said X", "Sam decided Y", "agent X did Y", "we agreed on Z", "you committed to W".
|
||||
8. **CAUSAL** — "X caused Y", "because of X", "X led to Y", "X broke Y".
|
||||
9. **COMPARATIVE** — "better than X", "most", "a few", "some", "more than", "the best", "fastest", superlatives.
|
||||
10. **EXISTENTIAL** — "X exists at path Y", "feature Z is shipped", "there is a Z", "file W is in the repo".
|
||||
# Decision Rules
|
||||
|
||||
# Protocol (execute silently, no narration)
|
||||
- Veto direct contradiction with high-trust memory.
|
||||
- Veto unsupported positive claims about the user's biography, finances,
|
||||
achievements, timeline, quantitative results, attribution, or vague
|
||||
positive outcomes.
|
||||
- Treat staged/current-turn evidence as context only. It is not durable memory and
|
||||
cannot satisfy the durable-evidence requirement.
|
||||
- Do not veto purely stylistic disagreement.
|
||||
- Do not veto technical claims just because Vestige lacks evidence; the draft
|
||||
may rely on source files or external docs.
|
||||
- If evidence is stale or superseded, prefer the newer higher-trust memory.
|
||||
|
||||
1. **Read the draft.** Extract EVERY atomic claim you find across ALL 10 classes above. Not 1-3 — every claim that could be wrong. An atomic claim is one subject-predicate-object assertion ("Sam won AIMO3 prize money" is one claim; "Sam shipped v2.3 and it passed all tests" is two).
|
||||
# Output
|
||||
|
||||
2. **For each claim, tag its class** (TECHNICAL / BIOGRAPHICAL / FINANCIAL / etc.).
|
||||
If the draft passes:
|
||||
|
||||
3. **Verify each claim** via `mcp__vestige__deep_reference` with `query` set to a specific question that would confirm or contradict the claim (e.g., "What prize money has Sam won?" for a FINANCIAL claim about Sam winning $X).
|
||||
```text
|
||||
yes
|
||||
```
|
||||
|
||||
4. **Read the response fields:**
|
||||
- `recommended` — highest-trust answer on the topic
|
||||
- `contradictions` — pairs of high-trust memories that conflict
|
||||
- `superseded` — memories replaced by newer, higher-trust versions
|
||||
- `evidence` — trust-sorted memory list
|
||||
- `confidence` — overall confidence 0-1
|
||||
If the draft should be rewritten:
|
||||
|
||||
5. **Apply the class-specific decision rule:**
|
||||
```text
|
||||
no - [Sanhedrin Veto] [CLASS]: [one-sentence reason under 120 chars]
|
||||
```
|
||||
|
||||
**HARD VETO classes** (BIOGRAPHICAL, FINANCIAL, ACHIEVEMENT, ATTRIBUTION):
|
||||
- If the claim contradicts a memory with trust > 0.5 → VETO.
|
||||
- If the claim is factual-shaped AND Vestige returns confidence < 0.3 with no supporting evidence → VETO (fail-closed, unverifiable positive claim about user's life).
|
||||
- If the claim uses vague qualifiers ("a few", "some", "most") in a factual assertion ("won prize money", "shipped features", "users paid") → VETO. Demand specificity.
|
||||
|
||||
**SOFT VETO classes** (TECHNICAL, EXISTENTIAL, TEMPORAL):
|
||||
- If the claim contradicts a memory with trust > 0.5 → VETO.
|
||||
- If the claim references a `superseded` memory without using its `recommended` replacement → VETO.
|
||||
- Unverifiable is NOT an automatic veto for these classes (the draft may be referencing external facts Vestige doesn't know).
|
||||
|
||||
**DECOMPOSE-FIRST classes** (CAUSAL, COMPARATIVE, QUANTITATIVE):
|
||||
- Break into constituent subject-object claims. Verify each as its own class. If any constituent hard-vetoes, the whole claim vetoes.
|
||||
|
||||
6. **If PASS:** output exactly `yes`.
|
||||
|
||||
7. **If VETO:** output exactly one line:
|
||||
```
|
||||
no - [Sanhedrin Veto] [CLASS]: [one-sentence reason under 120 chars citing memory id if applicable]
|
||||
```
|
||||
Examples:
|
||||
- `no - [Sanhedrin Veto] FINANCIAL: Draft claims "a few competitions won prize money" — Vestige has zero prize-money records, memory 6920e7fe shows AIMO3 finished 36/50, no payout.`
|
||||
- `no - [Sanhedrin Veto] ACHIEVEMENT: Draft claims "v2.3 codename Terrarium" — memory 7b6f5500 (Apr 20, trust 60%) states v2.3 codename is Thalamus.`
|
||||
- `no - [Sanhedrin Veto] TECHNICAL: Draft suggests "FastAPI shim" — memory de43be5a (trust 62%) states Vestige is a 2-crate Rust workspace (vestige-core + vestige-mcp), not Python.`
|
||||
|
||||
8. **If you cannot complete the analysis in under 12 tool calls, default to VETO** with reason `EXECUTION_INCOMPLETE` rather than `yes`. A false VETO costs a rewrite; a false PASS costs Sam's trust. Fail-closed.
|
||||
|
||||
9. **Output exactly ONE line.** Never more. No preamble, no conversation, no XML, no multi-line explanation.
|
||||
|
||||
# What NOT to do
|
||||
|
||||
- Do not limit yourself to "1-3 claims." Extract ALL atomic claims.
|
||||
- Do not paraphrase the draft.
|
||||
- Do not summarize Vestige memory contents.
|
||||
- Do not output multi-line responses.
|
||||
- Do not apologize.
|
||||
- Do not converse.
|
||||
- Do not assume a biographical/financial/achievement claim is verified just because you couldn't find a contradiction — fail-closed on unverifiable positive claims.
|
||||
- Do not veto on stylistic disagreement — only on factual contradiction or unverifiable positive assertion.
|
||||
- Do not claim to have checked a claim you skipped.
|
||||
|
||||
# Precedent — the failures this protocol was tuned to catch
|
||||
|
||||
- **2026-04-20 Terrarium-vs-Thalamus**: caught. Draft claimed v2.3 = Terrarium, memory 7b6f5500 said Thalamus. ACHIEVEMENT/EXISTENTIAL class.
|
||||
- **2026-04-20 FastAPI-vs-Rust**: caught. Draft suggested FastAPI shim, memory de43be5a said 2-crate Rust workspace. TECHNICAL class.
|
||||
- **2026-04-21 Prize-money lie**: MISSED on original protocol. Draft claimed "a few competitions won prize money" — no specific memory to contradict, but zero prize memories existed. v2 protocol catches this via COMPARATIVE vague-qualifier rule + FINANCIAL hard-veto-unverifiable rule.
|
||||
- **Nightvision-enum exhaustive-validation lesson** (memory efbec834): apply the same rule to claim extraction — validate ALL classes, not just the convenient ones.
|
||||
Output exactly one line.
|
||||
|
|
|
|||
|
|
@ -1,41 +1,46 @@
|
|||
---
|
||||
name: synthesis-composer
|
||||
description: Forces active synthesis mode for high-stakes prompts. Invoke for competition submissions (AIMO, Nemotron, Kaggle), architectural choices, purchases over $200, launches, and strategic decisions. The subagent runs in isolation with a hard system prompt that enforces the Composing / Never-composed / Recommendation response shape and blocks summary-pattern output at the source. Use when "what should Sam DO?" matters more than "what does the memory say?"
|
||||
tools: mcp__vestige__search, mcp__vestige__deep_reference, mcp__vestige__cross_reference, mcp__vestige__explore_connections, mcp__vestige__session_context, mcp__vestige__memory, mcp__vestige__smart_ingest, mcp__vestige__intention
|
||||
model: sonnet
|
||||
description: Optional decision helper that turns Vestige retrievals into concise recommendations. Use for high-stakes technical choices, launches, purchases, submissions, architecture decisions, and tradeoffs where memory evidence may change the answer.
|
||||
tools: mcp__vestige__deep_reference, mcp__vestige__explore_connections, mcp__vestige__search
|
||||
model: claude-haiku-4-5-20251001
|
||||
---
|
||||
|
||||
You are the Synthesis Composer. You exist to do ONE thing: turn Vestige retrievals into concrete recommendations Sam can act on.
|
||||
# Role
|
||||
|
||||
## The Hard Rule
|
||||
You are the Synthesis Composer. Your job is to turn retrieved Vestige evidence
|
||||
into a decision, not a memory summary.
|
||||
|
||||
Every response you emit MUST follow this exact shape. No exceptions. Deviation is a protocol violation and the entire response will be rejected.
|
||||
# Protocol
|
||||
|
||||
1. **Composing:** list the memory IDs you retrieved, then your composition logic. The logic is your own chain-of-thought about how the memories relate, NOT a restatement of their individual contents. If you catch yourself writing "Memory A says X, and Memory B says Y," STOP. That is the forbidden pattern.
|
||||
2. **Never-composed detected:** explicitly list combinations of retrieved memories that share tags or topics but have never been retrieved together before this session. If none, write "None." Do NOT skip this line. The whole point of your existence is to surface these.
|
||||
3. **Recommendation: Sam should DO [concrete action].** Not "Sam should consider." Not "Sam might want to." A specific executable step with a subject, a verb, and an object.
|
||||
1. Use the smallest Vestige retrieval plan that can materially change the
|
||||
answer.
|
||||
2. Search adjacent topics when the decision depends on related history.
|
||||
3. Convert each useful memory into `fact -> implication -> action`.
|
||||
4. Surface contradictions, stale evidence, or missing evidence before the
|
||||
recommendation.
|
||||
5. If no memory changes the recommendation, say that briefly and proceed from
|
||||
source evidence.
|
||||
|
||||
## Protocol — Do These Things In Order
|
||||
# Output Shape
|
||||
|
||||
1. Run a MINIMUM of 4 parallel Vestige queries across ADJACENT topics, not just the topic you were asked about. Example: if asked about an AIMO submission, query the asked topic AND proven-baseline memories AND parser-fix memories AND prompt-engineering memories AND failure-mode memories. Minimum 4 parallel searches.
|
||||
2. Call `explore_connections` with `action: "bridges"` to surface memories that share tags but have never been referenced together. This is your primary never-composed detection mechanism. Do not skip it.
|
||||
3. Cross-reference the retrieved memories in YOUR OWN reasoning before writing anything. Compose them in your head first. Ask yourself which combinations exist in Sam's store, which have been tested together in prior sessions, which have NOT been composed yet, and what Sam should DO given the composition.
|
||||
4. Only then write the response in the three-part shape above.
|
||||
Use this compact structure:
|
||||
|
||||
## Forbidden Output Pattern
|
||||
```text
|
||||
Evidence: ...
|
||||
Implication: ...
|
||||
Recommendation: ...
|
||||
```
|
||||
|
||||
If your draft begins with "Memory A says X. Memory B says Y. Memory C says Z." followed by a vague synthesis sentence, you are in the AIMO3 36/50 failure pattern. STOP. Rewrite into composition form with a concrete "Sam should DO" action.
|
||||
When useful, add:
|
||||
|
||||
The test is simple: if Sam can read your response and not know what to do next, you failed. If he can read your response and immediately execute the recommendation without further clarification, you succeeded.
|
||||
```text
|
||||
Contradictions: ...
|
||||
Next step: ...
|
||||
```
|
||||
|
||||
## Trust Overrides
|
||||
# Do Not
|
||||
|
||||
FSRS trust scores override your priors. A memory with retention greater than 0.7 and reps greater than 0 beats a fresh claim you were about to make 30 seconds ago, every single time. If a retrieved memory contradicts your draft, start your response with "Vestige is blocking this:" and surface the contradiction verbatim before proceeding.
|
||||
|
||||
## When To Decline
|
||||
|
||||
If after 4+ queries and a bridges call you cannot find a composition or a never-composed combination, respond with: "Insufficient memory context. Recommended action: run [specific query] or save [specific memory] before making this decision." That is a legitimate output. What is NOT legitimate is guessing.
|
||||
|
||||
## Origin
|
||||
|
||||
This subagent exists because on April 14-15, 2026, Claude retrieved three composable memories (4da778e2, 2f171e0e, b43da3be) for a $1.59M math olympiad submission and reported them as summaries instead of composing them. The result was 36/50 against a 47/50 prize threshold. The protocol you enforce makes that failure mode structurally impossible within your subagent context. You do not have permission to skip the shape.
|
||||
- Do not dump memory summaries as the final answer.
|
||||
- Do not invent hidden evidence.
|
||||
- Do not claim a memory was checked unless a tool result supports it.
|
||||
- Do not force a rigid template when the answer is simple.
|
||||
|
|
|
|||
9
apps/dashboard/.env.example
Normal file
9
apps/dashboard/.env.example
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Optional public waitlist capture endpoint used by /dashboard/waitlist.
|
||||
# The page POSTs JSON with: name, email, plan, priority, notes, source, createdAt.
|
||||
# Examples: Formspree, Tally webhook, Buttondown custom endpoint, Supabase Edge Function.
|
||||
VITE_WAITLIST_ENDPOINT=
|
||||
|
||||
# Optional support bot endpoint used by /dashboard/waitlist.
|
||||
# The page POSTs JSON with: question, plan, priority, source, and recent history.
|
||||
# If unset, the page uses the built-in deterministic onboarding FAQ.
|
||||
VITE_SUPPORT_BOT_ENDPOINT=
|
||||
File diff suppressed because one or more lines are too long
BIN
apps/dashboard/build/_app/immutable/assets/0.Bor8S3Zo.css.br
Normal file
BIN
apps/dashboard/build/_app/immutable/assets/0.Bor8S3Zo.css.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/assets/0.Bor8S3Zo.css.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/assets/0.Bor8S3Zo.css.gz
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
apps/dashboard/build/_app/immutable/assets/20.DKhUrxcR.css.br
Normal file
BIN
apps/dashboard/build/_app/immutable/assets/20.DKhUrxcR.css.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/assets/20.DKhUrxcR.css.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/assets/20.DKhUrxcR.css.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/A7po6GxK.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/A7po6GxK.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{a1 as u,a2 as v,a3 as h,N as i,a4 as g,a5 as f,Y as A,a6 as S}from"./CpWkWWOo.js";const N=Symbol("is custom element"),p=Symbol("is html"),T=f?"link":"LINK",E=f?"progress":"PROGRESS";function k(r){if(i){var s=!1,a=()=>{if(!s){if(s=!0,r.hasAttribute("value")){var e=r.value;_(r,"value",null),r.value=e}if(r.hasAttribute("checked")){var o=r.checked;_(r,"checked",null),r.checked=o}}};r.__on_r=a,A(a),S()}}function l(r,s){var a=d(r);a.value===(a.value=s??void 0)||r.value===s&&(s!==0||r.nodeName!==E)||(r.value=s??"")}function _(r,s,a,e){var o=d(r);i&&(o[s]=r.getAttribute(s),s==="src"||s==="srcset"||s==="href"&&r.nodeName===T)||o[s]!==(o[s]=a)&&(s==="loading"&&(r[u]=a),a==null?r.removeAttribute(s):typeof a!="string"&&L(r).includes(s)?r[s]=a:r.setAttribute(s,a))}function d(r){return r.__attributes??(r.__attributes={[N]:r.nodeName.includes("-"),[p]:r.namespaceURI===v})}var c=new Map;function L(r){var s=r.getAttribute("is")||r.nodeName,a=c.get(s);if(a)return a;c.set(s,a=[]);for(var e,o=r,n=Element.prototype;n!==o;){e=g(o);for(var t in e)e[t].set&&a.push(t);o=h(o)}return a}export{l as a,k as r,_ as s};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/A7po6GxK.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/A7po6GxK.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/A7po6GxK.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/A7po6GxK.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/B4yTwGkE.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/B4yTwGkE.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{b as T,N as o,ab as b,E as h,ac as R,ax as p,ad as A,ae as E,T as g,R as l}from"./CpWkWWOo.js";import{B as v}from"./DdEqwvdI.js";function m(t,c,u=!1){o&&b();var n=new v(t),_=u?h:0;function i(a,r){if(o){const e=R(t);var s;if(e===p?s=0:e===A?s=!1:s=parseInt(e.substring(1)),a!==s){var f=E();g(f),n.anchor=f,l(!1),n.ensure(a,r),l(!0);return}}n.ensure(a,r)}T(()=>{var a=!1;c((r,s=0)=>{a=!0,i(s,r)}),a||i(!1,null)},_)}export{m as i};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/B4yTwGkE.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/B4yTwGkE.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/B4yTwGkE.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/B4yTwGkE.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
const r="/api";async function t(e,o){const i=await fetch(`${r}${e}`,{headers:{"Content-Type":"application/json"},...o});if(!i.ok)throw new Error(`API ${i.status}: ${i.statusText}`);return i.json()}const n={memories:{list:e=>{const o=e?"?"+new URLSearchParams(e).toString():"";return t(`/memories${o}`)},get:e=>t(`/memories/${e}`),delete:e=>t(`/memories/${e}`,{method:"DELETE"}),promote:e=>t(`/memories/${e}/promote`,{method:"POST"}),demote:e=>t(`/memories/${e}/demote`,{method:"POST"}),suppress:(e,o)=>t(`/memories/${e}/suppress`,{method:"POST",body:o?JSON.stringify({reason:o}):void 0}),unsuppress:e=>t(`/memories/${e}/unsuppress`,{method:"POST"})},search:(e,o=20)=>t(`/search?q=${encodeURIComponent(e)}&limit=${o}`),stats:()=>t("/stats"),health:()=>t("/health"),timeline:(e=7,o=200)=>t(`/timeline?days=${e}&limit=${o}`),graph:e=>{const o=e?"?"+new URLSearchParams(Object.entries(e).filter(([,i])=>i!==void 0).map(([i,s])=>[i,String(s)])).toString():"";return t(`/graph${o}`)},dream:()=>t("/dream",{method:"POST"}),explore:(e,o="associations",i,s=10)=>t("/explore",{method:"POST",body:JSON.stringify({from_id:e,action:o,to_id:i,limit:s})}),predict:()=>t("/predict",{method:"POST"}),importance:e=>t("/importance",{method:"POST",body:JSON.stringify({content:e})}),consolidate:()=>t("/consolidate",{method:"POST"}),retentionDistribution:()=>t("/retention-distribution"),intentions:(e="active")=>t(`/intentions?status=${e}`),deepReference:(e,o=20)=>t("/deep_reference",{method:"POST",body:JSON.stringify({query:e,depth:o})})};export{n as a};
|
||||
const r="/api";async function t(e,o){const i=await fetch(`${r}${e}`,{headers:{"Content-Type":"application/json"},...o});if(!i.ok)throw new Error(`API ${i.status}: ${i.statusText}`);return i.json()}const n={memories:{list:e=>{const o=e?"?"+new URLSearchParams(e).toString():"";return t(`/memories${o}`)},get:e=>t(`/memories/${e}`),delete:e=>t(`/memories/${e}`,{method:"DELETE"}),promote:e=>t(`/memories/${e}/promote`,{method:"POST"}),demote:e=>t(`/memories/${e}/demote`,{method:"POST"}),suppress:(e,o)=>t(`/memories/${e}/suppress`,{method:"POST",body:o?JSON.stringify({reason:o}):void 0}),unsuppress:e=>t(`/memories/${e}/unsuppress`,{method:"POST"})},search:(e,o=20)=>t(`/search?q=${encodeURIComponent(e)}&limit=${o}`),stats:()=>t("/stats"),health:()=>t("/health"),timeline:(e=7,o=200)=>t(`/timeline?days=${e}&limit=${o}`),graph:e=>{const o=e?"?"+new URLSearchParams(Object.entries(e).filter(([,i])=>i!==void 0).map(([i,s])=>[i,String(s)])).toString():"";return t(`/graph${o}`)},dream:()=>t("/dream",{method:"POST"}),explore:(e,o="associations",i,s=10)=>t("/explore",{method:"POST",body:JSON.stringify({from_id:e,action:o,to_id:i,limit:s})}),predict:()=>t("/predict",{method:"POST"}),importance:e=>t("/importance",{method:"POST",body:JSON.stringify({content:e})}),consolidate:()=>t("/consolidate",{method:"POST"}),retentionDistribution:()=>t("/retention-distribution"),intentions:(e="active")=>t(`/intentions?status=${e}`),deepReference:(e,o=20)=>t("/deep_reference",{method:"POST",body:JSON.stringify({query:e,depth:o})}),sanhedrin:{latest:()=>t("/sanhedrin/latest"),telemetry:(e=7)=>t(`/sanhedrin/telemetry?days=${e}`),appeal:(e,o,i,s)=>t("/sanhedrin/appeal",{method:"POST",body:JSON.stringify({reason:e,note:o,claimId:i,receiptId:s})})}};export{n as a};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/B7CfdQuM.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/B7CfdQuM.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/B7CfdQuM.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/B7CfdQuM.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
import{az as g,aA as d,aB as c,A as m,aC as i,aD as b,g as p,aE as v,U as h,aF as k}from"./CvjSAYrz.js";function x(t=!1){const a=g,e=a.l.u;if(!e)return;let f=()=>v(a.s);if(t){let n=0,s={};const _=h(()=>{let l=!1;const r=a.s;for(const o in r)r[o]!==s[o]&&(s[o]=r[o],l=!0);return l&&n++,n});f=()=>p(_)}e.b.length&&d(()=>{u(a,f),i(e.b)}),c(()=>{const n=m(()=>e.m.map(b));return()=>{for(const s of n)typeof s=="function"&&s()}}),e.a.length&&c(()=>{u(a,f),i(e.a)})}function u(t,a){if(t.l.s)for(const e of t.l.s)p(e);a()}k();export{x as i};
|
||||
import{az as g,aA as d,aB as c,v as m,aC as i,aD as b,g as p,aE as v,z as h,aF as k}from"./CpWkWWOo.js";function x(t=!1){const a=g,e=a.l.u;if(!e)return;let f=()=>v(a.s);if(t){let n=0,s={};const _=h(()=>{let l=!1;const r=a.s;for(const o in r)r[o]!==s[o]&&(s[o]=r[o],l=!0);return l&&n++,n});f=()=>p(_)}e.b.length&&d(()=>{u(a,f),i(e.b)}),c(()=>{const n=m(()=>e.m.map(b));return()=>{for(const s of n)typeof s=="function"&&s()}}),e.a.length&&c(()=>{u(a,f),i(e.a)})}function u(t,a){if(t.l.s)for(const e of t.l.s)p(e);a()}k();export{x as i};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/BUoSzNdg.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BUoSzNdg.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/BUoSzNdg.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BUoSzNdg.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
import{J as T,K as m,P as D,g as P,c as b,h as B,L as M,M as N,N as U,O as Y,A as h,Q as x,R as $,T as q,U as w,V as z,W as C,S as G,X as J}from"./CvjSAYrz.js";import{c as K}from"./D81f-o_I.js";function W(r,a,t,s){var O;var f=!x||(t&$)!==0,v=(t&Y)!==0,o=(t&C)!==0,n=s,c=!0,g=()=>(c&&(c=!1,n=o?h(s):s),n),u;if(v){var A=G in r||J in r;u=((O=T(r,a))==null?void 0:O.set)??(A&&a in r?e=>r[a]=e:void 0)}var _,I=!1;v?[_,I]=K(()=>r[a]):_=r[a],_===void 0&&s!==void 0&&(_=g(),u&&(f&&m(),u(_)));var i;if(f?i=()=>{var e=r[a];return e===void 0?g():(c=!0,e)}:i=()=>{var e=r[a];return e!==void 0&&(n=void 0),e===void 0?n:e},f&&(t&D)===0)return i;if(u){var E=r.$$legacy;return(function(e,S){return arguments.length>0?((!f||!S||E||I)&&u(S?i():e),e):i()})}var l=!1,d=((t&q)!==0?w:z)(()=>(l=!1,i()));v&&P(d);var L=N;return(function(e,S){if(arguments.length>0){const R=S?P(d):f&&v?b(e):e;return B(d,R),l=!0,n!==void 0&&(n=R),e}return M&&l||(L.f&U)!==0?d.v:P(d)})}export{W as p};
|
||||
Binary file not shown.
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/BeMFXnHE.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/BeMFXnHE.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{H as a,v as m,aH as q,aC as x}from"./CpWkWWOo.js";function _(e,t,n){if(e==null)return t(void 0),n&&n(void 0),a;const r=m(()=>e.subscribe(t,n));return r.unsubscribe?()=>r.unsubscribe():r}const f=[];function z(e,t){return{subscribe:A(e,t).subscribe}}function A(e,t=a){let n=null;const r=new Set;function i(u){if(q(e,u)&&(e=u,n)){const o=!f.length;for(const s of r)s[1](),f.push(s,e);if(o){for(let s=0;s<f.length;s+=2)f[s][0](f[s+1]);f.length=0}}}function b(u){i(u(e))}function l(u,o=a){const s=[u,o];return r.add(s),r.size===1&&(n=t(i,b)||a),u(e),()=>{r.delete(s),r.size===0&&n&&(n(),n=null)}}return{set:i,update:b,subscribe:l}}function k(e,t,n){const r=!Array.isArray(e),i=r?[e]:e;if(!i.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const b=t.length<2;return z(n,(l,u)=>{let o=!1;const s=[];let d=0,p=a;const y=()=>{if(d)return;p();const c=t(r?s[0]:s,l,u);b?l(c):p=typeof c=="function"?c:a},h=i.map((c,g)=>_(c,w=>{s[g]=w,d&=~(1<<g),o&&y()},()=>{d|=1<<g}));return o=!0,y(),function(){x(h),p(),o=!1}})}function B(e){let t;return _(e,n=>t=n)(),t}export{k as d,B as g,_ as s,A as w};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/BeMFXnHE.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BeMFXnHE.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/BeMFXnHE.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BeMFXnHE.js.gz
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
apps/dashboard/build/_app/immutable/chunks/BlVfL1ME.js
Normal file
2
apps/dashboard/build/_app/immutable/chunks/BlVfL1ME.js
Normal file
File diff suppressed because one or more lines are too long
BIN
apps/dashboard/build/_app/immutable/chunks/BlVfL1ME.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BlVfL1ME.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/BlVfL1ME.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BlVfL1ME.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
import{D as s,F as v,y as o,a3 as c,a7 as b,a8 as m,a9 as h,I as y}from"./CvjSAYrz.js";function _(e,r,f=!1){if(e.multiple){if(r==null)return;if(!b(r))return m();for(var a of e.options)a.selected=r.includes(i(a));return}for(a of e.options){var t=i(a);if(h(t,r)){a.selected=!0;return}}(!f||r!==void 0)&&(e.selectedIndex=-1)}function q(e){var r=new MutationObserver(()=>{_(e,e.__value)});r.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),c(()=>{r.disconnect()})}function p(e,r,f=r){var a=new WeakSet,t=!0;s(e,"change",u=>{var l=u?"[selected]":":checked",n;if(e.multiple)n=[].map.call(e.querySelectorAll(l),i);else{var d=e.querySelector(l)??e.querySelector("option:not([disabled])");n=d&&i(d)}f(n),v!==null&&a.add(v)}),o(()=>{var u=r();if(e===document.activeElement){var l=y??v;if(a.has(l))return}if(_(e,u,t),t&&u===void 0){var n=e.querySelector(":checked");n!==null&&(u=i(n),f(u))}e.__value=u,t=!1}),q(e)}function i(e){return"__value"in e?e.__value:e.value}export{p as b};
|
||||
import{Z as s,_ as v,W as o,F as c,a7 as b,a8 as m,a9 as h,a0 as y}from"./CpWkWWOo.js";function d(e,r,f=!1){if(e.multiple){if(r==null)return;if(!b(r))return m();for(var a of e.options)a.selected=r.includes(i(a));return}for(a of e.options){var t=i(a);if(h(t,r)){a.selected=!0;return}}(!f||r!==void 0)&&(e.selectedIndex=-1)}function q(e){var r=new MutationObserver(()=>{d(e,e.__value)});r.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),c(()=>{r.disconnect()})}function p(e,r,f=r){var a=new WeakSet,t=!0;s(e,"change",u=>{var l=u?"[selected]":":checked",n;if(e.multiple)n=[].map.call(e.querySelectorAll(l),i);else{var _=e.querySelector(l)??e.querySelector("option:not([disabled])");n=_&&i(_)}f(n),v!==null&&a.add(v)}),o(()=>{var u=r();if(e===document.activeElement){var l=y??v;if(a.has(l))return}if(d(e,u,t),t&&u===void 0){var n=e.querySelector(":checked");n!==null&&(u=i(n),f(u))}e.__value=u,t=!1}),q(e)}function i(e){return"__value"in e?e.__value:e.value}export{p as b};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/BnXDGOmJ.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BnXDGOmJ.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/BnXDGOmJ.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/BnXDGOmJ.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
import{aH as N,k as v,x as u,aI as w,M as p,aJ as T,aK as x,m as d,w as i,aL as y,ab as b,aM as A,v as L,aN as C}from"./CvjSAYrz.js";var h;const m=((h=globalThis==null?void 0:globalThis.window)==null?void 0:h.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function D(e){return(m==null?void 0:m.createHTML(e))??e}function g(e){var a=N("template");return a.innerHTML=D(e.replaceAll("<!>","<!---->")),a.content}function n(e,a){var r=p;r.nodes===null&&(r.nodes={start:e,end:a,a:null,t:null})}function P(e,a){var r=(a&T)!==0,f=(a&x)!==0,s,c=!e.startsWith("<!>");return()=>{if(d)return n(i,null),i;s===void 0&&(s=g(c?e:"<!>"+e),r||(s=u(s)));var t=f||w?document.importNode(s,!0):s.cloneNode(!0);if(r){var _=u(t),o=t.lastChild;n(_,o)}else n(t,t);return t}}function H(e,a,r="svg"){var f=!e.startsWith("<!>"),s=(a&T)!==0,c=`<${r}>${f?e:"<!>"+e}</${r}>`,t;return()=>{if(d)return n(i,null),i;if(!t){var _=g(c),o=u(_);if(s)for(t=document.createDocumentFragment();u(o);)t.appendChild(u(o));else t=u(o)}var l=t.cloneNode(!0);if(s){var E=u(l),M=l.lastChild;n(E,M)}else n(l,l);return l}}function R(e,a){return H(e,a,"svg")}function F(e=""){if(!d){var a=v(e+"");return n(a,a),a}var r=i;return r.nodeType!==A?(r.before(r=v()),L(r)):C(r),n(r,r),r}function I(){if(d)return n(i,null),i;var e=document.createDocumentFragment(),a=document.createComment(""),r=v();return e.append(a,r),n(a,r),e}function $(e,a){if(d){var r=p;((r.f&y)===0||r.nodes.end===null)&&(r.nodes.end=i),b();return}e!==null&&e.before(a)}export{$ as a,R as b,I as c,n as d,P as f,F as t};
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/C2TQQEIa.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/C2TQQEIa.js
Normal file
File diff suppressed because one or more lines are too long
BIN
apps/dashboard/build/_app/immutable/chunks/C2TQQEIa.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/C2TQQEIa.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/C2TQQEIa.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/C2TQQEIa.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/C4h_mRt2.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/C4h_mRt2.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{J as y,b as u,K as _,M as o,N as t,O as g,Q as i,R as l,T as d,U as p,V as m}from"./CpWkWWOo.js";function T(n,r){let s=null,E=t;var a;if(t){s=p;for(var e=m(document.head);e!==null&&(e.nodeType!==g||e.data!==n);)e=i(e);if(e===null)l(!1);else{var f=i(e);e.remove(),d(f)}}t||(a=document.head.appendChild(y()));try{u(()=>r(a),_|o)}finally{E&&(l(!0),d(s))}}export{T as h};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
v`‡éĆ)wä<77>KĆÖ„Mڜ˿Q@ÉĆşWőv<>á·E†śYt°c°Gş.˛h€Ă2DŢJżĐšźŞ<C5BA>dSŰŤ$g›d“D1€Úćěŕ,Jy>´U–`+&
|
||||
ŐźĐxS<s.Ć‚§%©5ą±áhGlĎŐÁź~˙Řɲ»g°ĽXĹŁÎv1ßÁٸŁ8Ňłú<C582>„rO†|°<<3C>'Šż2…ř &=UdTă…ÚnYBĐ&¨•’¬¶$ˇC†Äs ©â%{<BÍuéř ńîŐÄ<1D>ż€F *ő”ľîČěá<07>Čž÷źx Ď4<yA5ťŃOŽPs,†˘RĎ_$±ÓýăY
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/C4h_mRt2.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/C4h_mRt2.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/C6HuKgyx.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/C6HuKgyx.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{s as c,g as l}from"./BeMFXnHE.js";import{F as o,G as b,H as a,I as p,g as d,h as g}from"./CpWkWWOo.js";let s=!1,i=Symbol();function y(e,n,r){const u=r[n]??(r[n]={store:null,source:p(void 0),unsubscribe:a});if(u.store!==e&&!(i in r))if(u.unsubscribe(),u.store=e??null,e==null)u.source.v=void 0,u.unsubscribe=a;else{var t=!0;u.unsubscribe=c(e,f=>{t?u.source.v=f:g(u.source,f)}),t=!1}return e&&i in r?l(e):d(u.source)}function m(){const e={};function n(){o(()=>{for(var r in e)e[r].unsubscribe();b(e,i,{enumerable:!1,value:!0})})}return[e,n]}function I(e){var n=s;try{return s=!1,[e(),s]}finally{s=n}}export{y as a,I as c,m as s};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/C6HuKgyx.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/C6HuKgyx.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/C6HuKgyx.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/C6HuKgyx.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/CGEBXrjl.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/CGEBXrjl.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{J as z,b as fe,aa as re,N as k,T as L,V as ie,ab as le,g as Z,ac as ue,ad as se,ae as $,R as q,U as F,O as oe,af as ve,ag as y,_ as te,ah as T,ai as Y,aj as de,ak as ce,A as pe,a7 as _e,al as U,am as he,an as ge,I as Ee,ao as j,ap as me,aq as ne,ar as ae,as as V,Y as Te,at as Ae,au as Ce,av as we,aw as Ie,Q as Ne}from"./CpWkWWOo.js";function ke(e,i){return i}function Se(e,i,l){for(var t=[],g=i.length,s,u=i.length,c=0;c<g;c++){let E=i[c];ae(E,()=>{if(s){if(s.pending.delete(E),s.done.add(E),s.pending.size===0){var o=e.outrogroups;B(U(s.done)),o.delete(s),o.size===0&&(e.outrogroups=null)}}else u-=1},!1)}if(u===0){var f=t.length===0&&l!==null;if(f){var v=l,n=v.parentNode;we(n),n.append(v),e.items.clear()}B(i,!f)}else s={pending:new Set(i),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(s)}function B(e,i=!0){for(var l=0;l<e.length;l++)Ie(e[l],i)}var ee;function He(e,i,l,t,g,s=null){var u=e,c=new Map,f=(i&re)!==0;if(f){var v=e;u=k?L(ie(v)):v.appendChild(z())}k&&le();var n=null,E=pe(()=>{var a=l();return _e(a)?a:a==null?[]:U(a)}),o,d=!0;function C(){r.fallback=n,xe(r,o,u,i,t),n!==null&&(o.length===0?(n.f&T)===0?ne(n):(n.f^=T,M(n,null,u)):ae(n,()=>{n=null}))}var N=fe(()=>{o=Z(E);var a=o.length;let S=!1;if(k){var x=ue(u)===se;x!==(a===0)&&(u=$(),L(u),q(!1),S=!0)}for(var _=new Set,w=te,R=ce(),p=0;p<a;p+=1){k&&F.nodeType===oe&&F.data===ve&&(u=F,S=!0,q(!1));var I=o[p],b=t(I,p),h=d?null:c.get(b);h?(h.v&&y(h.v,I),h.i&&y(h.i,p),R&&w.unskip_effect(h.e)):(h=Re(c,d?u:ee??(ee=z()),I,b,p,g,i,l),d||(h.e.f|=T),c.set(b,h)),_.add(b)}if(a===0&&s&&!n&&(d?n=Y(()=>s(u)):(n=Y(()=>s(ee??(ee=z()))),n.f|=T)),a>_.size&&de(),k&&a>0&&L($()),!d)if(R){for(const[O,D]of c)_.has(O)||w.skip_effect(D.e);w.oncommit(C),w.ondiscard(()=>{})}else C();S&&q(!0),Z(E)}),r={effect:N,items:c,outrogroups:null,fallback:n};d=!1,k&&(u=F)}function H(e){for(;e!==null&&(e.f&Ae)===0;)e=e.next;return e}function xe(e,i,l,t,g){var h,O,D,J,Q,X,G,K,P;var s=(t&Ce)!==0,u=i.length,c=e.items,f=H(e.effect.first),v,n=null,E,o=[],d=[],C,N,r,a;if(s)for(a=0;a<u;a+=1)C=i[a],N=g(C,a),r=c.get(N).e,(r.f&T)===0&&((O=(h=r.nodes)==null?void 0:h.a)==null||O.measure(),(E??(E=new Set)).add(r));for(a=0;a<u;a+=1){if(C=i[a],N=g(C,a),r=c.get(N).e,e.outrogroups!==null)for(const m of e.outrogroups)m.pending.delete(r),m.done.delete(r);if((r.f&T)!==0)if(r.f^=T,r===f)M(r,null,l);else{var S=n?n.next:f;r===e.effect.last&&(e.effect.last=r.prev),r.prev&&(r.prev.next=r.next),r.next&&(r.next.prev=r.prev),A(e,n,r),A(e,r,S),M(r,S,l),n=r,o=[],d=[],f=H(n.next);continue}if((r.f&V)!==0&&(ne(r),s&&((J=(D=r.nodes)==null?void 0:D.a)==null||J.unfix(),(E??(E=new Set)).delete(r))),r!==f){if(v!==void 0&&v.has(r)){if(o.length<d.length){var x=d[0],_;n=x.prev;var w=o[0],R=o[o.length-1];for(_=0;_<o.length;_+=1)M(o[_],x,l);for(_=0;_<d.length;_+=1)v.delete(d[_]);A(e,w.prev,R.next),A(e,n,w),A(e,R,x),f=x,n=R,a-=1,o=[],d=[]}else v.delete(r),M(r,f,l),A(e,r.prev,r.next),A(e,r,n===null?e.effect.first:n.next),A(e,n,r),n=r;continue}for(o=[],d=[];f!==null&&f!==r;)(v??(v=new Set)).add(f),d.push(f),f=H(f.next);if(f===null)continue}(r.f&T)===0&&o.push(r),n=r,f=H(r.next)}if(e.outrogroups!==null){for(const m of e.outrogroups)m.pending.size===0&&(B(U(m.done)),(Q=e.outrogroups)==null||Q.delete(m));e.outrogroups.size===0&&(e.outrogroups=null)}if(f!==null||v!==void 0){var p=[];if(v!==void 0)for(r of v)(r.f&V)===0&&p.push(r);for(;f!==null;)(f.f&V)===0&&f!==e.fallback&&p.push(f),f=H(f.next);var I=p.length;if(I>0){var b=(t&re)!==0&&u===0?l:null;if(s){for(a=0;a<I;a+=1)(G=(X=p[a].nodes)==null?void 0:X.a)==null||G.measure();for(a=0;a<I;a+=1)(P=(K=p[a].nodes)==null?void 0:K.a)==null||P.fix()}Se(e,p,b)}}s&&Te(()=>{var m,W;if(E!==void 0)for(r of E)(W=(m=r.nodes)==null?void 0:m.a)==null||W.apply()})}function Re(e,i,l,t,g,s,u,c){var f=(u&he)!==0?(u&ge)===0?Ee(l,!1,!1):j(l):null,v=(u&me)!==0?j(g):null;return{v:f,i:v,e:Y(()=>(s(i,f??l,v??g,c),()=>{e.delete(t)}))}}function M(e,i,l){if(e.nodes)for(var t=e.nodes.start,g=e.nodes.end,s=i&&(i.f&T)===0?i.nodes.start:l;t!==null;){var u=Ne(t);if(s.before(t),t===g)return;t=u}}function A(e,i,l){i===null?e.effect.first=l:i.next=l,l===null?e.effect.last=i:l.prev=i}export{He as e,ke as i};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/CGEBXrjl.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CGEBXrjl.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/CGEBXrjl.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CGEBXrjl.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/CHOnp4oo.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/CHOnp4oo.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{aI as M,J as v,V as o,aJ as y,o as T,aK as p,aL as b,N as d,U as i,aM as w,ab as x,aN as A,T as L,aO as C}from"./CpWkWWOo.js";var h;const m=((h=globalThis==null?void 0:globalThis.window)==null?void 0:h.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function O(e){return(m==null?void 0:m.createHTML(e))??e}function g(e){var a=M("template");return a.innerHTML=O(e.replaceAll("<!>","<!---->")),a.content}function n(e,a){var r=T;r.nodes===null&&(r.nodes={start:e,end:a,a:null,t:null})}function R(e,a){var r=(a&p)!==0,f=(a&b)!==0,s,c=!e.startsWith("<!>");return()=>{if(d)return n(i,null),i;s===void 0&&(s=g(c?e:"<!>"+e),r||(s=o(s)));var t=f||y?document.importNode(s,!0):s.cloneNode(!0);if(r){var _=o(t),u=t.lastChild;n(_,u)}else n(t,t);return t}}function D(e,a,r="svg"){var f=!e.startsWith("<!>"),s=(a&p)!==0,c=`<${r}>${f?e:"<!>"+e}</${r}>`,t;return()=>{if(d)return n(i,null),i;if(!t){var _=g(c),u=o(_);if(s)for(t=document.createDocumentFragment();o(u);)t.appendChild(o(u));else t=o(u)}var l=t.cloneNode(!0);if(s){var E=o(l),N=l.lastChild;n(E,N)}else n(l,l);return l}}function F(e,a){return D(e,a,"svg")}function H(e=""){if(!d){var a=v(e+"");return n(a,a),a}var r=i;return r.nodeType!==A?(r.before(r=v()),L(r)):C(r),n(r,r),r}function I(){if(d)return n(i,null),i;var e=document.createDocumentFragment(),a=document.createComment(""),r=v();return e.append(a,r),n(a,r),e}function $(e,a){if(d){var r=T;((r.f&w)===0||r.nodes.end===null)&&(r.nodes.end=i),x();return}e!==null&&e.before(a)}export{$ as a,F as b,I as c,n as d,R as f,H as t};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/CHOnp4oo.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CHOnp4oo.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/CHOnp4oo.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CHOnp4oo.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/CJCPY1OL.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/CJCPY1OL.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{b as p,E as t}from"./CpWkWWOo.js";import{B as c}from"./DdEqwvdI.js";function E(r,s,...a){var e=new c(r);p(()=>{const n=s()??null;e.ensure(n,n&&(o=>n(o,...a)))},t)}export{E as s};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/CJCPY1OL.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CJCPY1OL.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/CJCPY1OL.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CJCPY1OL.js.gz
Normal file
Binary file not shown.
1
apps/dashboard/build/_app/immutable/chunks/CJsMJEun.js
Normal file
1
apps/dashboard/build/_app/immutable/chunks/CJsMJEun.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{W as S,X as h,v as k,Y as T,S as Y}from"./CpWkWWOo.js";function t(r,i){return r===i||(r==null?void 0:r[Y])===i}function x(r={},i,a,c){return S(()=>{var f,s;return h(()=>{f=s,s=[],k(()=>{r!==a(...s)&&(i(r,...s),f&&t(a(...f),r)&&i(null,...f))})}),()=>{T(()=>{s&&t(a(...s),r)&&i(null,...s)})}}),r}export{x as b};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/CJsMJEun.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CJsMJEun.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/CJsMJEun.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CJsMJEun.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
import{Y as u,Z as v,_ as h,m as i,$ as g,a0 as f,B as A,a1 as S}from"./CvjSAYrz.js";const p=Symbol("is custom element"),N=Symbol("is html"),T=f?"link":"LINK",E=f?"progress":"PROGRESS";function k(r){if(i){var s=!1,a=()=>{if(!s){if(s=!0,r.hasAttribute("value")){var e=r.value;_(r,"value",null),r.value=e}if(r.hasAttribute("checked")){var o=r.checked;_(r,"checked",null),r.checked=o}}};r.__on_r=a,A(a),S()}}function l(r,s){var a=d(r);a.value===(a.value=s??void 0)||r.value===s&&(s!==0||r.nodeName!==E)||(r.value=s??"")}function _(r,s,a,e){var o=d(r);i&&(o[s]=r.getAttribute(s),s==="src"||s==="srcset"||s==="href"&&r.nodeName===T)||o[s]!==(o[s]=a)&&(s==="loading"&&(r[u]=a),a==null?r.removeAttribute(s):typeof a!="string"&&L(r).includes(s)?r[s]=a:r.setAttribute(s,a))}function d(r){return r.__attributes??(r.__attributes={[p]:r.nodeName.includes("-"),[N]:r.namespaceURI===v})}var c=new Map;function L(r){var s=r.getAttribute("is")||r.nodeName,a=c.get(s);if(a)return a;c.set(s,a=[]);for(var e,o=r,n=Element.prototype;n!==o;){e=g(o);for(var t in e)e[t].set&&a.push(t);o=h(o)}return a}export{l as a,k as r,_ as s};
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
import{D as k,F as f,G as m,A as t,z as _,m as b,I as i}from"./CvjSAYrz.js";function E(e,a,v=a){var c=new WeakSet;k(e,"input",async r=>{var l=r?e.defaultValue:e.value;if(l=o(e)?u(l):l,v(l),f!==null&&c.add(f),await m(),l!==(l=a())){var h=e.selectionStart,d=e.selectionEnd,n=e.value.length;if(e.value=l??"",d!==null){var s=e.value.length;h===d&&d===n&&s>n?(e.selectionStart=s,e.selectionEnd=s):(e.selectionStart=h,e.selectionEnd=Math.min(d,s))}}}),(b&&e.defaultValue!==e.value||t(a)==null&&e.value)&&(v(o(e)?u(e.value):e.value),f!==null&&c.add(f)),_(()=>{var r=a();if(e===document.activeElement){var l=i??f;if(c.has(l))return}o(e)&&r===u(e.value)||e.type==="date"&&!r&&!e.value||r!==e.value&&(e.value=r??"")})}function S(e,a,v=a){k(e,"change",c=>{var r=c?e.defaultChecked:e.checked;v(r)}),(b&&e.defaultChecked!==e.checked||t(a)==null)&&v(e.checked),_(()=>{var c=a();e.checked=!!c})}function o(e){var a=e.type;return a==="number"||a==="range"}function u(e){return e===""?null:+e}export{S as a,E as b};
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
import{w as S,g as T}from"./DfQhL-hC.js";import{e as R}from"./CtkE7HV2.js";import{E as u}from"./DzfRjky4.js";const M=4,x=1500;function F(){const{subscribe:y,update:i}=S([]);let m=1,b=0;const d=new Map,a=new Map,l=new Map;function f(e,o){l.set(e,Date.now());const t=setTimeout(()=>{d.delete(e),l.delete(e),g(e)},o);d.set(e,t)}function w(e){const o=m++,t=Date.now(),s={id:o,createdAt:t,...e};i(n=>{const r=[s,...n];return r.length>M?r.slice(0,M):r}),f(o,e.dwellMs)}function g(e){const o=d.get(e);o&&(clearTimeout(o),d.delete(e)),a.delete(e),l.delete(e),i(t=>t.filter(s=>s.id!==e))}function C(e,o){const t=d.get(e);if(!t)return;clearTimeout(t),d.delete(e);const s=l.get(e)??Date.now(),n=Date.now()-s,r=Math.max(200,o-n);a.set(e,{remaining:r})}function D(e){const o=a.get(e);o&&(a.delete(e),f(e,o.remaining))}function N(){for(const e of d.values())clearTimeout(e);d.clear(),a.clear(),l.clear(),i(()=>[])}function _(e){const o=u[e.type]??"#818CF8",t=e.data;switch(e.type){case"DreamCompleted":{const s=Number(t.memories_replayed??0),n=Number(t.connections_found??0),r=Number(t.insights_generated??0),p=Number(t.duration_ms??0),c=[];return c.push(`Replayed ${s} ${s===1?"memory":"memories"}`),n>0&&c.push(`${n} new connection${n===1?"":"s"}`),r>0&&c.push(`${r} insight${r===1?"":"s"}`),{type:e.type,title:"Dream consolidated",body:`${c.join(" · ")} in ${(p/1e3).toFixed(1)}s`,color:o,dwellMs:7e3}}case"ConsolidationCompleted":{const s=Number(t.nodes_processed??0),n=Number(t.decay_applied??0),r=Number(t.embeddings_generated??0),p=Number(t.duration_ms??0),c=[];return n>0&&c.push(`${n} decayed`),r>0&&c.push(`${r} embedded`),{type:e.type,title:"Consolidation swept",body:`${s} node${s===1?"":"s"}${c.length?" · "+c.join(" · "):""} in ${(p/1e3).toFixed(1)}s`,color:o,dwellMs:6e3}}case"ConnectionDiscovered":{const s=Date.now();if(s-b<x)return null;b=s;const n=String(t.connection_type??"link"),r=Number(t.weight??0);return{type:e.type,title:"Bridge discovered",body:`${n} · weight ${r.toFixed(2)}`,color:o,dwellMs:4500}}case"MemoryPromoted":{const s=Number(t.new_retention??0);return{type:e.type,title:"Memory promoted",body:`retention ${(s*100).toFixed(0)}%`,color:o,dwellMs:4500}}case"MemoryDemoted":{const s=Number(t.new_retention??0);return{type:e.type,title:"Memory demoted",body:`retention ${(s*100).toFixed(0)}%`,color:o,dwellMs:4500}}case"MemorySuppressed":{const s=Number(t.suppression_count??0),n=Number(t.estimated_cascade??0);return{type:e.type,title:"Forgetting",body:n>0?`suppression #${s} · Rac1 cascade ~${n} neighbors`:`suppression #${s}`,color:o,dwellMs:5500}}case"MemoryUnsuppressed":{const s=Number(t.remaining_count??0);return{type:e.type,title:"Recovered",body:s>0?`${s} suppression${s===1?"":"s"} remain`:"fully unsuppressed",color:o,dwellMs:5e3}}case"Rac1CascadeSwept":{const s=Number(t.seeds??0),n=Number(t.neighbors_affected??0);return{type:e.type,title:"Rac1 cascade",body:`${s} seed${s===1?"":"s"} · ${n} dendritic spine${n===1?"":"s"} pruned`,color:o,dwellMs:6e3}}case"MemoryDeleted":return{type:e.type,title:"Memory deleted",body:String(t.id??"").slice(0,8),color:o,dwellMs:4e3};case"Heartbeat":case"SearchPerformed":case"RetentionDecayed":case"ActivationSpread":case"ImportanceScored":case"MemoryCreated":case"MemoryUpdated":case"DreamStarted":case"DreamProgress":case"ConsolidationStarted":case"Connected":return null;default:return null}}let h=null;return R.subscribe(e=>{if(e.length===0)return;const o=[];for(const t of e){if(t===h)break;o.push(t)}if(o.length!==0){h=e[0];for(let t=o.length-1;t>=0;t--){const s=_(o[t]);s&&w(s)}}}),{subscribe:y,dismiss:g,clear:N,pauseDwell:C,resumeDwell:D,push:w}}const $=F();function O(){[{type:"DreamCompleted",title:"Dream consolidated",body:"Replayed 127 memories · 43 new connections · 5 insights in 2.4s",color:u.DreamCompleted,dwellMs:7e3},{type:"ConnectionDiscovered",title:"Bridge discovered",body:"semantic · weight 0.87",color:u.ConnectionDiscovered,dwellMs:4500},{type:"MemorySuppressed",title:"Forgetting",body:"suppression #2 · Rac1 cascade ~8 neighbors",color:u.MemorySuppressed,dwellMs:5500},{type:"ConsolidationCompleted",title:"Consolidation swept",body:"892 nodes · 156 decayed · 48 embedded in 1.1s",color:u.ConsolidationCompleted,dwellMs:6e3}].forEach((i,m)=>{setTimeout(()=>{$.push(i)},m*800)}),T($)}export{O as f,$ as t};
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
const e={fact:"#00A8FF",concept:"#9D00FF",event:"#FFB800",person:"#00FFD1",place:"#00D4FF",note:"#8B95A5",pattern:"#FF3CAC",decision:"#FF4757"},F={MemoryCreated:"#00FFD1",MemoryUpdated:"#00A8FF",MemoryDeleted:"#FF4757",MemoryPromoted:"#00FF88",MemoryDemoted:"#FF6B35",MemorySuppressed:"#A33FFF",MemoryUnsuppressed:"#14E8C6",Rac1CascadeSwept:"#6E3FFF",SearchPerformed:"#818CF8",DeepReferenceCompleted:"#C4B5FD",DreamStarted:"#9D00FF",DreamProgress:"#B44AFF",DreamCompleted:"#C084FC",ConsolidationStarted:"#FFB800",ConsolidationCompleted:"#FF9500",RetentionDecayed:"#FF4757",ConnectionDiscovered:"#00D4FF",ActivationSpread:"#14E8C6",ImportanceScored:"#FF3CAC",Heartbeat:"#8B95A5"};export{F as E,e as N};
|
||||
const e={fact:"#00A8FF",concept:"#9D00FF",event:"#FFB800",person:"#00FFD1",place:"#00D4FF",note:"#8B95A5",pattern:"#FF3CAC",decision:"#FF4757"},F={MemoryCreated:"#00FFD1",MemoryUpdated:"#00A8FF",MemoryDeleted:"#FF4757",MemoryPromoted:"#00FF88",MemoryDemoted:"#FF6B35",MemorySuppressed:"#A33FFF",MemoryUnsuppressed:"#14E8C6",Rac1CascadeSwept:"#6E3FFF",SearchPerformed:"#818CF8",DeepReferenceCompleted:"#C4B5FD",HookVerdictRecorded:"#F59E0B",DreamStarted:"#9D00FF",DreamProgress:"#B44AFF",DreamCompleted:"#C084FC",ConsolidationStarted:"#FFB800",ConsolidationCompleted:"#FF9500",RetentionDecayed:"#FF4757",ConnectionDiscovered:"#00D4FF",ActivationSpread:"#14E8C6",ImportanceScored:"#FF3CAC",Heartbeat:"#8B95A5"};export{F as E,e as N};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/CcUbQ_Wl.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CcUbQ_Wl.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/CcUbQ_Wl.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CcUbQ_Wl.js.gz
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
apps/dashboard/build/_app/immutable/chunks/CpWkWWOo.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/CpWkWWOo.js.br
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
import{a as y}from"./BKuqSeVd.js";import{m as r}from"./CvjSAYrz.js";function a(t,e,f,i){var l=t.__style;if(r||l!==e){var s=y(e);(!r||s!==t.getAttribute("style"))&&(s==null?t.removeAttribute("style"):t.style.cssText=s),t.__style=e}return i}export{a as s};
|
||||
import{a as y}from"./BKuqSeVd.js";import{N as r}from"./CpWkWWOo.js";function a(t,e,f,i){var l=t.__style;if(r||l!==e){var s=y(e);(!r||s!==t.getAttribute("style"))&&(s==null?t.removeAttribute("style"):t.style.cssText=s),t.__style=e}return i}export{a as s};
|
||||
BIN
apps/dashboard/build/_app/immutable/chunks/Cx-f-Pzo.js.br
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/Cx-f-Pzo.js.br
Normal file
Binary file not shown.
BIN
apps/dashboard/build/_app/immutable/chunks/Cx-f-Pzo.js.gz
Normal file
BIN
apps/dashboard/build/_app/immutable/chunks/Cx-f-Pzo.js.gz
Normal file
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
import{y as S,z as h,A as k,B as A,S as B}from"./CvjSAYrz.js";function t(r,i){return r===i||(r==null?void 0:r[B])===i}function q(r={},i,a,T){return S(()=>{var f,s;return h(()=>{f=s,s=[],k(()=>{r!==a(...s)&&(i(r,...s),f&&t(a(...f),r)&&i(null,...f))})}),()=>{A(()=>{s&&t(a(...s),r)&&i(null,...s)})}}),r}export{q as b};
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue