feat: add bounded fleet recaps and resilient supervision - #33
Merged
Merged
Conversation
Port the final upstream bearings stack tip state rather than serial-cherrying the conflicting kunchenguid#475/kunchenguid#485/kunchenguid#555/kunchenguid#640/kunchenguid#830/kunchenguid#875 family. New bin/fm-bearings-snapshot.sh projects fm-fleet-snapshot.sh into a bounded TOON-by-default fm-bearings.v1 view (local-only unless --include-prs). Rewrite .agents/skills/bearings to the four-section chat contract (Captain's Call / Recently Landed / Underway / Charted Next). Fork adaptations (not taking kunchenguid#593 decision-hold in this batch): - Soft-gate fm-afk-return.sh when absent. - Omit captain_actionable captain-hold surfaces; decisions_open uses fork status hints / last_event needs-decision|blocked text instead. - gates.blocked_by falls back to the string backlog.blocked_by field. Upstream provenance (tip family, newest first): - 5549834 kunchenguid#875 preserve trustworthy data in partial snapshots - f61e65c kunchenguid#830 surface main inventory gaps - c115561 kunchenguid#640 balance landed baseline - 8934c17 kunchenguid#555 authoritative secondmate state - 9ecd7c4 kunchenguid#485 concise and accurate bearings - a6508b7 kunchenguid#475 deterministic bounded bearings snapshots Tests: adapted core suite + decision-hold stub + blocked_by + chat contract. shellcheck clean on the new script.
(cherry picked from commit 593e3a2)
* fix(cmux): close the last/selected workspace in a window at teardown cmux keeps every window at >=1 workspace, so close-workspace on the only workspace in a window silently no-ops (returns OK, workspace stays), and a window holding a live session cannot be closed over the control socket. That left a selected task workspace open at teardown (the last workspace in a window is always the selected one). Add fm_backend_cmux_window_of_workspace and have fm_backend_cmux_kill create a throwaway default sibling in the target's window before closing when the target is the last workspace there, so the close lands; the window keeps a fresh default workspace (cmux's own "closed the last tab" outcome). Non-last teardown closes directly, as before. Cover both kill branches plus the helper with fake-CLI unit tests, add a real-cmux window/count detection smoke assertion, and record the empirical evidence in docs/cmux-backend.md. * no-mistakes(review): Derive cmux count from membership snapshot * no-mistakes(document): Document cmux last-workspace teardown behavior (cherry picked from commit 3f549c1)
(cherry picked from commit ad39e49)
…guid#520) * fix: recover X/Discord follow-up platform after inbox cleanup A milestone follow-up posted directly by request_id after the inbox was drained - and with no task link, because one persistent secondmate's single x_request slot collides across concurrent requests - resolved platform only from the local inbox, so a >280 Discord reply silently defaulted to the X 280-char budget and threaded as (1/2). - fm-x-poll records a durable per-request reply context (state/x-context/<rid>.json) at stash time, keyed by request_id so concurrent requests never overwrite each other; it survives inbox cleanup and restart. - fm-x-reply resolves platform/budget through registry -> inbox -> relay (the relay lookup confined to a live follow-up), recovering the original platform independent of task-link availability. - Fail-safe: a follow-up whose platform/budget cannot be authoritatively resolved and that would split is refused (exit 8) and held for retry, never wrongly split; fm-x-followup keeps the link on that exit. - fm-x-dismiss clears the durable context for a dismissed mention. Refactors reply-context extraction into a single owner and adds regression coverage for all four cases. * no-mistakes(review): Captain, fail closed on incomplete follow-up context * no-mistakes(review): Captain, bound X context registry retention * no-mistakes(review): Captain, align context retention with answer binding * no-mistakes(document): Align X follow-up context documentation * no-mistakes(document): Align durable X follow-up documentation (cherry picked from commit b708731)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
/ahoysession recap and rebuild/bearingsaround bounded, deterministic fleet snapshots covering main and secondmate work.Risk Assessment
✅ Low: The three requested behaviors are satisfied, the fixes are bounded and fail closed where retry metadata matters, and no additional material source regression was substantiated.
Testing
Completed 1 recorded test check.
Pipeline
Updates from git push no-mistakes
⏭️ **intent** - skipped
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 2 issues found → auto-fixed (6) ✅
bin/fm-bearings-snapshot.sh:448- Whenunresolved_blocker_idsis present but empty, the projection falls back to rawblocked_by, so completed dependencies are still reported as blockers. Fall back only when the normalized field is absent; apply the same fix to the secondmate mapping at line 460.bin/backends/cmux.sh:649- Teardown validates the expected label throughfm_backend_cmux_target_ready, whose workspace lookup is current-window-only. Tasks in another cmux window return before the new all-window membership helper runs, leaving their workspace open. Make expected-label validation window-aware before returning.🔧 Fix: Captain, fix blocker projection and cross-window cmux teardown
1 warning still open:
bin/fm-bearings-snapshot.sh:362- A structured secondmate home whose only open decision comes from the supportedneeds-decision/blockedstatus path is classified ascaptain_decisionbyfm-fleet-snapshot, but this projection recognizes only backlogcaptain-holdrows from the deliberately excluded feat: add durable captain decision holds kunchenguid/firstmate#593 path and downgrades the home tounknown. Preservecaptain_decisionfor supported status decisions and summarize those rows without adding feat: add durable captain decision holds kunchenguid/firstmate#593 behavior.🔧 Fix: Captain, preserve secondmate status decisions in bearings
1 warning still open:
bin/fm-bearings-snapshot.sh:399- The fix adds any secondmate with active children toin_flight, even when its aggregatebearings_stateiscaptain_decision, and hardcodes the duplicate row toactive_child_work. This conflicts with the changed Bearings contract that the four buckets are mutually exclusive and a secondmate’s own row appears Underway only foractive_child_work; decide whether mixed homes should remain solely captain-decision aggregates or whether the documented categorization should change.🔧 Fix: Captain, enforce exclusive secondmate bearings buckets
2 warnings still open:
bin/fm-fleet-snapshot.sh:552-registry_secondmates_jsonreads all ofdata/secondmates.mddirectly into jq and always reportsinput_truncated:falseandrecords_truncated:false; the advertisedFM_SNAPSHOT_REGISTRY_LINES,FM_SNAPSHOT_REGISTRY_BYTES, andFM_SNAPSHOT_REGISTRY_RECORDScontrols are not implemented. A large registry therefore bypasses the bounded-snapshot contract, while a read failure aborts the snapshot instead of producing the supportedavailable:falserecord. Add a bounded reader that reports truncation and converts read failures into availability metadata.bin/backends/cmux.sh:659- The all-window stale-ID fallback takes the first workspace matching the expected title, although cmux permits duplicate titles and uniqueness checks remain current-window-only. After ID churn, same-title workspaces in different windows can cause teardown to close an arbitrary duplicate. Collect all-window matches and fail closed on ambiguity, or enforce all-window uniqueness before title-based recovery.🔧 Fix: Captain, bound secondmate registry and harden cmux recovery
1 warning still open:
bin/backends/cmux.sh:695-fm_backend_cmux_window_of_workspacecollapses list/JSON failures into the same empty result as “not found”; teardown then skips creating the throwaway sibling and still callsclose-workspace. If the target is last in its window, cmux silently no-ops whilefm-teardown.shremoves task metadata, leaving an orphaned workspace. Distinguish scan failure from a verified non-last result and preserve or retry teardown instead of proceeding unverified.🔧 Fix: Captain, preserve cmux metadata on scan failure
4 warnings still open:
bin/fm-teardown.sh:1016- Forced cleanup propagates direct cmux child-kill failures, but the recursivecleanup_firstmate_home_children "$child_home"result remains unchecked. If a nested secondmate contains a cmux child whose scan fails, cleanup removes the nested home and metadata anyway, orphaning the deeper workspace. Propagate recursive cleanup and home-removal failures before deleting the parent record.bin/backends/cmux.sh:675- After all-window membership verifies the expected workspace,fm_backend_cmux_surface_id_for_workspacestill collapses failedlist-panesor invalid JSON into empty output, which teardown interprets as “target absent.” Kill then reports success and metadata is removed while the workspace remains live. Make surface lookup status-aware and return the retryable failure code for incomplete scans.bin/backends/cmux.sh:717- The fail-closed teardown path still masks a non-zeroclose-workspaceresult with|| true, so metadata is removed even when cmux reports that the workspace was not closed. Existing tests describe this as intentional best-effort behavior; confirm that intent, or propagate the failure so teardown remains retryable.bin/fm-fleet-snapshot.sh:567- The bounded reader captureshead -c limit+1through command substitution, which strips trailing newlines before${#input}checks the size. When bytelimit+1is a newline,input_truncatedremains false and later registry rows are silently omitted. Preserve the probe byte independently or determine truncation from file/read metadata.🔧 Fix: Captain, preserve nested cleanup and cmux retry state
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.