Skip to content

fix(bin): speed local Bearings snapshot composition - #3499

Open
kunchenguid wants to merge 11 commits into
mainfrom
fm/fm-bearings-local-snapshot-cost-r1
Open

fix(bin): speed local Bearings snapshot composition#3499
kunchenguid wants to merge 11 commits into
mainfrom
fm/fm-bearings-local-snapshot-cost-r1

Conversation

@kunchenguid

@kunchenguid kunchenguid commented Sep 2, 2026

Copy link
Copy Markdown
Owner

api_response:
body: "## Intent\n\nCut local Bearings snapshot-composition cost from ~13-16s to under 5s on a large home by fixing the dominant local hot paths in fm-fleet-snapshot.sh/fm-bearings-snapshot.sh (large-backlog parse, per-task reads, scout-report scan, repeated jq), with the fm-bearings.v1 projection output identical apart from timestamps; behavioral test bounds local composition on a synthetic large backlog\n\n## What Changed\n- Collect local task state and endpoint observations concurrently with configurable worker limits.\n- Capture task metadata up front and discard mutable observations when task generations change during composition.\n- Stream large JSON inventories through jq, reduce repeated subprocess parsing, and add regression coverage for large backlogs, teardown races, and projection stability.\n\n## Risk Assessment\n\n✅ Low: The generation-bound observation fixes are coherent, preserve stable-state projection behavior, and introduce no additional source-verifiable defects.\n\n## Testing\n\nTargeted Bearings and backend behavior tests passed; an end-to-end 305-row fixture composed the public fm-bearings.v1 snapshot in 2 seconds with byte-identical serial/concurrent projections, while the base commit reproduced the regression at 7 seconds. Reviewer-visible JSON and benchmark logs were captured, and the worktree was left clean.\n\n

\nEvidence: Large-local Bearings benchmark and projection identity\n\nSource: Large-local Bearings benchmark and projection identity\n\ntext\nevidence - elapsed_seconds=2 synthetic_backlog_rows=305 in_flight=5 landed_visible=6 serial_sha256=e95621240a81331d083d1d500951e2d31c389079cd5db0d537cc57554ccddf27 parallel_sha256=e95621240a81331d083d1d500951e2d31c389079cd5db0d537cc57554ccddf27 schema=fm-bearings.v1\nok - large local snapshot stays under five seconds with byte-identical serial and concurrent projections\n\n
\n
\nEvidence: Rendered fm-bearings.v1 JSON from the synthetic large home\n\nSource: Rendered fm-bearings.v1 JSON from the synthetic large home\n\ntext\n{\n \"schema\": \"fm-bearings.v1\",\n \"home\": \"fm-bearings.QUhyDl/large-local-snapshot\",\n \"generated\": \"2026-07-11T18:00:00Z\",\n \"prs\": \"not_requested (run: /bearings include PRs)\",\n \"in_flight\": [\n {\n \"id\": \"local-1\",\n \"kind\": \"ship\",\n \"state\": \"unknown\",\n \"doing\": \"harness state unavailable (unknown missing)\"\n },\n {\n \"id\": \"local-2\",\n \"kind\": \"ship\",\n \"state\": \"unknown\",\n \"doing\": \"harness state unavailable (unknown missing)\"\n },\n {\n \"id\": \"local-3\",\n \"kind\": \"ship\",\n \"state\": \"unknown\",\n \"doing\": \"harness state unavailable (unknown missing)\"\n },\n {\n \"id\": \"local-4\",\n \"kind\": \"ship\",\n \"state\": \"unknown\",\n \"doing\": \"harness state unavailable (unknown missing)\"\n },\n {\n \"id\": \"local-5\",\n \"kind\": \"ship\",\n \"state\": \"unknown\",\n \"doing\": \"harness state unavailable (unknown missing)\"\n }\n ],\n \"secondmates\": [],\n \"secondmate_reconcile\": [],\n \"decisions_open\": [],\n \"landed\": [\n {\n \"id\": \"history-99\",\n \"what\": \"Historical completed item 99\",\n \"artifact\": \"https://github.com/acme/firstmate/pull/99\",\n \"owner\": \"(main)\"\n },\n {\n \"id\": \"history-98\",\n \"what\": \"Historical completed item 98\",\n \"artifact\": \"https://github.com/acme/firstmate/pull/98\",\n \"owner\": \"(main)\"\n },\n {\n \"id\": \"history-97\",\n \"what\": \"Historical completed item 97\",\n \"artifact\": \"https://github.com/acme/firstmate/pull/97\",\n \"owner\": \"(main)\"\n },\n {\n \"id\": \"history-96\",\n \"what\": \"Historical completed item 96\",\n \"artifact\": \"https://github.com/acme/firstmate/pull/96\",\n \"owner\": \"(main)\"\n },\n {\n \"id\": \"history-95\",\n \"what\": \"Historical completed item 95\",\n \"artifact\": \"https://github.com/acme/firstmate/pull/95\",\n \"owner\": \"(main)\"\n },\n {\n \"id\": \"history-94\",\n \"what\": \"Historical completed item 94\",\n \"artifact\": \"https://github.com/acme/firstmate/pull/94\",\n \"owner\": \"(main)\"\n }\n ],\n \"gates\": [],\n \"reports\": [],\n \"recorded_prs\": [],\n \"omitted\": [\n {\n \"surface\": \"backlog item bodies\",\n \"reveal\": \"--fields bodies\"\n },\n {\n \"surface\": \"task paths\",\n \"reveal\": \"--fields paths\"\n },\n {\n \"surface\": \"watch/steer actions\",\n \"reveal\": \"--fields actions\"\n },\n {\n \"surface\": \"healthy endpoint detail\",\n \"reveal\": \"--fields endpoints\"\n },\n {\n \"surface\": \"full scout-report inventory\",\n \"reveal\": \"--all-reports\"\n },\n {\n \"surface\": \"superseded or prose-deferred queued items\",\n \"reveal\": \"--all-queued\"\n },\n {\n \"surface\": \"landed per-home capped at 6 for 1 home(s)\",\n \"reveal\": \"--all-landed\"\n },\n {\n \"surface\": \"live PR discovery + checks\",\n \"reveal\": \"--include-prs\"\n }\n ]\n}\n\n
\n
\nEvidence: Base-commit regression reproduction\n\nSource: Base-commit regression reproduction\n\ntext\nnot ok - five local current-state reads exceeded the local composition target (7s)\nbase_commit_test_exit=1 (nonzero expected; old serial implementation exceeds target)\n\n
\n
\nEvidence: Targeted Bearings behavior suite transcript\n\nSource: Targeted Bearings behavior suite transcript\n\ntext\nok - task teardown during metadata capture is omitted without aborting the snapshot\nok - reused live state is discarded when task generation changes\nok - large local snapshot stays under five seconds with byte-identical serial and concurrent projections\nok - remote ledgers collect concurrently under one budget, reuse aged cache, and cancel wedged collectors\nok - a missing remote ledger stays explicitly unreadable without remote summary computation\nok - Domain Alpha structured state overrides a stale parent Phase 7 event\nok - GNU stat file reads select -c without BSD filesystem-report pollution\nok - parent activity evidence is bounded and disclosed\nok - Bearings excludes a status-only child decision\nok - a structured child captain hold reaches Captain's Call\nok - missing, invalid, unreadable, malformed, and unavailable-child homes stay explicit unknowns\nok - oversized ledgers stay strict unknown\nok - secondmate and per-home child counts are bounded, disclosed, and explicitly expandable\nok - parent decisions remain untrusted contradiction evidence\nok - parent evidence reconciliation distinguishes matching holds, blocks, and decisions\nok - nonprogressing child states are explicit and inconsistent terminal rows invalidate\nok - registry unavailability and bounded truncation remain explicit\nok - repeated snapshots keep the same current landed baseline and ignore prior reports\nok - default output is bounded, local-only, and marks omitted surfaces\nok - TOON and JSON are parity representations of the same model\nok - landed includes secondmate-managed merges alongside main-home merges\nok - default landed selection balances one dominant home with sparse homes\nok - landed selection refills capacity after sparse homes exhaust\nok - landed selection uses deterministic home order when homes exceed the cap\nok - landed selection preserves deterministic home and internal tie ordering\nok - landed selection handles no landed items\nok - --all-landed keeps the complete global landed output\nok - landed stays bounded with per-home + overall caps and omitted[] disclosure\nok - Bearings keeps a live blocker in structured live state and never converts it to Charted Next queue work\nok - action-free items (working/done/queued/landed) do not leak into Captain's Call\nok - main orphan in-flight stays out of Underway and is disclosed in omitted/gates\nok - main unstructured current is disclosed while structured siblings still project\nok - counterfactual meta clears main inventory warning and projects the live task\nok - mixed secondmate roles, partial state, and captain readiness project independently\nok - main and secondmate captain actionability use the same blocker readiness\nok - a completed scout with decision-like report prose is a pointer, not pending\nok - an authoritative captain hold surfaces end-to-end\nok - current report pointers surface\nok - superseded queued items are dropped by default and restored with --all-queued\nok - --include-prs is the only path that fetches, and it enriches correctly\nok - a partial GitHub failure degrades gracefully\nok - Perl fallback bounds stalled GitHub calls without coreutils timeout\nok - all fleet-sized sections are capped with counted opt-in expansion\nok - captain-held tasks of any kind reach Captain's Call, deferral is honored, and landed excludes answered calls\nok - live PR enrichment caps repositories with counted expansion\nok - per-repository open-PR caps are disclosed with an expansion knob\nok - projection and TOON rendering failures exit nonzero with diagnostics\n\n
\n
\nEvidence: Targeted backend metadata behavior suite transcript\n\nSource: Targeted backend metadata behavior suite transcript\n\ntext\nok - fm_backend_name: FM_BACKEND env > config/backend > default tmux\nok - fm_backend_detect: no markers -> undetected, HERDR_ENV=1 -> herdr, $TMUX -> tmux, CMUX_WORKSPACE_ID -> cmux, nested combinations resolve innermost-first\nok - fm_backend_detect: falls back to __CFBundleIdentifier=com.cmuxterm.app when CMUX_WORKSPACE_ID is absent (signal bundle-id; foreign bundle ids rejected)\nok - fm_backend_detect: the cmux fallback signals are macOS-only (inert on a non-Darwin uname)\nok - fm_backend_detect: an inherited cmux bundle id never outranks $TMUX or HERDR_ENV (tmux/herdr-inside-cmux false positive absorbed)\nok - fm_backend_detect: ancestry fallback matches the lsappinfo-resolved (bundle-id) cmux app pid in the parent chain\nok - fm_backend_detect: ancestry fallback matches a bundle-shaped cmux comm path at any install location when lsappinfo cannot resolve a pid\nok - fm_backend_detect: ancestry fallback stops undetected at launchd (a reparented tmux server never reaches cmux)\nok - fm_backend_name: a fallback-detected cmux prints a NOTICE naming the fallback signal; the primary-marker notice is unchanged\nok - fm_backend_name: auto-detect selects herdr or cmux (loud notice) or tmux (silent, including nested tmux-in-herdr/tmux-in-cmux)\nok - fm_backend_name: an explicit FM_BACKEND or config/backend setting always wins over runtime auto-detection, including an ambient cmux marker\nok - fm_backend_validate: implemented adapters accepted, unknown and blocked codex-app backends refused loudly\nok - zsh: fm_backend_source recognizes known backends and rejects unknown ones\nok - bash: fm_backend_source recognizes known backends and rejects unknown ones\nok - fm_backend_validate_spawn: all implemented lifecycle backends are spawn-supported\nok - fm_meta_get / fm_backend_of_meta: read last key=value and default backend to tmux\nok - fm_backend_resolve_selector: session:window literal, exact task id first, legacy fm-<id> label fallback, ad hoc bare name via tmux list-windows\nok - fm_backend_of_selector: exact task ids, legacy fm-<id> labels, and matching explicit targets inherit metadata backend\nok - fm-send.sh: explicit tmux targets are verified; text types once and submits with Enter\nok - fm-peek.sh: capture-pane invocation and output are byte-identical old vs new\nok - fm-spawn.sh: a project reached through a symlinked prefix (e.g. macOS /tmp -> /private/tmp) does not trip the isolation guard's false refusal\nok - fm-teardown.sh: treehouse return remains compatible while tmux cleanup uses exact selectors\nok - fm-spawn.sh --backend bogus is refused loudly\nok - fm-spawn.sh --backend codex-app is refused\nok - fm-spawn.sh honors FM_BACKEND and refuses an unimplemented value loudly\nok - fm-spawn.sh: an explicit --backend tmux resolves silently and writes no backend= (missing means tmux)\nok - fm-spawn.sh: explicit --backend tmux wins over an ambient HERDR_ENV=1 auto-detect marker\nok - fm-spawn.sh: auto-detect resolves nested tmux-in-herdr to tmux and stays silent end to end\n\n
\n\n## Pipeline\n\nUpdates from git push no-mistakes\n\n\n\n
\nintent - passed\n\n✅ No issues found.\n
\n\n
\nRebase - passed\n\n✅ No issues found.\n
\n\n
\n🔧 Review - 2 issues found → auto-fixed (2) ✅\n\n- 🚨 bin/fm-fleet-snapshot.sh:562 - Task metadata is globbed once during prefetch and again during rendering. If a spawn atomically publishes a new state/<id>.meta while the multi-second prefetch is running, the second loop includes it but no corresponding temporary observation exists; line 600 then fails the entire snapshot. Capture one metadata manifest before prefetch and use that same manifest for both observation and rendering so concurrent publication is deferred to the next snapshot.\n- 🚨 bin/fm-fleet-snapshot.sh:1817 - The required intent explicitly calls for fixing the “large-backlog parse, per-task reads, scout-report scan, repeated jq” hot paths, but this branch only changes metadata reads and concurrent task observations. The backlog parser, scout-report pipeline (including per-report dirname/basename/jq), and repeated per-task jq processing remain unchanged; the new timed fixture also contains no scout reports. Confirm whether the named hot paths are mandatory or authorize narrowing the stated intent.\n\n🔧 Fix: Stabilize task inventory during concurrent snapshot composition\n1 error still open:\n\n- 🚨 bin/fm-fleet-snapshot.sh:1815 - The required goal explicitly calls for fixing the “large-backlog parse, per-task reads, scout-report scan, repeated jq” hot paths, but this change only optimizes metadata access and concurrent task observations. The backlog parser is unchanged, scout_report_lines still launches basename/dirname/jq per report, and numerous per-task jq invocations remain; the timing fixture also creates no scout reports. Confirm that narrowing the required scope is acceptable, or implement and behaviorally exercise the remaining named hot paths.\n\n- 🚨 bin/fm-fleet-snapshot.sh:674 - The captured status event retains the original live path, which secondmate_current_json later reopens at lines 1601-1607; terminal_evidence_json can likewise probe the reusable endpoint after prefetch validation. If a secondmate is relaunched after prefetch completes, replacement status activities, mtime, or terminal output can be attributed to the captured generation and alter reconciliation/contradiction fields. Keep generation-bound observations through secondmate composition, and collect or revalidate every late status/terminal read at the prefetch generation boundary.\n- 🚨 bin/fm-fleet-snapshot.sh:525 - Every task report is copied in full even though rendering only tests whether the captured path exists. A large report now adds unbounded I/O and temporary-disk consumption, while an unreadable or space-exhausting report aborts a snapshot that previously only checked presence—directly undermining the under-five-second composition goal. Record a generation-validated presence marker instead of copying report contents.\n\n🔧 Fix: Keep secondmate observations generation-bound without copying reports\n✅ Re-checked - no issues remain.\n
\n\n
\nTest - passed\n\n✅ No issues found.\n- tests/fm-backend.test.sh\n- /usr/bin/time -p tests/fm-bearings-snapshot.test.sh (initially reproduced the 5-second failure; passed after reducing repeated per-task process work)\n- End-to-end bin/fm-bearings-snapshot.sh --json run with 300 completed backlog rows, five local workers, and one-second delayed status reads; compared serial and concurrent outputs byte-for-byte\n\n✅ No issues found.\n- Inspected git diff 521de54cb964125e1544f8ff36f4ba695d034c13..97786e1cedffdf75d5767810fccf9c94c79ab3a2 and worktree status.\n- /bin/bash tests/fm-bearings-snapshot.test.sh\n- /bin/bash tests/fm-backend.test.sh\n- Executed the focused large-local snapshot test against the target with 300 completed rows, five delayed local workers, fixed timestamps, and FM_SNAPSHOT_LOCAL_READ_CONCURRENCY=8; captured the public JSON projection and timing.\n- Executed the same focused performance regression against base commit 521de54cb964125e1544f8ff36f4ba695d034c13; it reproduced the old failure at 7 seconds.\n- Validated the captured artifact with jq -e and removed transient worktree harnesses and the archived baseline fixture.\n
\n\n
\nDocument - passed\n\n✅ No issues found.\n\n✅ No issues found.\n
\n\n
\nLint - passed\n\n✅ No issues found.\n\n✅ No issues found.\n
\n\n
\nPush - passed\n\n✅ No issues found.\n\n✅ No issues found.\n
"
truncated: false

@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Reviews (7): Last reviewed commit: "no-mistakes(document): Document generati..." | Re-trigger Greptile

Comment thread bin/fm-fleet-snapshot.sh Outdated
Comment thread bin/fm-fleet-snapshot.sh Outdated
Comment thread bin/fm-fleet-snapshot.sh Outdated
Comment thread bin/fm-fleet-snapshot.sh Outdated
Comment thread bin/fm-fleet-snapshot.sh Outdated
…patible with stock macOS Bash 3.2, snapshotting task metadata before concurrent observations to prevent generation drift, strengthening the behavioral race regression, and updating the stock-Bash Bearings test count to 45. Verified fleet snapshot tests (15), Bearings tests (45), workflow lint tests, project lint, Bash 3.2 parsing, and diff checks
…acklog/task JSON through jq command-line arguments, which exceeded the per-argument size limit. Both inventory projections now stream large JSON inputs through stdin. Verified with fm-bearings-snapshot.test.sh (45 tests), fm-fleet-snapshot-view.test.sh (15 tests), Bash syntax, and git diff checks
…re: vanished metadata is now omitted while genuine copy failures remain fatal. Added a deterministic public Bearings regression test and updated CI’s expected test count. Verified with the full Bearings suite, workflow-lint suite, Bash syntax checks, and git diff checks
… fleet JSON through jq stdin to avoid Linux argument limits, kept crew-state reads bound to captured metadata generations, and strengthened the behavioral race test. Bearings (46 tests), fleet snapshot (15 tests), crew-state, backend, lint, Bash syntax, and diff checks pass locally. Serial shard 5’s unrelated task-inbox segmentation fault appears infrastructural/flaky
…ng captured spawn_gen before and after local endpoint probes, falling back to exact metadata identity for legacy tasks. Stale probe results now become unknown instead of false unhealthy state. Added a behavioral relaunch-race regression test. Verified the full Bearings snapshot suite, shellcheck, bash syntax, and git diff checks
@kunchenguid
kunchenguid force-pushed the fm/fm-bearings-local-snapshot-cost-r1 branch from bb1ad3d to 3b3e751 Compare September 2, 2026 07:08
@kunchenguid kunchenguid changed the title fix(bin): speed up local Bearings snapshot composition fix(bin): speed local Bearings snapshot composition Sep 2, 2026
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