Skip to content

feat: v0.11.0 — forget/correct facts (tombstones) + onboarding & banner polish#15

Merged
rumitvn merged 2 commits into
mainfrom
feat/forget-facts-onboarding-banner
Jun 7, 2026
Merged

feat: v0.11.0 — forget/correct facts (tombstones) + onboarding & banner polish#15
rumitvn merged 2 commits into
mainfrom
feat/forget-facts-onboarding-banner

Conversation

@rumitvn

@rumitvn rumitvn commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Why

Memory was append-only — a graduated/pinned fact could never be removed or corrected, even after a leader's PR feedback or a bug found in QC. Worse, once a fact was shared it lived in .tre-mem/ (append-only, content-hash-deduped, git-committed, auto-imported), so deleting the local row left every teammate's clone holding the stale fact forever. v0.11 makes removal propagate through git, and adds a smoother first run + a banner that shows once, below claude-mem.

A — Forget / correct facts (tombstone propagation)

  • Tombstone sync record (kind:'tombstone') — carries the removed fact's content_hash. Stays at SYNC_SCHEMA_VERSION = 1: pre-v0.11 clients hit the existing unknown-kind catch and skip it (the fact just lingers for them until they upgrade). No schema bump.
  • Store deletes (repo.ts) — by id / observation / content_hash, for pins and graduated.
  • Two-pass tombstone-aware import — gather tombstoned hashes first, then insert non-tombstoned facts + delete targets. Order-independent within a file, idempotent across re-imports; a removal can never be resurrected by an earlier line. readLiveSyncRecords applies tombstones so the web layer never surfaces a forgotten fact.
  • forget.ts — writes the tombstone at call time (before deleting the row — once gone, export_memory has nothing to emit), then deletes locally. Unshared facts → local-only delete, no tombstone (idempotent append).
  • MCP tools unpin_fact / ungraduate_fact (7 → 9) + CLI tre unpin / tre ungraduate. Correcting a fact = ungraduate the old one + graduate_fact the fixed observation.

B — Onboarding & tre status

  • tre init [--all] [--verbose] — guided first run; --all wires every installed tool + backfills in one step.
  • tre status — regrouped into Identity / Memory / Tools / claude-mem with a full / shared-only headline.

C — SessionStart banner (dedup + below claude-mem)

  • Root cause of duplicate banners: the hook was registered in two settings files (project .claude/settings.json and global ~/.claude/settings.json). tre doctor flags it by exact path; tre doctor --fix-hooks collapses it to one (keeps the global copy by default).
  • Banner defers via TRE_MEM_HOOK_DELAY_MS (default 250 ms when claude-mem is present on Claude Code) so it renders below claude-mem instead of racing it.

Compatibility

On-disk format + SYNC_SCHEMA_VERSION unchanged (tombstone is a new kind, not a new schema). Old clients skip tombstones; new clients honor them. No claude-mem schema changes.

Test plan

  • Pre-push gate: format:check, lint, typecheck, 394 tests, build — all green.
  • Unit: tombstone format round-trip + back-compat skip; store deletes; two-pass import (pin & graduated, same-file + re-import idempotency); forget shared-vs-unshared; MCP validation/dispatch; cross-file duplicate-hook detection.
  • Live cross-clone: Dev B imports a graduated fact (1 row) → tombstone appended → re-import drops it (0 rows).
  • Live MCP tools/list returns all 9 tools including unpin_fact / ungraduate_fact.
  • tre init guided output, sectioned tre status, tre doctor flags the real duplicate on this machine.

Docs

Version → 0.11.0 (package.json + src/version.ts), CHANGELOG, docs/plan/PLAN-PHASE8.md, PLAN/CLAUDE phase chains, tool-count 7 → 9 across README/README.vi/CROSS-TOOL/DEMO, SYNC-FORMAT tombstone spec.

v-rumnv added 2 commits June 7, 2026 14:25
…g & banner polish

Memory was append-only — a graduated/pinned fact could never be removed,
even after PR feedback or QC proved it wrong, and a shared fact lived in
.tre-mem/ on every teammate's clone forever. v0.11 adds removal that
propagates through git, plus a smoother first run and a clean banner.

Forget / correct facts (tombstone propagation):
- New `tombstone` sync record (kind, no schema bump — pre-v0.11 clients
  skip it gracefully). Carries the removed fact's content_hash.
- Store deletes (repo.ts): delete pins/graduated by id / observation /
  content_hash.
- Two-pass tombstone-aware import: collect tombstoned hashes first, then
  insert non-tombstoned + delete targets. Order-independent, idempotent —
  a removal can never be resurrected by an earlier line.
- forget.ts: forgetPin / forgetGraduated write the tombstone at call time
  (before deleting the row), then delete locally. Unshared facts → local
  delete, no tombstone. readLiveSyncRecords applies tombstones for the web.
- MCP tools unpin_fact / ungraduate_fact (7 → 9); CLI tre unpin / tre
  ungraduate. Correcting a fact = ungraduate old + graduate fixed.

Onboarding & status:
- tre init [--all] [--verbose] — guided first run, wires tools + backfills.
- tre status — Identity / Memory / Tools / claude-mem sections, mode headline.

SessionStart banner:
- Cause of duplicate banners: hook registered in both project and global
  settings. tre doctor flags it by path; tre doctor --fix-hooks collapses it.
- Banner defers (TRE_MEM_HOOK_DELAY_MS, default 250ms when claude-mem
  present) so it renders below claude-mem.

Docs: version → 0.11.0 (package.json + src/version.ts), CHANGELOG,
PLAN-PHASE8.md, PLAN/CLAUDE chains, tool count 7 → 9, SYNC-FORMAT tombstone
spec. 394 tests green; live cross-clone tombstone (1 → 0) + MCP tools/list
(9 tools) verified.
…ude-code wiring

Two follow-ups after live testing the v0.11 banner fix:

- The real duplicate-banner cause is a stale GLOBAL hook (an absolute
  `…/dist/cli.js hook session-start` in ~/.claude/settings.json that fires
  this repo's build in every project), alongside the committed, portable
  project hook. So `tre doctor --fix-hooks` now keeps the **project** copy by
  default (it's the canonical, team-shared wiring `tre setup` writes) and
  strips the others. Added `--keep <project|global>` to override.
- `tre status` showed `claude-code·` (not wired) because detection looked for
  the literal "tre-mem", but the hook command is `tre hook session-start`.
  detectTools now recognizes the session-start hook → `claude-code✓`.

396 tests green.
@rumitvn rumitvn merged commit 2d5de50 into main Jun 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants