Skip to content

feat(session): add anti-drift session notes#7

Open
vicary wants to merge 8 commits into
mainfrom
feat/session-notes-anti-drift
Open

feat(session): add anti-drift session notes#7
vicary wants to merge 8 commits into
mainfrom
feat/session-notes-anti-drift

Conversation

@vicary
Copy link
Copy Markdown
Owner

@vicary vicary commented Apr 11, 2026

Summary

  • Redesign memory around a search-first architecture where session_search() is the canonical recall API and injected XML is only a bounded hint surface.
  • Add durable session notes without TTL, freshness-aware note ranking, timestamped note hits, and same-project delete-by-id cleanup.
  • Introduce normalized memory result contracts, dream summary storage/job scaffolding, detached shutdown proof coverage, and updated smoke-test documentation for the new model.

Design

Authority Model

  • opencode db / SQLite is the exact chronological source of truth for user turns, assistant turns, and tool calls.
  • Redis/FalkorDB stores derived local artifacts and operational state, not duplicate exact transcript authority.
  • Graphiti remains asynchronous enrichment and a one-off hint source; it is not on the hot path and is not the authoritative memory reader.

Canonical Recall Path

  • session_search() becomes the default memory read API.
  • Query mode accepts query plus optional when, searches normalized exact/history, notes, and summaries, and returns exact-style results before summaries.
  • Reflection mode is represented by an empty query and returns chronological summaries around when.
  • Results use a shared normalized model with type: "entry" | "note" | "summary", ref, snippet, score, created_at, and optional metadata.

Injection Contract

  • Injected continuity now uses one top-level <memory version="2"> wrapper.
  • <persistent_memory> is nested inside <memory> instead of being a separate top-level block.
  • Exact entries are never injected; exact recall must go through session_search().
  • Compaction/startup continuity may include bounded summaries and up to 10 current-session notes, but not raw exact entries.
  • Legacy <session_memory> expectations were updated in tests to the normalized <memory> envelope.

Durable Session Notes

  • Session-local note hashes no longer receive TTLs, and reads no longer refresh note TTL.
  • Project note metadata now records last_read_at on successful session_notes_read(id) calls.
  • session_search note hits expose created_at and updated_at, but not last_read_at.
  • Note ranking now uses relevance multiplied by write freshness and bounded read freshness.
  • Same-project sessions may delete obsolete notes by id, while non-empty replacement remains ownership-conservative.

Dream Summary Layer

  • Adds local dream summary/job scaffolding for durable summary artifacts.
  • Dream summaries are intended as lossy chronological hints for reflection and injection, not exact transcript truth.
  • Shutdown handoff now has proof-only detached worker coverage plus explicit warning fallback behavior when detached work cannot be started safely.

Graphiti Role

  • Graphiti remains optional and asynchronous.
  • Graphiti-derived material is treated as hint-only summary material.
  • If a Graphiti hint matters, agents should reconnect to exact evidence through session_search().

Retention Model

  • Durable memory artifacts such as notes and summaries do not expire by TTL.
  • Operational state remains bounded separately.
  • Staleness is handled by ranking and relevance rather than deleting useful memory by age.

Implementation Notes

  • Added normalized memory result types and memory-search orchestration.
  • Updated session_search schemas and runtime wiring for normalized ref / refs responses and optional when.
  • Updated note storage, note search, note read metadata, note delete semantics, and entrypoint wiring.
  • Updated message/compaction scrubbing and assertions for the <memory version="2"> wrapper.
  • Added dream store, dream runner, dream job, detached-worker proof, and shutdown warning coverage.
  • Updated smoke tests and design/implementation docs for the search-first unified memory direction.

Test Plan

  • deno test -A
  • deno task check
  • deno task lint
  • deno task fmt --check

Latest full-suite verification before commit: 66 passed (692 steps), 0 failed.

@vicary vicary force-pushed the feat/session-notes-anti-drift branch from ff69c1e to cfac4be Compare May 10, 2026 12:53
Copilot AI review requested due to automatic review settings May 21, 2026 21:21
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR advances the “search-first unified memory” architecture by introducing normalized memory result contracts, durable session notes (no TTL) with freshness-aware ranking, and a new <memory version="2"> injection envelope that avoids injecting exact <entry> records. It also adds dream summary storage/job scaffolding and extends shutdown/teardown coverage to prove graceful waiting behavior.

Changes:

  • Introduces normalized memory result models and a unified session_search() orchestration path that can merge entries/notes/summaries.
  • Adds durable session notes (no TTL), note read metadata (last_read_at), freshness-based ranking, and MCP note read/write tools.
  • Updates continuity injection to <memory version="2"> (nested <persistent_memory> and optional compaction-only <session_notes>), plus adds shutdown warning/proof scaffolding.

Reviewed changes

Copilot reviewed 47 out of 48 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/types/index.ts Adds NormalizedMemoryResult contract for unified memory search/injection.
src/testing/detached-dream-proof.ts Adds proof-only plugin to validate graceful shutdown waiting behavior.
src/testing/detached-dream-proof.test.ts Tests detached dream proof plugin behavior/artifact writing.
src/session.ts Updates injection envelope to <memory version="2">, strips <entry> blocks, adds compaction-only note injection.
src/session.test.ts Adds tests for compaction notes injection and v2 envelope invariants.
src/services/session-snapshot.test.ts Updates expectations to <memory version="2">.
src/services/session-notes.ts Introduces durable session notes service with freshness-aware search and same-project delete-by-id semantics.
src/services/session-mcp-types.ts Extends MCP schemas: normalized search results (ref/refs) and note tool request/response types.
src/services/session-mcp-runtime.ts Wires session_search through unified memory search, adds note tools + descriptions, increases response budget.
src/services/runtime-teardown.ts Adds createRuntimeTeardownTask helper and refines Deno vs Node signal listener wiring.
src/services/runtime-teardown.test.ts Adds “live runtime” shutdown-wait proofs for SIGINT and beforeExit flows.
src/services/redis-snapshot.ts Adds helper to emit snapshot summaries as NormalizedMemoryResult.
src/services/redis-client.test.ts Makes waitFor async-friendly to reduce flakiness.
src/services/opencode-warning.ts Adds notifyDreamShutdownDelay() warning helper.
src/services/memory-search.ts Adds unified memory search service (entries + notes + summaries) with query vs reflection mode behavior.
src/services/memory-search.test.ts Tests ordering and query/reflection mode behavior for unified memory search.
src/services/memory-results.ts Adds ordering utilities for normalized memory results.
src/services/hot-tier-slice.test.ts Updates continuity assertions for <memory version="2"> envelope.
src/services/exact-history.ts Adds adapter interface/scaffold for exact-history searching.
src/services/dream-store.ts Adds Redis-backed dream summary storage + retrieval around a reference time.
src/services/dream-runner.ts Adds dream runner that buckets inputs and advances watermark.
src/services/dream-runner.test.ts Tests dream store + runner watermark/summary behavior.
src/services/dream-jobs.ts Adds pending dream job storage/preparation.
src/services/dream-jobs.test.ts Tests dream job write/read/clear and prepare semantics.
src/services/detached-dream-worker.ts Adds detached worker spawn scaffold (currently returns false).
src/index.ts Wires notes service into runtime/session manager; adds session_search biasing and dream shutdown warning teardown task.
src/index.test.ts Extends entrypoint tests for notes service wiring, biasing, dream shutdown warning behavior, and tool arg exposure.
src/handlers/tool-before.ts Uses deny guidance as the thrown error message when present.
src/handlers/tool-before.test.ts Updates tests to assert new thrown-denial guidance behavior.
src/handlers/messages.ts Updates scrubbing logic for the new <memory> envelope and logging text.
src/handlers/messages.test.ts Updates tests for <memory version="2"> injection and scrubbing behavior.
src/handlers/compacting.ts Passes { forCompaction: true } to inject compaction-only session notes and updates log messages.
src/handlers/compacting.test.ts Updates compaction tests for v2 envelope and compaction options.
src/handlers/chat.ts Updates log messages to “memory” naming.
src/handlers/chat.test.ts Updates chat handler tests for new prepareInjection signature.
opencode.json Removes local dev plugin config from repo root.
docs/superpowers/specs/2026-05-10-session-notes-freshness-without-ttl-design.md Adds design doc for durable notes and freshness ranking.
docs/superpowers/specs/2026-04-21-search-first-unified-memory-design.md Adds design doc for search-first unified memory architecture.
docs/superpowers/specs/2026-04-11-session-notes-anti-drift-design.md Adds spec doc for cross-session notes recall model.
docs/superpowers/plans/2026-05-10-session-notes-freshness-without-ttl.md Adds implementation plan for durable notes + freshness ranking.
docs/superpowers/plans/2026-03-20-context-mode-mcp-first-implementation.md Updates bounded-response budget documentation to 32 KB.
docs/SmokeTests.md Updates smoke-test coverage and procedures for notes/tools and dream shutdown proof.
deno.lock Adds @std/async dependency lock entry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +243 to +245
session_notes_read: {
id: pluginSchema.string().min(1).optional(),
},
Comment on lines +153 to +157
"- To check whether pinned session notes already contain the context you need.",
"",
'Results may include indexed memory content (type: "memory") and, when pinned',
'session notes exist, matching notes (type: "note"). Note results include',
'`id`, `root_session_id`, `scope: "local" | "project"`, `created_at`, and',

- `session:{rootSessionId}:notes` stores current-session note bodies and is used
for compaction note injection
- `project:{groupId}:notes` stores same-project notes for cross-session search
- `created_at`
- `updated_at`

2. `project:{groupId}:notes`
Comment thread docs/SmokeTests.md
Comment on lines 844 to +857
- pre-compaction delegated work appears in the compaction-preserved memory
envelope;
- the compaction-time `<session_memory>` evidence includes a
`<session_notes source="note_tools">` section with the complete pinned note
body as input material;
- the root resumes correctly after compaction without the operator replaying
the history;
- the resumed children continue from the preserved state rather than starting
a fresh branch.
a fresh branch, and the reopened note text still matches the pinned
pre-compaction note.
- **Evidence to collect:** pre-compaction prompt/evidence; compaction occurrence
note or log; post-compaction root answer; post-compaction child tool results;
post-compaction `<session_memory>` envelope.
note or log; `session_notes_write` and `session_notes_read` responses;
post-compaction root answer; post-compaction child tool results; post-
compaction `<session_memory>` envelope.
Comment thread docs/SmokeTests.md
Comment on lines 490 to 513
### 5.9 Suite I — Continuity assembly and compaction survival

- **Objective:** Prove that `session_*` activity folds into local continuity,
`<session_memory>` assembly stays deterministic, and continuity survives
compaction.
- **Prerequisites:** Same as Suite A.
- **Exact commands:**

```bash
deno test src/handlers/chat.test.ts src/handlers/messages.test.ts src/handlers/compacting.test.ts src/handlers/event.test.ts src/services/session-snapshot.test.ts src/services/hot-tier-slice.test.ts
deno test src/session.test.ts src/handlers/chat.test.ts src/handlers/messages.test.ts src/handlers/compacting.test.ts src/handlers/event.test.ts src/services/session-snapshot.test.ts src/services/hot-tier-slice.test.ts
deno task check
```

- **Expected result:** PASS. Local continuity sections and snapshots are
assembled from hot-tier state, optional cached `<persistent_memory>` is
additive only, stale envelopes are scrubbed, and compaction preserves
continuity for both direct and delegated work.
additive only, stale envelopes are scrubbed, normal chat-turn injection omits
`<session_notes>`, compaction-only injection includes complete pinned note
bodies inside `<session_notes source="note_tools">` from the current root
session only (same-project foreign-session note bodies are excluded), and
compaction preserves continuity for both direct and delegated work.
- **Artifacts/evidence to save:** Full test output; representative emitted
`<session_memory>` blocks; compaction-hook assertions; snapshot-related
assertions.
`<session_memory>` blocks with and without `<session_notes>` as applicable;
compaction-hook assertions; snapshot-related assertions.
- **Common failure signatures:** Missing or duplicated `<session_memory>`
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