Skip to content

chore: release v0.0.2#51

Closed
ScriptedAlchemy wants to merge 1 commit into
masterfrom
release-plz-2026-06-18T23-40-24Z
Closed

chore: release v0.0.2#51
ScriptedAlchemy wants to merge 1 commit into
masterfrom
release-plz-2026-06-18T23-40-24Z

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

🤖 New release

  • tracedecay: 0.0.1 -> 0.0.2
Changelog

[0.0.2] - 2026-06-18

Changed

  • Project renamed: TokenSave → TraceDecay. The crate, binary, CLI command, and MCP server are now tracedecay, and the MCP tools are prefixed tracedecay_*. The data directory is now .tracedecay/ (an existing .tokensave/ directory is still honored as a fallback), and environment variables use the TRACEDECAY_* prefix (legacy TOKENSAVE_* variables are still honored as a fallback). All entries below predate the rename and intentionally retain the historical tokensave/TokenSave names.
  • Version reset for the rebranded crate. tracedecay now restarts at 0.0.2 as a fresh crate line; 0.0.1 is already occupied on crates.io by the name-reservation placeholder, so 0.0.2 is the first publishable release number.

Added

  • Local web dashboard (tokensave dashboard + tokensave_dashboard MCP tool). A self-contained axum server with compile-time-embedded UI assets serving three tabs: Holographic Memory (fact/entity/bank inspector, 2D PCA semantic map, association graph, phase-cosine similarity explorer with brushable histogram, and feature-flagged curation), LCM (overview, FTS search with role/source/session facets, session/node drilldowns, timeline, compression analytics over the global DB), and Code Graph (overview analytics plus a force-directed canvas explorer with search-to-focus, progressive neighbor expansion, callers/callees, filters, and shortest-path mode). CLI flags: --path, --host, --port (0 = auto, parseable URL on stdout), --open. The tokensave_dashboard MCP tool starts/stops the same server as a background task and returns the URL. GET /api/capabilities advertises feature flags (memory, lcm, graph, curation, llm_curation) for host/UI feature detection. Dark + light themes, responsive down to ~420px.

  • Memory curation with hard-delete semantics. POST /api/plugins/holographic/curate proposes (dry-run) or applies similarity-based deduplication: the lower-trust fact of each likely_duplicate pair is permanently deleted via the canonical store path (FK-cascaded entity links, FTS trigger cleanup, bank dirty-marking) — no archive state, no restore. POST /curate/apply exposes a generic delete/merge ops contract for external (e.g. LLM-backed) planners; per-op failures are reported per-op. Migration v13 only cleans up a never-shipped archive-column experiment from local dev databases.

  • Hermes wrapper for the dashboard. dashboard/hermes-wrapper/ (canonical; deployed to the hermes-agent working tree) reverse-proxies /holographic/*, /lcm/*, and /graph/* to a spawned or externally configured tokensave dashboard, re-hosts the same UI bundles under the combined "TokenSave" tab, layers an optional LLM curation planner on the /curate/apply contract, and hardens the subprocess lifecycle (stderr drain, parent-death signal, spawn-failure backoff).

  • Dashboard build + test infrastructure. dashboard/ npm workspace (esbuild) building all bundles, 16 frontend unit tests (node run-unit-tests.mjs), Playwright smoke (npm run smoke -- --expect-lcm=empty|non-empty), Rust integration suites (tests/dashboard_api_test.rs, dashboard_lcm_fixes_test.rs, dashboard_graph_api_test.rs, mcp_dashboard_tool_test.rs), a dashboard CI job, and build.rs rerun-if-changed guards so frontend dist changes force re-embedding.

  • Curation previews survive dashboard restarts. The last dry-run curation plan is mirrored to a .tokensave/dashboard/curation_preview.json sidecar and re-hydrated when the server starts; applying curation (or any /curate/apply mutation) clears both the in-memory copy and the sidecar. The GET /curation/preview API shape is unchanged, and staleness is still recomputed against the live fact count on every read.

  • tokensave install --agent hermes deploys the dashboard plugin page. The Hermes wrapper (manifest, plugin_api.py reverse proxy, and the UI bundles — all embedded in the binary, no source checkout needed) is now written to <hermes_home>/plugins/tokensave/dashboard/ as part of the default install, where Hermes' dashboard-plugin discovery (stock and forked) picks it up as a "TokenSave" tab with Memory / LCM / Code Graph / Savings sub-tabs. The deployed proxy bakes in the installing binary path and the profile's pinned project_root as spawn-mode defaults (TOKENSAVE_BIN / TOKENSAVE_DASHBOARD_PROJECT env vars still win); reinstalls preserve the pin, --no-dashboard opts out (and removes a previous deploy), and uninstall cleans the page up. The wrapper also gained the Savings sub-tab (/savings/* proxy to /api/plugins/savings/*). On Hermes versions without dashboard-plugin discovery the deployed directory is inert.

  • Dashboard assets build themselves on fresh checkouts. When the embedded dashboard/*/dist bundles are missing, build.rs now runs the frontend build automatically (npm ci, falling back to npm install, then npm run build) with progress reported as build warnings — so cargo build / cargo install --path . work from a clean clone. If npm is unavailable, the build still fails fast with actionable instructions. Cargo.toml switched to an explicit package.include whitelist that ships the prebuilt dist bundles inside the crate package, making cargo package/cargo publish verifiable and letting crates.io/docs.rs builds proceed with no Node.js toolchain. The release workflows (release.yml build + publish-crate jobs, release-beta.yml) gained the same dashboard prebuild step as CI.

  • Tokenizer-backed cost tier for the Savings & Cost tab (token-counting feature, on by default). When transcripts carry no usage counters (all Cursor stores — verified to contain none — plus cline/vibe and any Codex/Claude rows without usage), stored message text is now counted with a real BPE tokenizer (tiktoken-rs, o200k_base/cl100k_base) instead of the chars/4 heuristic: exact for OpenAI-family models, a labeled approximation for vendors without a public tokenizer (Claude/Gemini). The API gains a third cost_basis value "tokenized" (between "actual" and "estimated"; "mixed" semantics unchanged), additive tokenized token blocks, tokenized_messages counts, and per-model tokenizer provenance ({"encoder", "exact"}); the UI shows tier badges and an updated methodology note. Counts are cached per message (in-process map + a dashboard_token_counts sidecar table in the global accounting DB, keyed by message identity with a text-length guard) and pre-warmed in the background at dashboard startup, so 15k+-message stores pay the BPE pass once instead of per request. Disable the feature for a leaner binary (~4 MB embedded vocabularies, lazily decoded) — everything degrades to the chars/4 tier.

Fixed

  • The savings ledger records by default again — the Savings tab is no longer empty while lifetime counters grow. The holographic-fact-store commit made the MCP server's global accounting DB opt-in via TOKENSAVE_ENABLE_GLOBAL_DB, which silently disabled savings_ledger writes (and worldwide-counter flushes) for every default install: tool calls still printed tokensave_metrics lines and CLI paths kept growing projects.tokens_saved, but the dashboard showed "ledger calls: 0 / no events yet". Global accounting is now on by default; opt out with TOKENSAVE_DISABLE_GLOBAL_DB=1 (set automatically for cargo-launched processes via .cargo/config.toml so test runs stay hermetic) or TOKENSAVE_ENABLE_GLOBAL_DB=0, with an explicit TOKENSAVE_ENABLE_GLOBAL_DB=1 always winning. The dashboard now also surfaces the gate verdict (savings.recording in the overview API, a recording: on/off badge, and an honest explanation when the ledger is empty — including the "restart your MCP server to pick this up" case) instead of an unconditional "no events yet". Covered by a default-on ledger regression test plus env-precedence unit tests; long-running MCP servers must be restarted/reloaded to pick up the fix.
  • Hermes wrapper spawn mode no longer drops its child server after idle periods. The wrapper's Linux parent-death guard (PR_SET_PDEATHSIG) fires when the thread that forked the child exits — and FastAPI sync endpoints run on anyio threadpool workers that are reaped after ~10s idle, so the spawned tokensave dashboard was SIGTERMed shortly after quiet spells (surfacing as intermittent 502 "connection reset by peer" on the next tab click). plugin_api.py now spawns from a single long-lived worker thread, binding the child's lifetime to the Hermes host process as intended.
  • Hermes wrapper cold starts no longer 502. After spawning, the wrapper now waits (bounded, 30s) for the engine's /api/capabilities to answer before proxying the first request, returns a clear 503 with Retry-After if the engine truly fails to come up, and transparently retries GET proxies once after re-resolving the upstream (which reaps and respawns a dead child). POSTs are never retried so curation applies cannot run twice.
  • Fallback branch DBs are now read-only for sync/index writes. tokensave sync, lazy single-file syncs, and full indexing now refuse to write when the active git branch is being served from an ancestor branch database, preventing branch-only files from being indexed into the fallback DB.
  • tokensave install --agent hermes generates a plugin that loads on newer Hermes hosts. Four generator/installer fixes: (1) the generated TokenSaveContextEngine implements the now-abstract update_from_response(usage) method (normalizes prompt/input, completion/output, and total token counts into last_*_tokens attributes), so plugin load no longer dies with Can't instantiate abstract class; (2) the skill registers under the bare name tokensave — newer Hermes derives the namespace from the plugin and rejects : in skill names; (3) the installer now matches the existing indentation of plugins.enabled/plugins.disabled lists (Hermes writes 2-space items) instead of always inserting 4-space items, which produced unparseable mixed-indent YAML; and (4) flow-style empty lists (disabled: [], which Hermes itself writes) are accepted instead of failing with "unsupported Hermes plugins config" — an empty enabled: [] is rewritten to a block list. The generated context engine additionally honors a project_root config key so profiles can pin the indexed project (explicit host kwargs win; the session cwd stays the last fallback).
  • tokensave install --agent hermes --project-root <abs path> pins a profile's plugin to one project. The pin is written into the generated plugin (PINNED_PROJECT_ROOT in tools.py): every plugin tool call then passes --project <pin> so memory + LCM stores resolve to <pin>/.tokensave/ regardless of the Hermes process cwd, and the context engine uses it ahead of cwd inference (kwargs > config > pin > cwd). Reinstalls without the flag preserve an existing pin; the flag is hermes-only, requires an absolute path, and conflicts with --all-profiles (pins are per-profile).
  • tokensave tool now walks up from subdirectories to the nearest initialised project when --project is not given, matching how sync, status, serve, and dashboard resolve project roots.
  • Cursor hook hints use the quote-aware shell parser. tool_hints classified search commands with a naive split_whitespace, so a quoted pattern like grep "needle -r" file leaked a fake -r flag and misclassified as a recursive search. It now shares hooks.rs's quote/escape-aware shell_words parser (single shared implementation, regression-tested).
  • Hermes generated plugin files are written atomically. write_text_file now uses the write-to-.new-then-rename pattern (like the config writer), so a mid-write crash can no longer leave a truncated __init__.py/tools.py behind. Unsupported-config errors during install also name the exact retry command (tokensave install --agent hermes).
  • v13 archive-column cleanup handles generated-column dev databases. The migration enumerated columns with PRAGMA table_info, which hides GENERATED columns — so a dev DB where the abandoned archive revision left superseded_by as a generated column referencing merged_into skipped that drop and then failed with no such column: merged_into. The migration now uses PRAGMA table_xinfo and drops the columns in reverse-addition order (dependent generated columns first). Covered by a regression test seeding exactly that odd state.
  • Archive-semantics purge (policy: deleted memories are permanently hard-deleted). Removed the last UI remnants of the never-shipped archive feature: the CurationPanel no longer recognizes/renders archive or supersede ops (neither planner can produce them; the curate ops contract is delete/merge only), the archive action field is gone from the frontend types, and stale Hermes-wrapper docstrings naming archive/archive/{fact_id}/restore routes were corrected. A new store-level test pins the full hard-delete cascade: MemoryStore::remove_fact removes the fact row, its FTS mirror row, its entity links, and its feedback events, and marks the fact's banks dirty.


This PR was generated with release-plz.

@changeset-bot

changeset-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f978cf4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f978cf46b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -1,1748 +0,0 @@
# TokenSave LCM Session Rewrite Implementation Plan

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore the historical superpowers plans/specs

This release-only commit deletes the historical superpowers plan/spec artifacts, including the approved LCM session rewrite plan, but the repo's rebrand policy explicitly says old plans/specs should be preserved as history unless factually wrong (docs/REBRAND-COMPATIBILITY-POLICY.md:63-68, docs/REBRAND-COMPATIBILITY-POLICY.md:291-292). Since the deleted files already carry rebrand notes and are referenced by the compatibility audit as high-archival-value history, removing them erases intended design context rather than fixing stale product docs.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant