Skip to content

Merge upstream: verified Kimi adapter, Claude Stop auto-arm cooperation, tmux composer rewrite - #34

Merged
Bre77 merged 17 commits into
mainfrom
fm/fm-upstream-integrate-0727
Jul 27, 2026
Merged

Bre77 merged 17 commits into
mainfrom
fm/fm-upstream-integrate-0727

Conversation

@Bre77

@Bre77 Bre77 commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Intent

Conflict resolution (8 files)

Every conflict was resolved by combining both intents; no fork-only file or behavior was dropped.

  • bin/fm-spawn.sh - two independent function additions collided at the same insertion point: the fork's per-crew systemd --user memory cap (crew_memory_cap_available, wrap_launch_with_memory_cap) and upstream's resolve_kimi_binary. Kept both as sibling functions.
  • bin/fm-tmux-lib.sh - the fork's simple single-cursor-row fm_tmux_composer_state collided with upstream's generalized fm_tmux_composer_row_state at the same spot. Upstream's own later structural rewrite (already auto-merged elsewhere in the file) fully supersedes the fork's simple version, so kept upstream's row classifier and dropped the now-dead duplicate definition.
  • bin/fm-turnend-guard.sh - the fork's watcher re-arm grace tolerance (FM_TURNEND_REARM_GRACE: don't block on a fresh beacon with no live lock, since the watcher may just be mid-restart) collided with upstream's whole --claude auto-arm cooperation rewrite (budget, epoch, cooperative wait). Kept upstream's structure and inserted the re-arm grace check as a shared early-exit after the common fm_watcher_healthy check, applying to both the default and --claude paths.
  • bin/fm-watch.sh - same shape as bin/fm-spawn.sh's: the fork's busy_state_is_busy(bs, tail40) (resolves the backend busy state once and shares it with the stale-dedup signal, so herdr's agent.get isn't called twice per pane per poll) collided with upstream's window_is_busy(window, tail40) (harness-scoped fm_busy_lines_match fallback, replacing the old combined-pattern-only regex). Kept the fork's name/signature and folded upstream's harness-scoped fallback into it, adding a <window> parameter for the harness lookup.
  • docs/architecture.md, docs/configuration.md - narrow prose/config-var collisions describing the two features above from opposite sides. Merged into one paragraph covering both facts, and kept both sides' new env vars.
  • docs/herdr-backend.md - the conflict was almost entirely upstream's doc-restructure commit (docs: separate current guidance from verification evidence kunchenguid/firstmate#994) deleting/relocating content the fork had never touched, plus five genuinely fork-only incident write-ups (NBSP composer fix, --source CLI bug, SGR-90 ghost-text + away-daemon-outlived-afk fix, queued-message-hint fix, watcher stale-dedup semantic signal) anchored nearby in the old monolithic file. Adopted upstream's file wholesale and relocated the five fork-only sections into docs/verification/runtime-backends.md under the existing ## Herdr section, fixing their cross-references to sections that moved or no longer exist.
  • docs/turnend-guard.md - same shape: merged the re-arm-grace prose into upstream's rewritten invariant section, and relocated the fork's two watcher-lock-race incident write-ups (2026-07-15 write-side and read-side races) into docs/verification/supervision.md's ## Turn-end guard section, matching upstream's own doc-restructure pattern.

Fixes for silent (non-textual) integration gaps

Three problems surfaced only by running the suite - each an upstream change interacting with fork-only code that never textually overlapped, so the merge produced no conflict but the tree broke at runtime or the doc gate failed:

  • bin/fm-doc-audience-check.sh (new upstream gate): flagged 8 fork-only docs as unclassified (betterstack/clickstack webhook receiver docs, skills, and examples, plus docs/crew-memory-cap.md and docs/fork-only-delivery.md). Added all 8 to docs/documentation-audiences.json with the audience that matches their closest existing analogue (agent-runtime for the two alert-response skills, operator-current for the webhook/fork-only-delivery docs, operator-example for the .env examples, maintainer-verification for the memory-cap evidence doc).
  • tests/fm-turnend-guard.test.sh: test_hook_claude_mode_allow_resets_budget removes the watch lock but left .last-watcher-beat fresh from an earlier step, expecting the next call to re-block - but the fork's new re-arm grace tolerance (above) now correctly reads a fresh beacon with no lock as "re-arm plausibly in flight" and allows. Aged the beacon past the grace window before the "later unhealthy chain" assertion, matching how every other genuinely-dead-watcher case in the same file is set up.
  • tests/fm-kimi-harness.test.sh (new upstream): two gaps. (1) test_kimi_launch_then_send_is_verified asserts the exact unwrapped launch text, but an ambient real systemd-run --user on this host made the fork's memory-cap wrapper (above) actually wrap it - stubbed systemd-run unavailable in this test's fake bin, mirroring tests/fm-backend.test.sh's existing precedent for the same interaction. (2) test_watcher_scopes_moon_spinner_to_recorded_kimi_task called the pre-merge window_is_busy <window> <tail> signature directly; updated all six call sites to the merged busy_state_is_busy <bs> <tail> <window> signature with the test's already-overridden constant bs=unknown.

Validation

  • bin/fm-lint.sh (pinned ShellCheck 0.11.0) - clean.
  • bin/fm-doc-audience-check.sh - clean (surfaces=63 local_links=153).
  • Targeted suite: fm-backend-herdr, fm-composer-ghost, fm-composer-lib, fm-tmux-submit-busy, fm-turnend-guard, fm-watch-checkpoint, fm-watcher-lock, fm-watch-triage, fm-spawn-dispatch-profile, fm-spawn-batch, fm-spawn-worktree-settle, fm-backend-tmux-smoke - all green after the turnend-guard test fix above.
  • Broader sweep via bin/fm-test-run.sh --family: pure-contract-unit (31/0, including fm-kimi-harness after both fixes above and fm-documentation-audiences after the inventory fix), session-bootstrap (8/0), secondmate (8/0).
  • No fork-only file, feature, or test was deleted; the Kimi adapter, Claude auto-arm cooperation, and tmux composer rewrite all landed intact alongside the fork's memory cap, re-arm grace tolerance, and stale-dedup signal.

kunchenguid and others added 17 commits July 23, 2026 20:26
* 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
…id#994)

* docs: separate current guides from verification

* no-mistakes(review): Restore Herdr 0.7.5 restart-reclaim verification evidence
…d#997)

* feat(claude): Stop-owned tokenless watcher continuity via asyncRewake auto-arm

Claude primaries (main home and marked secondmate homes) no longer depend
on the model remembering to re-arm the watcher after each wake. A tracked
Stop asyncRewake hook (bin/fm-claude-stop-autoarm.sh, timeout 28800s)
fires on every turn end, claims one home-scoped single-flight owner,
foregrounds bin/fm-watch-arm.sh inside the hook-owned process tree, and
translates an actionable close or typed watcher failure into exactly one
exit-2 rewake. The hook scopes to genuine primary checkouts, requires the
session lock to be held by its own harness ancestor, stays inert while
AFK owns triage or the home is idle, and hands AFK transitions mid-cycle
to the daemon without rewaking.

The synchronous turn-end guard gains a --claude cooperative mode: it
ignores stop_hook_active (true on every post-continuation stop, which is
what re-opened the 2026-07-21 blind window), waits briefly for a watcher
health proof, a live auto-arm owner claim, or a fresh rewake epoch, and
re-blocks only when the auto-arm genuinely failed to establish - bounded
to 3 consecutive blocks per session, safely below Claude Code's 8-block
override, then a degraded allow with a visible systemMessage. Codex
keeps the previous one-block loop guard byte-identically, and Pi,
OpenCode, and Grok adapters are untouched.

Continuity PreToolUse gate and durable wake queue are preserved; the
gate's recovery guidance now names the Stop-owned re-arm and reserves
manual background arms for auto-arm failure. Claude supervision protocol,
harness-adapters facts, architecture, configuration, and continuity docs
updated; docs/turnend-guard.md records the 2026-07-24 Claude 2.1.218
contract revalidation (tokenless multi-cycle rewake, no-dedup, timeout
process-group kill, 8-block cap, interactive non-stall) and the 2.1.219
product live E2Es.

Regression matrix: hermetic tests cover scope, identity, AFK, need,
single-flight, translation, guard cooperation, budget, and registration;
the new live E2E proves two full tokenless auto-arm rewake cycles with
zero model arm commands; Pi and OpenCode Option B live E2Es pass
unchanged.

* no-mistakes(review): Fix Claude X-mode auto-arm continuity backstop

* no-mistakes(review): Remove unsupported Claude contract-lab verification claims

* no-mistakes(document): Update Claude auto-arm continuity documentation
* Clean stale Herdr projections at session start

* no-mistakes(document): Document stale Herdr session-start projection cleanup

* no-mistakes(review): Enforce locked exact Herdr projection cleanup

* no-mistakes(review): Fail closed on unverified session lock ownership

* no-mistakes(review): Serialize session lock acquisition atomically

* no-mistakes(document): Align session-start and Herdr cleanup documentation

* no-mistakes(document): Generalize lock-refusal diagnostics

* no-mistakes(lint): Avoid reserved keyword in concurrency test

* no-mistakes: apply CI fixes

* no-mistakes: apply CI fixes
…uid#1001)

* fix: recover Claude supervision at session start

* fix: remove Claude watcher-status command gate

* no-mistakes(document): docs: remove stale continuity gate references
* Replace quota dispatch selector instructions

* no-mistakes(review): Align bootstrap docs with agent-owned dispatch selection
* remove vestigial dispatch selector

* no-mistakes(review): Synchronize isolation proof and portable shard evidence

* no-mistakes(review): Correct shard history and proof archive date

* no-mistakes(review): Remove reintroduced selector documentation reference

* no-mistakes(document): Remove stale dispatch strategy documentation
…1039)

quota-axi 0.1.13 emits schemaVersion 2 with a quotaSemantics object per
provider, so the successor named in the interim rule has landed and the
rule's own removal condition is satisfied.

Keep the ownership clause so quota-axi remains the single owner of how
model or product windows relate to bounding account windows, and drop
the interim weakest-headroom instruction. The unknown-semantics case is
already covered by the existing requirement to stop and report a
candidate whose applicable quota data or interpretation cannot be
established.

Drop the matching assertion phrase from
tests/fm-instruction-owners.test.sh; the retained ownership phrase still
asserts.
…unchenguid#1049)

* fix(tmux): scope Claude busy detection by harness

* no-mistakes(review): Separate verified and fallback busy signatures

* no-mistakes(test): Scope busy signatures to supplied harnesses

* no-mistakes(document): Document harness-scoped busy detection
* Add verified Kimi crewmate harness adapter

* no-mistakes(review): Scope Kimi moon detection to spinner lines

* no-mistakes(review): Match only complete Kimi spinner rows

* no-mistakes(review): Resolve Kimi binary portably before pane creation

* no-mistakes(document): Align Kimi adapter documentation

* no-mistakes(lint): Suppress false-positive ShellCheck warning for sourced watcher override

* Fix Kimi busy spinner detection

* no-mistakes(review): Recognize Kimi session-lock ancestry and holders

* no-mistakes(review): Scope pending-reply Kimi busy detection by harness

* no-mistakes(document): Correct Kimi spinner capture documentation

* no-mistakes(document): Clarify optional Kimi spinner whitespace

* no-mistakes(lint): Silence intentional pending-reply test stub warnings

* test: align rebased Kimi busy fixtures

* no-mistakes: apply CI fixes

* Reconcile Kimi busy detection after per-harness scoping

* no-mistakes(review): Clarify observed Kimi spinner whitespace contract

* no-mistakes(document): Clarify Kimi harness documentation
* fix kimi pointer submission and spinner conformance

* no-mistakes(review): Preserve Kimi submit target ownership guard
* Add guarded Kimi turn-end hook

* no-mistakes(review): Require jq before installing Kimi turn-end hook

* no-mistakes(review): Expose jq inside isolated Kimi test fixtures

* no-mistakes(review): Preserve Kimi config boundaries during hook removal

* no-mistakes(review): Document Kimi removal newline safeguard

* no-mistakes(document): Document Kimi shared-home preservation
)

* Fix structural tmux composer reading

* Verify Calm compatibility with Pi 0.82

* no-mistakes(review): Harden structural composer classification boundaries

* no-mistakes(review): Refresh composer and Kimi regression fixtures

* no-mistakes(review): Fail closed on unbounded composer edges

* no-mistakes(review): Enforce aligned composer geometry safely

* no-mistakes(review): Make composer ambiguity locale-safe

* no-mistakes(review): Preserve ambiguity through composer submission

* no-mistakes(review): Carry composer proof through retries

* no-mistakes(document): Document structural tmux composer delivery guarantees

* no-mistakes: apply CI fixes
…grate-0727

# Conflicts:
#	bin/fm-spawn.sh
#	bin/fm-tmux-lib.sh
#	bin/fm-turnend-guard.sh
#	bin/fm-watch.sh
#	docs/architecture.md
#	docs/configuration.md
#	docs/herdr-backend.md
#	docs/turnend-guard.md
@Bre77
Bre77 merged commit 90ba1c5 into main Jul 27, 2026
9 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.

2 participants