Skip to content

feat(orchestration): implement Mode-2 route_to reroute-to-alternate recovery - #6346

Merged
bug-ops merged 2 commits into
mainfrom
feat/issue-6244/route-to-redesign
Jul 17, 2026
Merged

feat(orchestration): implement Mode-2 route_to reroute-to-alternate recovery#6346
bug-ops merged 2 commits into
mainfrom
feat/issue-6244/route-to-redesign

Conversation

@bug-ops

@bug-ops bug-ops commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • Implements Mode-2 route_to reroute-to-alternate-node recovery for the orchestration scheduler (spec 075-orchestration-node-control-parity FR-D-01), the LangGraph node-error-handler parity mode deferred from PR spec(075-orchestration-node-control-parity): add specification #6242 after the original naive design (dependency-based dormancy) was found unworkable during a three-round architect/critic review (N5/N1/N3).
  • New non-terminal TaskStatus::Dormant state, RecoveryAction.route_to: Option<TaskId> on-failure activation edge, and a completion-time resolve_dormant_after_terminal sweep close N5 (dormancy inversion), N1 (Skip-BFS stranding the fallback's subtree), and N3 (Failed-source output never reaching the fallback's prompt).
  • DispatchStrategy::LevelBarrier now treats Dormant as parked and lets an activated fallback dispatch out-of-level, closing a livelock where a route_to source deeper than its depth-0 fallback would never get scheduled.
  • /plan retry re-arms a previously-activated fallback branch back to Dormant so retry semantics compose correctly with a prior reroute.
  • A rerouted source stays terminal Failed even inside a Completed graph (by design, to keep the Completed-only aggregator/grounding filters from leaking the failure's error into synthesis) and is now tallied into tasks_failed.
  • A review round caught that the routed_from prompt injection read TaskNode.result, which no production Failed-transition path populated — only the Completed handler and Mode-1's try_recover wrote it, so the failed-source context injection silently rendered empty outside the one test that hand-fabricated .result. Fixed by populating .result at all three Failed-transition sites in tick/mod.rs, and replaced the masking test with one that drives the real handle_failed_outcome/tick() path end-to-end.
  • No config/CLI/wizard/migration surface: route_to, like Mode-1's state_injection, is authored programmatically rather than exposed to the LLM planner schema.

Design process

Full architect → critic (2 rounds) → developer → (tester, perf, security, impl-critic) → reviewer (2 rounds) chain. Design and review handoffs: .local/handoff/2026-07-16T22-{20-21,28-07,41-21,47-11}-*.md, .local/handoff/2026-07-16T23-{27-47,33-22,33-57,35-46}-*.md, .local/handoff/2026-07-17T{01-23-28,01-37-49,01-57-22}-*.md.

Closes #6244

Test plan

  • 34 new unit/integration tests across dag.rs, scheduler/mod.rs, scheduler/planner.rs, scheduler/router.rs, zeph-core::compaction_e2e — including the two D4 LevelBarrier hang scenarios, a resume_from-specific Dormant-stays-Dormant regression, and an end-to-end real-failure-path prompt-injection test
  • cargo +nightly fmt --check clean
  • cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings clean
  • cargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins — 13912/13912 passed, 0 failed, zero regressions
  • Rustdoc gate (RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace) clean
  • Workspace doc-tests clean
  • gitleaks protect --staged clean
  • Live /plan session test — not yet possible, route_to has no LLM-facing authoring surface yet (same constraint as Mode-1's state_injection); see the playbook's harness-based verification approach instead

@github-actions github-actions Bot added documentation Improvements or additions to documentation rust Rust code changes core zeph-core crate enhancement New feature or request size/XL Extra large PR (500+ lines) labels Jul 17, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 17, 2026 00:25
@bug-ops
bug-ops force-pushed the feat/issue-6244/route-to-redesign branch 2 times, most recently from 510388a to db59cf4 Compare July 17, 2026 00:36
bug-ops added 2 commits July 17, 2026 02:46
…ecovery

Adds a route_to reroute-to-alternate recovery mode to the orchestration
scheduler (LangGraph node-error-handler parity), deferred from the
original spec-075 design in PR #6242 after the naive dependency-based
approach was found unworkable (N5/N1/N3). A new non-terminal
TaskStatus::Dormant state, an on-failure activation edge on
RecoveryAction, and a completion-time resolution sweep close those
findings; a review round additionally caught that the routed_from
prompt injection read TaskNode.result, which no production Failed
transition populated, silently defeating the failed-source context
injection in real usage.

Closes #6244
…erals

Two RunningTask test literals in planner.rs and router.rs were missing
the last_progress_at field added by the idle_timeout progress-signal
feature merged into main, breaking the MSRV/test build.
@bug-ops
bug-ops force-pushed the feat/issue-6244/route-to-redesign branch from 4d74200 to 359aa4a Compare July 17, 2026 00:46
@bug-ops
bug-ops merged commit 3c00d84 into main Jul 17, 2026
79 of 81 checks passed
@bug-ops
bug-ops deleted the feat/issue-6244/route-to-redesign branch July 17, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core zeph-core crate documentation Improvements or additions to documentation enhancement New feature or request rust Rust code changes size/XL Extra large PR (500+ lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

orchestration: Mode 2 route_to reroute-to-alternate recovery — needs Dormant/on-failure-edge redesign

1 participant