What happened
A successful explicit context-compaction turn can durably commit its terminal RuntimeEvent before its transcript context_compacted system note is written. If the process crashes in that interval, or all bounded note-write retries fail, reopening the session shows a completed compaction with no durable transcript row.
The canonical terminal fact already exists: the compaction turn's RuntimeEvent contains stateDelta.contextCompactionOutcome. Terminal transcript reads do not use a live overlay, and later passive checkpoint replay intentionally does not emit another note, so the missing row is not repaired.
Expected: session load/recovery idempotently reconciles a terminal context-compaction outcome into exactly one matching durable system note.
How to reproduce
- Complete an explicit context compaction.
- Inject a process crash after the terminal RuntimeEvent commit and before
appendDurableCompactionNote, or make all three appendMessage attempts fail.
- Reopen the session.
- Observe that the compaction turn is terminal but no
context_compacted row is present.
A fault-injection regression should cover the crash window and prove repeated recovery cannot duplicate the note.
Environment
Logs, screenshots, or additional context
PR #3651 intentionally uses a bounded three-attempt retry with one stable note id. That handles transient storage errors in-process, but cannot close the crash window. Implement reconcile-on-load from the canonical terminal RuntimeEvent, preserving these semantics:
compacted → exactly one context_compacted note
failed → exactly one context_compaction_failed_open note
unchanged or interrupted → no durable note
- recovery is idempotent and never duplicates an already-written note
What happened
A successful explicit context-compaction turn can durably commit its terminal RuntimeEvent before its transcript
context_compactedsystem note is written. If the process crashes in that interval, or all bounded note-write retries fail, reopening the session shows a completed compaction with no durable transcript row.The canonical terminal fact already exists: the compaction turn's RuntimeEvent contains
stateDelta.contextCompactionOutcome. Terminal transcript reads do not use a live overlay, and later passive checkpoint replay intentionally does not emit another note, so the missing row is not repaired.Expected: session load/recovery idempotently reconciles a terminal context-compaction outcome into exactly one matching durable system note.
How to reproduce
appendDurableCompactionNote, or make all threeappendMessageattempts fail.context_compactedrow is present.A fault-injection regression should cover the crash window and prove repeated recovery cannot duplicate the note.
Environment
Logs, screenshots, or additional context
PR #3651 intentionally uses a bounded three-attempt retry with one stable note id. That handles transient storage errors in-process, but cannot close the crash window. Implement reconcile-on-load from the canonical terminal RuntimeEvent, preserving these semantics:
compacted→ exactly onecontext_compactednotefailed→ exactly onecontext_compaction_failed_opennoteunchangedor interrupted → no durable note