Problem
Task metadata has one lifecycle lock, but two Firstmate writers can bypass it. A remote secondmate spawn publishes <task>.meta after taking route-specific locks, and the Orca abort cleanup path can republish fallback metadata after worktree removal fails. Teardown takes the metadata lock before validating and retiring the task. A delayed writer can therefore restore metadata after teardown has retired the endpoint.
Observed behavior
The PR 68 standards review identified both unguarded writers and the absence of race coverage. Current main still contains the remote writer's explicit exclusion from fm_meta_lock_path and the equivalent Orca abort-recovery write.
Expected invariant
Every task-metadata write, replacement, and retirement participates in the same task-scoped metadata transaction. Once teardown has authoritatively retired a task, no delayed launch or abort path may republish metadata for that task. Ambiguous ownership preserves records instead of guessing.
Evidence and causal boundary
- Remote secondmate metadata is assembled and renamed without the metadata lock at
bin/fm-spawn.sh:756-792.
- Orca abort recovery can write
$STATE/$ID.meta without that lock at bin/fm-spawn.sh:987-1014.
- Teardown acquires
fm_meta_lock_path before metadata validation and cleanup at bin/fm-teardown.sh:220-225, then removes metadata while still in that lifecycle at :2726-2735.
- The source review identifies the same two gaps and their missing race tests at
data/pr68-standards-impact/report.md:7-23.
The causal boundary is the shared Firstmate task-metadata lifecycle in fm-spawn.sh and fm-teardown.sh. The exact timing needed to produce a republish-after-retirement race has not been exercised against a live endpoint, but the lock omission is source-proven.
Impact
Supervision can target a retired or foreign endpoint, fleet records can resurrect after cleanup, and later cleanup can act on stale ownership data. This can produce repeated recovery notifications or unsafe lifecycle decisions.
Relationship to existing work
PR #68 is merged and introduced the shared metadata-lock contract, but its review explicitly left these writers outside that contract. PRs #70 and #71 are merged adjacent remote/reporting and inbox changes; PR #72 is the separate away-composer fix. PR #69 is superseded and unrelated to this narrow lock boundary. Open issue #74 owns stale advisory supersession, not metadata publication. No issue in the complete dnth/firstmate history covers this writer race.
Acceptance criteria
- The remote secondmate metadata writer holds the canonical metadata lock through validation, temporary-file publication, rename, and post-write verification.
- The Orca abort-recovery republish path uses the same lock and cannot recreate metadata after teardown has retired the task; if ownership is uncertain it preserves the existing durable evidence and reports the refusal.
- Teardown and every other task-metadata writer share one documented lock/order contract, with no excluded writer comments remaining.
- Deterministic race tests cover remote publication versus teardown and Orca abort republish versus teardown, proving one authoritative outcome and no resurrection after retirement.
- Existing route-specific locks, endpoint identity checks, and unlanded-work protections remain intact.
Deterministic regression scenario
Use a temporary Firstmate home with a valid task record. Pause a remote metadata writer after route validation and before rename, run teardown to completion under the metadata lock, then release the writer; assert no metadata or endpoint record is recreated. Repeat with the Orca abort fallback while remove_worktree is blocked. Run the inverse ordering too, and assert the final metadata is either one current validated record or absent after confirmed teardown, never a stale republished record.
Problem
Task metadata has one lifecycle lock, but two Firstmate writers can bypass it. A remote secondmate spawn publishes
<task>.metaafter taking route-specific locks, and the Orca abort cleanup path can republish fallback metadata after worktree removal fails. Teardown takes the metadata lock before validating and retiring the task. A delayed writer can therefore restore metadata after teardown has retired the endpoint.Observed behavior
The PR 68 standards review identified both unguarded writers and the absence of race coverage. Current
mainstill contains the remote writer's explicit exclusion fromfm_meta_lock_pathand the equivalent Orca abort-recovery write.Expected invariant
Every task-metadata write, replacement, and retirement participates in the same task-scoped metadata transaction. Once teardown has authoritatively retired a task, no delayed launch or abort path may republish metadata for that task. Ambiguous ownership preserves records instead of guessing.
Evidence and causal boundary
bin/fm-spawn.sh:756-792.$STATE/$ID.metawithout that lock atbin/fm-spawn.sh:987-1014.fm_meta_lock_pathbefore metadata validation and cleanup atbin/fm-teardown.sh:220-225, then removes metadata while still in that lifecycle at:2726-2735.data/pr68-standards-impact/report.md:7-23.The causal boundary is the shared Firstmate task-metadata lifecycle in
fm-spawn.shandfm-teardown.sh. The exact timing needed to produce a republish-after-retirement race has not been exercised against a live endpoint, but the lock omission is source-proven.Impact
Supervision can target a retired or foreign endpoint, fleet records can resurrect after cleanup, and later cleanup can act on stale ownership data. This can produce repeated recovery notifications or unsafe lifecycle decisions.
Relationship to existing work
PR #68 is merged and introduced the shared metadata-lock contract, but its review explicitly left these writers outside that contract. PRs #70 and #71 are merged adjacent remote/reporting and inbox changes; PR #72 is the separate away-composer fix. PR #69 is superseded and unrelated to this narrow lock boundary. Open issue #74 owns stale advisory supersession, not metadata publication. No issue in the complete
dnth/firstmatehistory covers this writer race.Acceptance criteria
Deterministic regression scenario
Use a temporary Firstmate home with a valid task record. Pause a remote metadata writer after route validation and before rename, run teardown to completion under the metadata lock, then release the writer; assert no metadata or endpoint record is recreated. Repeat with the Orca abort fallback while
remove_worktreeis blocked. Run the inverse ordering too, and assert the final metadata is either one current validated record or absent after confirmed teardown, never a stale republished record.