fix(subagent,core): replay journaled result on durable subagent resume#6014
Merged
Conversation
bug-ops
enabled auto-merge (squash)
July 11, 2026 12:50
bug-ops
force-pushed
the
fix/5944-durable-resume-replay
branch
from
July 11, 2026 12:53
00d0b7c to
7bd3484
Compare
Restarting a crashed parent whose sub-agent had already finished and resolved its durable promise previously discarded that promise and spawned a brand-new child from scratch, duplicating LLM calls and any side-effecting tool calls the finished child had already performed. maybe_make_durable_seat is replaced by resolve_durable_spawn_gate, which on a resumed run performs a non-blocking check (zeph_durable::DurableContext::take_resolved_promise, exposed via the new zeph_subagent::try_replay_durable_subagent) for whether the child already resolved its promise before the crash. If so, handle_agent_background and handle_agent_spawn_foreground skip mgr.spawn(...) entirely and feed the journaled SubagentResult through the normal completion path instead. A still-pending resumed promise falls back to the pre-existing spawn behavior, matching the documented v1 scope boundary, and now logs a warning so the residual duplicate-spawn window is observable rather than silent (tracked as a known v1 limitation in #6010). Closes #5944
bug-ops
force-pushed
the
fix/5944-durable-resume-replay
branch
from
July 11, 2026 13:02
7bd3484 to
b89b350
Compare
This was referenced Jul 11, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
zeph-subagent's durable-promise adapter (durable.rs) implemented the "finished-child replay" case documented since feat(sub-agents): durable promise for subagent spawn/await resume (P4) #4954, but the only production call site inzeph-corediscarded the resumed promise unconditionally and always re-spawned the sub-agent, duplicating LLM calls and any side-effecting tool calls (git operations, GitHub issue/PR creation, file writes) a finished child had already performed.maybe_make_durable_seatis replaced byresolve_durable_spawn_gate(DurableSpawnGate::{Fresh, Replayed, None}). On a resumed run it performs a non-blocking check via the newzeph_subagent::try_replay_durable_subagent(wrappingDurableContext::take_resolved_promise, nowpub) for whether the child already resolved before the crash.handle_agent_background/handle_agent_spawn_foregroundskipmgr.spawn(...)entirely when the promise already resolved, feeding the journaledSubagentResultthrough the normal completion-notification path instead.tracing::warn!so the residual duplicate-spawn window is observable rather than silent. Tracked as a known v1 limitation in durable sub-agent resume: still-pending promise falls back to spawn, may duplicate a genuinely in-flight child #6010.specs/064-durable-execution/spec.md§888 updated to record that the v1LocalBackendintegration falls back to spawn rather than re-parking, and why.Closes #5944.
Test plan
cargo +nightly fmt --checkcargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warningscargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins(12695/12695 passing, includes 3 new end-to-end regression tests exercisinghandle_agent_background/handle_agent_spawn_foregroundthrough the replay branch and the still-pending fallback, using two independently-constructedAgentinstances over a shared on-disk sqlite journal to simulate a real parent-process restart)RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler"cargo test --doc -p zeph-subagent -p zeph-durable -p zeph-core