Skip to content

feat: sync upstream improvements while preserving fork-local guardrails#17

Merged
mielyemitchell merged 64 commits into
mainfrom
fm/upstream-sync-u7
Jul 14, 2026
Merged

feat: sync upstream improvements while preserving fork-local guardrails#17
mielyemitchell merged 64 commits into
mainfrom
fm/upstream-sync-u7

Conversation

@mielyemitchell

@mielyemitchell mielyemitchell commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Intent

Finish upstream sync PR after review: preserve fork-local guardrails, restore bootstrap TASKS_AXI cwd-trap diagnostic with bounded no-mistakes probe work intact, keep bin/fm-tasks-axi.sh wrapper docs/tests, and validate merge branch to CI green.

What Changed

  • Merged upstream/main into the fork, bringing in a large batch of upstream features and fixes: hardened Herdr backend and lab lifecycle, AFK/away-mode daemon lifecycle hardening, bearings status snapshots, Codex App/OpenCode/Grok harness support, arm-command and cd-command pretool guards, quota-balanced crew dispatch selection, fleet snapshot/view tooling, wedge alarms, deterministic bounded bearings snapshots, and many watcher/supervision/backend robustness fixes, each with accompanying test coverage.
  • Restored fork-specific guardrails that the upstream merge had dropped or weakened: fork-local upstream-merge safety checks, the FM_HOME ownership guard section in docs/architecture.md, and bin/fm-tasks-axi.sh as the canonical invocation form (with AGENTS.md/README/docs reconciled to match).
  • Fixed and documented the bootstrap TASKS_AXI cwd-trap diagnostic: restored the cwd-trap warning with its bounded no-mistakes probe timeout intact, documented the behavior, and extended tests/fm-stow-contract.test.sh to assert the tasks-axi wrapper form.

Risk Assessment

✅ Low: The reviewable delta is a set of careful, mechanical restorations of fork-local guardrails (popup-risk send verification, fleet-freeze refusal in fm-watch.sh, the bounded no-mistakes probe, the tasks-axi cwd-trap warning) plus doc reconciliation; every restored code path was verified byte-for-byte against its pre-merge fork original, every doc claim was cross-checked against the actual scripts/files it references, and each change carries a matching passing-oriented test that was inspected for correctness. The large bulk of the diff is the upstream merge itself (166 files) which represents adoption of already-published upstream firstmate code rather than new authored logic in this session.

Testing

The baseline full-suite run (tests/*.test.sh under tmux) already passed per the task setup; I additionally ran the two test files directly touched by this change set (fm-bootstrap.test.sh and fm-stow-contract.test.sh) and both pass cleanly on the target commit, confirming the cwd-trap warning and the tasks-axi wrapper doc/test contract both work as intended. However, checking the live GitHub PR (#17) showed its 'Behavior tests' CI check is still red, and log inspection proved that's because the remote branch is two commits behind this worktree's HEAD - it's missing exactly the two fix commits I just verified locally. The code fix itself is confirmed working; getting CI green requires pushing those commits, which I left for you to authorize.

  • Outcome: ⚠️ 1 warning across 1 run (20m30s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

⚠️ **Test** - 1 warning
  • ⚠️ PR feat: sync upstream improvements while preserving fork-local guardrails #17 (fm/upstream-sync-u7) is pushed to GitHub only as far as commit 74dd161 - it's missing the two newest local commits (f2a4d87 'fix: restore bootstrap tasks-axi cwd trap' and 0b7a092 'test: expect tasks-axi wrapper in stow contract'). GitHub Actions' 'Behavior tests' check is currently FAILING on the pushed 74dd161 with exactly 'not ok - stow skill does not require inspecting task notes first' - the bug those two unpushed commits fix. Locally, on the target commit 0b7a092, tests/fm-stow-contract.test.sh and tests/fm-bootstrap.test.sh both pass cleanly. So the fix is correct and complete in the worktree, but CI on the PR won't go green until the branch is pushed. Since pushing to a shared PR branch is a state-changing action, I did not push it myself - that decision belongs to you.
  • 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"
  • bash tests/fm-bootstrap.test.sh (full file, 13 cases including the new 'bootstrap warns when repo-root and FM_HOME backlogs diverge' case) - all pass
  • bash tests/fm-stow-contract.test.sh (both cases: stow skill and AGENTS.md task-note contract) - all pass
  • grep verification that AGENTS.md and .agents/skills/stow/SKILL.md already use the bin/fm-tasks-axi.sh show/update wrapper form the new test asserts
  • gh run view 29211904987 --log-failed on PR #17's failing CI run to identify the exact failing assertion and confirm it matches the bug fixed by the two unpushed local commits
  • gh pr view 17 --json commits to confirm the PR's newest known commit (74dd161) predates the two local fix commits
  • git status --short to confirm no stray test artifacts were left in the worktree
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

kunchenguid and others added 30 commits July 6, 2026 19:35
…-governance section (kunchenguid#307)

* Encode project AGENTS authoring bar

* no-mistakes(review): Captain, centralize CLAUDE promotion governance

* no-mistakes(review): make ensure_maintenance_section idempotent-success, drop || true guards

* no-mistakes(review): separate appended maintenance section on newline-less CLAUDE.md promotion

* no-mistakes(review): assert maintenance heading present before separator check in test

* no-mistakes(document): sync docs with AGENTS.md authoring bar and self-governance

---------

Co-authored-by: fmtest <fmtest@example.invalid>
…chenguid#300)

* Add captain-invocable bearings skill

Generates a pick-up-where-I-left-off status report from live fleet
state to data/status-report-<YYYY-MM-DD>.md plus a concise chat
summary. Read-mostly procedure: reads backlog, per-task crew state
via bin/fm-crew-state.sh, open PRs via gh-axi, scout reports,
pending decisions, and date-gated queued work; composes the
exemplar's sections (TL;DR, Check first, Landed, In flight, Plans,
Decisions pending, Date-gated/queued); never tears down, merges, or
mutates task state as a side effect.

* no-mistakes(document): docs: list new /bearings skill in README built-in skills table
* fix(watcher): pin LC_ALL=C in fm_pid_identity for locale-invariant identity

ps's lstart date format follows the caller's LC_TIME/LC_ALL. The watcher records
its process identity under one locale, but arm/guard/turn-end re-read it under the
machine's ambient locale. On a non-C locale (e.g. ko_KR) the two strings differ
only in the date portion, so fm_watcher_lock_matches_pid / fm_watcher_healthy
reject a genuinely live watcher - breaking fm-watch-arm.sh, fm-guard.sh, and
fm-turnend-guard.sh on every non-C-locale machine.

Pin LC_ALL=C on that one ps call so the write and read sides agree regardless of
machine locale, matching the LC_ALL=C determinism the file already uses elsewhere.
Add a colocated regression test asserting fm_pid_identity is locale-invariant
across exported LC_ALL/LC_TIME.

* no-mistakes(document): Document watcher PID identity coverage
* docs: reconcile Codex App backend contract

* no-mistakes(document): Sync backend docs

* docs: clarify Codex Desktop bridge blocker

* no-mistakes(document): Align Codex App backend docs

* no-mistakes(test): Captain, stabilize watcher self-eviction test cadence

* no-mistakes(document): Document Codex App backend contract

* no-mistakes(document): Captain, document blocked codex-app coverage

* docs: make Codex App contract doc authoritative

* no-mistakes(document): Align Codex App backend docs

* docs: redact local Codex App smoke paths

---------

Co-authored-by: Stephen Brouhard <vesta@stephens-macbook-air.tail2122af.ts.net>
* docs: add Codex App coordination skill

* no-mistakes(review): Captain, mark Codex App skill agent-only

* no-mistakes(document): Document Codex App backend boundary

* no-mistakes(document): Captain, document Codex Desktop backend boundary

* no-mistakes(lint): Captain, lint clean

* no-mistakes(document): Document Codex Desktop boundaries

* docs: narrow Codex App skill playbook
* fix(afk): recognize unbordered herdr composer rows to stop escalation redelivery loop

fm_backend_herdr_composer_state only recognized bordered composer rows
(the grok shape). Real claude and codex render their live input row
with no border at all, so once a harness's own startup banner scrolled
out of the capture window the classifier read the composer as unknown
forever. fm_backend_herdr_send_text_submit never confirmed "empty", so
escalate_flush never cleared state/.subsuper-escalations, and the
away-mode daemon retyped and resubmitted the same buffered digest every
housekeeping cycle - reproduced live against a real herdr+claude pane
(5+ identical deliveries in 40s).

The classifier now recognizes an unbordered (bare) composer row led by
a known prompt glyph alongside the existing bordered shape, keeping
whichever match is bottom-most so a stale decorative box never
outranks the live composer.

* no-mistakes(review): Narrow herdr bare prompt matcher

* no-mistakes(document): Sync herdr composer docs
…guid#323)

* fix(herdr): confirm message submit via native agent-state, not composer text

fm_backend_herdr_send_text_submit now confirms a landed submit by polling
herdr's own agent-state (agent get) for the idle->working transition instead
of reading composer content. Composer scraping remains, unchanged, for the
away-mode daemon's pre-injection empty-box guard only.

This fixes the practical effect of the codex idle-tip gap from the
2026-07-07 incident: codex's dynamic idle-composer hint text can no longer
misread as pending and block/mis-confirm a send, since confirmation no
longer looks at composer text at all. Verified empirically against real
claude and codex agents (timing, swallowed-Enter, unreadable-target, and
already-busy-target scenarios), and against the real away-mode daemon
end-to-end after updating its synthetic supervisor-pane test fixture to
register itself as a real herdr agent (herdr's own report-agent primitive)
so it can still exercise the new confirmation path.

* no-mistakes(review): Captain, harden herdr submit confirmation

* no-mistakes(review): Captain, harden herdr submit confirmation

* no-mistakes(document): Sync Herdr submit docs

* no-mistakes: apply CI fixes
* Add quota-balanced dispatch selection

* no-mistakes(document): Document dispatch selector guidance
* fix(session-start): deterministically respawn dead-shell secondmates

A secondmate agent that exits leaves its backend pane alive as a bare
shell. The session-start endpoint check only verified pane presence, so
recovery and the watcher (which exempts secondmates from stale-pane
detection) never noticed - evidence 2026-07-07: every secondmate in one
fleet was found sitting at a dead zsh shell.

Add fm_backend_agent_alive (bin/fm-backend.sh), a deeper per-backend
liveness probe distinct from pane presence: fm_backend_tmux_agent_alive
classifies the pane's live foreground process via tmux's own
pane_current_command, and fm_backend_herdr_agent_alive reuses the
already-verified pane_agent_state husk classifier. Both are conservative:
anything ambiguous reports unknown, never a false dead.

Wire this into a new session-start-only, locked-and-primary-only sweep in
bin/fm-bootstrap.sh that kills and respawns only a confidently dead
secondmate endpoint, leaving alive/unknown readings untouched - idempotent
by construction, so repeated runs converge without duplicating agents.

* no-mistakes(review): Guard raw secondmate liveness respawns

* no-mistakes(review): Fix detect-only bootstrap test

* no-mistakes(test): Pin liveness fixture harness

* no-mistakes(document): Sync secondmate liveness docs

* no-mistakes: apply CI fixes
* Fix NUDGE_SECONDMATES to print stable fm-<id> selectors.

Session-start secondmate sync used to accumulate raw backend window targets
into NUDGE_SECONDMATES, but the liveness sweep in the same bootstrap run can
respawn secondmates onto new endpoints. fm-send with those stale explicit
targets bypasses meta resolution and fails, while fm-<id> resolves correctly.

Accumulate fm-<id> in process_secondmate, update the bootstrap/update contracts
and /updatefirstmate skill, and add a herdr respawn regression test.

* no-mistakes(review): Captain, guard herdr regression jq dependency

* no-mistakes(document): Document stable secondmate nudge selectors

* no-mistakes(lint): Fix shell lint hints
* Make tasks-axi and quota-axi required bootstrap tools

Add both to the normal toolchain checks alongside lavish-axi, keep the
tasks-axi 0.1.1+ compatibility gate, and report quota-axi through the
standard MISSING install-consent flow. TASKS_AXI: available remains a
backlog-backend capability signal only; manual opt-out no longer suppresses
the missing-tool report.

Update bootstrap tests and point docs/configuration.md at the canonical
toolchain contract.

* no-mistakes(review): Clarify manual backlog bootstrap reporting

* no-mistakes(document): Document bootstrap AXI tools
Replace overwrite-in-place wording with explicit delete-then-create
instructions so agents do not modify an existing daily report file.
* Add primary turn-end guards for all harnesses

* no-mistakes(review): Normalize Codex hook cwd resolution

* no-mistakes(review): Fix OpenCode guard worktree anchoring

* no-mistakes(review): Anchor Codex guard outside nested roots

* no-mistakes(review): Anchor Codex guard to hook root

* no-mistakes(review): Avoid Grok permission escalation

* no-mistakes(document): Sync turn-end guard docs
* fix backend selector task id resolution

* no-mistakes(document): Document selector resolution behavior
* fix bootstrap fleet sync timeout

* no-mistakes(review): Fix bootstrap fleet-sync timeout regressions

* no-mistakes(document): Sync bootstrap timeout docs

* no-mistakes(lint): Clean ShellCheck directives

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
* Add fleet snapshot and view

* no-mistakes(review): Fix fleet snapshot parsing and overrides

* no-mistakes(review): Fix secondmate fleet rendering

* no-mistakes(review): Fix backlog title and completion parsing

* no-mistakes(review): Include durable scout reports

* no-mistakes(review): Fix fleet snapshot edge cases

* no-mistakes(review): Captain: gate fleet hints on current state

* no-mistakes(review): Captain: parse bracketed Done PR artifacts

* no-mistakes(document): Sync fleet snapshot docs
* Make fm-send fail loudly on unresolved targets

* no-mistakes(review): Document fm-send FM_HOME contract

* Fix fm-send readiness docs and backend send path

* Fix fm-send docs for cmux and X skill metadata

* Make gotmp teardown test home-explicit

* Scope watcher warning wording to fm-send

* Fix fm-send review findings

* Verify explicit tmux targets before sending

* Isolate turnend guard test home

* no-mistakes(document): Documented fm-send FM_HOME/backend guard additions missing from doc inventories

---------

Co-authored-by: mielyemitchell <249051873+mielyemitchell@users.noreply.github.com>
* fix afk codex ghost composer delivery

* no-mistakes(review): Harden AFK startup flag writes

* no-mistakes(review): Harden AFK daemon liveness checks

* no-mistakes(document): Sync AFK herdr docs

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
* Add harness-aware supervision

* no-mistakes(review): Captain, harden watcher supervision regressions

* no-mistakes(review): Captain, harden watcher supervision cadence

* no-mistakes(review): Harden watcher supervision ownership

* no-mistakes(review): Captain, harden Pi extension marker

* no-mistakes(review): Captain, harden Pi supervision restart checks

* no-mistakes(review): Harden watcher ownership checks

* no-mistakes(review): Captain, harden Pi supervision loading

* no-mistakes(review): Captain, require Pi guard extension loading

* no-mistakes(review): Captain, harden watcher supervision recovery

* no-mistakes(test): Fix fm-send baseline log filtering

* no-mistakes(document): Sync harness supervision docs

* no-mistakes: apply CI fixes
* fix: make x replies split by platform

* no-mistakes(review): Captain: preserve Discord recovery relink context

* no-mistakes(test): Captain: keep split markers outside fences

* no-mistakes(document): Sync X-mode reply docs
* docs: make stow inspect-then-update

* no-mistakes(review): Remove unsupported archive-body guidance

* no-mistakes(review): Clarify stow read-before-write exception

* no-mistakes(test): Require archive-body for stow task notes

* no-mistakes(document): Sync stow memory docs

* no-mistakes(lint): Silence ShellCheck source warning
…d#375)

* fix: attach-and-wait when arm finds a healthy watcher

Grok and Claude re-arm after every turn with work in flight. When a
watcher was already healthy, fm-watch-arm exited immediately with
watcher: healthy, which completed the harness background task and
injected an empty false wake.

Attach to the live identity-matched holder instead, stay until that
cycle ends, then exit 0 so notify fires for a real end-of-cycle. The
peer-startup-race path uses the same contract. --restart and the
started path are unchanged.

* no-mistakes(review): Gate restart watcher peer attach

* no-mistakes(document): Sync watcher arm docs
* docs(readme): reformat Quick Start and recommend Grok equally with Claude Code

* no-mistakes(review): Captain: align harness launch guidance

* no-mistakes(review): Captain, clarify Pi supervised launch

* no-mistakes(review): Captain, document Pi first-launch bridge

* feat(pi): track primary watcher extension for plain-pi launch

Move Pi's primary watcher bridge from a generated state/ file to a
tracked .pi/extensions/fm-primary-pi-watch.ts, matching how the turn-end
guard extension already works: self-hashing version, project-local
auto-discovery after one-time Pi trust. This drops the state/-generation
step and dual -e requirement from the happy path, so Pi's Quick Start
launch becomes plain 'pi', the same friction class as 'claude' and
'grok --trust'.

- bin/fm-pi-watch-extension.sh is removed; nothing generates the
  extension anymore since it is committed.
- fm-session-start.sh and fm-supervision-instructions.sh resolve the
  watcher extension path from FM_ROOT instead of state/, and the
  session-start diagnostic now points at restarting plain pi after
  trust, with -e as a documented fallback.
- fm-spawn.sh points Pi secondmate launches at the tracked extension
  path in the secondmate home instead of generating a state/ copy.
- README Quick Start Pi block is now just 'pi' plus a trust note.
- Tests, docs, and the harness-adapters skill updated to match.

* fix(pi): drop backticks from session-start diagnostic to satisfy shellcheck SC2016
* feat(supervision): add PreToolUse seatbelt against watcher-arm anti-patterns

Adds bin/fm-arm-pretool-check.sh, a shared PreToolUse-style checker that
denies a primary shell command backgrounding, piping, or bundling the
watcher arm/checkpoint, or force-killing the watcher process broadly -
the exact shapes that silently took Grok's supervision down. Wires it
into all five verified harnesses (grok, claude, codex, opencode, pi),
each validated empirically against the real harness.

Also fixes a grok 0.2.93 regression discovered during that validation: the
existing turnend-guard Stop hook's bare root variable broke grok's own
variable pre-substitution and silently no-op'd the hook.

* no-mistakes(review): Harden watcher arm validation

* no-mistakes(review): Harden arm guard metacharacter checks

* no-mistakes(review): Harden nested shell arm guard

* fix(lint): rewrite SC2015 guards in fm-arm-pretool-check.sh as if/then

A && B || C is not if-then-else; C can run when A is true. Replace both
occurrences of the quote-state early-continue with an explicit if/then.
* fix Pi primary supervision lifecycle

* no-mistakes(document): Synchronize Pi primary extension documentation
…#398)

* fix secondmate backlog guidance

* no-mistakes(review): Require reasons for captain backlog holds

* no-mistakes(test): Document secondmate handoff skill requirement

* fix secondmate teardown reminder

* no-mistakes(document): sync teardown reminder docs to work-items-only backlog contract
…kunchenguid#401)

* fix(backlog-handoff): move full item blocks including indented bodies

fm-backlog-handoff only moved the checklist header line, so multi-line
item bodies were left orphaned in the source backlog and never reached
the secondmate. Move the full block (header plus indented body lines)
atomically, treating body membership by indentation so lines like
## Intent stay with the item, and add regression coverage.

* no-mistakes(review): Captain: preserve EOF handoff terminators

* no-mistakes(review): treat blank lines inside item bodies as movable body

* no-mistakes(document): sync backlog-handoff docs with full-block move behavior
…kunchenguid#402)

* guard Herdr lab lifecycle in briefs

* no-mistakes(review): Fix Herdr lab helper and provisioning safety

* no-mistakes(review): Captain, harden Herdr lab lifecycle safety

* no-mistakes(review): fix Herdr lab test cleanup ordering and brief help range

* no-mistakes(review): reject leading options in Herdr lab run guard

* no-mistakes(review): strip leading non-alnum in Herdr lab name generator

* no-mistakes(document): document Herdr lab helper and --herdr-lab brief flag

* no-mistakes(lint): add shellcheck disable for deliberate SC2016 literals in fm-brief herdr-lab

* no-mistakes: apply CI fixes
…nchenguid#403)

* fix watcher arm command policy

* no-mistakes(review): Harden watcher command policy parsing

* no-mistakes(review): Captain: harden watcher policy parsing

* no-mistakes(review): harden watcher policy for expanded paths, direct-watch, and sound prefilter

* no-mistakes(review): close prefilter and classifier locale/ANSI-C watcher-path decode gaps

* no-mistakes(review): fail closed on loop-wrapped broad watcher kills

* no-mistakes(document): sync docs for watcher-arm command-position policy
* fix(agents-md): inject self-governance section into existing AGENTS.md

fm-ensure-agents-md.sh only appended the canonical "## Maintaining this
file" section on skeleton create or CLAUDE.md promotion, so an existing
AGENTS.md that lacked it exited unchanged and forced hand-copying the
wording during a rollout across existing projects. Call the already-
idempotent ensure_maintenance_section on the existing-AGENTS.md paths and
report whether the file changed; a re-run and an already-complete file stay
byte-identical.

Also fixes kunchenguid#389: refuse a case-variant real memory file (e.g. a lowercase
agents.md) instead of silently emitting a CLAUDE.md symlink whose uppercase
literal target dangles once the tree lands on a case-sensitive filesystem.

Tests extend tests/fm-ensure-agents-md.test.sh; skeleton-create and
CLAUDE.md-promotion regressions still pass. Docs updated to match.

* no-mistakes(review): Captain: preserve CRLF maintenance-section idempotency

* no-mistakes(review): Preserve CRLF during maintenance-section injection

* no-mistakes(review): Captain: harden dangling-symlink regression coverage

* no-mistakes(document): Document agent-memory injection outcomes
Deeds67 and others added 24 commits July 10, 2026 12:18
…enguid#432)

* fix(session-start): isolate harness env markers in suite runner

Neutralize CLAUDECODE, PI_CODING_AGENT, and GROK_AGENT in
run_session_start so ambient interactive shells cannot override the
suite's fake ps harness (local-vs-CI split on the pi supervision case).

* no-mistakes(document): Correct Pi marker documentation
…nchenguid#435)

* fix(teardown): retry treehouse return on transient index.lock

Killed crew git ops can leave a short-lived worktree index.lock that
makes treehouse return fail. Retry on that error signature with a
bounded wait (env-overridable), never force-delete a live lock, and
only then fall back to the existing provably-stale cleanup path.

* no-mistakes(review): Harden teardown retry configuration

* no-mistakes(document): Document teardown index-lock retry behavior

* no-mistakes(lint): Fix empty shell variable assignments
* docs: de-feature the scripts.md and CONTRIBUTING test inventories

Slice 1 of the documentation redundancy cleanup wave (firstmate scope).

docs/scripts.md: every row is now one purpose clause; script headers
are the declared owner of behavior, flags, and contracts. Coverage
stays 61/61 scripts; bytes drop 19,922 -> 7,958.

CONTRIBUTING.md: the 54-row per-test inventory is gone; contributors
discover tests by listing tests/*.test.sh and reading each script's
own header, and gated tests print their own skip gates. The run
commands, symlink assertions, and watcher smoke line are unchanged.
Lines drop 135 -> 84 (18,797 -> 7,831 bytes).

Two facts that existed only as inventory rows moved into their
owners' headers first: fm-brief.sh's paused-vs-blocked scaffold
distinction and fm-session-start.sh's Pi extension-loaded check.

No instruction-surface or behavior change; AGENTS.md untouched.

* no-mistakes(review): Captain, fix brief help and Grok test discovery

* no-mistakes(review): Captain: document Grok lock-holder test coverage
* docs: consolidate universal backend contracts into configuration.md

Slice 2 of the documentation redundancy cleanup wave (firstmate scope).

docs/configuration.md is now the declared single owner of three
universal contracts, each with an explicit ownership sentence:
- the universal toolchain list (Toolchain), now also carrying the
  per-tool purpose clauses that previously lived only in the tmux guide;
- the task-selector vocabulary (Runtime backend);
- the tasks-axi compatibility definition (Backlog backend).

The five backend guides' prerequisites replace their verbatim
universal-requirements parentheticals (5 full copies) with a pointer
plus only backend-specific items; zellij/cmux selector restatements
and architecture.md's partial copy become pointers or are dropped;
CONTRIBUTING's compatibility sentence becomes a pointer; two
near-verbatim orca-bootstrap restatements (configuration.md Runtime
backend, orca guide) collapse into the Toolchain owner copy.

Backend-specific setup, behavior, target-string shapes, and every
empirical verification record are untouched. AGENTS.md untouched
(slice 3).

* docs: include git and GitHub auth in the toolchain owner list

The review flagged that the new universal-toolchain owner omitted git
and GitHub authentication while every backend guide now defers its
prerequisites here; bootstrap's NEEDS_GH_AUTH check makes them real
universal requirements.

* no-mistakes(review): Detect Git in bootstrap toolchain

* no-mistakes(document): Clarify GitHub CLI and centralize selector documentation
* feat(daemon): backend-independent active alert for the wedge alarm

When away-mode injection wedges past max-defer, inject_wedge_alarm only
actively signalled via the tmux status-line, which is skipped on non-tmux
backends. A wedged claude-on-herdr primary left only the passive
state/.subsuper-inject-wedged marker (2026-07-10 overnight incident).

Add a config-gated active alert (config/wedge-alarm, local/gitignored;
FM_WEDGE_ALARM_CHANNEL) that reaches the captain even when every pane and
its status-line is unreadable: an OS-level macOS notification (osascript),
a herdr notification, or a captain-supplied command. Default-on (auto) so
the alarm is never silent; each channel best-effort, degrading to the next
and never crashing the daemon loop. The tmux flash and durable marker stay.

The OS notifiers route through a single FM_WEDGE_ALARM_EXEC seam. When the
daemon is sourced (only tests do this; production execs it) the seam
defaults to "discard", and tests/wake-helpers.sh points it at a recorder,
so it is structurally impossible for any test to post a real notification.

Channels verified once manually on macOS 26.5.2 / herdr 0.7.3; see
docs/wedge-alarm.md.

* no-mistakes(review): Bound wedge alarm notifier execution

* no-mistakes(review): Captain: harden wedge alarm notifier safety

* no-mistakes(review): Captain: harden wedge alarm test notifier isolation

* no-mistakes(review): Captain: harden wedge alarm throttling

* no-mistakes(review): Redact wedge alarm directive logs

* no-mistakes(review): Harden wedge alarm notifier safety

* no-mistakes(review): Track notifier process groups through cleanup

* no-mistakes(document): Document wedge-alarm active alert behavior
* docs(agents): extract conditional AGENTS.md material to owned homes

Slice 3 of the documentation redundancy cleanup wave (firstmate scope):
the always-loaded instruction surface drops from 941 lines / 116,733
bytes (~29k tokens per session per fleet member) to 785 / 91,353
(~22.8k tokens), moving only audit-identified conditional and
situational material while preserving every load-bearing invariant at
its trigger point via the inline-stub pattern.

Moves, each to one declared owner plus an inline stub:
- section 3's bootstrap output-line handbook (~44 lines) -> new
  agent-only bootstrap-diagnostics skill, added to the section 13
  trigger index; the detect-consent-install rule and the
  do-not-dispatch gate stay inline as safety-critical.
- section 4's crew-dispatch JSON schema and field semantics ->
  docs/configuration.md 'Crew dispatch profiles' (pointer direction
  flipped); the intake procedure, precedence, backstop, and
  never-select-unverified rules stay inline.
- section 4's quota-balanced algorithm -> bin/fm-dispatch-select.sh
  header (now the declared owner; usage() converted to the dynamic
  header extraction pattern PR kunchenguid#438 established for fm-brief.sh).
- section 7's spawn resolution narrative and example sprawl ->
  bin/fm-spawn.sh header; the isolated-worktree assertion, refusal-is-
  a-blocker rule, and post-spawn duties stay inline.
- section 7's teardown landed-work mechanics -> bin/fm-teardown.sh
  header (section 1's containment pointer retargeted); the fork benign
  case and never-force rule stay inline.
- section 8's watcher classification narrative -> docs/architecture.md
  'Event-driven supervision' (already the owner); every operative rule
  (one live cycle, no turn ends blind, drain first, wake ladder,
  never-pkill, guard responses) stays inline.
- sections 3/4/6/7 secondmate sync, propagation, schema, and handoff
  restatements -> secondmate-provisioning skill, now the declared
  owner including the literal-file inheritance nuance.
- section 14's X-mode cadence mechanism -> docs/configuration.md
  'X mode (.env)', closing issue kunchenguid#363; activation semantics, the
  fmx-respond trigger, and the terminal-wake final-follow-up duty
  stay inline.

CLAUDE.md stays a symlink; no behavior or test change.

* no-mistakes(document): Centralize contract-owner documentation
* 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
…d#453)

* fix(fleet-sync): recover from an orphaned packed-refs.lock

A git ref rewrite (fetch --prune, pack-refs, branch -D) killed after
creating .git/packed-refs.lock but before renaming it - e.g. bootstrap's
timed-out fleet-sync kill or teardown's process kills - leaves a lock that
makes the next sync's fetch fail with "Unable to create
'...packed-refs.lock': File exists", leaving the clone unsynced.

On that signature only, fm-fleet-sync.sh now retries the fetch with a
bounded wait (transient locks self-clear), then removes the lock and
retries once more ONLY when it is provably stale: still present, mtime
age past a threshold, and no lsof holder of the lock file or of the clone
worktree itself (a live git keeps that as its cwd even in the window after
it closes the lock and before it exits). A live lock, a missing lsof, any
failed check, or any other fetch failure keeps today's behavior. Every
wait/retry/removal prints to stderr, and a successful recovery also prints
one "recovered:" summary to stdout so a session-start refresh - which
discards fleet-sync stderr and relays only stdout - still surfaces it.

The shared "is this git lock provably abandoned?" proof is extracted into
bin/fm-lock-lib.sh so it has one owner, used by both fm-teardown.sh and
fm-fleet-sync.sh. Constants are env-overridable knobs. tests/fm-gotmp.test.sh
gains the fm-lock-lib.sh symlink teardown now needs in its fake bin/.

* no-mistakes(review): Captain, remove obsolete teardown wake dependency

* no-mistakes(document): Document packed-refs lock recovery architecture
* feat(herdr): immediate blocked-state escalation via native events.subscribe push

Fold herdr's native pane.agent_status_changed stream into the single watcher so
a crew entering blocked wakes its supervisor sub-second (measured 0.129s)
instead of after the ~240s stale-pane wedge timer.

- bin/fm-transition-lib.sh: backend-neutral normalized-transition record shape
  plus the single-owner status->action policy table (blocked=actionable,
  working=absorb+clear-dedupe, idle/done=defer, else=fall back to polling).
- bin/backends/herdr.sh + herdr-eventwait.py: a raw AF_UNIX events.subscribe
  subscriber over one connection for all this home's herdr panes, subscribing to
  ALL statuses, returning the first fresh blocked edge, with a per-pane dedupe
  marker and a reconnect level-reconcile. Version/schema capability gate.
- bin/fm-backend.sh: has-push / events-capable / wait-transition dispatchers so
  the watcher stays backend-agnostic and the shape+policy are reusable.
- bin/fm-watch.sh: splice the bounded event wait in as the watcher's terminal
  wait primitive (replacing the blind sleep POLL for push-capable homes),
  behind a source guard so the splice is unit-testable; secondmate/paused
  exemptions; map pane->window->task and enqueue a stale wake. No second
  watcher process; the single-cycle invariant and every guard/beacon/turn-end
  mechanism are unchanged.
- Polling stays the permanent fail-closed backstop: below-capability, subscribe
  failure, and repeated runtime failures all degrade to sleep.
- Tests: fake-CLI units (fm-transition-lib, wait/apply/dedupe/reconcile/
  fallbacks in fm-backend-herdr, watcher exemptions in fm-supervision-events)
  plus an isolated real-herdr idle->blocked smoke. docs/herdr-backend.md carries
  the dated evidence and retires the old gap note.

* no-mistakes(review): Captain, fix Herdr disconnect handling and dedupe docs

* no-mistakes(review): Captain, commit markers after wake and reuse capability cache

* no-mistakes(review): Captain, clear stale markers and secure Herdr FIFOs

* no-mistakes(review): Captain, subscribe before Herdr reconciliation

* no-mistakes(review): Captain, make Herdr FIFO handling Bash 3.2-safe

* no-mistakes(test): Captain: include lock library in teardown fixture

* no-mistakes(document): Captain: document Herdr immediate blocked escalation

* fix: clarify shellcheck conditionals
* feat(bearings): deterministic bearings snapshot + durable decision model

Add bin/fm-bearings-snapshot.sh: a bounded TOON-by-default projection over the
canonical fm-fleet-snapshot. Default is local-only (zero network); live open-PR
discovery and checks happen only under --include-prs, which fails soft. Every
dropped surface is marked in omitted[] with the flag that reveals it, and the
prs: line states when checks were not requested, so absence is never silent.

Fix the unresolved-decision masking bug in the canonical layer. fm-classify-lib
gains status_open_decisions, the one authoritative keyed open/resolved fold over
the whole status stream: needs-decision/blocked opens a keyed entry, only an
explicit keyed resolution (or, for run-backed tasks, run-step advancement)
closes it, so a later unrelated done/paused can no longer mask a still-open
captain decision. fm-fleet-snapshot surfaces hints.open_decisions and derives
pending_decision/blocked_event from it; the canonical schema stays complete.

Point the /bearings skill at the one command; add the resolved: writer line to
ship, scout, and secondmate briefs. Register the script and add regression
tests for the output bound, TOON/JSON parity, local-only default, opt-in PR
fetch, partial-failure degradation, decision durability, and report pointers.

* fix(bearings): completed scout report is a pointer, not a pending decision

A completed scout that raised a needs-decision and then finished (done) without
a keyed resolution falsely surfaced as an open/pending decision (the Lavish-103
case). Root cause: the open-decision reconciliation in bin/fm-fleet-snapshot.sh
cleared a stale decision only for a live run-step/pane activity read, so a
terminal task whose current state is read from the status log (a scout or ship
that reached done/failed) never cleared its stale, never-keyed-resolved
needs-decision, and it lingered as pending.

The open-decision set is still derived purely from the keyed fold - never from a
report body or decision-like prose - and reconciled against the crew lifecycle.
Extend that reconciliation so a terminal done/failed state on a single-owner
task (scout or ship), whose deliverable is its report or PR, also clears the set;
a completed scout now surfaces only as a report pointer. Secondmates are excluded
from the terminal clear (persistent, multiplexed stream), which keeps the
unrelated-event masking fix intact. Add regression tests: a completed scout with
decision-like report prose is a pointer not pending (canonical + end-to-end), and
a scout still parked at a decision stays pending so the terminal clear never
over-fires.

* no-mistakes(review): Captain, preserve keyed decisions across shared status parsing

* no-mistakes(review): Captain, close blockers and harden keyed decision parsing

* no-mistakes(review): Captain, bound GitHub enrichment without coreutils timeout

* no-mistakes(review): Captain, bound bearings sections and fail closed

* no-mistakes(review): Captain, disclose capped per-repository PR results

* no-mistakes(document): Refresh bearings documentation and status contracts

* fix(bearings): avoid ambiguous worktree guard
* fix(lint): one shellcheck owner pinned to 0.11.0 for CI/local parity

Firstmate PRs passed local no-mistakes validation but failed CI's
"Lint shell scripts" job on shellcheck findings (SC2015, SC1007, SC2034).
Two divergences caused it:

1. The no-mistakes gate had no commands.lint, so its lint step never ran
   the deterministic shellcheck bin/*.sh bin/backends/*.sh tests/*.sh that
   CI runs. Confirmed from state.sqlite: the lint step_result recorded
   findings:null with no lint agent invocation.
2. CI's shellcheck floated with the runner image while local ran a newer
   build; shellcheck retired SC2015 in 0.11.0, so an older CI shellcheck
   rejected an SC2015 that the newer local one no longer emits.

Establish bin/fm-lint.sh as the single owner of the lint definition: the
file set, the config, and the pinned shellcheck version (0.11.0, printed
via --required-version). Both CI (.github/workflows/ci.yml) and the
no-mistakes gate (.no-mistakes.yaml commands.lint) invoke it; CI installs
the exact version it names and logs the resolved version, and fm-lint.sh
refuses to lint under any other version. This is not a CI relaxation: it
adopts shellcheck 0.11.0's rule set consistently, dropping only the
upstream-retired, false-positive-prone SC2015; default severity and every
still-supported finding stay enforced (no severity downgrade, no excludes).

tests/fm-lint.test.sh asserts both gates invoke the owner, that CI installs
and logs the pinned version, that the owner refuses a non-pinned shellcheck,
and that it rejects a real lint defect the old no-op gate passed.

* no-mistakes(review): Captain, harden deterministic ShellCheck parity

* no-mistakes(review): Captain, neutralize ambient ShellCheck overrides
* feat: add cd-guard PreToolUse seatbelt for the primary shell

A stray persistent top-level `cd projects/<clone>` in the primary firstmate
shell relocates the shell, so a later firstmate-owned command (a backlog write,
an fm-* lifecycle call, tasks-axi) runs inside a project clone instead of the
home. The cd-guard denies exactly that command shape before it runs, across all
five verified primary harnesses, mirroring the watcher-arm PreToolUse seatbelt.

- bin/fm-cd-command-policy.mjs: sole block/allow decision owner. Reuses the
  shell classifier exported from bin/fm-arm-command-policy.mjs (no duplicate
  lexer; that file's CLI now runs only when invoked directly).
- bin/fm-cd-pretool-check.sh: transport, strict-superset prefilter, harness
  output rendering, and primary-checkout scoping - fires in a secondmate's own
  primary session, inert in crew/scout child worktrees and non-firstmate repos.
- Wired into claude, codex, grok, opencode, and pi PreToolUse-equivalents;
  per-harness hooks only call the owner.
- Blocks top-level cd/pushd/popd (including cd to an absolute path, X=1 cd,
  and command cd). Allows git -C, subshell / bash -c / env -C / make -C /
  find -execdir, pipeline and background forms, and cd-as-data. Fails open on
  malformed input; agent-mistake threat model.
- tests/fm-cd-pretool-check.test.sh: 43-case x 5-harness-entry-form matrix,
  end-to-end cwd-leak regression, scoping, fail-open, prefilter, and wiring.
- docs/cd-guard.md: full contract plus live validation (claude, codex,
  opencode, pi blocked end-to-end; grok live run blocked by an API balance
  limit, with mechanism parity and deterministic coverage recorded).

* no-mistakes(review): Captain, fix cd-guard classification and prefilter coverage

* no-mistakes(review): Captain, allow path-qualified command wrappers

* no-mistakes(review): Captain, allow non-executing command queries

* no-mistakes(test): Captain, clarify cd-guard safe-path remediation

* docs: clarify cd guard guidance

* no-mistakes(document): Clarify cd-guard safe target guidance
…kunchenguid#267)

Crews must never stop, restart, or update the shared no-mistakes
daemon since one instance serves every firstmate lane/home; a restart
kills other lanes' in-flight pipeline runs and forces expensive
re-runs. Encodes this as a new numbered rule in both the ship-task and
scout-task brief scaffolds.

Co-authored-by: mielyemitchell <249051873+mielyemitchell@users.noreply.github.com>
* feat(bearings): four-section chat contract, accurate secondmate landed, resolved-event state render

/bearings skill (one owner of the chat-response format): mandate the four
always-present chat sections - Captain's Call, Recently Landed, Underway,
Charted Next - each with an explicit empty-state sentence, no At Anchor,
materially shorter than and linking to the report file. Resolves the ambiguous
Check first / Decisions pending split into one strict captain-action section.

fm-crew-state: the log fallback derives current state only from a real
run-state verb, so a trailing decision-closing resolved: event no longer
renders a healthy idle crew (typically a secondmate) as unknown with the
resolution prose as its detail. The keyed-decision contract in
fm-classify-lib.sh is untouched; map_log_state stays the one verb->state owner.

fm-fleet-snapshot: add a bounded, read-only secondmate_landed roll-up of Done
records from registered secondmate homes, reusing the single backlog parser and
the one secondmate-home enumerator (meta home= with data/secondmates.md
fallback); no network, per-home capped.

fm-bearings-snapshot: landed now merges main-home Done with the secondmate
roll-up, bounded by a per-home cap and an overall cap with omitted[] disclosure
(also fixing the previously-silent landed truncation); --all-landed reveals the
full set.

tests: resolved-event state render, secondmate landed aggregation with caps and
omitted[] disclosure, Captain's Call anti-leak, and the four-section contract.

* no-mistakes(review): Captain, ensure bearings reveals all landed work

* no-mistakes(document): Document bearings accuracy contracts
* fix: script-owned non-visible away-daemon launch + stale-artifact lifecycle

Away-mode entry left "make the daemon a tracked background terminal" to the
operator; on a pi/herdr primary that meant splitting the captain's active pane,
which visibly shrank it. Add bin/fm-afk-launch.sh, a single owner that launches
the daemon in a non-visible tracked terminal per backend (herdr dedicated
--no-focus workspace, detached tmux session), never a split, pins the captain
pane as FM_SUPERVISOR_TARGET/FM_SUPERVISOR_BACKEND, records the exact terminal
id, and tears it down or reconciles a leaked one by that id. No shell &.
Extract supervisor-pane discovery into bin/fm-supervisor-target-lib.sh, shared
with the daemon (one owner).

Fix the stale subsuper-artifact leak: clear the prior away session's delivery
cache on a fresh entry (fm_afk_clear_stale_artifacts), and stop the daemon
before clearing state/.afk so its shutdown flush runs instead of being a no-op.

Tests: tests/fm-afk-launch.test.sh (per-backend topology invariant in a lab
session, stale clear-on-entry vs refresh, exit ordering). Docs: /afk SKILL.md,
docs/herdr-backend.md (dated herdr evidence), AGENTS.md exit stub, docs/scripts.md.

* no-mistakes(review): Captain, serialize AFK launcher lifecycle safely

* no-mistakes(review): Captain, harden AFK launcher lifecycle races

* no-mistakes(review): Captain, ensure AFK daemon launch readiness

* no-mistakes(review): Captain, unify AFK lifecycle ownership and teardown

* no-mistakes(review): Captain, preserve AFK reconciliation records uniformly

* no-mistakes(review): Captain, harden AFK recovery state durability

* no-mistakes(review): Captain, harden AFK tmux ownership checks

* no-mistakes(review): Captain, simplify AFK lifecycle failure handling

* no-mistakes(review): Captain, require confirmed AFK daemon shutdown

* no-mistakes(review): Captain, confirm AFK exit by process identity

* no-mistakes(document): Align AFK launcher lifecycle documentation

* no-mistakes: apply CI fixes
Upstream range merged: kunchenguid/firstmate upstream/main 138a9d0..ad9f3a7 (54 commits) into fork main 46cb39e. Merge base: 678f2b5.

Conflicts resolved:

- Instructions/docs/skills (AGENTS.md, README.md, CONTRIBUTING.md, .agents/skills/*, docs/*): kept upstream's centralized operating-contract rewrite as the base; reintroduced fork-specific wrapper/Fm-home guidance where behavior still exists.

- Backend/send/watch/teardown scripts: kept upstream's newer backend/event/composer/send architecture; re-applied fork-local fleet-freeze send refusal, dispatch-ack recording/scanning/pruning, tasks-axi wrapper reminder, Herdr protocol floor 16, and robust best-effort teardown kill semantics.

- Tests: kept upstream's expanded supervision/backend suites; adjusted fixtures for ambient FM_HOME isolation, optional tasks-axi 0.2.2 support, ack/freeze helper imports, and stricter send resolver semantics.

Fork-only survival table:

- e2e0da7 fleet freeze and fleet-map incident guardrails: survived/re-applied. fm-freeze/fm-fleet-map files and tests retained; fm-send freeze refusal re-applied. Verified by tests/fm-freeze.test.sh and full suite.

- 82a5a25 stale task-state reconciliation: survived. fm-reconcile-stale files/tests retained. Verified by tests/fm-reconcile-stale.test.sh and full suite.

- ecd88ce usage-tripwire watcher check: survived. fm-usage-tripwire files/tests retained. Verified by tests/fm-usage-tripwire.test.sh and full suite.

- 67f8a6d fm-send fail-closed unresolved targets: superseded by upstream strict resolver, with fork strict tests retained. Verified by tests/fm-send-strict.test.sh.

- 2aee766 fm-crew-state stale checks-green guard: survived in upstream/fork merged crew-state tests. Verified by tests/fm-crew-state.test.sh.

- d6849be PR merge green/non-cancelled checks: survived. Verified by tests/fm-pr-merge.test.sh.

- 8cc5238 dispatch-ack supervision: re-applied onto upstream send/watch/teardown. Verified by tests/fm-ack-loop.test.sh and full suite.

- 111c7d8 no-mistakes probe timeout: survived/superseded by upstream bootstrap diagnostics. Verified by tests/fm-bootstrap.test.sh.

- 5906a04 popup-risk unverified submit failure: superseded by upstream native submit verification; fork popup-settle coverage retained. Verified by tests/fm-send-popup-settle.test.sh.

- 1933d34 shared no-mistakes daemon safety rule in briefs: superseded by upstream cb6e8ed scaffold rule. Verified by tests/fm-brief.test.sh.

- e3b5606 AGENTS judgment criteria: survived in merged AGENTS/docs operating guidance. Verified by AGENTS reconciliation and full suite.

- 53c715f FM_HOME ownership guards: survived. fm-home-guard files/tests retained; tasks-axi wrapper reminder re-applied. Verified by tests/fm-home-guard.test.sh and tests/fm-tasks-axi.test.sh.

- 9bd3170 busy popup-risk idle-to-busy acceptance: superseded by upstream submit verification; retained tests pass. Verified by tests/fm-send-popup-settle.test.sh.

- 22f6dab Herdr min protocol floor 16: re-applied to upstream Herdr adapter/docs while retaining upstream event protocol split. Verified by tests/fm-backend-herdr.test.sh.

- 46cb39e real-Herdr smoke retry under treehouse contention: survived. Retry helper and smoke wrappers retained. Verified by real Herdr smoke tests in full suite without retry.

Verification:

- Ran every tests/*.test.sh sequentially. Result: pass, with environment skips: cmux socket not reachable/authenticated, zellij not found, Pi live opt-in unset, tsc not found, and installed tasks-axi lacks atomic multi-ID mv support (0.2.2+ required).

- shellcheck bin/*.sh bin/backends/*.sh tests/*.sh passed.

- /Users/mielyemitchell/firstmate/bin/fm-ensure-agents-md.sh . reported unchanged AGENTS.md/CLAUDE.md.
Independent review found the merge survival table overstated several fork-only rows after upstream rewrites. This follow-up preserves the original merge commit and corrects the branch with the missing fork intent reapplied.

Re-applied review findings:

- B1: restore popup-risk submit verification in bin/fm-send.sh. Unknown submit verdicts now hard-fail for popup-risk sends unless the backend moves from idle to busy, and the deleted codex dollar-skill unknown-verdict loud-fail test is restored.

- S1: restore fm_fleet_freeze_refuse in bin/fm-watch.sh and cover it in tests/fm-freeze.test.sh.

- S2: restore AGENTS.md judgment criteria lost during conflict resolution: secondmate routing by domain nouns/specific scope, dependency serialization, the yolo Routine definition, unknown crew-state recovery, and dead secondmate endpoint recovery.

- S3: restore the bounded no-mistakes probe in bin/fm-bootstrap.sh via FM_NO_MISTAKES_PROBE_TIMEOUT and cover it in tests/fm-bootstrap.test.sh.

Corrected fork-only survival table rows:

- e2e0da7 fleet freeze: re-applied; fm-spawn, fm-send, and fm-watch now refuse while frozen.

- 111c7d8 bootstrap diagnostics: re-applied; no_mistakes_bounded preserves FM_NO_MISTAKES_PROBE_TIMEOUT.

- 5906a04 AGENTS judgment criteria: re-applied; the yolo routine decision standard and crew-state recovery criteria are present again.

- e3b5606 fm-send loud-fail verification: re-applied; popup-risk unknown submit verdicts fail loudly unless the idle-to-busy evidence proves acceptance.

- 9bd3170 busy-popup risk: re-applied; popup-risk sends use the idle-to-busy probe and restored regression test.

- 67f8a6d send fail-closed: partially superseded by upstream exact id handling, but the popup-risk fail-closed core is explicitly retained here.

Verification before commit:

- bash tests/fm-send-popup-settle.test.sh

- bash tests/fm-freeze.test.sh

- bash tests/fm-bootstrap.test.sh
@mielyemitchell mielyemitchell changed the title feat: merge upstream firstmate improvements into fork, preserve fork-only behavior feat: merge upstream improvements, preserve fork-only behavior Jul 12, 2026
Restore the TASKS_AXI warning when the repo-root backlog and active FM_HOME backlog diverge. This keeps bootstrap aligned with the bin/fm-tasks-axi.sh wrapper mandate so agents do not run bare tasks-axi from the repo root and mutate the wrong home backlog.

Verification:

- bash tests/fm-bootstrap.test.sh

- bin/fm-lint.sh
Keep the stow/AGENTS task-note contract aligned with the merged wrapper mandate: use bin/fm-tasks-axi.sh instead of bare tasks-axi when FM_HOME can differ from the repo root.\n\nVerification:\n- bash tests/fm-stow-contract.test.sh\n- bash tests/fm-bootstrap.test.sh\n- git diff --check
@mielyemitchell mielyemitchell changed the title feat: merge upstream improvements, preserve fork-only behavior feat: sync upstream improvements while preserving fork-local guardrails Jul 12, 2026
@mielyemitchell
mielyemitchell merged commit 000ed28 into main Jul 14, 2026
5 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.

5 participants