Research — Canonical-State Integrity & Recovery (#4758, #4786)
Phase 0. Two profile-loaded opus grounding lenses reproduced live on HEAD b17f199576 (repo tree untouched). Full transcripts summarized here; this is the authoritative research the plan builds on.
Verdicts
- #4758 — REAL P0, unfixed, distinct from #4075 (failure-path txn ordering), #2802 (flattened-topology commit dest), #3311 (rerun rewrites existing lanes — opposite mode; its guard partly seals #4758's wedge). Reproduced live:
agent tasks finalize-tasksseedsgenesis→plannedevents with nolanes.json, thenmove-task --to doingsucceeds (planned→in_progress) with lanes still absent. - #4786 — PARTIAL; P0 "unclearable" framing is stale. Attribution-drop reproduces (bare rejection →
agent=null→ accept blocks atsummary_core.py:87), but is clearable viamove-task --to <lane> --agent <x>(±--force) — #3029 remedy-1, shipped ine455ce26c1. Two of four "broken remedies" already fixed (--agentretrofit;merge --dry-runOptionInfo crash does not reproduce via CLI, #4723 wrapped it). Scar tissue: same spot patched by #2512/#2960/#4673. Taken as full structural fix per operator ruling.
Seam map (file:line, HEAD b17f199576)
Canonical runtime state — the object
src/specify_cli/status/models.py:535-551—WPInnerStateDeltascalar family:shell_pid,shell_pid_created_at,agent,assignee,role,agent_profile,agent_profile_version,model,provider. Claim triple = agent + shell_pid + shell_pid_created_at.models.py:569release_runtime_claim: bool— explicit "clear the claim triple" signal;:579-588_SCALAR_FIELDSSSOT;:590-603guards a bareagent=""no-op.- Reducer folds latest-wins;
release_runtime_claimclears BEFORE the replace-slot loop, so a concrete value in the same delta overrides the clear.
#4758 — lanes.json minting split
src/specify_cli/cli/commands/agent/tasks_finalize.py:271—bootstrap_canonical_state(...), no_compute_and_write_lanesanywhere in the file. Docstring: "this legacy command family."src/specify_cli/cli/commands/agent/mission_finalize.py:2819→:2829— canonical path bootstraps THEN_compute_and_write_lanes(both writes co-located = correct).src/specify_cli/lanes/persistence.py:111require_lanes_json— file-existence gate; reached on approval/implement/owned-review (context/resolver.py:262,implement.py:1393,workspace/context.py:873,tasks_move_task.py:642) but NOT onmove-task --to doing.src/specify_cli/cli/commands/agent/mission_finalize.py:2039_execution_has_begun(lane-state) +:2210-2230refusal (execution begun AND lanes absent →typer.Exit(1)). Docstring asserts this "should never reach" — #4758 falsifies it.- Rollback refusal:
src/specify_cli/cli/commands/agent/tasks_transition_core.py:407-423WP_METADATA_UNSUPPORTED_ON_PROTECTED_COORD_BRANCH.
#4786 — attribution drop
src/specify_cli/acceptance/summary_core.py:86-98— accept gate.agentrequired on every lane (:87);assignee(:96)/shell_pid(:98) only for active lanes{doing,in_progress,for_review}(terminal exempt, #2369).strict_metadatatoggles;accept --lenientdowngrades all to advisory.src/specify_cli/cli/commands/agent/tasks_move_task.py:2891—release_runtime_claim=Trueon any rollback→planned (_build_claim_review_override, ~2838-2898).tasks_move_task.py:2970-2978— same-identity suppression: a same-actor restamp on a PLANNED target is suppressed so the release wins; passing--agenton a non-planned transition re-stamps (why the retrofit works).src/specify_cli/status/doctor.py:215-240— ALREADY DETECTS blanked runtime slots (#2960) but offers no repair — detect-without-cure.src/specify_cli/status/wp_metadata.py:437-505resolved_agent()— dispatch-time family resolution.
Existing recovery surfaces (extend, don't invent)
src/specify_cli/cli/commands/agent/mission_repair.py— cross-partition (coord vs primary) ff-reconciliation only (_classify_repair_state:69). Does NOT rebuild lanes.json or repair attribution.doctor coordination --fix(_coordination_doctor.py),doctor mission-state --fix→repair_repo(migration/mission_state.py:518, JSON-shape canonicalization),lanes/recovery.py(worktree crash-recovery only). None rebuild lanes-from-log or attribution.
Triple-authority (the wedge mechanism)
"Has lanes / execution begun" answered by three non-coincident authorities: require_lanes_json (file-existence) vs _execution_has_begun (lane-state) vs ~20 soft read_lanes_json→None sites. Their disagreement mints the unrecoverable state. Top brownfield fold: one "execution-ready" predicate.