fix: close spec-080 Command-handoff verification, rejection-visibility, and owner_key gaps#6416
Merged
Merged
Conversation
This was referenced Jul 17, 2026
bug-ops
enabled auto-merge (squash)
July 17, 2026 20:29
bug-ops
force-pushed
the
feat/issue-6394/command-handoff-outcomes-skip
branch
from
July 17, 2026 20:36
8cc9221 to
defd6a8
Compare
…y, and owner_key gaps Three follow-ups to spec-080 (cross-thread store + Command-style dynamic task handoff, PR #6363), combined into one PR as independent, unblocked gap-closing changes on the same feature. - TaskOutcome::Handoff now carries tool_trace and gets the same completeness-verification treatment Completed outcomes already had: handle_handoff_outcome emits SchedulerAction::CheckToolOutcome unconditionally and SchedulerAction::Verify when verify_completeness is enabled. Fixes a spawn-path gap where a commanded_from-linked goto target kept running after its source was corrected to Failed, via new dag::cancel_dangling_commanded_targets (#6394). - TaskNode.handoff_rejected is now surfaced in /plan status and the TUI plan view's task row, instead of only being logged (#6390). - ChannelMessage gains an owner_key field, threaded per-turn through SessionState and read by /store and Command-handoff store I/O. Gateway and A2A dispatch paths derive a real per-caller key instead of collapsing to the shared "local" sentinel; CLI/TUI/Telegram are unchanged (#6389). Closes #6394 Closes #6390 Closes #6389
bug-ops
force-pushed
the
feat/issue-6394/command-handoff-outcomes-skip
branch
from
July 17, 2026 20:39
defd6a8 to
a544766
Compare
8 tasks
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
Three follow-ups to spec-080 (cross-thread store + Command-style dynamic task handoff, PR #6363), combined into one PR as independent, unblocked, same-epic gap-closing changes.
TaskOutcome::Handoffnow carriestool_traceand gets the same completeness-verification treatmentCompletedoutcomes already had:handle_handoff_outcomeemitsSchedulerAction::CheckToolOutcomeunconditionally andSchedulerAction::Verifywhenverify_completenessis enabled. This also fixes a spawn-path gap found during this PR's own review: acommanded_from-linkedgototarget kept running after its source was post-hoc corrected toFailed, sincepropagate_corrected_task_failureonly walkeddepends_on-derived edges — closed via newdag::cancel_dangling_commanded_targets, scoped toPending/Readytargets only.TaskNode.handoff_rejectedis now surfaced in/plan status(CLI) and the TUI plan view's task row, instead of only being logged.ChannelMessagegains anowner_keyfield, threaded per-turn throughSessionState(mirrors the existingis_guest_contextpattern) and read by/storeand Command-handoff store I/O. Gateway and A2A dispatch paths now derive a real per-caller key (gateway:{sender},a2a:{context_id}) instead of collapsing to the shared"local"sentinel. CLI/TUI/Telegram/Discord/Slack/JSON-CLI are unchanged.Review notes
This PR went through a full two-round team-develop cycle: adversarial critique found 2 P2 findings and 1 P3 in the first pass; code review independently re-verified both P2s against the actual code before deciding severity, escalated the phantom-successor finding (#6394 spawn path) to merge-blocking after determining the correction chain that triggers it runs by default (not gated behind
verify_completenessas initially assumed), and approved on re-review after the fix landed.Known accepted, tracked-as-follow-up gaps (not fixed in this PR, documented in code comments and CHANGELOG.md):
owner_key/is_guest_contextcan go stale across a fast-path slash-command dispatch that skipsend_turn— pre-existing pattern, not a new hazard, no auth bypass (independently confirmed by security review).owner_keyinto the cross-thread store (only session-listing does).Closes #6394
Closes #6390
Closes #6389
Test plan
cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings— cleancargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins— 14173 passed, 0 failed, 35 skippedcargo +nightly fmt --check— cleanpropagate_corrected_task_failure_cancels_pending_commanded_from_target,propagate_corrected_task_failure_leaves_running_commanded_from_target_untouched).local/testing/playbooks/orchestration.mdand.local/testing/coverage-status.mdupdated (main repo) with live-testing scenarios for a future CI cycle