Skip to content

fix: recover retained Pi tasks and release stale anchors - #367

Merged
ruby-dlee merged 4 commits into
mainfrom
fm/grievance-stale-delivery-f3
Aug 27, 2026
Merged

fix: recover retained Pi tasks and release stale anchors#367
ruby-dlee merged 4 commits into
mainfrom
fm/grievance-stale-delivery-f3

Conversation

@ruby-dlee

Copy link
Copy Markdown
Owner

Intent

Reconcile the two retained non-Azure Firstmate repairs fm-internal-prs-rebase-land-b7 and fm-run-bounded-perl-supervisor-leak against their briefs, artifacts, preserved commit graphs, durable no-mistakes state, and current public main so work progresses to delivery or exact evidence-backed closure rather than occupying capacity indefinitely. Preserve every unlanded commit, carry only still-required current changes onto this clean branch, restore truthful completion evidence, and use focused executable proof. Work the repairs sequentially and deliver the first still-required coherent change, recording the remaining internal-PR repair as an explicit next delivery unless exact evidence proves it safe to close. The bounded-command supervisor must exit a childless Perl process-group anchor when the controller finish pipe reaches EOF after command reap, retry only EINTR, preserve explicit guarded retention on unverified cleanup, preserve status and TERM/KILL semantics, and include deterministic exact-process regressions. Priority correction: first fix fm-spawn --recover-direct-account so legacy local Pi-authored retained ship/scout tasks recover their dead endpoint instead of rejecting harness=pi and masking the refusal with SPAWN_TASK_TMP unbound; reuse the task-private Pi author snapshot, prove the observed worktree belongs to the recorded project, adopt then recheck its exact Git-dir and branch/detached-head identity, upgrade metadata, preserve task context and existing Claude/Codex recovery, and add focused executable success and early-refusal regressions. Do not convert Azure cloud placement into a local endpoint. Do not clean ambient processes, add broad scans/reapers, weaken tests, restart shared services, push main, or merge a PR. Routine engineering fixes and iteration are authorized; escalate only destructive, irreversible, security-sensitive, credential, or product decisions.

What Changed

  • Recover legacy local Pi ship/scout endpoints using their task-private author snapshot while validating and upgrading exact worktree identity metadata.
  • Fail closed for missing Pi snapshots, project/worktree mismatches, and cloud placements, while preserving existing Claude and Codex recovery behavior.
  • Release childless bounded-command anchors on controller-pipe EOF while retaining guarded anchors when cleanup cannot be verified, with deterministic process regressions.

Risk Assessment

✅ Low: The changes preserve the required process-group lifecycle semantics and make legacy local Pi recovery fail closed when its task-private author snapshot is unavailable, with no additional source-verifiable defects found.

Testing

The successful baseline was supplemented with focused executable recovery and process-lifecycle checks: legacy local Pi recovery reused its task-private author snapshot and upgraded exact worktree identity, failed closed when that snapshot was missing, rejected Azure placement without the prior unbound-variable masking error, and the bounded runner exited its exact childless anchor on EOF while preserving signal/status and TERM/KILL cleanup semantics; reviewer-visible CLI transcripts were captured and all checks passed.

Evidence: Legacy Pi direct-recovery behavioral evidence
== tests/fm-account-directory.test.sh ==
ok - legacy local Pi recovery reuses its author snapshot and upgrades exact worktree identity
ok - legacy local Pi recovery fails closed without its task-private author snapshot
ok - early direct recovery refusal keeps abort cleanup bounded before task temp resolution
Evidence: Bounded process-tree lifecycle evidence
== tests/fm-process-tree.test.sh ==
ok - finish-pipe EOF exits the exact childless anchor without a PPID-1 group
ok - a signal after command reap exits promptly with verified cleanup
ok - real fm_run_bounded preserves status and cleans a TERM-resistant owned command
fm-process-tree tests passed

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 warning
  • 🚨 bin/fm-spawn.sh:3941 - The required behavior says legacy Pi recovery must “reuse the task-private Pi author snapshot,” but recovery only reuses it when the directory exists. If the original snapshot capture failed (an already-supported path that warns and launches) or the directory was later lost, this branch recreates it from the current ambient PI_CODING_AGENT_DIR/HOME and silently launches under potentially different credentials. Recovery should fail closed when the recorded task-private snapshot is unavailable instead of recapturing ambient identity; add an executable missing-snapshot refusal regression.

🔧 Fix: Captain: refuse recovery without Pi author snapshot
2 issues (1 error, 1 warning) still open:

  • 🚨 tests/fm-account-directory.test.sh:897 - The Pi author-identity repair lacks verified fail-before proof: the executor’s exact public check exited 0 at cd8b64d, so the new missing-snapshot regression has not demonstrated that it reproduces the authorized failure before the fix. Because this is an auth-permission boundary and the repair proof is explicitly unverified, obtain executable fail-before/pass-after evidence before merging.
  • ⚠️ bin/fm-spawn.sh - The fixer could not prove the semantic repair with a public/executable fail-before/pass-after regression and relevant integration or consumer compatibility evidence; primary-agent handoff is required.

🔧 Fix: Validate Pi recovery refusal
1 warning still open:

  • ⚠️ The fixer could not prove the semantic repair with a public/executable fail-before/pass-after regression and relevant integration or consumer compatibility evidence; primary-agent handoff is required.
✅ **Test** - passed

✅ No issues found.

  • if [ "${FM_AZURE_VALIDATION_CELL:-0}" = 1 ]; then exec "$FM_AZURE_VALIDATION_SHARD_BRIDGE" behavior --count "${FM_AZURE_VALIDATION_SHARD_COUNT:-8}"; else exec bin/fm-no-mistakes-test-command.sh; fi
  • Pre-phase baseline (already successful): if [ "${FM_AZURE_VALIDATION_CELL:-0}" = 1 ]; then exec "$FM_AZURE_VALIDATION_SHARD_BRIDGE" behavior --count "${FM_AZURE_VALIDATION_SHARD_COUNT:-8}"; else exec bin/fm-no-mistakes-test-command.sh; fi
  • FM_TEST_FOCUSED=pi-direct-recovery tests/fm-account-directory.test.sh
  • tests/fm-process-tree.test.sh
  • Manual evidence check: verified both captured transcripts and confirmed git status --short remained empty
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@ruby-dlee
ruby-dlee merged commit adf8666 into main Aug 27, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant