Skip to content

feat(store): move the transcript archive flush off the commit path (RIG-5158) - #2223

Merged
mattwilkinsonn merged 2 commits into
mainfrom
compass-repo/rig-5158-flush-impl
Oct 12, 2026
Merged

mattwilkinsonn merged 2 commits into
mainfrom
compass-repo/rig-5158-flush-impl

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Move the transcript archive flush off CommitConversationFrame. The commit returns once the row lands in Postgres. A Store-owned flusher archives later, one pass at a time per session.

Why

AppendTranscriptEntry ran the compaction flush and the safety valve inline. The object-store PUT had no deadline. A slow or frozen store held the RPC until the agent's 5s attempt timeout, and the agent's serial frame chain stalled behind it. This is the measured root cause of the s3-outage e2e flake (RIG-5157).

Change

Implements the frozen record docs/designs/agent/compass-transcript-flush-off-commit.md (DL-491), both tasks.

  • Commit path: AppendTranscriptEntry commits the row and calls requestFlush. primaryFlush is gone. A deduped retry, or a store with no object store, requests nothing.
  • Flusher (go/internal/store/transcript_flusher.go):
    • one slot per session, with triggers that land mid-pass coalescing into one more pass;
    • at most maxConcurrentFlushes = 4 passes at once;
    • each pass runs under a 60s deadline and the commit's tenant and system scope;
    • a failed pass is logged at ERROR and counted in compass.store.transcript_flush_failures.
  • Lifecycle: Open starts the flusher. Close cancels it and waits for every pass before pool.Close().
  • Database guards for the new races:
    • HotTailBytes and HotTailSizes find the checkpoint inside the statement, and valveCut stops before any checkpoint row.
    • PruneTranscriptEntries is now :execrows. A pruning flush rolls back with errFlushRaced unless it deleted exactly the rows it archived.
    • SafetyValveSegments hides valve segments at or below the latest checkpoint.
  • Tests and callers: FlushTranscript is the synchronous barrier tests use. The sync-flush tests, the server resume S3 test and the e2e comments are updated.

Verification

  • New pgtests pass, and pass 5 of 5 under -race:

    • non-blocking commit (checkpoint and valve);
    • coalescing;
    • global cap;
    • checkpoint inside the cut;
    • DB guard with overlapping stores;
    • pass deadline;
    • Close joins the pass;
    • tenant;
    • segment filter;
    • valveCut cases;
    • runnerhub CommitConversationFrame returns while the PUT hangs.
  • Mutations, each killed by its test:

    Mutation Failing test
    Inline flush restored non-blocking test
    valveCut checkpoint stop removed TestValveCut
    Prune count check dropped DB guard test
    Segment filter dropped filter test
    Close skips the join shutdown test
    Semaphore capacity set to 5 global cap test
  • go test -tags pgtest -race passes for the full internal/store, internal/runnerhub and server packages on a fresh Postgres.

  • golangci-lint reports 0 issues with and without the full tag set. sqlc-drift is clean. go build -tags podman ./e2e/... succeeds.

  • Review loop: round 1 found 0 high, 1 medium, 1 low; both are fixed. Round 2 found 0/0/0.

Refs RIG-5158, RIG-5157.

Ledger-impact: none (implements DL-491, already recorded).

rigel-mintaka and others added 2 commits October 11, 2026 21:46
…IG-5158)

AppendTranscriptEntry ran the compaction flush and the safety valve inline, so CommitConversationFrame blocked on the object-store PUT. A slow or frozen store stalled the agent's serial frame chain, and each commit gave up at the agent's 5s attempt timeout. AppendTranscriptEntry now commits the row and asks the Store's flusher for a pass. The flusher runs one pass at a time per session, at most 4 at once, each under a 60s deadline. A failed pass is logged, counted in compass.store.transcript_flush_failures, and covered by the next commit. Open starts the flusher; Close joins every pass before closing the pool.

Commits can now land during a pass, so the database guards the two new races. The valve finds the latest checkpoint inside its size query and never cuts past a checkpoint row. A pruning flush rolls back unless it deletes exactly the rows it archived. SafetyValveSegments hides valve segments at or below the latest checkpoint.

FlushTranscript is the synchronous barrier tests use. The e2e s3 outage leg keeps gating on the committed row.

Implements docs/designs/agent/compass-transcript-flush-off-commit.md (DL-491).

Ledger-impact: none

Co-authored-by: Matt Wilkinson <matt@rigel.build>
Ledger-impact: none

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@trunk-io

trunk-io Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

😎 This pull request was merged.

@linear-code

linear-code Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RIG-5158

RIG-5157

@rigel-mintaka

Copy link
Copy Markdown
Contributor Author

Review loop at head c040cfc: round 1 found 0 high, 1 medium, 1 low. The medium was a missing global-cap test, now TestFlushPassesShareGlobalCap; the low was a stale SegmentKindSafetyValve comment. Both are fixed. Round 2 found 0/0/0. After review, the pre-push hook's nilaway flagged valveCut slicing a possibly-nil tail, so an empty-rows guard was added. TestValveCut passes and nilaway is clean.

@github-actions

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-repo-rig-5158-flush-l8mp.compass-eng-docs.pages.dev

Deployed from compass-repo/rig-5158-flush-impl at c040cfc.

@rigel-mintaka
rigel-mintaka marked this pull request as ready for review October 12, 2026 02:24
@mattwilkinsonn
mattwilkinsonn merged commit b7ea071 into main Oct 12, 2026
17 checks passed
@mattwilkinsonn
mattwilkinsonn deleted the compass-repo/rig-5158-flush-impl branch October 12, 2026 19:15
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