Skip to content

chore(docs): add session store research corpus and cross-product synthesis - #499

Merged
yordis merged 1 commit into
mainfrom
yordis/event-sourced-session-store
Jul 23, 2026
Merged

chore(docs): add session store research corpus and cross-product synthesis#499
yordis merged 1 commit into
mainfrom
yordis/event-sourced-session-store

Conversation

@yordis

@yordis yordis commented Jul 23, 2026

Copy link
Copy Markdown
Member
  • Grounds the upcoming event-sourced Session Store design in industry prior art, so persistence, resume, rewind, fork, and retention decisions are evidence-based rather than invented.
  • Follows the same method as the agent-platform corpus so both research bodies stay comparable and auditable as frozen decision-time input.

…hesis

Grounds the event-sourced Session Store design in industry prior art so persistence and resume decisions are evidence-based.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Copilot AI review requested due to automatic review settings July 23, 2026 18:50
@cursor

cursor Bot commented Jul 23, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Documentation-only addition under docs/research/; no production code, config, or data paths are modified.

Overview
Introduces docs/research/session-store/ as decision-time input for the platform’s event-sourced Session Store, mirroring the agent-platform research method.

RESEARCH_PROMPT.md defines a reusable, evidence-first questionnaire (storage model, keying, store interface, append/resume, listing/search, compaction, rewind/fork, subagents, retention, foreign interop) and the per-product output skeleton.

index.md indexes the corpus, links nine product dossiers (Claude Agent SDK/Code, Codex, Gemini CLI, Goose, Grok Build, Hermes, LangGraph, OpenCode, T3 Code), and points to synthesis.md for cross-product analysis on the append-log vs mutable-record spectrum. Status is documented as synthesis complete with the ADR not yet written.

The dossiers are large, source-anchored writeups (docs/API and/or pinned repo commits) that reconstruct each product’s durable session contract and end with “what this implies for our Session Store” plus open questions—no runtime or application code changes.

Reviewed by Cursor Bugbot for commit f190bac. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds a reproducible Session Store research corpus with a shared prompt, nine product dossiers, an index, and a synthesis describing common patterns, differences, and proposed event-sourced design requirements.

Changes

Session Store Research Corpus

Layer / File(s) Summary
Research method and corpus index
docs/research/session-store/RESEARCH_PROMPT.md, docs/research/session-store/index.md
Defines the research questions, evidence standards, dossier output structure, corpus status, product links, and synthesis navigation.
Filesystem and append-log product dossiers
docs/research/session-store/products/claude-agent-sdk.md, docs/research/session-store/products/codex-cli.md, docs/research/session-store/products/gemini-cli.md, docs/research/session-store/products/grok-build.md
Documents filesystem-backed session logs, projections, replay, append semantics, compaction, rewind, forks, nested sessions, retention, and interop boundaries.
Relational session-store dossiers
docs/research/session-store/products/goose.md, docs/research/session-store/products/hermes-agent.md
Documents SQLite session models, transactional writes, reconstruction, search, history mutation, lineage, retention, and import/export behavior.
Event and checkpoint-store dossiers
docs/research/session-store/products/langgraph.md, docs/research/session-store/products/opencode.md, docs/research/session-store/products/t3code.md
Documents checkpoint and event-sourced designs, projections, ordering, concurrency, replay, nested execution, retention, and provider integration.
Cross-product synthesis
docs/research/session-store/synthesis.md
Compares durable representations, identity, ordering, compaction, rewind, forks, retention, concurrency, and schema handling, then states target Session Store requirements.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Suggested reviewers: copilot

Poem

I’m a rabbit with notes in a burrow so neat,
Logs hop beside rows in a research retreat.
Checkpoints remember each turn and each trail,
While projections and summaries flutter their tail.
The Session Store map now is ready to grow—
With carrots of evidence lined in a row.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the PR’s main change: adding a session store research corpus and synthesis docs.
Description check ✅ Passed The description directly describes the research corpus and synthesis goals in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yordis/event-sourced-session-store

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI 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.

Pull request overview

Adds a new “Session Store Research” documentation corpus intended to ground an upcoming event-sourced Session Store design in audited, cross-product prior art, with a synthesis that extracts convergence/divergence axes and design implications (with ADRs remaining authoritative where they conflict).

Changes:

  • Adds a reusable research prompt and a new index for the session-store study corpus.
  • Adds a cross-product synthesis capturing common patterns (append-only logs + projections) and key divergence axes (identity, compaction artifacts, retention, multi-host).
  • Adds multiple product dossiers (e.g., T3 Code, LangGraph, Hermes, Grok Build, Goose, etc.) documenting each product’s on-disk/session model.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/research/session-store/index.md Introduces the corpus landing page and links to dossiers + synthesis.
docs/research/session-store/RESEARCH_PROMPT.md Defines the repeatable methodology and per-product output skeleton.
docs/research/session-store/synthesis.md Cross-product analysis and working definition for “stored session” in the corpus.
docs/research/session-store/products/t3code.md T3 Code dossier describing its event-log + projection architecture (CQRS/event-sourced).
docs/research/session-store/products/langgraph.md LangGraph dossier describing checkpoint-chain persistence and saver interface.
docs/research/session-store/products/hermes-agent.md Hermes dossier describing mutable SQLite session/message model + operational behaviors.
docs/research/session-store/products/grok-build.md Grok Build dossier describing filesystem event-log + derived caches/indexes.
docs/research/session-store/products/goose.md Goose dossier describing mutable SQLite store + compaction/rewind/fork behaviors.
docs/research/session-store/products/gemini-cli.md Gemini CLI dossier describing JSONL replay-reducer storage model + markers.
docs/research/session-store/products/codex-cli.md Codex CLI dossier describing authoritative JSONL log + derived SQLite projection.
docs/research/session-store/products/claude-agent-sdk.md Claude Agent SDK/Claude Code dossier describing local JSONL source-of-truth + mirror store contract.

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

Comment on lines +36 to +39
The event row is the source of truth
(`apps/server/src/persistence/Migrations/001_OrchestrationEvents.ts:8-23`):

```sql
@yordis
yordis merged commit 27d43cf into main Jul 23, 2026
7 of 8 checks passed
@yordis
yordis deleted the yordis/event-sourced-session-store branch July 23, 2026 18:54

@coderabbitai coderabbitai 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.

Actionable comments posted: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/research/session-store/products/claude-agent-sdk.md`:
- Around line 480-485: Revise the session-store description around the “Both
surfaces converge” passage so only projections derivable from the mirrored
transcript are described as rebuilt from the append-only log. Remove
file-content checkpoints and liveness registry from that projection list, and
document them separately as non-mirrored file state and per-process/per-host
liveness artifacts.
- Around line 504-505: Update the delivery semantics statement in the
session-store documentation to describe delivery as best-effort rather than
at-least-once, explicitly noting possible loss and duplicates, and recommend
UUID-based deduplication at the adapter boundary instead of claiming idempotent
append guarantees.

In `@docs/research/session-store/products/goose.md`:
- Around line 482-488: Remove the claim that transactional compaction and fork
rewrites can leave a torn transcript. Update the discussion around
replace_conversation and the downstream synthesis to describe supported risks
instead, such as rollback cost, contention, or incomplete fork creation when
work spans transactions, while preserving the valid O(history) copy and
rewind-history observations.
- Around line 277-287: Update the scalability sentence in the Enumeration
description to acknowledge that grouping the joined message history can scan and
aggregate all matching messages before keyset pagination, rather than implying
cost is limited to returned-page rows. Preserve the existing query and
pagination details, and replace only the “scales with rows matched, not total
history” claim with qualified wording about matched message-history cost.

In `@docs/research/session-store/products/hermes-agent.md`:
- Around line 177-179: Update the consistency-guarantees statement to
distinguish the Python threading.Lock as protection for access within a single
process, and identify SQLite transactions and retries as providing serialization
across processes sharing state.db. Preserve the existing single-writer,
ordering, and no-precondition guarantees.
- Around line 303-309: Update the “Store interpretation” description to call the
autoincrement id a row-identity field rather than a deduplication field.
Preserve the separate reference to the in-memory _DB_PERSISTED_MARKER for
live-agent deduplication and the later statement that Hermes lacks a durable
deduplication key.

In `@docs/research/session-store/products/langgraph.md`:
- Around line 312-319: Correct the fork description in the LangGraph
session-store documentation to remove the claim that source and target threads
share immutable, content-addressed ancestor blobs; describe copying as
preserving the complete parent chain under the new thread ID, with deduplication
limited to a single thread. Apply the same wording correction to the
corresponding fork discussion in the synthesis document.
- Around line 175-182: Update the `put` description in the LangGraph
session-store documentation to qualify “immutable snapshot”: state that fresh
checkpoint IDs make normal writes append-like, while reusing an existing
checkpoint ID allows the upsert to replace or update its contents. Preserve the
existing SQLite/Postgres upsert references and parent-checkpoint details.

In `@docs/research/session-store/products/opencode.md`:
- Around line 499-518: Qualify the multi-host safety statement in the session
synchronization discussion: distinguish the instance HTTP replay path, which
uses strictOwner: true, from the workspace sync loop’s live/reconnect replay
calls, which provide only ownerID. Do not claim that all live synchronization
paths reject owner mismatches unless verified elsewhere; narrow the conclusion
to the ownership guarantees directly supported by the cited code.

In `@docs/research/session-store/RESEARCH_PROMPT.md`:
- Around line 163-174: Make the evidence-record contract mandatory by adding a
required “## Evidence excerpts” section to the dossier output skeleton,
including fields for quote, direct URL or repository path and line, symbol or
section, version or commit, retrieval date, archive or snapshot URL, and content
digest. Update the “Method” instructions to explicitly require every captured
quote to be recorded in that section, preserving the existing auditability
requirements.

In `@docs/research/session-store/synthesis.md`:
- Around line 385-394: Clarify the fork invariant in the section beginning “Fork
always mints a new stream/session id”: distinguish copied event identity fields,
which must be rewritten to the new stream/session id, from an optional immutable
shared-prefix lineage reference, which may explicitly retain the source stream
id. Present physical-copy and shared-prefix implementations as alternatives
without implying that lineage references violate the copied-event identity rule.
- Around line 61-75: Revise the universal convergence claims in
docs/research/session-store/synthesis.md:61-75 to include LangGraph as a
non-marker model that selects an older checkpoint; update
docs/research/session-store/synthesis.md:103-117 to note Gemini’s nested child
files and path-based parent linkage alongside Claude; and change “every product”
to “most products” in docs/research/session-store/synthesis.md:119-129,
explicitly identifying Claude and Gemini as cascading-deletion exceptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f604db9-2aad-4e4c-87fe-658f50249385

📥 Commits

Reviewing files that changed from the base of the PR and between a1a24a4 and f190bac.

📒 Files selected for processing (12)
  • docs/research/session-store/RESEARCH_PROMPT.md
  • docs/research/session-store/index.md
  • docs/research/session-store/products/claude-agent-sdk.md
  • docs/research/session-store/products/codex-cli.md
  • docs/research/session-store/products/gemini-cli.md
  • docs/research/session-store/products/goose.md
  • docs/research/session-store/products/grok-build.md
  • docs/research/session-store/products/hermes-agent.md
  • docs/research/session-store/products/langgraph.md
  • docs/research/session-store/products/opencode.md
  • docs/research/session-store/products/t3code.md
  • docs/research/session-store/synthesis.md

Comment on lines +480 to +485
Both surfaces converge on the same shape: **a stored session is an append-only,
per-key log of opaque JSON entries plus derived projections (a summary/read
model, a message-chain view, a file-content checkpoint store, and a liveness
registry) rebuilt from that log.** That is within one small step of an
event-sourced Session Store, and the SDK interface is already stream-shaped:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not describe file checkpoints and liveness state as log-rebuildable projections.

The dossier states that checkpoint blobs are not mirrored (Lines 386-387) and that the liveness registry is per-process/per-host (Lines 438-439). Narrow this inference to projections actually derivable from the mirrored transcript; model file state and liveness should be documented as separate artifacts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/claude-agent-sdk.md` around lines 480 -
485, Revise the session-store description around the “Both surfaces converge”
passage so only projections derivable from the mirrored transcript are described
as rebuilt from the append-only log. Remove file-content checkpoints and
liveness registry from that projection list, and document them separately as
non-mirrored file state and per-process/per-host liveness artifacts.

Comment on lines +504 to +505
- Delivery is at-least-once with client-generated `uuid`, so our backing needs
idempotent append rather than exactly-once transport.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Change “at-least-once” to best-effort delivery.

The documented behavior allows loss: timed-out appends are not retried, and batches are dropped after retry exhaustion (Lines 249-254). Retries also permit duplicates. Describe this as best-effort delivery with duplicate risk, with UUID deduplication recommended at the adapter boundary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/claude-agent-sdk.md` around lines 504 -
505, Update the delivery semantics statement in the session-store documentation
to describe delivery as best-effort rather than at-least-once, explicitly noting
possible loss and duplicates, and recommend UUID-based deduplication at the
adapter boundary instead of claiming idempotent append guarantees.

Comment on lines +277 to +287
- **Enumeration** is a single grouped SQL query over `sessions LEFT JOIN
messages`, grouping by `s.id`, computing `message_count` and
`last_message_timestamp`, and ordering by a `sort_timestamp = COALESCE(MAX(msg
ts), updated_at)` then `id` (`list_sessions_matching`,
`session_manager.rs:1849-1950`). Pagination is **keyset**: the cursor is
`(sort_at, session_id)` and the query fetches `page_size + 1` rows to derive
`next_cursor` (`list_sessions_paged`, `1963-2005`; cursor type `318-322`).
Supporting indexes: `idx_sessions_updated`, `idx_sessions_type`,
`idx_sessions_parent`, `idx_messages_session` (`1001-1020`). No scale numbers
are quoted in-source; cost is a per-page grouped join, so it scales with rows
matched, not total history.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Qualify the listing-query scalability claim.

Because the query groups the joined sessions and messages rows before applying keyset pagination, it may scan and aggregate all matching history, not only the returned page. Replace “scales with rows matched, not total history” with wording that acknowledges the matched message-history cost.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/goose.md` around lines 277 - 287, Update
the scalability sentence in the Enumeration description to acknowledge that
grouping the joined message history can scan and aggregate all matching messages
before keyset pagination, rather than implying cost is limited to returned-page
rows. Preserve the existing query and pagination details, and replace only the
“scales with rows matched, not total history” claim with qualified wording about
matched message-history cost.

Comment on lines +482 to +488
- **Where it validates our direction**: the pain points our design avoids are
visible here. Compaction and fork both go through a `DELETE`-all +
re-`INSERT` (`replace_conversation`, `session_manager.rs:1800-1838`), so a
crash mid-rewrite risks a torn transcript, fork is O(history) copy, and rewind
destroys the pre-cutoff turns (`truncate_*`, `2344-2385`). An append-only log
with derived projections gets crash-safe rewind, cheap shared-prefix forks, and
intact history for free.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove the incorrect “torn transcript” crash claim.

The dossier states that compaction/fork rewrites risk a torn transcript, but it also documents that these multi-statement operations run inside SQLite transactions. A crash during the transaction should generally leave the pre-write or committed state, not a partially rewritten transcript. Describe the actual risks—rollback cost, contention, or incomplete fork creation if operations span transactions—and update the downstream synthesis accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/goose.md` around lines 482 - 488, Remove
the claim that transactional compaction and fork rewrites can leave a torn
transcript. Update the discussion around replace_conversation and the downstream
synthesis to describe supported risks instead, such as rollback cost,
contention, or incomplete fork creation when work spans transactions, while
preserving the valid O(history) copy and rewind-history observations.

Comment on lines +177 to +179
Consistency guarantees for all of the above: single writer connection guarded by a
Python `threading.Lock` plus SQLite `BEGIN IMMEDIATE` (`hermes_state.py:2018-2019`);
ordering by autoincrement `id`; no expected-version precondition on any operation.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Distinguish process-local locking from cross-process coordination.

threading.Lock only protects threads within one process. Since the dossier later describes multiple processes sharing state.db, state that the Python lock covers intra-process access while SQLite transactions/retries provide inter-process serialization.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/hermes-agent.md` around lines 177 - 179,
Update the consistency-guarantees statement to distinguish the Python
threading.Lock as protection for access within a single process, and identify
SQLite transactions and retries as providing serialization across processes
sharing state.db. Preserve the existing single-writer, ordering, and
no-precondition guarantees.

Comment on lines +312 to +319
- **Fork is a first-class metadata concept.** `CheckpointMetadata.source` includes
`"fork"` — "The checkpoint was created as a copy of another checkpoint"
(`:41-48`), and `parents` maps namespace → parent checkpoint id (`:56-60`). A
fork produces a new checkpoint whose `parent_checkpoint_id`/`parents` point at
the branch point, sharing the (immutable, content-addressed) ancestor blobs.
`copy_thread(source, target)` copies an entire thread's checkpoints + writes to
a new thread id, and its docstring **requires copying the complete parent
chain** so `DeltaChannel` state remains reconstructable (`:350-372`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not claim that forks share blobs across thread IDs.

The documented Postgres blob key includes thread_id (lines 60-68), while copy_thread creates a new thread ID. That supports deduplication within a thread, not shared blob rows across source and target threads. Please correct this wording here and in docs/research/session-store/synthesis.md:323-335.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/langgraph.md` around lines 312 - 319,
Correct the fork description in the LangGraph session-store documentation to
remove the claim that source and target threads share immutable,
content-addressed ancestor blobs; describe copying as preserving the complete
parent chain under the new thread ID, with deduplication limited to a single
thread. Apply the same wording correction to the corresponding fork discussion
in the synthesis document.

Comment on lines +499 to +518
- **Multi-host is a first-class path** here, unlike most of the corpus. Sessions
synchronize across hosts by **replaying events**, gated by owner:
- Each workspace runs a `syncWorkspaceLoop` that opens an SSE stream to a global
endpoint and, on each `{type:"sync", syncEvent}` message, calls
`events.replay(syncEvent, { publish: true, ownerID: space.id })`
(`packages/opencode/src/control-plane/workspace.ts:395-409`); on connect it
back-fills via a `syncHistory` fetch that `replay`s each missing event
(`workspace.ts:345-363`).
- The instance sync HTTP API exposes `replay` (accept a batch, `replayAll(...,
{ ownerID, strictOwner: true })`), `steal` (reassign a session's owning
workspace via `session.setWorkspace`), and `history` (return `event` rows the
caller is missing, computed from a per-aggregate high-water map)
(`packages/opencode/src/server/routes/instance/httpapi/handlers/sync.ts:34-85`).
- Ownership transfer uses `events.claim(sessionID, workspaceID)`
(`workspace.ts:589`). The `strictOwner` replay guard prevents two hosts from
diverging a shared aggregate (`packages/core/src/event.ts:254-261`).
The append transaction is `behavior: "immediate"` per DB, and cross-host safety
rests on **owner claims + idempotent, expected-seq replay**, not on a shared
filesystem. This is a real distributed event-sync design layered on the same
append-only log.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Qualify the multi-host safety claim for live synchronization.

The workspace sync loop calls replay with ownerID only (lines 501-506); strictOwner: true appears only on the instance HTTP replay path (lines 507-510). Therefore the cited evidence does not show that every reconnect/live-sync path rejects owner mismatches. Either verify that strict ownership is enforced elsewhere or narrow the claim in lines 515-517.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/products/opencode.md` around lines 499 - 518,
Qualify the multi-host safety statement in the session synchronization
discussion: distinguish the instance HTTP replay path, which uses strictOwner:
true, from the workspace sync loop’s live/reconnect replay calls, which provide
only ownerID. Do not claim that all live synchronization paths reject owner
mismatches unless verified elsewhere; narrow the conclusion to the ownership
guarantees directly supported by the cited code.

Comment on lines +163 to +174
## Method

1. Primary sources first: official docs, API reference, SDK source, config
schemas, on-disk layouts, official repos. Secondary sources only to
triangulate. When the source is a repository, pin the exact commit and cite
`path:line` for each claim.
2. Capture each exact quote as a checked-in source excerpt. Record its direct
URL or repo `path:line`, document section or repository symbol, source
version or commit when available, and retrieval date. Also record an
archive or snapshot URL when one exists and a content digest when the source
publishes or permits one. These evidence records must remain auditable if
the live URL changes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Make the evidence-record format mandatory in each dossier.

The method requires every quote to be stored as an auditable source excerpt with URL/path, symbol or section, version/commit, retrieval date, archive URL, and digest. However, the output skeleton has no required section or schema for those records, so a dossier can satisfy the documented headings while omitting the corpus’s core reproducibility evidence.

Add a required ## Evidence excerpts section to the skeleton and point the method at it.

Proposed contract update
-2. Capture each exact quote as a checked-in source excerpt. Record its direct
+2. Capture each exact quote in the dossier's required Evidence excerpts
+   section. Record its direct
   URL or repo `path:line`, document section or repository symbol, source
   version or commit when available, and retrieval date. Also record an
   archive or snapshot URL when one exists and a content digest when the source
   publishes or permits one.
...
 ## Output skeleton (per product file)
 ...
 - {additional anchors}
 
+## Evidence excerpts
+<!-- Each excerpt must include the quote, source URL or repo path:line,
+     section/symbol, version or commit, retrieval date, and optional
+     archive URL and content digest. -->
+
 ## The storage model

Also applies to: 187-214

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/RESEARCH_PROMPT.md` around lines 163 - 174, Make
the evidence-record contract mandatory by adding a required “## Evidence
excerpts” section to the dossier output skeleton, including fields for quote,
direct URL or repository path and line, symbol or section, version or commit,
retrieval date, archive or snapshot URL, and content digest. Update the “Method”
instructions to explicitly require every captured quote to be recorded in that
section, preserving the existing auditability requirements.

Comment on lines +61 to +75
**3. Rewind is implemented as an appended marker interpreted at replay, not
a destructive edit, everywhere except the pure-SQL stores.** Claude Agent
SDK's `/rewind` menu is "a non-destructive view operation over an
append-only log." Codex CLI's `ThreadRolledBack` event means "skip the next
N user-turn segments we finalize"; nothing is deleted. Gemini CLI's
`$rewindTo` line means the reducer "deletes it plus everything after" only
from the in-memory fold, not the file. Grok Build: "Every prompt is a
checkpoint, the list always contains [0, 1, ..., N-1]..."; separately, the
dossier notes nothing is deleted and replay applies dead-branch filtering.
T3 Code: "exactly
the append-marker-replayed pattern (as opposed to Hermes's in-place flag
mutation)." OpenCode's v2 `revert.commit` truncates only the *projection*;
"the underlying event rows are not deleted." The two exceptions prove the
axis: Goose's rewind is "a destructive delete" (`truncate_conversation`),
and Hermes's is an in-place flag flip (`active=0`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Narrow the universal convergence claims to match the documented exceptions.

  • docs/research/session-store/synthesis.md#L61-L75: include LangGraph as a non-marker rewind model; its documented behavior selects an older checkpoint.
  • docs/research/session-store/synthesis.md#L103-L117: Gemini also uses nested child files and path-based parent linkage, so Claude is not the sole structural exception.
  • docs/research/session-store/synthesis.md#L119-L129: Claude and Gemini document cascading deletion; change “every product” to “most products” and identify those exceptions.
📍 Affects 1 file
  • docs/research/session-store/synthesis.md#L61-L75 (this comment)
  • docs/research/session-store/synthesis.md#L103-L117
  • docs/research/session-store/synthesis.md#L119-L129
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/synthesis.md` around lines 61 - 75, Revise the
universal convergence claims in docs/research/session-store/synthesis.md:61-75
to include LangGraph as a non-marker model that selects an older checkpoint;
update docs/research/session-store/synthesis.md:103-117 to note Gemini’s nested
child files and path-based parent linkage alongside Claude; and change “every
product” to “most products” in docs/research/session-store/synthesis.md:119-129,
explicitly identifying Claude and Gemini as cascading-deletion exceptions.

Comment on lines +385 to +394
5. **Fork always mints a new stream/session id and rewrites identity
fields in the copied prefix; it must never let a copy reference the
source id.** Industry's answer: unanimous outside LangGraph (Claude
Agent SDK's explicit rationale for not using `CopyObject`; Codex CLI's
`history_base` prefix-pointer as the efficient variant of the same
rule). Decide whether fork is a physical copy (T3 Code, Goose, Hermes:
O(history) per fork) or a shared-prefix reference (Codex CLI's
`history_base`, LangGraph's shared content-addressed blobs); the
shared-prefix design is strictly cheaper and available to us because
events are immutable.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Separate fork identity rewriting from shared-prefix lineage references.

This requirement says a fork must never reference the source id, but immediately presents Codex’s history_base shared-prefix pointer as a valid alternative. Clarify the invariant: copied events must receive the new stream identity, while an immutable shared-prefix implementation may retain an explicit source-stream lineage reference.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/session-store/synthesis.md` around lines 385 - 394, Clarify the
fork invariant in the section beginning “Fork always mints a new stream/session
id”: distinguish copied event identity fields, which must be rewritten to the
new stream/session id, from an optional immutable shared-prefix lineage
reference, which may explicitly retain the source stream id. Present
physical-copy and shared-prefix implementations as alternatives without implying
that lineage references violate the copied-event identity rule.

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