Persist derived machine states for agent manifests so downstream monitors can distinguish working, blocked, degraded, and finished-cleanable lanes without inferring everything from prose. This also records commit provenance in terminal-state manifests and marks the new session-state classification roadmap item as done.
Constraint: Keep the change scoped to manifest persistence and tests without introducing a new monitoring service layer
Rejected: Leave state classification as downstream text scraping only | repeated dogfood runs showed quiet/finished lanes being misreported as stale
Confidence: medium
Scope-risk: narrow
Directive: Reuse derived_state + commit provenance from manifests before adding any new stale-session heuristics elsewhere
Tested: python .github/scripts/check_doc_source_of_truth.py
Tested: cd rust && cargo fmt --all --check
Tested: cd rust && cargo test -q -p tools
Tested: cd rust && cargo clippy -p tools --all-targets --no-deps -- -D warnings
Not-tested: full cargo clippy --workspace --all-targets -- -D warnings still fails on unrelated pre-existing runtime lint debt
Add MCP structured degraded-startup classification (P2.10):
- classify MCP failures as startup/handshake/config/partial
- expose failed_servers + recovery_recommendations in tool output
- add mcp_degraded output field with server_name, failure_mode, recoverable
Canonical lane event schema (P2.7):
- add LaneEventName variants for all lifecycle states
- wire LaneEvent::new with full 3-arg signature (event, status, emitted_at)
- emit typed events for Started, Blocked, Failed, Finished
Fix let mut executor for search test binary
Fix lane_completion unused import warnings
Note: mcp_stdio::manager_discovery_report test has pre-existing failure on clean main, unrelated to this commit.
Implement automatic lane completion detection:
- detect_lane_completion(): checks session-finished + tests-green + pushed
- evaluate_completed_lane(): triggers CloseoutLane + CleanupSession actions
- 6 tests covering all conditions
Bridges the gap where LaneContext::completed was a passive bool
that nothing automatically set. Now completion is auto-detected.
ROADMAP P1.3 marked done.