Skip to content

feat: adopt upstream multi-brain supervision and fleet upgrades - #11

Merged
rega10 merged 251 commits into
mainfrom
fm/firstmate-upstream-multibrain-sync
Aug 26, 2026
Merged

feat: adopt upstream multi-brain supervision and fleet upgrades#11
rega10 merged 251 commits into
mainfrom
fm/firstmate-upstream-multibrain-sync

Conversation

@rega10

@rega10 rega10 commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Intent

Bring the rega10 Firstmate fork fully up to the current kunchenguid/firstmate:main, preserving every intentional fork behavior, and ship the reconciliation through a reviewed fork PR. The captain explicitly requested the latest upstream Firstmate because upstream now includes Pi's persistent multi-brain supervision architecture (upstream commits 7b88520 persistent Pi supervision branch, d55e00a multi-brain architecture poster, 8fa0505 default-on branch supervision and heartbeat routing, plus later fixes through the exact live upstream tip) and wants to use it.

Required reconciliation, all accepted as stated: (1) fetch live fork and upstream refs and verify exact identities before branching (fork origin/main was bae3180, upstream/main was 038d0f7; fork diverged, 17 ahead / 231 behind, not fast-forwardable); (2) create a normal feature branch from fork origin/main and perform a history-preserving merge of exact upstream/main - never rebase, squash, reset, force-push, replace fork history, or write upstream; (3) resolve every semantic conflict deliberately, preserving intentional fork-specific safety, private-home behavior, dispatch preferences, runtime support, Herdr repairs (fork PRs #4, #6, #10), Claude worker transcript preservation (PR #8), spawn metadata-publication abort (PR #5), hosted Codex opaque lock owners (PR #1/#3/#9), and later fork fixes unless upstream supplies a demonstrably equivalent or stronger implementation; never mechanically choose ours/theirs for broad files; inventory every conflict and document each resolution; (4) adopt the complete upstream Pi multi-brain implementation and its later fixes as a coherent unit - branch extension, watcher dispatch, leases, outcome store, recovery, prompts, docs, tests, default-on heartbeat behavior - never cherry-pick only headline commits or create a competing implementation; (5) preserve the feature's upstream contract: default-on only for a Pi primary owning the fleet session; ordinary resolvable supervision and eligible heartbeat work moves to the persistent in-process branch; genuinely quiet heartbeat outcomes are silent; ordinary non-silent outcomes append a compact sailboat note; captain-relevant outcomes open exactly one main-session turn; fleet-wide/unresolvable events and watcher failures stay on main; away mode declines branch offers; broken/absent branch falls back to main without losing notifications; branch authority cannot merge, land local work, or freshly spawn; current captain approval and security boundaries remain unchanged; (6) verify whether any fork-only behavior conflicts with the upstream branch lease/role partition and adapt the smallest authoritative owner rather than bypassing new guards; (7) keep the diff to one reconciliation merge plus only narrowly necessary follow-up fixes for proven semantic conflicts or validation failures; do not opportunistically redesign unrelated systems.

Decisions and tradeoffs made while doing the work: fork PR #9 was squash-merged on GitHub (single-parent 3015811) although its branch had merged upstream f74d9e4, so git's raw merge base was the ancient 59ece45 and produced ~200 spurious add/add conflicts; a temporary LOCAL git replace --graft restoring that true parent was used only for merge-base computation, then deleted, and the resulting commit 17cd039 is an ordinary two-parent merge of bae3180 and 038d0f7 (both verified as ancestors). Ten real conflicts were resolved: harness-adapters skill (both fork sentences plus upstream's Zellij wording), ci.yml and docs/fm-test-portable-shards.md (upstream's measured timeout wording, same 20-minute value the fork raised in PR #9), bin/fm-session-start.sh (fork's opaque-owner completion read via fm_session_lock_owner_read retained plus upstream's COMPLETION_RECORDED flag), bin/fm-test-run.sh (both family entries; upstream's refreshed weight-hint table plus the fork's two fm-herdr-legacy-repair hints - hints are balance-only), tests/fm-gotmp.test.sh (all symlinks from both sides), tests/fm-pi-watch-extension.test.sh (upstream's later flake rework taken for every hunk because it supersedes the fork's PR #9 fix for the same flake; upstream's call list verbatim; the fork-original Node 22+ skip guard re-inserted before the Pi test calls; the fork's 500->1000 wait bound kept), tests/fm-session-start.test.sh and tests/fm-sessionstart-nudge.test.sh (conflicts split mid-function; regions rebuilt from both sides' complete functions so all tests survive), tests/fm-spawn-dispatch-profile.test.sh (the launch string now composes upstream's outer env -u CURSOR_AGENT -u CURSOR_INVOKED_AS with the fork's env -u CLAUDE_CODE_CHILD_SESSION -u CLAUDE_CODE_SESSION_ID -u CLAUDE_PID -u CLAUDE_JOB_DIR template, both intentional; expectations updated to the composed string). Every line the fork added over f74d9e4 was verified present in the merged tree except those deliberate resolutions. The fork's non-numeric Codex lock owners make fm_lease_live report not-live so lease guards are silent no-ops on non-Pi homes, exactly as upstream intends; no fork behavior needed adaptation.

Narrow follow-up commits, each justified by a proven validation failure: 9d21048 returns undefined explicitly from .pi/extensions/fm-calm.ts's terminal-input handler because installed Pi 0.83.0 types TerminalInputHandler as returning {consume?, data?} | undefined and the strict typecheck failed on the unmodified upstream file (upstream's evidence was against 0.80.10); f368599 records the dated Pi 0.83.0 real-SDK live guard and typecheck results in docs/verification/runtime-backends.md as that record's own refresh-after-upgrade contract requires; 2a2f3ed spells half-block glyphs literally in tests/fm-composer-lib.test.sh because stock macOS Bash 3.2 does not decode $'\uXXXX'; 9a3649e fixes bin/fm-public-followup.sh expanding empty arrays under set -u (fatal on Bash 3.2, so every Relay follow-up command died on macOS; reproduced on pristine upstream) using the repo's existing ${arr[@]+"${arr[@]}"} idiom, and fixes the rechain test's inline-quoted pattern substitution that Bash 3.2 splits at its first slash; 5fce5ef lets the fork-only CI contract test accept upstream's renamed Lint job (was Lint shell scripts); 3445ba5 applies the same empty-array idiom to bin/fm-remote-home-seed.sh so --no-projects remote seeding works on Bash 3.2 (both remote-secondmate suites failed on pristine upstream); 5e4f0cc adds a readability check before each adapter . in bin/fm-backend.sh's fm_backend_source because under set -e Bash 3.2 treats a failed . as fatal even inside ||, so a missing adapter killed teardown's Herdr preflight silently instead of refusing with its "nothing was changed" message (tests/fm-teardown.test.sh failed on pristine upstream). Stock macOS Bash 3.2 is a real runtime for the captain's fleet (#!/usr/bin/env bash resolves to /bin/bash here) and production scripts already guard BASHPID with ${BASHPID:-$$}, so these are in-scope compatibility fixes, not redesign.

Validation run on macOS 26.5.2 arm64 with /bin/bash 3.2.57, Node 24.19.0, Pi 0.83.0, pinned ShellCheck 0.11.0 and actionlint 1.7.12 (scratch installs, nothing global): bin/fm-lint.sh green, bin/fm-doc-audience-check.sh ok, coverage guard ok (167 tests), strict Pi typecheck ok against 0.83.0, tests/fm-pi-branch-extension.test.sh, tests/fm-branch-supervision.test.sh, tests/fm-pi-watch-extension.test.sh (36/36), and FM_PI_BRANCH_LIVE_E2E=1 real-SDK guard all green, proven-isolated lane 24/24, real-Herdr family 13/13, upstream's macos-stock-bash job steps replicated (207-file parse sweep, 15/15 and 42/42 snapshot suites). Known and deliberately unfixed: five tests still fail on this macOS/Bash 3.2 machine and fail identically on a pristine upstream/main export, none merge-caused - tests/fm-wake-queue.test.sh (new upstream self-held-lock reclaim case needs $BASHPID to distinguish a subshell; a lock-primitive change upstream should own), tests/fm-pending-reply.test.sh (test-only bare $BASHPID at line 692; production lib guards it), tests/fm-muse-harness.test.sh (macOS kills the fixture's unsigned copied bash; also fails on fork main), tests/fm-on.test.sh (upstream remote-root fixture omits fm-composer-lib.sh which the herdr adapter sources; also fails on fork main), tests/fm-bootstrap-network-parallel.test.sh (fake-ssh timing assertion failing 3/3 on both HEAD and pristine upstream here). Linux CI is the proof for those; no Bash >= 4 exists on this machine.

Constraints: never modify anything under projects/; never update, stop, or restart the shared no-mistakes service; do not change private data/, state/, or config/ except the generated task status protocol; never push or open anything against kunchenguid/firstmate - the delivery target is a new PR in rega10/firstmate:main only; never merge the fork PR; do not fold upstream PR kunchenguid#282 unless already in the upstream tip (it is not); do not touch other workers' branches. The private report with refs, ancestry, conflict inventory, fork preservation, activation requirements, validation and skip evidence, and the post-merge /updatefirstmate plus Pi restart procedure is at data/firstmate-upstream-multibrain-sync/report.md (private, not part of the PR).

Later accepted decisions, carried in their current form: the first pipeline run (01M0V9GQW0WQG4NFZ2VB6R5J0M) reached checks-passed as PR #11 with two accepted review-fix commits (84de0a2 semantic lint-job assertion plus Node-guard scoping so the OpenCode watcher tests keep running on old Node plus reconciled Pi version provenance; b925d75 requiring a parsed workflow step whose command token is bin/fm-lint.sh). Its CI auto-fix commit 097973e temporarily relaxed the fork's required "PR must be raised via no-mistakes" check to also accept the legacy pre-1.46.0 PR-body format because the shared gate was v1.45.4. The captain explicitly decided (Option B) to restore upstream's stronger structured-attestation requirement: after the shared no-mistakes was upgraded to v1.57.0, commit 9b724ab reverts exactly 097973e, returning .github/workflows/no-mistakes-required.yml to its byte-identical upstream-adopted form and removing the interim bin/fm-no-mistakes-pr-body-verify.sh, its test, and its runner family entry, while preserving every other commit. The revert of those interim files is deliberate and captain-approved, not a lost fix. The PR must remain unmerged; the same branch and PR are being revalidated.

What Changed

  • Add default-on persistent Pi supervision with branch leases, heartbeat routing, durable outcomes, recovery, fallback behavior, documentation, and tests.
  • Expand fleet operations with durable local and remote inboxes, captain-held task lifecycles, an interactive Bearings board, Cursor primary-harness support, and an optional voice relay.
  • Preserve fork-specific runtime safeguards while hardening backends, watchers, Relay workflows, remote seeding, and CI compatibility across supported environments.

Risk Assessment

⚠️ Medium: The source review found no substantiated defect or intent contradiction, but the change remains a broad multi-brain runtime reconciliation whose size and concurrency-sensitive behavior warrant moderate integration risk.

Testing

The supplied baseline had already covered lint, documentation, coverage, Pi 0.83 typechecking/live guards, portable and Herdr lanes, and macOS Bash 3.2 checks; this phase reran the focused workflow contract and core multi-brain suites, reproduced the shell-bypass regression against the predecessor, verified all inheritance-level bypasses are now rejected, and captured persisted startup-replay evidence. All targeted checks passed; no UI screenshot was applicable because the change exposes shell/CLI and workflow behavior rather than a rendered interface.

Evidence: Workflow shell-override regression matrix

Source: Workflow shell-override regression matrix

fixed | baseline | expected=accepted observed=accepted
ok - no-mistakes stays targeted and CI owns broad behavior coverage
predecessor | step-shell | expected=accepted observed=accepted
ok - no-mistakes stays targeted and CI owns broad behavior coverage
fixed | step-shell | expected=rejected observed=rejected
not ok - no-mistakes and CI YAML contracts must remain intact
predecessor | job-shell | expected=accepted observed=accepted
ok - no-mistakes stays targeted and CI owns broad behavior coverage
fixed | job-shell | expected=rejected observed=rejected
not ok - no-mistakes and CI YAML contracts must remain intact
predecessor | workflow-shell | expected=accepted observed=accepted
ok - no-mistakes stays targeted and CI owns broad behavior coverage
fixed | workflow-shell | expected=rejected observed=rejected
not ok - no-mistakes and CI YAML contracts must remain intact
Evidence: Persistent Pi supervision startup replay

Source: Persistent Pi supervision startup replay

Persistent Pi supervision outcome replay
Persisted outcomes before replay: 3
BRANCH OUTCOMES (handled by the supervision branch, not yet seen by this session):
{"seq":2,"epoch":1787725829,"task":"routine-steer","wake":"task-end","verdict":"routine","summary":"Worker steer delivered","silent":false}
{"seq":3,"epoch":1787725829,"task":"captain-call","wake":"milestone","verdict":"captain","summary":"Captain decision required","silent":false}
Unread outcomes after replay: 0
Replay cursor: 3
Evidence: Persisted supervision outcome store

Source: Persisted supervision outcome store

{"seq":1,"epoch":1787725828,"task":"quiet-heartbeat","wake":"heartbeat","verdict":"routine","summary":"No captain-facing change","silent":true}
{"seq":2,"epoch":1787725829,"task":"routine-steer","wake":"task-end","verdict":"routine","summary":"Worker steer delivered","silent":false}
{"seq":3,"epoch":1787725829,"task":"captain-call","wake":"milestone","verdict":"captain","summary":"Captain decision required","silent":false}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed (6) ✅
  • 🚨 tests/fm-nm-test-contract.test.sh:125 - The changed contract test still violates the test-quality rule: the serial-step check accepts echo bin/fm-test-run.sh --lane "$FM_SERIAL_LANE" because it searches any token subsequence, while lines 24, 90, 100-103, and 129-140 rely on raw YAML text and can pass on comments or unrelated content. Parse both YAML files semantically, require direct executable commands after optional environment assignments, assert companion-job behavior through normalized jobs/steps, and remove the commented-text assertion.

🔧 Fix: Make workflow contract assertions semantic
1 error still open:

  • 🚨 tests/fm-nm-test-contract.test.sh:75 - The semantic lint assertion remains bypassable because an empty expected argument list makes every invocation beginning with bin/fm-lint.sh match. For example, changing the CI step to bin/fm-lint.sh --list-files would pass this test but exit before running ShellCheck or actionlint. Require the lint workflow command to have exactly the executable and no arguments.

🔧 Fix: Require exact lint workflow command
1 error still open:

  • 🚨 tests/fm-nm-test-contract.test.sh:75 - The semantic workflow check remains bypassable because direct_command accepts any trailing tokens. For example, bin/fm-test-run.sh --lane portable-parallel-1 --list satisfies this assertion, but fm-test-run.sh then prints the inventory and exits 0 without running tests; the serial and Herdr assertions have the same bypass. Validate each command's complete permitted argument schema, rejecting --list, exclusion flags, shell operators, and other behavior-changing suffixes.

🔧 Fix: Enforce exact workflow command schemas
1 error still open:

  • 🚨 tests/fm-nm-test-contract.test.sh:111 - The exact-token check still accepts dead commands. For example, a step containing exit 0 followed by bin/fm-lint.sh satisfies include?, succeeds, and never runs lint; every lane assertion has the same flaw. Validate each owning step’s complete permitted command sequence, including only its real prologue and exact invocation, and reject early terminators or unexpected commands.

🔧 Fix: Enforce exhaustive workflow step sequences
1 error still open:

  • 🚨 tests/fm-nm-test-contract.test.sh:56 - The claimed exhaustive workflow-step check still ignores execution metadata. For example, adding if: ${{ false }} or continue-on-error: true to the exact run: bin/fm-lint.sh step leaves its normalized sequence unchanged, so this test passes while lint is skipped or cannot fail CI. This is another expansion of the same bespoke parser after four fix rounds: decide whether to extend the owning job/step model to require an enabled condition and failure propagation; that is the smallest correction and is recommended.

🔧 Fix: Enforce lint execution metadata
1 error still open:

  • 🚨 tests/fm-nm-test-contract.test.sh:165 - The lint predicate still ignores the effective shell. A step with the exact run: bin/fm-lint.sh plus shell: true {0} passes this contract, but GitHub executes true and exits successfully without running lint; job- or workflow-level defaults.run.shell has the same path. Reject shell overrides for the required lint step, including inherited defaults, and cover the no-op-shell case.

🔧 Fix: Reject lint shell overrides
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • /bin/bash tests/fm-nm-test-contract.test.sh
  • Temporary git archive fixture matrix comparing 450a1c4 and 4bf373c after step-, job-, and workflow-level shell: true {0} mutations; the predecessor accepted every bypass while the fix rejected all three
  • /bin/bash tests/fm-branch-supervision.test.sh
  • /bin/bash tests/fm-pi-branch-extension.test.sh
  • Three bin/fm-branch-outcome.sh append calls followed by startup-replay and unread, demonstrating durable quiet/routine/captain outcomes, silent quiet replay, visible routine/captain replay, and cursor advancement
✅ **Document** - passed

✅ No issues found.

⚠️ **Lint** - 1 warning
  • ⚠️ linter found issues (exit code 1)

🔧 Fix: Suppress intentional single-quoted Ruby ShellCheck warning
1 warning still open:

  • ⚠️ linter found issues (exit code 1)
✅ **Push** - passed

✅ No issues found.

kunchenguid and others added 30 commits July 21, 2026 19:50
* fix(no-mistakes): drop full-suite local Test override

Local no-mistakes Test is intent-targeted; CI Behavior keeps the broad
tests/*.test.sh suite. Keep commands.lint on bin/fm-lint.sh and add a
focused contract test so the override cannot silently return.

* no-mistakes(lint): Make CI contract assertion ShellCheck-clean
* feat(test): add canonical timed suite runner and honest CI timeout

Introduce bin/fm-test-run.sh as the single serial owner for selecting
one script, a family, a conservative changed-file set, or the explicit
complete suite, with per-script timing markers and a JSON artifact.
Wire CI Behavior through the runner, raise the hang-tripwire timeout to
25 minutes, and document entry points without restoring a full-suite
local no-mistakes Test command.

* no-mistakes(review): Captain: fix changed selection and empty summaries

* no-mistakes(review): Captain: fail closed on unmapped changed sources

* no-mistakes(document): Document canonical timed test entry points
* fix: disclose main-home orphan and unstructured inventory gaps

Main Bearings could report an empty fleet while structured in-flight rows
lacked meta or current backlog rows were free-form. Emit main_inventory from
the fleet snapshot, map it into Bearings omitted surfaces and a Charted Next
gate, and keep meta as the only live Underway source.

* no-mistakes(document): Document Bearings inventory-integrity projection

* no-mistakes: apply CI fixes
* feat: add concurrent test isolation proof for Phase 2

Prove an audited portable candidate set passes under concurrent
workers with private mode-0700 temp roots, without enabling
production CI sharding or fm-test-run --jobs.

* no-mistakes(review): Pin isolation proof to audited candidate manifest
* feat(secondmate): parent-owned guards for missed status reports

Marked parent-to-secondmate requests now create a durable pending-reply
expectation with a privacy-safe correlation id before delivery. Transport
success never resolves it; only a correlated parent status or document
pointer does. After a completed turn with no report, the parent sends one
recovery repost and escalates once if that turn is also missed, without
scraping the secondmate conversation or looping.

* no-mistakes(review): Deduplicate wrong-home pending-reply sightings

* no-mistakes(review): Harden pending-reply recovery and escalation guards

* no-mistakes(review): Bound pending-reply backend polling

* no-mistakes(review): Cache pending-reply status scans

* no-mistakes(review): Protect undelivered pending-reply records from scans

* no-mistakes(review): Close pending-reply delivery durability gaps

* no-mistakes(review): Separate pending-reply transport outcomes

* no-mistakes(review): Escalate stalled pending-reply deliveries once

* no-mistakes(review): Resolve attempted deliveries from correlated reports

* no-mistakes(review): Resolve late reports after delivery escalation

* no-mistakes(document): Document pending-reply grace and ownership

* no-mistakes(lint): Silence intentional pending-reply test fixture lint warnings
* feat: add required pinned Herdr CI lane

Install exact Herdr 0.7.4 and Treehouse 2.0.1 with official assets and
SHA-256 pins, run the real-herdr-gated family serially through
fm-test-run with hard-fail on herdr-not-found, and keep portable
Behavior free of claimed Herdr coverage.

* no-mistakes(document): Consolidate real-Herdr CI documentation ownership

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
…guid#841)

* feat: shard portable CI tests after isolation proof

Balance the Phase 2 proven-isolated set into two LPT portable parallel
lanes from Phase 1 timing evidence, keep stateful work in a required
portable serial lane, exclude real Herdr to its dedicated required lane,
and prove complete inventory coverage with a deterministic guard.
Add bounded local --jobs only for the proven set, per-lane timing plus
aggregate artifacts, and reduce the interim portable hang tripwire now
that the serial remainder owns the long wall-clock path.

* no-mistakes(review): Captain, fix CI contracts and completion-order worker scheduling

* no-mistakes(review): Captain, preserve stderr gate-skip detection in parallel tests

* no-mistakes(document): Document portable sharding and timing aggregation

* no-mistakes: apply CI fixes
)

* feat: fence primary-session delegation outside the fleet

A firstmate primary that delegates through Claude Code's built-in
delegation tools creates work with no state/<id>.meta. Because
fm-supervision-lib.sh counts *.meta and fm-turnend-guard.sh exits
silently at zero, such work does not merely go unsupervised: it makes
the whole guard stack structurally inert, and it dies with the primary
session. On 2026-07-22 that cost two workers mid-flight and left
supervision down for 73 minutes unnoticed.

Layer 1, the primary fix: a permissions.deny list in
.claude/settings.json removes the 18 delegation, scheduling, worktree,
and task-tracking tools from the model's schema, so they are never
offered. This is removal rather than interception, so there is no call
to intercept and no fail-open path. The list is flat and in one file so
its width stays reviewable; the captain owns that width.

Layer 2, bin/fm-subagent-pretool-check.sh: a deny list is fail-open
against tools that do not exist yet, and permissions.allow is a
pre-approval list rather than an availability list, so there is no
fail-closed allowlist to use instead. This backstop classifies the tool
NAME by shape rather than against a fixed list, so a delegation tool
that ships before the deny list is updated is still refused. It excludes
mcp__* names and observe-or-stop operations, scopes itself to a genuine
primary home via the shared fm_primary_scope_matches predicate so a
crewmate's task worktree is unaffected, and offers one deliberate
FM_ALLOW_SUBAGENT=1 escape hatch that must be set at launch.

Verified live against Claude Code 2.1.217, including a deny-key A/B with
a nonsense-name control, layer 2 denying an un-denied Workflow call, the
same call allowed in a linked worktree, and the escape hatch. Corrects a
prior finding: both Task and Agent work as deny keys, so both are
pinned. Codex 0.144.1 verified to expose no delegation tool; grok,
opencode, and pi are inspected and documented as not wired because those
binaries are absent from this host and the repo requires live validation
before trusting a harness hook. Evidence in docs/subagent-guard.md.

* no-mistakes(review): Ship scoped Claude delegation guard

* no-mistakes(test): Ship Claude delegation deny list

* no-mistakes(document): Clarify PreToolUse guard ownership

* no-mistakes(lint): Keep Claude deny list local
Reproduction: portable-parallel-2 completed successfully without tasks-axi while fm-decision-hold-lifecycle emitted a gate skip in 30 ms. The pre-shard lane installed tasks-axi and exercised the test fully. Installing tasks-axi is the smallest counterfactual and makes the representative shard execute the test with gate_skip=false in about 20 seconds. Both parallel jobs receive symmetric setup, while the exact 91-test inventory and coverage guard remain unchanged.
* feat: make dispatch profiles quota aware

* no-mistakes(review): Fix quota window and Grok product scoping

* no-mistakes(document): Document implicit quota-aware dispatch accurately
…guid#875)

* fix: preserve mixed Bearings projections

* no-mistakes(review): Enforce strict invalidity precedence for partial snapshots

* no-mistakes(review): Enforce ownership for unknown child metadata

* no-mistakes(document): Document partial structured Bearings projections

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
* Add session-local Pi calm mode

* no-mistakes(review): Preserve Pi HTML exports during calm mode

* no-mistakes(review): Preserve calm exports across submit bindings and share

* no-mistakes(document): Document calm-mode feasibility across supported harnesses
* fix(pi): limit watcher arm tool to recovery

* no-mistakes(review): Strengthen Pi live re-arm regression coverage

* no-mistakes(document): Document Pi first-cycle and recovery-only watcher arming
* fix(pi): clean up Calm transcript rendering

* no-mistakes(review): Captain, preserve Calm exports and classify Pi launch briefs

* no-mistakes(review): Captain, eliminate Calm gaps and verify exported conversations

* no-mistakes(review): Restore Calm rows received while active

* no-mistakes(review): Preserve diagnostics during Calm restoration

* no-mistakes(document): Clarify Calm transcript behavior and injection paths
* fix: execute every PR body compliance event

* no-mistakes(document): Document independent PR compliance events
…#899)

* fix: distinguish operational input in ahoy

* no-mistakes(review): Handle legacy Ahoy operational boundaries

* no-mistakes(review): Narrow legacy Ahoy boundaries with live regressions

* no-mistakes(document): Document Ahoy operational marker ownership

* no-mistakes(lint): Suppress intentional literal fixture lint warnings
…nguid#909)

* fix: type canonical operational inputs

* no-mistakes(document): Correct canonical operational-input documentation ownership
* fix: avoid generic secondmate acknowledgements

* no-mistakes(document): Document sparse secondmate acknowledgement behavior

* no-mistakes: apply CI fixes
* fix(pi): preserve calm presentation across sessions

* no-mistakes(review): Fix Calm home fallback persistence

* no-mistakes(document): Clarify Calm gapless and export contracts

* no-mistakes: apply CI fixes
…nguid#932)

* fix: retire merged PR polls after notification

* no-mistakes(review): Decouple PR retirement recovery from template updates

* no-mistakes(review): Recover pending PR retirements before poll migration

* no-mistakes(document): Document merged PR poll retirement contracts
* Clarify intake evidence and overlap handling

* no-mistakes(review): Align scout guard with intake classification

* no-mistakes(document): Clarify scout documentation and intake ownership
* fix(pi): preserve operational follow-up semantics in Calm

* no-mistakes(document): Correct Calm operational-row visibility documentation
* perf(lint): shrink shell source graph

* no-mistakes(review): Ensure lint workers terminate fully on cancellation

* no-mistakes(document): Repair stale lint documentation ownership
* fix(pi): remove Calm hidden-block gaps

* no-mistakes(review): Validate Calm geometry against current viewport

* no-mistakes(review): Synchronize Calm geometry checks with reload completion
* fix: escalate ask-user contract expansion

* no-mistakes(document): Point project management to authority owner
* fix(pi): hide Calm operational user rows

* no-mistakes(review): Narrow Calm operational input suppression

* no-mistakes(review): Avoid Calm replay classifier subprocesses

* no-mistakes(document): docs: point Pi verification to Calm owner
* fix(session-start): relaunch missing second mates

* fix(test): detect completed parallel workers

* no-mistakes(review): Isolate session-start recovery test cleanup

* no-mistakes(review): Complete backend-safe secondmate session recovery

* no-mistakes(review): Resolve Zellij task ownership before recovery

* no-mistakes(review): Recover relocated Zellij ghost tabs safely

* no-mistakes(review): Restore conservative Zellij recovery boundary

* no-mistakes(review): Reject malformed tmux recovery targets

* no-mistakes(document): Align secondmate recovery documentation

* no-mistakes: apply CI fixes
…id#967)

* fix(herdr): reclaim resumed task projections safely

* no-mistakes(review): Enforce safe Herdr reclaim close boundaries

* no-mistakes(document): docs: clarify Herdr restart projection contract
kunchenguid and others added 28 commits August 23, 2026 15:19
…#2901)

* feat(bin): deliver remote secondmate steers through durable task inboxes

Stage 2 of the inbox+doorbell steer channel (stage 1: kunchenguid#2856). A remote
secondmate steer now crosses fm-on.sh as a durable record written
idempotently into the remote home's steering inbox plus a best-effort
remote doorbell, and the last typed-payload steer transport is deleted:

- fm-remote-secondmate-control.sh cmd_send writes the record via the new
  fm_task_inbox_write_idempotent and rings the doorbell; it no longer
  types the payload through an inner fm-send at an explicit pane target.
- fm-send.sh routes every remote text steer (harness-native included,
  which marking already reduced to chat) onto the remote inbox leg,
  retries the identical leg once on ssh 255, closes --resolve-key
  decisions at enqueue for remote too, and preserves a marked request's
  reply expectation when completion stays unknown. The exit-3-as-
  delivered remap, the 255 do-not-resend trap, and the remote typed
  submit block are removed.
- fm-task-inbox-lib.sh owns the idempotent enqueue: an exact-body re-run
  lands on the existing record, handled or not, so an ambiguous
  transport can always be safely re-run.
- Tests pin the new contract end to end (record + doorbell + no typed
  payload across ssh, one-record idempotence under an ambiguous
  transport, enqueue-time decision close, loud real failures, and the
  deleted typed-payload behaviors gone), and AGENTS.md plus
  docs/remote-secondmates.md describe the remote leg's new semantics.

* no-mistakes(review): Harden remote inbox delivery against lifecycle races

* no-mistakes(review): Enable correlation-preserving remote steer resends

* no-mistakes(review): Fail closed on stale correlation resends

* no-mistakes(review): Include home context in remote resend commands

* no-mistakes(review): Lock and revalidate remote parent routes

* no-mistakes(document): Clarify remote steer retry documentation

* no-mistakes: apply CI fixes
* wip: forked supervision on Pi (checkpoint before docs)

* fix(pi-branch): harden mirror delivery, fallback encoding, and session replacement

Peek-then-shift mirror flush so a failed append retries instead of dropping;
durable mirror cursor commits only after delivery into the branch;
the main fallback wake is operational-encoded like every watcher injection;
session_shutdown quiesces the generation and session_start re-arms, so /new
and /resume no longer kill the branch permanently. Registers the extension in
the strict typecheck, adds the dispatch handshake test, the branch extension
suite, the bash-level regression suite, the session-start replay test, and
the opt-in real-SDK live guard.

* test(fixtures): carry the branch-dispatch lib and lease lib into isolated fixtures

The watcher extension now imports lib/fm-branch-dispatch.ts and fm-teardown
sources fm-lease-lib.sh, so every fixture that copies or symlinks those
files in isolation gains the new sibling.

* no-mistakes(review): Prevent shutdown wake loss and serialize lease claims

* no-mistakes(review): Durably hand off wakes and retain portable leases

* no-mistakes(review): Require durable reports and clear disposed branch leases

* no-mistakes(review): Enforce per-wake outcomes and quiescent lease cleanup

* no-mistakes(review): Require wake acknowledgements and tighten branch lifecycle boundaries

* no-mistakes(review): Require complete acknowledgements and replay cleanup failures

* no-mistakes(review): Bind supervision to lock ownership and durable delivery

* no-mistakes(review): Activate branch lazily after session lock acquisition

* no-mistakes(review): Preserve undelivered mirror context across extension rebinds

* no-mistakes(review): Acknowledge startup replay only after main delivery

* no-mistakes(review): Isolate replay metadata from untrusted digest content

* no-mistakes(review): Reject duplicate reports for active wake sequences

* no-mistakes(review): Retain failed fallbacks and deduplicate outcome replay

* no-mistakes(review): Deduplicate durable outcomes and cache delivery receipts

* no-mistakes(review): Anchor wake sequence matching to outcome fields

* no-mistakes(document): Clarify Pi supervision durability contracts

* no-mistakes(lint): Fix ShellCheck issues in branch supervision scripts

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* refactor(pi-branch): collapse to confused-agent-grade guards per captain decision

Captain decision A: the lease/actor guards target the CONFUSED-AGENT threat
model bin/fm-gate-refuse-lib.sh already documents; adversarial-grade
separation is impossible in the shared-process design and is filed as
separate follow-up work. Rip out the machinery that chased it: the
generation fence and shell-provenance markers, the wrapper-tagged ancestry
walks, guard auto-claim with per-script release traps, the pending-wake
files and ack-receipt correlation (the durable wake queue already
re-presents anything unacknowledged), the delivery-receipt store with
contiguous cursor advancement, the session-start replay-metadata channel,
and the branch tool quiescence counters.

Keep the behaviors the board requires, each on its simplest implementation:
lazy per-action session-lock ownership (cold start activates after the lock
lands; a secondary session stays inert), mirror durability across extension
rebinds via the durable cursor, replay-exactly-once from the one read
cursor, the awaited operational-encoded fallback, per-generation stray-lease
cleanup, session-lock-bound lease liveness (a recycled pid or a non-Pi home
never honors a leftover lease), the loud accidental-override guards
(readonly actor prelude, cross-actor claim refusal), and the role-partition
refinements (no forced teardown, no direct relaunch for the branch).
Default-on-for-Pi is unchanged.

* no-mistakes(review): Enforce lock ownership and serialize lease mutations

* no-mistakes(review): Synchronize guard cleanup and bind leases to lock owner

* no-mistakes(review): Report outcomes before acknowledging durable wakes

* no-mistakes(review): Restrict leases to Pi and instruct main claims

* no-mistakes(review): Reject malformed lease locks and torn outcome tails

* no-mistakes(review): Validate complete outcome tails before appending

* no-mistakes(review): Guard branch side effects across session replacements

* no-mistakes(document): Update Pi supervision durability and lease documentation

* no-mistakes(lint): Suppress intentional nested-shell expansion warning

* no-mistakes: apply CI fixes

* fix(pi-branch): authorize lease releases by caller

* fix(lint): break redundant source-analysis path in fm-lease-lib.sh

fm-lease-lib.sh's lazy fallback source of fm-wake-lib.sh gave ShellCheck's
--external-sources traversal a second path into an already 1540-line file
that fm-send.sh and fm-teardown.sh also source directly, blowing up the
recursive analysis past CI's lint timeout. Mark it a source=/dev/null
analysis boundary, matching the existing fm-task-inbox-lib.sh convention.

Also restores bin/fm-lint.sh and tests/fm-lint.test.sh to the shared
serial-lint definition (dropping an unrelated parallel-sharding change
that was itself hanging and masked this root cause).

* no-mistakes(document): Correct lease caller-authorization documentation

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
* feat(bin): parallelize session-start remote secondmate network sweeps

Run per-secondmate liveness and convergence probes concurrently and overlap clone refresh, while replaying each mate's fail-closed diagnostic in original order. Ignore scratchpad* so untracked scratch no longer blocks remote sync.

Co-authored-by: Cursor <cursoragent@cursor.com>

* no-mistakes(document): Document parallel startup network sweeps

* no-mistakes(lint): Fix empty environment assignment lint warning

* no-mistakes: apply CI fixes

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(tests): count declared-pause wakes without crashing on an absent queue

The exited-declared-pause case counts queued stale wakes by handing
state/.wake-queue straight to awk. A watcher that queues nothing never
creates that file, and awk aborts on a missing path before its END rule
runs, so the count collapses to the empty string. The next comparison
then fails as an integer-expression error and surfaces as a wake flood
with no number, hiding the real contract breach the following grep names.

Read the queue the way the drain-count assertion at the end of this file
already does: silence awk's open error and default an absent queue to
zero. Applied to all four counts in this case, including the live
external-decision gate pair whose queue an acknowledged drain can also
leave behind. An absent queue now reports "did not use the bounded
paused recheck", while a genuine flood still fails with its real count.

Fixes kunchenguid#2628

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
… icon (kunchenguid#2934)

* style(pi): restyle supervision merge notes with a sailboat and matching pad

Secondary-session notes were flush against the TUI edge and fully tinted.
Use the sailboat prefix, Pi's default outputPad, boat-only color, and dim remainder so they sit like real messages.

* style(pi): distinguish routine and captain merge notes by icon only

Visible notes now lead with a sailboat or anchor, then only the dim outcome.
Drop the branch-merged wording and verdict brackets so the icon is the only kind signal.
…id#2938)

The markdown contract stays the owner; the still is only the visual of the idea.
* fix(bin): bound remote worker supervisors

* no-mistakes(review): release incumbent supervisor before starting its replacement

* no-mistakes(review): wait out a healthy same-root supervisor instead of replacing it

* no-mistakes(review): narrow remote worker change to restart accounting only

* no-mistakes(document): clarify supervisor restart guard is a lifetime total
…sion

Merge kunchenguid/firstmate:main at 038d0f7 into
rega10/firstmate:main at bae3180, preserving both
histories. Conflicts were resolved against the fork's last reconciled upstream tip
(f74d9e4, merged by fork PR #9) so only genuine fork-vs-upstream divergence needed
manual resolution; every fork-only behavior (Claude session sanitize, hosted Codex
lock owners, landed-work library, Herdr legacy repair, install/contract tests) is
retained alongside upstream's persistent Pi supervision branch.
Pi 0.83.0 types TerminalInputHandler as returning {consume?, data?} | undefined,
so the strict no-emit typecheck in tests/fm-pi-primary-types.test.sh rejected the
void-returning submit interceptor. Returning undefined explicitly leaves the
keystroke untouched on every Pi version and restores the typecheck.
Refresh the Pi supervision branch record with the dated real-SDK guard and strict
typecheck results against the installed Pi 0.83.0, as the record's own refresh
contract requires after a Pi upgrade.
Stock macOS Bash 3.2 does not decode $'\uXXXX' escapes, so the Herdr half-block
rule fixture compared literal backslash sequences and failed on every macOS run.
Spell the glyphs directly, the way bin/fm-composer-lib.sh already does.
Bash 3.2 aborts on "${arr[@]}" for an empty array under set -u, so every
fm-public-followup.sh invocation died at its registry-lock helpers on macOS
(tests/fm-backlog-handoff.test.sh and tests/fm-public-followup.test.sh both
failed on unmodified upstream). Use the repo's existing ${arr[@]+"${arr[@]}"}
idiom. The rechain test also relied on an inline-quoted pattern substitution
that Bash 3.2 splits at its first slash; substitute through variables instead.
Upstream renamed the CI lint job from "Lint shell scripts" to "Lint" when it
grew workflow linting; the fork-only contract test still asserted the old
name. Accept either spelling so the assertion keeps guarding the job's
presence rather than its label.
Bash 3.2 aborts on "${PROJECT_NAMES[@]}" when the array is empty under set -u,
so every --no-projects remote seed died before provisioning on macOS (both
remote secondmate suites failed on unmodified upstream). Use the repo's
existing ${arr[@]+"${arr[@]}"} idiom.
Under set -e, Bash 3.2 treats a failed `.` of a missing file as fatal even
inside `||`, so fm_backend_source could never return 1 and a caller such as
teardown's Herdr preflight died silently instead of refusing with its
"nothing was changed" message (tests/fm-teardown.test.sh failed on
unmodified upstream). Check readability before sourcing each adapter.
This reverts commit 097973e.

The reverted commit was a temporary compatibility relaxation: it let the
required "PR must be raised via no-mistakes" check accept the legacy
pre-1.46.0 PR-body format because the shared no-mistakes gate was still
v1.45.4. The captain approved restoring upstream's stronger structured
attestation requirement (upstream kunchenguid#2710) once the shared gate was upgraded;
it now runs v1.57.0, which emits the required attestation, so the fork's
workflow returns to the exact upstream check and the interim verifier
script, its test, and its runner family entry are removed.
@rega10
rega10 merged commit c50bfa6 into main Aug 26, 2026
13 checks passed
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.