You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Vercel backend (persist seam + session store + route read)
Reusability impact
none
Production mutate?
no
Cloud ops path
N/A
Living docs
N/A this phase (parent Phase 5 owns docs)
Review notes (2026-09-05)
#
Axis
Score
Notes
1
Correctness
5
All four baseline claims verified @ main (writeSegment + model_messages_write_failed in lib/agent/turnPersistSeam.ts; isObjectIdBoundTo read guard in app/api/turns/route.ts; RESERVED_META_KEYS + copy-forward helpers in lib/sessions/sessionStore.ts; route seed chain). Fallback order locked (checkpoint → modelMessages → legacy promptHistory).
2
Performance
4
One extra bounded Blob read on the route pre-start; object cap MODEL_MSG_SEED_MAX_BYTES + 256 KiB (2.25 MiB — composes with the Phase-1 tail rail); no polling/loop additions. Persist seam writes only when a compaction ran.
3
Architecture
5
Vercel-backend-only; checkpoint server-side; reuses the landed sibling pattern (modelMessagesPointer/freshnessReminderPointer/workingNotes); no new DI seam. Worker-overlay seam (WORKER_META_KEYS in lib/agent/workerMetaOverlay.ts) accepts patch.compactionPointer via sanitizeWorkerKeyValue.
4
Testing
4
Locked DoD matrix (1,2,4,5,6): persist, route preference, copy-forward, confused-deputy, gates. Case 3 (fallback chain) over-and-above.
5
Cloud ops
N/A
Header + DoD explicitly lock "no Production mutate" — correct.
6
Living docs
N/A
This phase defers docs to parent Phase 4 (#951) — consistent with the parent's post-#944 re-split; parent's own Living-docs row was superseded by the re-plan.
7
Caps
5
Caps table present: 1 NEW cap (COMPACTION_CHECKPOINT_MAX_BYTES = MODEL_MSG_SEED_MAX_BYTES + 256 KiB / 2.25 MiB — raised on PR #954 adversarial from the original 1 MiB so a Phase-1-legal findCompactionCut tail can persist; NEW unmerged, no existing-on-main ceiling changed); HARNESS_SESSION_MAX_META_BYTESunchanged. No existing cap raised/lowered → no human gate.
8
Parent adherence
5
Phase number correct vs parent map; scope ⊆ parent; no lock re-open; refinements table declares the lock-tightenings (seed fallback order, no-new-DI-seam).
9
Layer/UI
N/A
No DOM/Wasm surface; Wasm paints nothing new; DOM host unchanged. Forbidden wiring locked.
(Minor) checkpointPointer is an existing unrelated reserved key (older projection-checkpoint sibling); the plan's new compactionPointer is a distinct sibling — no collision. Phase 3/5 must add compactionPointer to lib/agent/workerMetaOverlay.tsWORKER_META_KEYS (+ a sanitizeWorkerKeyValue arm) for patch.compactionPointer to survive the worker overlay — a Phase-3 wire-up note, not this phase's DoD.
Verdict: HANDOFF-READY — no Blockers; all Majors cleared by baseline verification; scores ≥4 on all required axes; parent adherence clean; cloud ops N/A (no Production mutate); living docs correctly N/A; caps table complete, no human gate.
Intent lock
In scope: persist the checkpoint as its own session-bound Blob object + reserved meta key compactionPointer (worker-authored, copy-forward on envelope PUT), and make POST /api/turnsprefer the checkpoint on seed (read, re-validate, re-pair, fall back to modelMessagesPointer).
Out of scope: the compaction trigger decision and the summarizer step (Phase 3). This phase only lands the write-once/read carrier so a persisted checkpoint (produced by Phase 3, or by a prior session) seeds correctly.
Forbidden: dual DOM chat · secrets in Wasm · laptop-only Production ops. The checkpoint stays server-side; Wasm paints nothing new.
Depends on
Phase 1 merged (needs COMPACTION_* caps + renderSummaryRow / checkpoint type from lib/agent/compaction.ts).
lib/sessions/sessionStore.ts — add compactionPointer to RESERVED_META_KEYS and a copyForwardCompactionPointer helper inside upsertEnvelope (worker-authored sibling, same exception class as modelMessagesPointer / workingNotes / freshnessReminderPointer). Host cloudMetaFor never emits the key; an explicit incoming value (worker overlay) wins; Clear is DELETE.
lib/agent/turnPersistSeam.ts — on the terminal persist, write the checkpoint object (when a compaction ran this turn) via writeSegment with maxBytes: COMPACTION_CHECKPOINT_MAX_BYTES, then patch.compactionPointer = <objectId> on the worker meta overlay. Fail-closed compaction_write_failed. (Phase 3 supplies the in-turn compaction result; the persist seam accepts it on the derivePersistFold input.)
app/api/turns/route.ts — on seed, prefer envelope.meta?.compactionPointer when present and isObjectIdBoundTo bound; read, JSON.parse, buildModelMessages-rebuild + re-pair the checkpoint's retainedTail, and seed priorMessages = [renderSummaryRow(...), ...tail]. Fall back to meta.modelMessagesPointer (today's behavior) when absent/malformed/unbound; when both are missing, fall back to the legacy promptHistory sidecar. The route reads via services.createBlobTranscriptStore() exactly as the plan: structured truncated tool_result on the wire (A1, source #549) #936 projection read does today — no new DI seam.
Caps table
Cap / ceiling
Value
Rationale
Code location
NEW COMPACTION_CHECKPOINT_MAX_BYTES
MODEL_MSG_SEED_MAX_BYTES + 256 KiB (2.25 MiB)
The checkpoint Blob object ({summary, filesTouched, retainedTail}) is its own session-bound object, never envelope meta (only the ≤512-char pointer id rides meta). Must compose with the Phase-1 findCompactionCut tail rail (MODEL_MSG_SEED_MAX_BYTES = 2 MiB): a legal cut’s retainedTail may serialize to that size; 256 KiB slack covers summary (≤8 000 chars + honesty suffixes), filesTouched (≤256 short paths), and object keys. Raised on PR #954 adversarial from 1 MiB so a Phase-1-legal checkpoint can persist — NEW unmerged cap, not a change to an existing-on-main ceiling. Still well under the 8 MiB model-messages object. An oversized write fail-closes (compaction_write_failed), never a truncation lie.
lib/sessionCloudCaps.ts
HARNESS_SESSION_MAX_META_BYTES — unchanged
1 MiB
compactionPointer is a ≤512-char id inside the existing whole-meta budget. No change
Plan header
Review notes (2026-09-05)
writeSegment+model_messages_write_failedinlib/agent/turnPersistSeam.ts;isObjectIdBoundToread guard inapp/api/turns/route.ts;RESERVED_META_KEYS+ copy-forward helpers inlib/sessions/sessionStore.ts; route seed chain). Fallback order locked (checkpoint → modelMessages → legacypromptHistory).MODEL_MSG_SEED_MAX_BYTES + 256 KiB(2.25 MiB — composes with the Phase-1 tail rail); no polling/loop additions. Persist seam writes only when a compaction ran.modelMessagesPointer/freshnessReminderPointer/workingNotes); no new DI seam. Worker-overlay seam (WORKER_META_KEYSinlib/agent/workerMetaOverlay.ts) acceptspatch.compactionPointerviasanitizeWorkerKeyValue.COMPACTION_CHECKPOINT_MAX_BYTES=MODEL_MSG_SEED_MAX_BYTES + 256 KiB/ 2.25 MiB — raised on PR #954 adversarial from the original 1 MiB so a Phase-1-legalfindCompactionCuttail can persist; NEW unmerged, no existing-on-main ceiling changed);HARNESS_SESSION_MAX_META_BYTESunchanged. No existing cap raised/lowered → no human gate.Findings (all informational; none block):
186a3c9) Caps table originally locked 1 MiB; implementation raised the NEW unmerged cap toMODEL_MSG_SEED_MAX_BYTES + 256 KiBso a Phase-1-legal tail can persist. Table below matches code. Phase 3 must import the constant — do not re-introduce a 1 MiB producer ceiling.checkpointPointeris an existing unrelated reserved key (older projection-checkpoint sibling); the plan's newcompactionPointeris a distinct sibling — no collision. Phase 3/5 must addcompactionPointertolib/agent/workerMetaOverlay.tsWORKER_META_KEYS(+ asanitizeWorkerKeyValuearm) forpatch.compactionPointerto survive the worker overlay — a Phase-3 wire-up note, not this phase's DoD.Verdict: HANDOFF-READY — no Blockers; all Majors cleared by baseline verification; scores ≥4 on all required axes; parent adherence clean; cloud ops N/A (no Production mutate); living docs correctly N/A; caps table complete, no human gate.
Intent lock
In scope: persist the checkpoint as its own session-bound Blob object + reserved meta key
compactionPointer(worker-authored, copy-forward on envelope PUT), and makePOST /api/turnsprefer the checkpoint on seed (read, re-validate, re-pair, fall back tomodelMessagesPointer).Out of scope: the compaction trigger decision and the summarizer step (Phase 3). This phase only lands the write-once/read carrier so a persisted checkpoint (produced by Phase 3, or by a prior session) seeds correctly.
Forbidden: dual DOM chat · secrets in Wasm · laptop-only Production ops. The checkpoint stays server-side; Wasm paints nothing new.
Depends on
Phase 1 merged (needs
COMPACTION_*caps +renderSummaryRow/ checkpoint type fromlib/agent/compaction.ts).Current baseline (live code @ main)
writeSegment+ fail-closedmodel_messages_write_failedsibling patternlib/agent/turnPersistSeam.tsisObjectIdBoundTo(oid, scope)on readapp/api/turns/route.ts,lib/sessions/blobStore.tsRESERVED_META_KEYS+ copy-forward on envelope PUTlib/sessions/sessionStore.ts(copyForwardModelMessagesPointer,copyForwardFreshnessReminderPointer)priorMessagesapp/api/turns/route.tsDesign
lib/sessions/sessionStore.ts— addcompactionPointertoRESERVED_META_KEYSand acopyForwardCompactionPointerhelper insideupsertEnvelope(worker-authored sibling, same exception class asmodelMessagesPointer/workingNotes/freshnessReminderPointer). HostcloudMetaFornever emits the key; an explicit incoming value (worker overlay) wins; Clear is DELETE.lib/agent/turnPersistSeam.ts— on the terminal persist, write the checkpoint object (when a compaction ran this turn) viawriteSegmentwithmaxBytes: COMPACTION_CHECKPOINT_MAX_BYTES, thenpatch.compactionPointer = <objectId>on the worker meta overlay. Fail-closedcompaction_write_failed. (Phase 3 supplies the in-turn compaction result; the persist seam accepts it on thederivePersistFoldinput.)app/api/turns/route.ts— on seed, preferenvelope.meta?.compactionPointerwhen present andisObjectIdBoundTobound; read,JSON.parse,buildModelMessages-rebuild + re-pair the checkpoint'sretainedTail, and seedpriorMessages = [renderSummaryRow(...), ...tail]. Fall back tometa.modelMessagesPointer(today's behavior) when absent/malformed/unbound; when both are missing, fall back to the legacypromptHistorysidecar. The route reads viaservices.createBlobTranscriptStore()exactly as the plan: structured truncated tool_result on the wire (A1, source #549) #936 projection read does today — no new DI seam.Caps table
COMPACTION_CHECKPOINT_MAX_BYTESMODEL_MSG_SEED_MAX_BYTES+ 256 KiB (2.25 MiB){summary, filesTouched, retainedTail}) is its own session-bound object, never envelopemeta(only the ≤512-char pointer id ridesmeta). Must compose with the Phase-1findCompactionCuttail rail (MODEL_MSG_SEED_MAX_BYTES= 2 MiB): a legal cut’sretainedTailmay serialize to that size; 256 KiB slack covers summary (≤8 000 chars + honesty suffixes),filesTouched(≤256 short paths), and object keys. Raised on PR #954 adversarial from 1 MiB so a Phase-1-legal checkpoint can persist — NEW unmerged cap, not a change to an existing-on-main ceiling. Still well under the 8 MiB model-messages object. An oversized write fail-closes (compaction_write_failed), never a truncation lie.lib/sessionCloudCaps.tsHARNESS_SESSION_MAX_META_BYTES— unchangedcompactionPointeris a ≤512-char id inside the existing whole-meta budget. No changelib/sessionCloudCaps.ts(existing)No existing cap changed → no human gate.
Implementation order
lib/sessions/sessionStore.ts—compactionPointerreserved key +copyForwardCompactionPointer.lib/agent/turnPersistSeam.ts— checkpointwriteSegment+patch.compactionPointer.app/api/turns/route.ts— prefer-checkpoint seed with fallback chain (checkpoint → modelMessages → legacy sidecar).Testing
compactionPointer; fail-closedcompaction_write_failedvitest run lib/agent/turnPersistSeam.test.tscompactionPointerovermodelMessagesPointerand seeds[summaryRow, ...retainedTail]vitest run app/api/turns(route test file)modelMessagesPointer; both missing → legacypromptHistorysidecarvitest run app/api/turnscompactionPointerdoes not delete the checkpoint (copy-forward on the LWW read)vitest run lib/sessions/sessionStore.test.tsvitest run app/api/turnsnpm run typecheck,npm testMinimum locked for DoD: 1, 2, 4, 5, 6.
Definition of done
meta.compactionPointer; next turn seeds checkpoint + retained tail"Corrections / refinements vs parent
promptHistorysidecarservices.createBlobTranscriptStore()— no new DI seam, mirroring the #936 projection read