Reflection follow-up: subagent post-PR PATCH must flip status:in_progress atomically with branch/pr_number writes
failedAgent: will-engineer
Priority: 2
Branch:
wilbo/atomic-status-patch-on-pr-openPR: #551
Linear: ALL-1993
## Problem
Canonical-store query on 2026-06-24 04:05 UTC reflection cron surfaced two fleet-tasks with `branch` and `pr_number` fields populated but `status` still `queued`:
- `e66b208e` (ALL-1873 PR-4): branch=wilbo/all-1873-drc-ui-entrypoint, pr=12704
- `10e9e587` (ALL-1875 PR-5): branch=wilbo/all-1875-merge-ui, pr=12707
Both PRs are OPEN/MERGEABLE/REVIEW_REQUIRED in Will's queue. The subagent fan-out on 2026-06-23 18:36 UTC opened the PRs and PATCHed metadata, but never PATCHed status. Row becomes internally incoherent: PR URLs present, status claims 'not started'. `fleet-resume.sh` reports these as queued (action: pick up), but they're not pickable — the work shipped, they're parked for review.
Same failure-class as the 6/22 reflection's read-side gap (LEARNINGS 2026-06-22), but on the WRITE side. Read-side audits cannot detect a row whose own fields disagree with each other unless the audit specifically cross-references them.
## Fix (acceptance criteria)
1. **Subagent task template (the one used by `sessions_spawn` for PR-shipping subagents) MUST emit a PATCH that includes `status: in_progress` whenever it sets `branch` or `pr_number`.** Single atomic PATCH:
```json
{"status": "in_progress", "branch": "wilbo/...", "pr_number": <N>}
```
2. Update AGENTS.md Phase 2 (Execute with Sub-Agents) to document this explicitly: 'opening a PR is the state-transition queued→in_progress; the PATCH that records branch/pr_number must include status: in_progress in the same request.'
3. (Optional, defensive) Write a small `bin/fleet-task-coherence-check.sh` that scans all queued tasks and flags any with non-null `pr_number`. Could be wired into heartbeat STEP 1.x. Not required for this task to close, but a candidate follow-up.
## Out of scope
- Auto-fixing the canonical store retroactively (the two divergent rows from 6/23 already PATCHed manually in the 6/24 reflection cron — see memory/2026-06-24.md).
- Status flips on PR merge (that flow works correctly today — `completed` already fires via a different code path).
## Evidence pointers
- LEARNINGS.md 2026-06-24 entry (deepest learning section)
- LEARNINGS.md 2026-06-22 entry (read-side variant — the dual of this)
- AGENTS.md Phase 2 (current sub-agent workflow)
Event Timeline
created
status_change
queued → in_progress
failed
lease expired — re-queued for retry
in_progress → queued
status_change
queued → in_progress
failed
lease expired — re-queued for retry
in_progress → queued
status_change
queued → in_progress
failed
lease expired — max retries reached, marking failed (poison pill)
in_progress → failed