Skip to content

perf(hub): seal run digest on crash/failure + session-less terminate (#118 §4)#296

Merged
physercoe merged 1 commit into
mainfrom
perf/118-fold-on-session-close
Jun 27, 2026
Merged

perf(hub): seal run digest on crash/failure + session-less terminate (#118 §4)#296
physercoe merged 1 commit into
mainfrom
perf/118-fold-on-session-close

Conversation

@physercoe

Copy link
Copy Markdown
Owner

Second of the Tier-A perf PRs for #118. Defensive fold-on-close so the first Insight open on an ended run is an O(1) read, not a full O(n) backfill.

Problem (#118 bottleneck #3/#4)

Only the operator stop path (stopSessionInternal) finalized the run digest at terminal time (stop_session.go:179). Two other terminal transitions fell through without folding:

  • crash / failurePATCH status=crashed|failed (handlers_agents.go), the path the host-runner reconcile uses.
  • session-less terminate — the rare branch in applyAgentTerminationEffects where no live session points at the agent.

For those runs, the digest stayed behind the event log, so the first Insight open paid the full backfill (10k events → ~10s for the reported session) on the user's read path.

Fix

Converge both missing terminal transitions through the existing finalizeDigestOutcome hook (folds the digest current if stale, then stamps the terminal outcome — O(1)), the same hook the stop path already uses.

Chose finalizeDigestOutcome's idempotent full recompute over the background worker's incremental foldDirtyAgent: calling foldDirtyAgent synchronously here would double-fold against the concurrent fold worker (both read the same watermark and fold the same tail). The recompute is race-safe and already battle-tested on the stop path.

Changes

  • handlePatchAgent crashed/failed branch → finalizeDigestOutcome
  • applyAgentTerminationEffects session-less branch → finalizeDigestOutcome
  • test TestDigestSealedOnCrash: a crashed agent's digest is sealed (watermark == max seq, outcome stamped) right after the PATCH, so no read-time backfill is owed

Verification

go build, go vet, gofmt clean. Digest/stop/terminate/patch suites pass, including -race (107s, clean).

Part of #118 (Tier A). Sibling: #295 (sessionAgentIDs denorm).

🤖 Generated with Claude Code

…118 §4)

Only the operator stop path (stopSessionInternal) finalized the run digest at
terminal time. A crash/failure (PATCH status=crashed|failed) and a session-less
terminate fell through without folding, so the FIRST Insight open on those runs
paid the full O(n) backfill (#118 bottleneck #3/#4) on the user's read path.

Converge both missing terminal transitions through finalizeDigestOutcome (fold
current if stale, then O(1) outcome stamp) — same hook the stop path already
uses. Chose finalizeDigestOutcome's idempotent recompute over the background
worker's incremental foldDirtyAgent to avoid a double-fold race with that
worker.

- handlePatchAgent crashed/failed branch -> finalizeDigestOutcome
- applyAgentTerminationEffects session-less branch -> finalizeDigestOutcome
- test: a crashed agent's digest is sealed (watermark==max, outcome stamped)
  right after the PATCH, so no read-time backfill is owed

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@physercoe physercoe merged commit 4afddc2 into main Jun 27, 2026
4 checks passed
@physercoe physercoe deleted the perf/118-fold-on-session-close branch June 27, 2026 12:58
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.

1 participant