Skip to content

feat: integrate upstream main advances (#367-#444, #435 deferred) - #8

Merged
Keigyoku merged 30 commits into
mainfrom
fm/upstream-integration
Jul 11, 2026
Merged

Keigyoku merged 30 commits into
mainfrom
fm/upstream-integration

Conversation

@Keigyoku

Copy link
Copy Markdown
Owner

What Changed

Integrates kunchenguid upstream main advances into fork main: 24 upstream commits cherry-picked with -x (kunchenguid#367 harness-aware supervision, kunchenguid#369 X-mode platform split, kunchenguid#372-kunchenguid#429 watcher/composer/secondmate/backlog fixes, kunchenguid#402 herdr lab, kunchenguid#134 stable-window-id tmux spawn, kunchenguid#432 test isolation, kunchenguid#438 docs consolidation, kunchenguid#445 backend config centralization, kunchenguid#444 wedge alerts), plus reconciliation commits.

Deliberately excluded:

Key reconciliations preserving fork-landed behavior:

  • cursor/hermes adapters, their model/effort bracket, busy signatures, and tmux liveness classification kept (the last two restored by the review gate after upstream's tmux files were adopted).
  • herdr-lab helper imported with the leading --session global flag per the fork's verified herdr 0.7.3 pane-run finding (upstream still documents the trailing form).
  • fork's jq-universal requirement and Orca CLI-shape probe grafted into upstream's centralized toolchain section; upstream's git requirement added.
  • upstream's composer-lib refactor and fix(spawn): make tmux window handling robust under non-default config kunchenguid/firstmate#134 window-id spawn adopted with the fork's adopt-worktree/LAUNCH_CWD semantics.
  • the successor's X-link carry adapted to upstream's platform-aware relink contract (forwards x_platform/x_reply_max_chars, defaults legacy links to the X budget instead of halting the watchdog).

Validation (no-mistakes gate, pr/ci skipped per operator standing order)

  • Rebase, Review (1 fix round restoring cursor/hermes detection, ending 0 findings), Test (full suite), Document, Lint, Push: all green.
  • Local pre-gate: watchdog (metrics/steer/successor/embargo), composer, daemon, tangle-guard, and x-mode suites green; full shellcheck clean; zero conflict markers.

Follow-up

Copilot AI review requested due to automatic review settings July 11, 2026 02:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Captain, this PR syncs a large set of upstream main improvements into the fork while preserving fork-specific harness and supervision behavior, and it expands the test/docs surface to lock in those operational contracts.

Changes:

  • Adds harness-aware supervision protocol rendering, including a Codex-oriented bounded foreground watcher checkpoint helper.
  • Strengthens supervision safety and determinism (tmux stable window-id targeting, composer “dead shell vs empty composer” safety, away-mode wedge alarm channels).
  • Tightens toolchain/backlog mechanics (stronger tasks-axi compatibility gating; secondmate seed-marker gitignore + sync tolerance), and broadens regression coverage across backends/harness hooks.

Reviewed changes

Copilot reviewed 75 out of 114 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/wake-helpers.sh Installs a wedge-alarm notifier recorder seam for daemon/wake suites to prevent real OS/UI notifications in tests.
tests/fm-watch-checkpoint.test.sh Adds behavior coverage for the new bounded foreground watcher checkpoint flow.
tests/fm-teardown.test.sh Extends the fake tasks-axi to include help output needed by the compatibility probe.
tests/fm-tangle-guard.test.sh Adds regression tests pinning robust tmux window construction (append-form, stable window id, rename pinning).
tests/fm-supervision-instructions.test.sh Adds tests for harness-aware supervision instruction rendering and repair-line output.
tests/fm-stow-contract.test.sh Pins /stow inspect-then-update task-note contract (no append; archive via --archive-body).
tests/fm-secondmate-sync.test.sh Adds tests and helpers for .fm-secondmate-home marker gitignore convergence and safety.
tests/fm-secondmate-lifecycle-e2e.test.sh Makes backlog-handoff phase conditional on compatible tasks-axi; ensures secondmate teardown emits no main-backlog reminder.
tests/fm-pi-primary-types.test.sh Adds strict no-emit TypeScript typecheck for the two tracked Pi primary extensions.
tests/fm-grok-harness.test.sh Clarifies test intent in header comment (grok hook auth/cleanup/lock-holder detection).
tests/fm-crew-state.test.sh Adds tests for paused: as a first-class “declared external wait” state (including configurable paused verb).
tests/fm-composer-lib.test.sh Adds tests pinning shared composer classification safety (bare shell glyphs => unknown, bordered => empty, etc.).
tests/fm-bootstrap.test.sh Extends bootstrap cases for new tasks-axi feature gating and adds a missing-git requirement test.
tests/fm-backend-orca.test.sh Adds coverage for bare-shell prompt safety in Orca composer-state handling.
tests/fm-backend-herdr-workspace-per-home-e2e.test.sh Uses isolated “lab” session naming and prepares the Herdr lab session before running.
tests/fm-backend-herdr-smoke.test.sh Same Herdr lab session isolation + uses lab stop helper for restart checks.
tests/fm-backend-herdr-respawn-idem-e2e.test.sh Same Herdr lab session isolation + uses lab stop helper.
tests/fm-backend-herdr-prune-safety-e2e.test.sh Makes collision repro deterministic by explicit workspace label; adopts lab session isolation.
tests/fm-backend-autodetect-smoke.test.sh Uses isolated Herdr lab session naming + preparation.
tests/fm-afk-inject-herdr-e2e.test.sh Uses isolated Herdr lab session naming + preparation.
README.md Updates requirements wording, adds recommended harness guidance, and links supervision-protocol docs + wedge-alarm doc.
docs/zellij-backend.md Consolidates prerequisites references into docs/configuration.md and aligns selector-contract wording.
docs/wedge-alarm.md New doc describing away-mode injection wedge alarm channels, safety seam, and verification notes.
docs/tmux-backend.md Moves universal prerequisites to docs/configuration.md and documents composer-emptiness safety note.
docs/supervision-protocols/unknown.md New unknown-harness fallback supervision protocol.
docs/supervision-protocols/pi.md New Pi primary supervision protocol (extension-owned watcher arm + safety constraints).
docs/supervision-protocols/opencode.md New OpenCode primary supervision protocol (plugin-owned watcher arm).
docs/supervision-protocols/grok.md New Grok primary supervision protocol (background-notify + sourcing effective x-mode env).
docs/supervision-protocols/codex.md New Codex primary supervision protocol (bounded checkpoint loop, avoid background).
docs/supervision-protocols/claude.md New Claude primary supervision protocol (background-notify arm, attach semantics).
docs/orca-backend.md Consolidates prerequisites references and notes shared composer classifier behavior.
docs/examples/wedge-alarm Provides copyable local config/wedge-alarm example.
docs/cmux-backend.md Consolidates prerequisites references and clarifies shared selector-contract ownership.
bin/fm-x-reply.sh Adds platform-aware reply sizing (X vs Discord) based on inbox context and explicit overrides.
bin/fm-x-poll.sh Renames header wording to “X-mode mention” for platform-split clarity.
bin/fm-x-followup.sh Threads platform/budget context into followups; clarifies X-mode wording.
bin/fm-x-dismiss.sh Renames header wording to “X-mode mention”.
bin/fm-watch-checkpoint.sh Adds a bounded foreground runner for fm-watch.sh, with timeout/gtimeout/perl fallback.
bin/fm-watch-arm.sh Introduces “attached” behavior (wait on existing healthy cycle) and adds attach polling.
bin/fm-wake-lib.sh Makes watcher-path comparison robust to symlinked path spellings via fm_paths_same_file.
bin/fm-wake-drain.sh Minor comment clarification (supervision chain wording).
bin/fm-turnend-guard.sh Uses harness-aware supervision renderer to generate repair guidance; adds x-mode/afk awareness.
bin/fm-turnend-guard-grok.sh Aligns fallback repair text with new supervision operating block phrasing.
bin/fm-teardown.sh Suppresses backlog refresh reminder for secondmate teardown (since secondmates aren’t backlog items).
bin/fm-tasks-axi-lib.sh Strengthens compatibility: requires --archive-body and multi-id tasks-axi mv support.
bin/fm-successor.sh Carries X-link platform/budget context into successor relink behavior with safe defaults.
bin/fm-spawn.sh Makes tmux spawn robust via stable window-id targeting and pins Pi secondmate launches to load both primary extensions.
bin/fm-session-start.sh Emits harness-specific supervision operating instructions; adds Pi extension-loaded detection and reminder line.
bin/fm-guard.sh Uses harness-aware supervision renderer for repair guidance (afk/x-mode/queue-aware).
bin/fm-ff-lib.sh Documents linked-worktree vs clone behavior and seed-marker tolerance/gitreasoning.
bin/fm-ensure-agents-md.sh Makes maintenance section injection idempotent for existing AGENTS.md; adds case-variant filename refusal; CRLF-aware injection.
bin/fm-crew-state.sh Adds paused state mapping via shared classify logic so declared external waits are distinguishable from idle/wedge.
bin/fm-bootstrap.sh Adds git requirement; updates tasks-axi gating description; updates x-mode setup messaging to reference harness-aware repair guidance.
bin/backends/tmux.sh Captures tmux window id on creation and disables rename options to keep fm-<id> stable.
bin/backends/orca.sh Delegates composer content classification to shared composer-lib and fixes dead-shell safety semantics.
bin/backends/cmux.sh Delegates composer content classification to shared composer-lib and fixes dead-shell safety semantics.
.pi/extensions/fm-primary-turnend-guard.ts Adds lock/marker “loaded” signaling, embeds PreToolUse seatbelt, and refines follow-up loop guard behavior.
.opencode/plugins/fm-primary-turnend-guard.js Uses realpath-based root resolution and yields to the watch-arm coordinator when present; updates repair wording.
.opencode/plugins/fm-primary-pretool-check.js Adds OpenCode PreToolUse seatbelt plugin to block unsafe watcher-arm command patterns.
.grok/hooks/fm-primary-turnend-guard.json Simplifies hook invocation to exec the guard script directly from workspace root.
.grok/hooks/fm-primary-pretool-check.json Adds Grok PreToolUse hook for the watcher-arm seatbelt.
.gitignore Ignores .fm-secondmate-home marker and local config/wedge-alarm.
.github/workflows/ci.yml Installs tasks-axi in CI to support backlog-handoff delegation tests.
.codex/hooks.json Adds PreToolUse hook wiring to enforce watcher-arm command-position policy.
.claude/settings.json Adds PreToolUse hook wiring to enforce watcher-arm command-position policy.
.agents/skills/stow/SKILL.md Updates /stow contract to “inspect then rewrite” for task notes (no append; archive body).
.agents/skills/secondmate-provisioning/SKILL.md Adds --no-projects option and updates backlog handoff to delegate to tasks-axi mv with stronger guarantees.
.agents/skills/firstmate-codexapp/SKILL.md Extends allowed status verbs to include paused: with guidance on when it’s appropriate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

kunchenguid and others added 27 commits July 10, 2026 21:33
* 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

(cherry picked from commit 090483e)
* 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

(cherry picked from commit 4790bc5)
* 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

(cherry picked from commit af5361e)
…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

(cherry picked from commit 7302a95)
* 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

(cherry picked from commit 1b5a9f5)
* 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.

(cherry picked from commit 766f772)
* fix Pi primary supervision lifecycle

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

(cherry picked from commit 80ecc8d)
…#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

(cherry picked from commit 7525a37)
…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

(cherry picked from commit 600075e)
…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

(cherry picked from commit 4bc0824)
…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

(cherry picked from commit 22b1d71)
* 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

(cherry picked from commit 96244f4)
* feat(secondmate): support project-less homes via --no-projects

fm-brief.sh --secondmate and fm-home-seed.sh now accept an explicit
--no-projects signal to scaffold, seed, and register a secondmate home
whose subject is the firstmate repo itself (no clones). The signal is
mutually exclusive with a project list; omitting both still fails loudly
so an accidental omission is never a silent project-less seed. The
registry line renders an empty projects: field, which spawn and the
snapshot already tolerate. Docs updated in the secondmate-provisioning
skill and both script headers.

* no-mistakes(review): Captain: document project-less secondmate flow

* no-mistakes(review): Captain: refuse project-less reseeding of populated homes

* fix(seed): fail closed on unreadable project data

* no-mistakes(review): Captain: reject stale projectful charters

* no-mistakes(review): Captain: fail closed on unsafe project paths

* no-mistakes(review): Captain: validate project-less charter clone sections

* no-mistakes(document): Document project-less secondmate seeding

(cherry picked from commit 08453f9)
* wip(handoff): record verified delegation design + tasks-axi mv blocker

No production code changed yet. tasks-axi mv (v0.2.1) cannot atomically
move a blocked-by-linked item set across backlogs (deadlocks both orders,
no batch/--force), which fm-secondmate-lifecycle-e2e requires. Parked
pending a tasks-axi connected-set mv enhancement; note captures the
verified design, semantics, test/CI/doc changes, and resume checklist.

* refactor(handoff): delegate the item move to tasks-axi mv

fm-backlog-handoff.sh's two-pass awk was a second parser of the backlog
format and the source of the PR kunchenguid#401 body-orphaning drift. Delete it and
delegate the move to `tasks-axi mv <id>... --to <dest>` (v0.2.2 atomic
multi-id), the single owner of the format: a connected set (blocker plus
dependents) moves together with blocked-by preserved, item blocks stay
byte-exact, and destination section placement holds. The helper keeps only
the fleet-level validation tasks-axi cannot know - secondmate-home
resolution, the seeded-home safety checks, the In-flight refusal, and
idempotent per-key reporting - and is atomic: on any move failure nothing
moves.

Tests: fm-backlog-handoff.test.sh keeps PR kunchenguid#401's regression matrix but now
exercises the delegated path and skips cleanly when tasks-axi is absent; the
two whole-file fixtures move to tasks-axi's canonical whitespace. The
lifecycle-e2e and safety move-cases gain the same skip guard. CI installs
tasks-axi so the delegated path is exercised. Docs state that
config/backlog-backend=manual governs firstmate's own hand-editing, not this
validated helper, which delegates fleet-wide because bootstrap requires
tasks-axi on PATH.

Remove the now-redundant WIP design note.

* no-mistakes(review): Captain: harden atomic backlog handoffs

* no-mistakes(review): Captain: enforce queued-only backlog handoffs

* no-mistakes(review): Captain: harden handoff section parsing

* no-mistakes(document): Document delegated backlog handoffs

* no-mistakes(lint): Silence ShellCheck source diagnostics

(cherry picked from commit 31afb8c)
* fix: gitignore the secondmate home marker

bin/fm-home-seed.sh writes an untracked .fm-secondmate-home marker into
every seeded secondmate home. A secondmate home is a worktree of the
firstmate repo, so any plain `git status --porcelain` dirtiness check
counted the untracked marker and the home read as dirty forever:
fleet-sync reported it STUCK and the local fast-forward convergence
sweeps risked leaving it stale on firstmate updates.

Add .fm-secondmate-home to the tracked .gitignore so the marker is
invisible to every dirtiness check uniformly, without weakening
fleet-sync's deliberate untracked-counting for project clones.

Convergence chicken-and-egg: existing homes predate the fix and it only
arrives by fast-forward. The already-present marker-tolerant ff-skip
(ignore_seed_marker=yes, used by the bootstrap sweep, /updatefirstmate,
and spawn pre-launch) advances such a home past the fix commit, after
which .gitignore takes over - no hand intervention.

Tests in tests/fm-secondmate-sync.test.sh cover a freshly seeded home
reading clean, an existing marker-only home converging then reading
clean, and a genuinely dirty home still skipping.

* no-mistakes(review): Captain: document standalone-clone update path

* no-mistakes(document): Document secondmate marker migration

(cherry picked from commit 171207c)
* fix(composer): stop reading dead-shell prompts as empty agent composers

Consolidate composer empty/pending/unknown classification into one shared
owner, bin/fm-composer-lib.sh's fm_composer_classify_content, delegated to by
all four backend adapters (tmux via fm-tmux-lib.sh, herdr, orca, cmux). This
replaces four drifting copies of the glyph decision.

Safety fix: a bare shell prompt glyph (> $ % #) on an unstructured row is now
classified unknown (a dead shell, unsafe for injection), not empty. It is only
empty inside a bordered composer box (the harness's own prompt). Agent glyphs
❯ (claude) and › (codex) read empty either way. The away-mode injector
(inject_msg) now requires an affirmatively-empty composer, deferring on pending
or unknown, so an escalation can never be typed into (or executed by) a pane
whose agent exited to its login shell.

Regression coverage: new tests/fm-composer-lib.test.sh pins the shared owner;
per-backend dead-shell tests in fm-daemon (tmux + injector), orca, and the
existing herdr/cmux suites. shellcheck clean; herdr incident regressions stay
green.

* no-mistakes(review): Captain: harden composer safety checks

* no-mistakes(test): Stabilize Herdr prune safety setup

* no-mistakes(document): Document composer injection safety

* no-mistakes(lint): Clean composer safety lint

* no-mistakes: apply CI fixes

(cherry picked from commit a955a05)
* feat(watcher): add paused/awaiting-external crew state

A crew (or firstmate steering it) can declare a deliberate wait on a known
external dependency with a paused: <reason> status. Both the always-on watcher
and the away-mode daemon absorb such an idle pane through shared fm-classify-lib.sh
vocabulary instead of tripping the possible-wedge stale escalation, and re-surface
it for a recheck only on a long bounded cadence (FM_PAUSE_RESURFACE_SECS) so a
forgotten pause cannot rot invisibly. fm-crew-state.sh reports state: paused
distinctly. A crew that goes idle without declaring a pause classifies exactly as
before. Docs and brief scaffold state lists updated; tests colocated.

* no-mistakes(review): Captain: fix paused-state transitions

* init

* no-mistakes(review): Captain: fix paused-state supervision transitions

* no-mistakes(review): Captain: fix paused supervision handoffs

* no-mistakes(review): Reconcile paused supervision markers

* no-mistakes(review): Captain: prioritize paused states over captain relevance

* no-mistakes(review): Captain: preserve paused-working wedge timer

* no-mistakes(review): Captain: honor configured pause verb in briefs

* no-mistakes(test): Captain: fix AFK paused watcher handoff

* no-mistakes(document): Document declared external waits

* no-mistakes(lint): Clean paused-state lint

---------

Co-authored-by: fmtest <fmtest@example.invalid>
(cherry picked from commit 7788fa3)
* fix(x-mode): make follow-up platform splitting immune to link ordering

A ~470-char Discord follow-up posted as a (1/2)(2/2) thread split at ~280
chars because fm-x-link only learned the platform from the inbox payload,
and the fmx-respond ack path can drain that inbox file before the task is
linked. A link recorded after cleanup silently lost the platform and the
splitter defaulted to the X 280-char budget.

Make platform resolution ordering-proof:

- fm-x-link now resolves the platform AUTHORITATIVELY by request_id via a
  new fmx_request_relay_context helper (POST /connector/request-context)
  when neither the inbox payload nor carry flags carry it. The request_id
  survives the inbox drain, so a post-cleanup link still learns the right
  split budget. Best-effort: no token/curl or a non-2xx relay degrades to
  the loud warning below rather than a silent X default.
- fm-x-link warns loudly when no platform source resolves, so the loss is
  never silent.
- The fmx-respond procedure now orders link-before-inbox-cleanup so the
  fast local path stays correct without a relay round-trip.

Colocated regression tests: a Discord follow-up >280 <2000 posts as ONE
message even when linked after inbox cleanup, and an unresolvable platform
warns loudly instead of splitting silently. docs/configuration.md documents
the request-context lookup.

The relay endpoint is the companion durable change (see done status); until
it ships, the link-before-cleanup reorder keeps the normal path correct.

* no-mistakes(document): Document X-mode platform recovery

(cherry picked from commit 5f808cc)
* fix(composer): one ANSI-aware ghost owner covers claude dim + grok truecolor

Away-mode injection wedged all night on the primary claude-on-herdr pane:
the herdr composer classifier never stripped generic dim ghost text (only a
narrow codex bold-wrapped byte-pattern check), so claude's rotating
prompt-suggestion ghost - a bare "❯" then SGR-2 dim text, which herdr's ANSI
pane read preserves - read as real pending input and every escalation deferred
(6524 lifetime "pending input (non-empty composer)" defers; wedge 30623s).

Consolidate ghost extraction into one fleet-wide ANSI-aware owner,
fm_composer_strip_ghost (bin/fm-composer-lib.sh), that drops every
de-emphasised run - dim/faint (SGR 2: claude, codex) AND a dark/muted truecolor
foreground (grok's placeholder, luminance below FM_COMPOSER_GHOST_LUMA_MAX,
default 128, dark-theme assumption). Both ANSI-capable backends route through
it: fm_tmux_composer_state (fm_tmux_strip_ghost is now a thin adapter) and
fm_backend_herdr_composer_state. The herdr-only faint byte-pattern check is
removed and fm_backend_herdr_strip_ansi reduced to a thin adapter over the
shared fm_composer_strip_ansi. Bordered detection now reads the plain row so a
dark box border dropped with the ghost does not lose the composer shape.

This also closes the documented grok TRUECOLOR placeholder gap by the same
mechanism (harness-adapters skill note updated).

Empirical evidence (read-only live capture + isolated tmux, no herdr lifecycle)
and the incident write-up are in docs/herdr-backend.md; deterministic
regressions feed the exact captured bytes through the real classifiers
(tests/fm-backend-herdr.test.sh, tests/fm-composer-ghost.test.sh). Two prior
ghost-test fixtures that used a near-black 38;2;1;2;3 as "real" colored text
(never a realistic real-input color) are corrected to a bright 38;2;224;222;244,
preserving the truecolor payload-skip parser intent.

* no-mistakes(review): Preserve dark shell prompt safety

* no-mistakes(review): Harden erased shell prompt classification

* no-mistakes(document): Document shared composer ghost extraction

* no-mistakes(lint): Normalize tmux comment punctuation

(cherry picked from commit 0eaf293)
…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

(cherry picked from commit 3e3dff6)
* 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

(cherry picked from commit 492c937)
* 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

(cherry picked from commit bc558c6)
* 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

(cherry picked from commit 52241a5)
Integration reconciliation: upstream's platform-aware fm-x-link.sh
requires carried reply context on relink, so the successor's X-link
carry now forwards the predecessor's x_platform/x_reply_max_chars,
defaulting a pre-platform link to the X budget instead of halting
the watchdog.
Keigyoku added 3 commits July 10, 2026 21:38
Rebase reconciliation: re-port the unset-CLAUDE_PROJECT_DIR fallback
and physical-identity tests that the Pi logical-run test replay had
displaced, on top of the logical-run suite.
@Keigyoku
Keigyoku force-pushed the fm/upstream-integration branch from 947f197 to 8775f42 Compare July 11, 2026 03:20
@Keigyoku
Keigyoku merged commit 6ad2457 into main Jul 11, 2026
@Keigyoku
Keigyoku deleted the fm/upstream-integration branch July 11, 2026 18:52
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.

4 participants