Skip to content

Compaction notes (failed_open / compacted) are only written at send settlement — invisible when the turn is stopped #4850

Description

@me2seeks

What happened

When a send's history fold fails open (e.g. a durable history-compact checkpoint is rejected at replay), the context_compaction_failed_open system note is only appended together with token_usage at send settlement (ai-sdk-turn.ts). If the turn is aborted before settlement — the user presses stop, the stream errors, the process dies — the note is never written. The transcript then shows a prior "Context compacted." while every request silently sends the full uncompacted history.

This exact sequence hid #4842: the checkpoint failed open with source_hash_mismatch at 18:18:45, the turn ran for tens of minutes without settling, and the only visible signal was a ctx indicator pinned at 100%. The compaction decision (replaced / failedOpen, with failOpenReason) is already known at turn start when buildPriorMessages returns — the note just waits for settlement for no reason.

The same delay applies to context_compacted on the send path: a mid-turn/request-hook fold is only acknowledged when the send settles.

How to reproduce

  1. Produce a session whose replay fails open (e.g. on main before fix(runtime): match history-compact checkpoints against the raw ledger prefix #4845: archive a stale tool result, compact, send again).
  2. While the resulting turn is still running, press stop.
  3. Inspect the transcript: no context_compaction_failed_open note exists, even though the send's first request already carried the full history.

Environment

  • Maka commit: 3fdaddb (main)
  • Surface: Desktop / TUI / Runtime (ai-sdk backend)

Proposed fix

Append context_compaction_failed_open / context_compacted at decision time — immediately after buildPriorMessages resolves the context-budget diagnostic for the send — instead of at settlement. Keep the settlement-time write behind the existing *NoteWritten flags so a send still writes at most one note. Include the failOpenReason in the note's data so the transcript says why the fold was refused (e.g. source_hash_mismatch vs summarizer_failed), which today requires digging through token_usage.contextBudget diagnostics.

No TUI/Desktop changes needed: both renderers already label both note kinds wherever the note message appears (packages/cli/src/pi-transcript.ts, packages/ui/src/materialize.ts); the fix only changes when the runtime writes it.

Scope note: this is Maka-internal event visibility, distinct from #4623's provider-behavior degraded modes (no usage / unclassified rejection / silent eviction). Happy to hand off if you'd rather fold it into that track @Joob1n — otherwise I'll take it.

I can take this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions