| 1 | # Canonical session v4 implementation report |
| 2 | |
| 3 | Date: 2026-09-14 |
| 4 | Base: `main-v2` at `744c2e94ec77b577fbe3f1c93c769b1c3388bd21` |
| 5 | |
| 6 | ## Delivered behavior |
| 7 | |
| 8 | - `internal/session` is the single production session service. New and resumed |
| 9 | writes use `reasonix.session.linear/v4` with `storageRevision: 1`; older |
| 10 | checkpoints, DAG logs, preview logs, linear v3/v3.1 logs, and the unpublished |
| 11 | v4 draft are migration inputs only. |
| 12 | - Large fields are published to the SHA-256 content store before their event |
| 13 | references are accepted. Content is streamed, range-readable, block-verified, |
| 14 | deduplicated within the authorization domain, and included in export closure. |
| 15 | - Logical commits use bounded, independently verified Zstandard frames and |
| 16 | begin/event/end transaction records. Accepted and durable watermarks remain |
| 17 | separate, incomplete transactions remain invisible, and write pressure causes |
| 18 | cancellable backpressure instead of a session-size rejection. |
| 19 | - Legacy schema-1/checkpoint migration copies and hashes the source as a stream, |
| 20 | parses messages incrementally, stages imports on disk, validates the target, |
| 21 | and publishes it atomically. The source remains unchanged on failure. |
| 22 | - Durable history is projected to a rebuildable SQLite index. Desktop, Serve, |
| 23 | remote transcript APIs, search, large-field expansion, and Goal diagnostics |
| 24 | use bounded pages or streaming writers rather than whole-history RPC values. |
| 25 | - Runtime memory retains the current business state, accepted tail, and model |
| 26 | workset instead of all durable message bodies. Export/import, fork, recovery, |
| 27 | and diagnostics retain fixed-snapshot and execution-authorization rules. |
| 28 | - Goal CAS, armed/disarmed state, unique continuation reservation, user-input |
| 29 | priority, and pre-side-effect Flush checkpoints are retained from the merged |
| 30 | Goal lifecycle. Goal rounds have no hidden product ceiling. |
| 31 | |
| 32 | ## Compatibility result |
| 33 | |
| 34 | | Format | Current reader | Current writer | Downgrade behavior | Result | |
| 35 | | --- | --- | --- | --- | --- | |
| 36 | | checkpoint / schema-1 | streamed migration or read-only discovery | never | source bytes remain available | compatible | |
| 37 | | schema-2 DAG | graph-aware migration adapter | never | source graph remains available | compatible | |
| 38 | | preview and linear v3/v3.1 | explicit migration adapter | never | source bytes remain available | compatible | |
| 39 | | draft v4 revision 0 | explicit migration adapter | never | draft remains untouched | compatible migration boundary | |
| 40 | | v4 revision 1 | native | only production format | previous releases do not write this directory | explicit one-way boundary | |
| 41 | |
| 42 | The canonical v4 directory is separate from legacy storage. Migration does not |
| 43 | rewrite old data, and cold browse, migration, import, or fork never restores |
| 44 | approval or Goal activation. |
| 45 | |
| 46 | ## Cache contract |
| 47 | |
| 48 | Storage references, hashes, disk paths, cursors, and watermarks do not enter |
| 49 | provider requests. System prompts, tool schemas, message order, reasoning |
| 50 | signatures, provider metadata, visibility, and compaction triggers retain their |
| 51 | existing behavior. The serialized-byte guard covers OpenAI Chat Completions, |
| 52 | Anthropic, and OpenAI Responses before and after a v4 close/reopen cycle. |
| 53 | |
| 54 | ## Verification evidence |
| 55 | |
| 56 | - Root Go suite: `go test -p 2 ./... -count=1 -timeout=15m` |
| 57 | - Desktop Go suite: `cd desktop && go test ./... -count=1 -timeout=15m` |
| 58 | - Race suite: `go test -race ./internal/session ./internal/sessioncontent ./internal/control -count=1 -timeout=15m` |
| 59 | - Exact former replay failure: a `134,308,416` byte legacy log migrates, opens, |
| 60 | validates, and can continue writing. |
| 61 | - Large-record migration: a single legacy record larger than 64 MiB migrates |
| 62 | without the former record-size rejection. |
| 63 | - Provider bytes: OpenAI, Anthropic, and Responses serialized request bytes are |
| 64 | identical after v4 persistence and reopen. |
| 65 | - Capacity run: 100,001 events, 1 GiB logical history, 1 GiB attachments, and a |
| 66 | 16 MiB retained model workset completed. The measured indexed-page P95 was |
| 67 | 597 milliseconds and process peak RSS was approximately 235 MiB on the |
| 68 | reference macOS host. Cold open completed in 10.1 seconds. Initial index |
| 69 | construction took 115.1 seconds, so the aspirational 60-second reference-host |
| 70 | target is not met; index construction remains cancellable and does not prevent |
| 71 | reopening or streaming access. These are measurements, not admission limits. |
| 72 | - A 256 MiB run measured 153 milliseconds indexed-page P95 and approximately |
| 73 | 230 MiB peak RSS. |
| 74 | - Repository ratchets remain enabled. Their baseline was regenerated because |
| 75 | the versionless package rename changes path-keyed findings and the new |
| 76 | migration/query code intentionally increases measured source complexity. |
| 77 | |
| 78 | Frontend type/tests, the production frontend build, and native transcript |
| 79 | layout evidence are recorded in the pull request check results. |
| 80 | |
| 81 | ## Deliberately omitted evidence |
| 82 | |
| 83 | Windows installation and packaged-application validation were removed from this |
| 84 | delivery at the request of the task owner. This report does not claim native |
| 85 | Windows filesystem, installer, signing, or WebView2 evidence. It also does not |
| 86 | claim recovery of the original user log because that artifact was not provided; |
| 87 | the exact-size regression above is synthetic. |
| 88 |