Skip to content

fix(bin): account for every registered secondmate in liveness sweep - #4989

Open
keenvc wants to merge 1 commit into
kunchenguid:mainfrom
keenvc:fm/fm-secondmate-liveness-gap
Open

keenvc wants to merge 1 commit into
kunchenguid:mainfrom
keenvc:fm/fm-secondmate-liveness-gap

Conversation

@keenvc

@keenvc keenvc commented Sep 20, 2026

Copy link
Copy Markdown

Problem

The session-start secondmate liveness sweep walked only state/<id>.meta records filtered to kind=secondmate. That made two classes of registered secondmate invisible to the sweep meant to guarantee they are running:

  • A secondmate registered in data/secondmates.md with no state/<id>.meta record was never enumerated at all.
  • A secondmate with a record but no recorded backend endpoint (window= empty) was silently skipped by the [ -n "$window" ] || return 0 guard.

Both are recovery-grade failures. Because the sweep reports healthy when it declines, the outage was invisible until a new secondmate happened to be requested on a project that already had two.

Fix

bin/fm-bootstrap.sh secondmate_liveness_sweep now enumerates the union of:

  • registered ids from data/secondmates.md (the durable "which secondmates exist" authority), and
  • kind=secondmate state/<id>.meta records,

deduplicated so a running registered secondmate is probed exactly once. A registered id with no record, or with a record that has no endpoint, is relaunched from its registry entry and persistent home via the existing bin/fm-spawn.sh <id> --secondmate recovery path. A relaunch that fails is reported as an explicit named gap:

SECONDMATE_LIVENESS: secondmate <id>: gap: <cause> and relaunch from registry failed: <error>

A meta record whose kind is not secondmate is not treated as the secondmate's endpoint, so a colliding task record cannot be probed.

Behavior preserved

  • Recovery still only authorizes dead / missing classifier states; ambiguous, unreadable, unverified-harness, and unreachable-remote targets remain skipped: with their reason.
  • Already-live and successfully relaunched secondmates stay silent by default.
  • A secondmate's own home still sees a silent no-op (it holds no kind=secondmate meta and registers no secondmates).

Tests

tests/fm-secondmate-liveness.test.sh extended with six cases:

  • a registered secondmate with no metadata record is recovered from the registry, not passed over;
  • a record with no recorded endpoint is recovered rather than skipped;
  • an unrecoverable registered secondmate (relaunch fails) is named as a gap;
  • a registered secondmate whose home is not seeded is named as a gap;
  • a registered id with a live record is probed once and never relaunched;
  • a kind=secondmate record absent from the registry is still accounted for.

All existing cases in the file pass, plus fm-bootstrap, fm-session-start, fm-secondmate-sync, fm-bootstrap-network-parallel, fm-remote-secondmate-lifecycle-e2e, fm-secondmate-lifecycle-e2e, and fm-secondmate-safety. bin/fm-doc-audience-check.sh passes.

Docs

Updated the owned prose in AGENTS.md, docs/configuration.md, .agents/skills/bootstrap-diagnostics/SKILL.md, and .agents/skills/secondmate-provisioning/SKILL.md so the documented contract matches the enforced behavior.

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