feat: route crew by quota pace and rearm Pi watchers - #10
Conversation
* fix(pi): rearm watcher across same-process session transitions Pi emits session_shutdown for ordinary /new, /resume, and /fork replacement as well as terminal quit. The primary watcher extension latched a module-level stopping flag on every shutdown, so a replacement session in the same process could not arm monitoring until Pi restarted. Own arm authority per session generation so only the active live generation may start, stop, or rearm the child. Replacement sessions can arm again without restarting Pi, stale prior-generation callbacks cannot mutate the active cycle, and real quit still blocks late rearm. * no-mistakes(review): Preserve Pi generation isolation and exit cleanup * no-mistakes(document): Correct Pi watcher transition documentation
* Consume quota-axi pace signals in dispatch profile array selection. Add quota-array-dispatch as the single owner of the pace-aware candidate choice, keep AGENTS.md to the intake boundary and load trigger, and cover the acceptance cases with sanitized schemaVersion 3 fixtures. * no-mistakes(review): Stop and report genuine quota dispatch ties * no-mistakes(document): Document quota pace freshness and uncertainty
Brings in the two upstream commits this fork lacked: - fa0d85d feat: route crew dispatch using quota-window pace (kunchenguid#1172) - 9ea1a1a fix(pi): rearm watcher across session transitions (kunchenguid#1166) (b29621b, the pi-signed runtime adapter, was already present via the earlier sync merge 94ca122.) One conflict, in docs/watcher-continuity.md's regression-coverage list: our #8 rewrote the fm-watcher-lock and fm-claude-stop-autoarm lines while upstream inserted a new fm-pi-watch-extension line immediately above them. The two sides are additive, not contradictory - they describe different layers - so both survive, each sentence kept adjacent to the suite it describes.
|
Two facts discovered after the PR body was generated. 1. Review finding approved, deliberately not fixed (upstream defect, carried verbatim) The review step raised one warning in The finding is real, but it was approved rather than fixed, on two grounds:
It is a candidate to raise upstream, tracked separately. 2. No CI checks ran on this PR - Actions is disabled on this fork
Relatedly, the pipeline's lint step reported ShellCheck missing (exit 127) and passed vacuously for the same reason. The lint evidence in the body comes from a separate run against the pinned ShellCheck 0.11.0 fetched for exact CI parity, which was clean. |
Intent
Sync the captain's knowttl/firstmate fork with its upstream template kunchenguid/firstmate, bringing in the two upstream commits the fork lacked: fa0d85d 'feat: route crew dispatch using quota-window pace (kunchenguid#1172)' and 9ea1a1a 'fix(pi): rearm watcher across session transitions (kunchenguid#1166)'. (A third pinned commit, b29621b pi-signed runtime adapter, was already present via the earlier sync merge 94ca122, so it is correctly absent from this diff.) This is deliberately a MERGE, never a rebase or reset of main: the fork is ahead with its own commits (PRs #6/#7/#8 and prior sync merges) and ALL of them are kept, matching how prior syncs were done (see merge 3827d75). The merge-commit shape is a hard requirement - if the pipeline's rebase step cannot preserve it, that must stop and escalate rather than silently flatten the merge. The captain explicitly scoped this as a sync-only PR under standing scope discipline. Exactly one conflict occurred, in docs/watcher-continuity.md's regression-coverage list: our PR #8 rewrote the fm-watcher-lock and fm-claude-stop-autoarm coverage lines while upstream 9ea1a1a inserted a new fm-pi-watch-extension coverage line immediately above them. The two sides are additive and describe different layers, not contradictory, so the resolution deliberately KEEPS BOTH, ordering each sentence adjacent to the suite it describes. This was verified against shipped code, not just prose: our delivering-close prints the wake reason on its own line and the Pi extension's actionableLine/classifyClose classifies a close by that reason line, while upstream's change only gates which session generation may act and never touches classification - so a delivering close still restores continuity correctly under the new generation ownership. Verification already done locally: bin/fm-lint.sh clean at exact CI parity with the pinned ShellCheck 0.11.0, and green across the watch, wake, watcher-lock, turn-end guard, claude-stop-autoarm, bootstrap, spawn, doc-audience, instruction-owners and the new quota-array-dispatch suites. KNOWN AND DELIBERATELY OUT OF SCOPE: tests/fm-pi-watch-extension.test.sh has one PRE-EXISTING failing subtest ('OpenCode watch plugin must arm only when this session owns the fleet lock') that fails identically on origin/main before this merge and was never touched by upstream. Root cause is the OpenCode plugin's module-level launchInFlight single-flight coalescing a second session.idle event into the still-in-flight lock-refused launch so the lock is never rechecked - it fails deterministically at the test's 120ms gap and passes deterministically at a 2000ms gap. The captain decided (option A) to land this sync as-is and file that plugin defect separately as a captain-gated item, so do NOT fix the OpenCode plugin or that test in this PR - a sync merge stays a sync merge. Deliverable is a PR on the captain's own repo with base named explicitly (knowttl/firstmate, base main), never upstream.
What Changed
quota-array-dispatchskill, with updated guidance and schema fixtures.Risk Assessment
Testing
Inspected the merge topology, ancestry, first-parent scope, and read-only merge preview; ran the focused quota suite; ran the Pi suite through its explicitly accepted untouched OpenCode failure; reran the imported Pi transition and cleanup scenarios cleanly; exercised real delivering-close and stale-receipt watcher flows with reviewer-visible logs; and confirmed a clean worktree. The sync satisfies the tested intent, with no actionable failures.
Evidence: Merge topology, retained ancestry, conflict scope, and resolved documentation
Evidence: Quota dispatch acceptance scenarios
Evidence: Focused imported Pi watcher behaviors
Evidence: Full Pi watcher suite including accepted OpenCode failure
Evidence: Delivering-close arm output with repeated signal reason
Evidence: Delivering-close lifecycle ledger
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
.pi/extensions/fm-primary-pi-watch.ts:212- This module-scope exit listener leaks across real Pi/reloadcycles. Pi clears the extension cache and reloads extensions withmoduleCache: false(loader source), so each reload reevaluates this line.session_shutdownstops the old generation but no longer removes its listener, causing repeated reloads to retain stopped generations and eventually emitMaxListenersExceededWarning. Register the fallback per factory runtime, remove it on shutdown, and re-register it on same-instancesession_start. The current test reuses one module import and therefore misses this path.✅ **Test** - passed
✅ No issues found.
git show -s --format='%H%n%P%n%s' c73b8a1d719c5780c708a90a41a16d846e2506ceand targeted commit graph/diff inspectiongit merge-tree $(git merge-base 94ca1223198af3ace94d5978769dc08bf4c08c58 fa0d85d00be145196d60eee5dffcbe18ab3af901) 94ca1223198af3ace94d5978769dc08bf4c08c58 fa0d85d00be145196d60eee5dffcbe18ab3af901conflict-path inspectiontests/fm-quota-array-dispatch.test.shtests/fm-pi-watch-extension.test.shthrough the documented pre-existing OpenCode lock-recheck failure; every imported Pi scenario before it passedFocusedtest_pi_actionable_close_starts_single_successor_before_delivery,test_pi_session_transition_generation_owner,test_pi_process_exit_cleanup_listener_lifecycle, andtest_pi_process_exit_cleanup_stops_arm_childexecutionFocusedtest_attached_arm_accounts_delivered_close_as_successandtest_attached_arm_rejects_stale_delivery_receiptexecution with preserved arm and lifecycle outputsgit diff --quiet 94ca1223198af3ace94d5978769dc08bf4c08c58..c73b8a1d719c5780c708a90a41a16d846e2506ce -- .opencode/plugins/fm-primary-watch-arm.jsgit status --shortafter testing✅ **Document** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.