Commit b529e67
feat: recover beta-only workflows onto main (#10)
* feat: pin and restore fleet toolchain offline (#4)
* feat: standardize fleet secrets on Doppler (#3)
* test: make scheduler refill proof deterministic
* feat: standardize fleet secrets on Doppler
* no-mistakes(review): Captain: Hardened Doppler runner gates and migration review windows
* no-mistakes(review): Captain: Enforced workflow runner validation and sealed clock bypass
* no-mistakes(review): Captain: Made Doppler workflow parsing refuse uncertain job structures
* no-mistakes(review): Captain: Sealed public and fork-exposed Doppler override paths
* no-mistakes(review): Captain: Unified Doppler permission across all trust axes
* no-mistakes(review): Captain: Made tracked workflow validation complete and fail-closed
* no-mistakes: apply CI fixes
---------
Co-authored-by: juniorlovestmh <[email protected]>
* feat: add offline fleet toolchain mirror
* no-mistakes(review): Captain: restore now uses validated captured npm bin mappings
---------
Co-authored-by: juniorlovestmh <[email protected]>
* feat(mobile-mode): add verified Moshi Pro mobile review workflow (#6)
* docs: separate current guidance from verification evidence (kunchenguid#994)
* docs: separate current guides from verification
* no-mistakes(review): Restore Herdr 0.7.5 restart-reclaim verification evidence
* fix: preserve Claude watcher continuity across Stop hooks (kunchenguid#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
* fix(herdr): clean stale projections at session start (kunchenguid#996)
* 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
* fix: recover Claude supervision without watcher-status gate (kunchenguid#1001)
* fix: recover Claude supervision at session start
* fix: remove Claude watcher-status command gate
* no-mistakes(document): docs: remove stale continuity gate references
* fix: make quota-aware profile selection agent-owned (kunchenguid#1018)
* Replace quota dispatch selector instructions
* no-mistakes(review): Align bootstrap docs with agent-owned dispatch selection
* fix(bin): remove vestigial dispatch selector (kunchenguid#1026)
* 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
* docs(agents): drop superseded interim quota-window rule (kunchenguid#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.
* fix(tmux): scope busy detection and recognize current Claude turns (kunchenguid#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
* feat: add verified Kimi crewmate adapter (kunchenguid#1047)
* 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: harden Kimi submission and spinner matching (kunchenguid#1058)
* fix kimi pointer submission and spinner conformance
* no-mistakes(review): Preserve Kimi submit target ownership guard
* feat(bin): add guarded Kimi turn-end wake (kunchenguid#1059)
* 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(tmux): classify bordered composers across all rows (kunchenguid#1066)
* 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
* feat(bin): add verified pi-signed runtime adapter (kunchenguid#1145)
* feat: add verified pi-signed adapter
* no-mistakes(review): Correct pi-signed maintainer verification date
* no-mistakes(review): Correct remaining pi-signed verification dates
* no-mistakes(review): Preserve authoritative pi-signed runtime identity
* no-mistakes(document): Document pi-signed shared adapter semantics
* no-mistakes: apply CI fixes
* fix(pi): rearm watcher across session transitions (kunchenguid#1166)
* fix(pi): rearm watcher across same-process session transitions
Pi emits session_shutdown for ordinary /new, /resume, and /fork replacement
as well as terminal quit. The primary watcher extension latched a module-level
stopping flag on every shutdown, so a replacement session in the same process
could not arm monitoring until Pi restarted.
Own arm authority per session generation so only the active live generation
may start, stop, or rearm the child. Replacement sessions can arm again without
restarting Pi, stale prior-generation callbacks cannot mutate the active cycle,
and real quit still blocks late rearm.
* no-mistakes(review): Preserve Pi generation isolation and exit cleanup
* no-mistakes(document): Correct Pi watcher transition documentation
* feat: route crew dispatch using quota-window pace (kunchenguid#1172)
* Consume quota-axi pace signals in dispatch profile array selection.
Add quota-array-dispatch as the single owner of the pace-aware candidate
choice, keep AGENTS.md to the intake boundary and load trigger, and cover
the acceptance cases with sanitized schemaVersion 3 fixtures.
* no-mistakes(review): Stop and report genuine quota dispatch ties
* no-mistakes(document): Document quota pace freshness and uncertainty
* fix: adapt Grok Stop continuation and harden endpoint cleanup (kunchenguid#1171)
* fix(grok): adapt Stop continuation to runtime capability
* no-mistakes(review): Reject ambiguous Grok Stop payloads
* no-mistakes(review): Reject duplicate Grok fields and accept spaced tmux sessions
* no-mistakes(review): Enforce exact tmux cleanup selectors
* no-mistakes(test): Fix historical tmux fixture and validate Grok Stop
* no-mistakes: apply CI fixes
* fix: restore stock macOS Bash 3.2 brief scaffolding (kunchenguid#1093)
* fix(brief): make DOD scaffolding parse-safe on stock macOS Bash 3.2
fm-brief.sh built each Definition-of-done block and the not-enabled
Herdr declaration with `VAR=$(cat <<EOF ... EOF)`. On Bash 3.2 (macOS
/bin/bash) the lexer scans for the command substitution's closing `)`
textually and tracks quote state through the heredoc body, so a single
apostrophe, unbalanced quote, or unbalanced paren in that prose breaks
parsing of the whole script. Every ship-brief scaffold (no-mistakes,
direct-PR, local-only) failed with `unexpected EOF while looking for
matching )`. Bash 4+ parses it fine, so the breakage stayed invisible
everywhere except stock macOS.
Replace all four command-substitution heredocs with
`IFS= read -r -d '' VAR <<EOF || true`. That removes the `$(...)`
wrapper and the entire defect class regardless of future prose, and
preserves the variable expansion the direct-PR and local-only bodies
need. `read` keeps the heredoc's trailing newline that `$(...)` used to
strip, so trim one newline to keep every generated brief byte-identical
to prior output.
Guard the structure, not one historical phrase: a new test rejects any
heredoc nested in a command substitution anywhere in fm-brief.sh, where
the old assertion pinned a single apostrophe phrase and so missed the
reintroduction. Extend the stock-macOS Bash CI job from parsing one
script to the whole maintained shell surface (bin/*.sh,
bin/backends/*.sh, tests/*.sh), matching bin/fm-lint.sh's canonical file
set so parse scope and lint scope cannot drift apart.
* no-mistakes(review): Captain: harden Bash structure and inventory guards
* no-mistakes(document): Align stock macOS Bash contributor checks
* no-mistakes(lint): Suppress deliberate SC2016 literal fixture warnings
* test: stabilize tmux teardown conformance baseline (kunchenguid#1209)
* fix(test): pin teardown tmux baseline to historical kill selectors
merge-base HEAD main collapses to HEAD after the exact-selector change
lands on the default branch, so the old teardown fixture was accidentally
exercising current exact targets. Resolve a content-historical permissive
tmux adapter from first-parent history and force that post-squash topology
inside the conformance case so main and feature branches keep the same
old-vs-new contract.
* no-mistakes(lint): Suppress intentional literal-pattern ShellCheck warnings
* docs: slim quota-array-dispatch to the pace selection core (kunchenguid#1197)
Cut the runtime skill to the compact pace-aware selection procedure plus
minimum owner pointers. Keep every distinct decision rule and move expanded
acceptance scenarios to deterministic fixture ownership assertions.
Size: 170/1374/10187 -> 63/544/4068 (about 63%/60%/60% reduction).
* feat(bin): inherit backend config into secondmate homes (kunchenguid#1219)
* Inherit config/backend into secondmate homes with deliberate-override preservation
Add backend to the shared inheritable config allowlist so launch, locked
bootstrap, and config-push converge a primary pin into secondmate homes as each
home local future-spawn default. Track last-inherited bytes in a private state
provenance marker so deliberate per-home overrides survive present and absent
primary convergence, keep --backend and FM_BACKEND stronger, and extend the
existing inheritance tests plus docs and skill claims.
* no-mistakes(review): Preserve equal unprovenanced backend overrides
* no-mistakes(review): Preserve symlink overrides and verify spawn precedence
* no-mistakes(review): Snapshot backend inheritance for consistent provenance
* no-mistakes(review): Simplify backend inheritance to primary-authoritative convergence
* no-mistakes(document): Document inherited backend override preservation
* fix: restore primary-authoritative backend inheritance after document regression
The document step reintroduced provenance and deliberate per-home override
semantics after review had simplified config/backend to plain primary-authoritative
allowlist membership. Restore the primary-always-wins path: present overwrites,
absent removes, no provenance marker, and docs/tests match that contract.
* no-mistakes(review): Add divergent backend precedence regression fixtures
* no-mistakes(document): Document backend inheritance contract
* fix(pi): remove Calm's upper version ceiling (kunchenguid#1226)
* fix(pi): remove Calm's exclusive Pi upper-version ceiling
tests/fm-calm-pi-extension.test.sh gated on a closed PI_COMPAT_VERSIONS
allowlist ("0.81.1 0.82.0") that refused any other installed Pi, and docs
described that range as "supported" rather than verified evidence. The
Calm CHANGELOG shows no API introduced at either version, so there is no
evidence for a real minimum; the presentation adapters already probe the
exact method they patch rather than checking a version.
Replace the allowlist with dated version evidence that never rejects a
newer Pi, and make each presentation adapter degrade independently with
a diagnostic if a future Pi removes its API, instead of the whole Calm
extension failing to load. Rewrite the feasibility doc's "Pi 0.81.1
through 0.82.0" phrasing to state it as verified evidence, not a
ceiling.
* no-mistakes(review): Probe missing Calm adapter exports safely
* no-mistakes(document): Document Calm's unbounded Pi compatibility
* fix(bin): allow session-local todo tools in the subagent guard (kunchenguid#1204)
* fix(guard): allow session-local todo tools in the primary
The delegation-shape guard denied TaskCreate and TaskUpdate because their
normalized names contain the `task` stem. Those tools write only the harness's
session-local todo list, which has no executor: it spawns no agent, allocates
no worktree, registers no schedule, and starts nothing that outlives the
session. That is not the unaccounted work the guard exists to stop, so the stem
match was a false positive, and the deny text told the primary to run
bin/fm-brief.sh and bin/fm-spawn.sh to create a todo entry.
Add a separately-reasoned PLAN_ONLY_TOOLS exact-name exclusion rather than
widening OBSERVE_ONLY_TOOLS, whose documented contract is tools that only
observe or stop existing work. Both lists stay exact-name so neither can widen
by substring.
Tests cover the two allowed names and six near-miss names that a substring or
shortened-stem widening would release; both mutations were watched red.
* no-mistakes(review): drop session-local todo tools from recommended deny list
* no-mistakes: apply CI fixes
* fix(session-lock): resolve Claude bg-spare ancestry to the outermost claude pid (kunchenguid#1206)
* fix(session-lock): resolve Claude bg-spare ancestry to the outermost claude pid
fm_harness_ancestry_pid() previously returned the first ancestor process
whose command matched a verified harness name. Claude Code's Stop hook
fires as a bg-spare worker several levels below the session's actual
lock-owning claude process (hook shell -> claude bg-spare ->
claude bg-pty-host -> claude -> claude(lock)), so the first match was
the bg-spare worker, not the lock owner. fm_session_lock_owned_by_self()
then never matched state/.lock, and the Claude Stop auto-arm silently
treated its own primary session as an unrelated live owner and never
armed the watcher.
The walk now keeps going past a claude-named match, looking for a still
more ancestral claude-named match, and stops the instant a non-match
follows an already-found match (bounding it to a contiguous run rather
than the literal ancestry top, so an unrelated claude-named process
further up the real process tree is never mistaken for part of this
session's own nested chain). Every other harness keeps the original
first-match-wins behavior, since e.g. Pi's shared signed-wrapper
ancestry actually holds the session at the inner engine pid, not an
outer wrapper pid. Hop limit raised from 8 to 16 to cover the deeper
bg-spare chain.
* no-mistakes(review): Add nested-claude-ancestry regression test; fix nudge doc depth claim
* no-mistakes: apply CI fixes
* fix: conferma l'avvio del watcher su Windows/MSYS (kunchenguid#1212)
* fix: confirm watcher startup on MSYS
* no-mistakes(review): gate MSYS arm ready timeout, cache uname, harden locale test
* no-mistakes(review): validate OpenCode ready timeout, make uname cache internal
* fix(spawn): forward CLAUDE_CONFIG_DIR to claude crewmates (kunchenguid#1195)
* fix(spawn): forward firstmate's CLAUDE_CONFIG_DIR to claude crewmates
Crewmate panes are created by a long-lived tmux/herdr daemon that does not
inherit firstmate's current environment. When firstmate runs under a non-default
CLAUDE_CONFIG_DIR (for example a work-vs-personal subscription split), a bare
`claude` in the crewmate pane fell back to the default ~/.claude store and
launched unauthenticated, blocking the crewmate before it could do any work.
fm-spawn now prefixes the claude launch with firstmate's own resolved
CLAUDE_CONFIG_DIR when set, so the crewmate uses the same credential/config
store firstmate is authenticated with. An unset value is the single-store
default and adds no prefix; non-claude harnesses are unaffected.
Adds three tests in fm-spawn-dispatch-profile.test.sh (forwarded-when-set,
omitted-when-unset, non-claude-ignored) and pins CLAUDE_CONFIG_DIR in the test
helper so launch assertions no longer depend on the developer's environment.
* no-mistakes: apply CI fixes
* fix: preserve dispatch identity across authentication checks (kunchenguid#1233)
* fix: preserve dispatch harness identity
* no-mistakes(review): Fix Grok counterfactual tuple validation
* no-mistakes(document): Scope dispatch authentication to selected tuple
* fix: restore dispatch instruction budget
* no-mistakes(review): Scope dispatch authentication after candidate selection
* fix(bin): normalize relative durable paths (kunchenguid#1256)
* fix(bin): handle dash-leading harness process names (#2)
* fix: handle dash-leading harness process names
* no-mistakes(review): Make dash-leading harness regression hermetic
* fix: preserve secondmate reply routes across relative homes
Resolve relative home, data, and state inputs before durable charter generation, and fail when caller-relative directories cannot be resolved.
Use absolute paths at the related spawn, AFK daemon, and X-mode cross-process handoffs so later processes cannot reinterpret them from another working directory.
* no-mistakes(review): Preserve absolute overrides and normalize relative durable paths
* no-mistakes(review): Normalize relative home before deriving durable paths
* no-mistakes(document): Document relative durable-path normalization
* no-mistakes(review): Captain: Ignore inherited CDPATH during relative path normalization
* no-mistakes(lint): Fix empty CDPATH assignments for ShellCheck
* refactor(skills): make Bearings chat-only by default (kunchenguid#1136)
* Add internal status skill
* no-mistakes(document): register /status skill in documentation-audiences inventory
* no-mistakes(lint): replace grep|wc -l with grep -c in status skill test
* test: silence literal status skill patterns
* Refactor bearings default to chat-only
---------
Co-authored-by: Kun Chen <[email protected]>
* Clarify follow-up routing during validation (kunchenguid#1277)
* fix: honor concrete approval for project operations (kunchenguid#1272)
* docs: add captain-approved project operation exception to hard rule 1
Firstmate stays read-only over projects by default, but when the captain
clearly approves a concrete project operation and scope in the moment,
firstmate may perform exactly that approved operation with its own tools.
The approval is never inferred, broadened, or standing, and it does not
relax the existing force, discard, unlanded-work, or merge-authority
boundaries.
* no-mistakes(review): Clarify captain-approved project operation boundaries
* no-mistakes(document): Clarify captain-approved project operation scope
* docs: cover directories and preserve the operation-or-scope alternative
Widen the captain-approved project operation exception in AGENTS.md to
files or directories, and restore the explicit operation-or-scope
alternative that a prior pipeline auto-fix had collapsed into "and".
Rework project-management SKILL.md's Remove section, which previously
told firstmate to refuse project removal until a guarded helper existed;
that helper was never built, so the text directly contradicted the new
instruction-only exception. It now points at the exception plus the
existing removal preflight it still requires unchanged.
Update the one instruction-owners test assertion that hard-coded the
sentence removed above, so the suite tracks current, not obsolete, text.
* docs: add captain-approved project operation exception to hard rule 1
Firstmate stays read-only over projects by default, but when the captain
clearly approves a concrete project operation and scope in the moment,
firstmate may perform exactly that approved operation with its own tools.
The approval is never inferred, broadened, or standing, and it does not
relax the existing force, discard, unlanded-work, or merge-authority
boundaries.
* no-mistakes(review): Clarify captain-approved project operation boundaries
* no-mistakes(document): Clarify captain-approved project operation scope
* docs: cover directories and preserve the operation-or-scope alternative
Widen the captain-approved project operation exception in AGENTS.md to
files or directories, and restore the explicit operation-or-scope
alternative that a prior pipeline auto-fix had collapsed into "and".
Rework project-management SKILL.md's Remove section, which previously
told firstmate to refuse project removal until a guarded helper existed;
that helper was never built, so the text directly contradicted the new
instruction-only exception. It now points at the exception plus the
existing removal preflight it still requires unchanged.
Update the one instruction-owners test assertion that hard-coded the
sentence removed above, so the suite tracks current, not obsolete, text.
* no-mistakes(review): Align project removal preflight with approved exception
* no-mistakes(document): Align project removal documentation with approved exception
* fix: restore removal test byte-for-byte and preserve the default sentence
tests/fm-instruction-owners.test.sh had been changed to assert different
text; restore it byte-for-byte to origin/main. project-management SKILL.md's
Remove section now keeps the exact default "Never issue a raw removal
command from Firstmate." sentence that test still asserts, immediately
followed by the already-approved captain-operation-or-scope exception, so
the default and the exception both stay explicit and consistent.
* no-mistakes(document): Align project-write boundary documentation
* fix(skills): route new project intake through secondmate scopes (kunchenguid#1275)
* Route project intake through secondmate scopes
* no-mistakes(test): Guard all main-home project registry mutations
* no-mistakes(document): Consolidate secondmate routing documentation
* no-mistakes: apply CI fixes
* Restore new-project routing scope
* no-mistakes(document): Clarify secondmate routing for new-project intake
* no-mistakes: apply CI fixes
* fix: scope validation corrections by accepted behavior (kunchenguid#1281)
* fix: scope validation corrections by accepted behavior
* no-mistakes(review): Classify stale delivery evidence as an autonomous correction
* test: replace source assertions with behavioral coverage (kunchenguid#1282)
* test: remove source-content assertions
* no-mistakes(review): Replace source assertions with runtime behavior coverage
* no-mistakes(review): Isolate Kimi task temp runtime coverage
* no-mistakes(document): Refresh test cleanup documentation
* no-mistakes: apply CI fixes
* fix(watch): escalate busy workers with no completed turn (kunchenguid#1286)
* fix(watch): bound how long a busy pane may run with no completed turn
A busy pane (backend busy state or the harness's rendered footer) was
unconditional, unbounded proof of liveness in every escalation path, so a
hung foreground tool call behind a busy signature could run for hours
undetected (2026-07 hibit-agent-focus-nonsteal-r1 incident: a catastrophic-
backtracking regex hung one bash call for 25h behind an unchanging
"Working..." footer).
FM_BUSY_TURN_MAX_SECS (default 3600s) now bounds how long a busy pane may
run with no completed turn (state/<id>.turn-ended, or its spawn record
before any turn has completed). Past the bound, busy_turn_over_age routes
the pane through the existing wedge_timer_check, reusing the identical
stale reason, escalation counter, and demand-deep-inspection marker for
human inspection only - never an automatic interrupt, signal, or restart
of the worker or its tool process. A completed turn resets the age.
Reproduced end-to-end against the real installed Pi TUI: a foreground
`sleep 999999` bash call with no timeout renders the actual busy footer,
and two captures ~15s apart show the elapsed counter changing the pane
hash while the same turn stays unfinished. Running the pre-fix watcher
against the real captures showed it never starts a wedge timer no matter
how long the pane stays busy; the fixed watcher starts and escalates the
timer through the same mechanism, while the real hung process remained
untouched and alive throughout.
* no-mistakes(review): fix: parse enriched AFK stale reasons
* no-mistakes(review): fix: preserve enriched wedges during AFK supervision
* no-mistakes(review): fix: route all enriched AFK wedges
* no-mistakes(document): Clarify busy-turn age supervision documentation
* fix(gitignore): ignore config/ as a directory, not by exact filename (kunchenguid#1261)
A name-by-name list of config/ entries silently stops ignoring any new or
home-local file placed there, which makes the working tree read as dirty and
blocks guarded sync paths that refuse to touch a dirty home. AGENTS.md
already documents config/ as captain-private and gitignored as a category;
this makes .gitignore match that contract.
* fix(tests): replace source-content .gitignore assertion with behavioral coverage (kunchenguid#1304)
The second assertion in fm-gitignore-config.test.sh (added by kunchenguid#1261) greps
.gitignore for a specific spelling of the config/ ignore pattern. It fails
on a semantically equivalent pattern like config/** and does not prove Git
actually ignores anything, per the completed source-content-test audit.
Replace it with a real git check-ignore control test on a generated
unrelated path, and strengthen the existing directory-coverage test with
generated unpredictable direct and nested config/ paths.
* feat: bound and consolidate startup memory during stow (kunchenguid#1303)
* Add bounded startup memory curation
* no-mistakes(review): Record reproducible stow verification evidence
* no-mistakes(review): Validate inherited secondmate stow evidence
* no-mistakes(document): Document editable startup-memory budget propagation
* no-mistakes(review): Captain: restored ADHD coverage and Doppler CLI validation
* no-mistakes(review): Classify CLI-only Doppler jobs as injecting
* no-mistakes(document): Refresh test-isolation documentation terminology
* fix: satisfy pinned shellcheck for merge tests
* docs: add Moshi mobile review mode
Red proof: the pre-change public agent surface had no Moshi/mobile-mode trigger or durable Browser Preview handoff.
Verification: fm-doc-audience-check passes; focused captain-translation and documentation-audience tests pass; fm-test-run --changed passes 26 of 27 selected scripts. The unrelated live Pi 0.83 Calm /export interaction timed out, while this branch changes no Calm or Pi test surface.
* no-mistakes(review): Captain: align Chat View with numbered Firstmate fallback
* no-mistakes(test): Documented unavailable Moshi dogfood; preserved captain checklist
* no-mistakes(document): Consolidated Moshi documentation ownership
---------
Co-authored-by: Kun Chen <[email protected]>
Co-authored-by: Christopher McKay <[email protected]>
Co-authored-by: Daniel Kuykendall IV <[email protected]>
Co-authored-by: Trillium Smith <[email protected]>
Co-authored-by: Unknownzed <[email protected]>
Co-authored-by: lhalbert <[email protected]>
Co-authored-by: AG <[email protected]>
Co-authored-by: deeto15 <[email protected]>
Co-authored-by: juniorlovestmh <[email protected]>
* feat(brief): add self-authenticating launch provenance (#7)
* fix: make quota-aware profile selection agent-owned (kunchenguid#1018)
* Replace quota dispatch selector instructions
* no-mistakes(review): Align bootstrap docs with agent-owned dispatch selection
* feat: route crew dispatch using quota-window pace (kunchenguid#1172)
* Consume quota-axi pace signals in dispatch profile array selection.
Add quota-array-dispatch as the single owner of the pace-aware candidate
choice, keep AGENTS.md to the intake boundary and load trigger, and cover
the acceptance cases with sanitized schemaVersion 3 fixtures.
* no-mistakes(review): Stop and report genuine quota dispatch ties
* no-mistakes(document): Document quota pace freshness and uncertainty
* test: stabilize tmux teardown conformance baseline (kunchenguid#1209)
* fix(test): pin teardown tmux baseline to historical kill selectors
merge-base HEAD main collapses to HEAD after the exact-selector change
lands on the default branch, so the old teardown fixture was accidentally
exercising current exact targets. Resolve a content-historical permissive
tmux adapter from first-parent history and force that post-squash topology
inside the conformance case so main and feature branches keep the same
old-vs-new contract.
* no-mistakes(lint): Suppress intentional literal-pattern ShellCheck warnings
* docs: slim quota-array-dispatch to the pace selection core (kunchenguid#1197)
Cut the runtime skill to the compact pace-aware selection procedure plus
minimum owner pointers. Keep every distinct decision rule and move expanded
acceptance scenarios to deterministic fixture ownership assertions.
Size: 170/1374/10187 -> 63/544/4068 (about 63%/60%/60% reduction).
* fix: preserve dispatch identity across authentication checks (kunchenguid#1233)
* fix: preserve dispatch harness identity
* no-mistakes(review): Fix Grok counterfactual tuple validation
* no-mistakes(document): Scope dispatch authentication to selected tuple
* fix: restore dispatch instruction budget
* no-mistakes(review): Scope dispatch authentication after candidate selection
* refactor(skills): make Bearings chat-only by default (kunchenguid#1136)
* Add internal status skill
* no-mistakes(document): register /status skill in documentation-audiences inventory
* no-mistakes(lint): replace grep|wc -l with grep -c in status skill test
* test: silence literal status skill patterns
* Refactor bearings default to chat-only
---------
Co-authored-by: Kun Chen <[email protected]>
* test: replace source assertions with behavioral coverage (kunchenguid#1282)
* test: remove source-content assertions
* no-mistakes(review): Replace source assertions with runtime behavior coverage
* no-mistakes(review): Isolate Kimi task temp runtime coverage
* no-mistakes(document): Refresh test cleanup documentation
* no-mistakes: apply CI fixes
* no-mistakes(review): Captain: restored ADHD coverage and Doppler CLI validation
* fix: satisfy pinned shellcheck for merge tests
* fix brief launch provenance and stale regeneration
* no-mistakes(review): Captain: fixed atomic regeneration and guidance; focused tests pass, shellcheck unavailable
* no-mistakes(lint): Captain: ordered overlapping lint case patterns
---------
Co-authored-by: Kun Chen <[email protected]>
Co-authored-by: deeto15 <[email protected]>
Co-authored-by: juniorlovestmh <[email protected]>
* fix(no-mistakes): make lint command valid YAML
---------
Co-authored-by: juniorlovestmh <[email protected]>
Co-authored-by: Kun Chen <[email protected]>
Co-authored-by: Christopher McKay <[email protected]>
Co-authored-by: Daniel Kuykendall IV <[email protected]>
Co-authored-by: Trillium Smith <[email protected]>
Co-authored-by: Unknownzed <[email protected]>
Co-authored-by: lhalbert <[email protected]>
Co-authored-by: AG <[email protected]>
Co-authored-by: deeto15 <[email protected]>1 parent 87f25e0 commit b529e67
17 files changed
Lines changed: 1157 additions & 18 deletions
File tree
- .agents/skills/mobile-mode
- bin
- docs
- verification
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
38 | 42 | | |
39 | 43 | | |
40 | 44 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
387 | 387 | | |
388 | 388 | | |
389 | 389 | | |
| 390 | + | |
390 | 391 | | |
391 | 392 | | |
392 | 393 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
200 | 200 | | |
201 | 201 | | |
202 | 202 | | |
| 203 | + | |
203 | 204 | | |
204 | 205 | | |
205 | 206 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
10 | | - | |
| 9 | + | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
29 | 35 | | |
30 | 36 | | |
31 | 37 | | |
| |||
44 | 50 | | |
45 | 51 | | |
46 | 52 | | |
47 | | - | |
| 53 | + | |
48 | 54 | | |
49 | 55 | | |
50 | 56 | | |
| |||
94 | 100 | | |
95 | 101 | | |
96 | 102 | | |
| 103 | + | |
97 | 104 | | |
98 | 105 | | |
99 | 106 | | |
100 | 107 | | |
101 | 108 | | |
102 | 109 | | |
103 | 110 | | |
| 111 | + | |
104 | 112 | | |
105 | 113 | | |
106 | 114 | | |
107 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
108 | 121 | | |
109 | 122 | | |
110 | 123 | | |
| |||
117 | 130 | | |
118 | 131 | | |
119 | 132 | | |
120 | | - | |
121 | | - | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
122 | 200 | | |
123 | 201 | | |
124 | 202 | | |
| |||
140 | 218 | | |
141 | 219 | | |
142 | 220 | | |
| 221 | + | |
143 | 222 | | |
144 | 223 | | |
145 | 224 | | |
| |||
149 | 228 | | |
150 | 229 | | |
151 | 230 | | |
152 | | - | |
| 231 | + | |
| 232 | + | |
153 | 233 | | |
154 | 234 | | |
155 | 235 | | |
| |||
205 | 285 | | |
206 | 286 | | |
207 | 287 | | |
| 288 | + | |
208 | 289 | | |
209 | 290 | | |
210 | 291 | | |
| |||
213 | 294 | | |
214 | 295 | | |
215 | 296 | | |
216 | | - | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
217 | 303 | | |
218 | 304 | | |
219 | 305 | | |
| |||
248 | 334 | | |
249 | 335 | | |
250 | 336 | | |
251 | | - | |
| 337 | + | |
| 338 | + | |
252 | 339 | | |
253 | 340 | | |
254 | 341 | | |
| |||
291 | 378 | | |
292 | 379 | | |
293 | 380 | | |
| 381 | + | |
294 | 382 | | |
295 | 383 | | |
296 | 384 | | |
297 | 385 | | |
298 | 386 | | |
299 | 387 | | |
300 | 388 | | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
301 | 393 | | |
302 | | - | |
| 394 | + | |
303 | 395 | | |
304 | 396 | | |
305 | 397 | | |
| |||
356 | 448 | | |
357 | 449 | | |
358 | 450 | | |
359 | | - | |
| 451 | + | |
| 452 | + | |
360 | 453 | | |
361 | 454 | | |
362 | 455 | | |
| |||
407 | 500 | | |
408 | 501 | | |
409 | 502 | | |
| 503 | + | |
410 | 504 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
11 | 16 | | |
12 | 17 | | |
13 | 18 | | |
| |||
29 | 34 | | |
30 | 35 | | |
31 | 36 | | |
| 37 | + | |
32 | 38 | | |
33 | 39 | | |
34 | 40 | | |
| |||
56 | 62 | | |
57 | 63 | | |
58 | 64 | | |
59 | | - | |
| 65 | + | |
60 | 66 | | |
61 | 67 | | |
62 | 68 | | |
63 | 69 | | |
64 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
65 | 75 | | |
66 | 76 | | |
67 | 77 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
131 | | - | |
| 131 | + | |
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| |||
685 | 685 | | |
686 | 686 | | |
687 | 687 | | |
688 | | - | |
689 | | - | |
690 | | - | |
691 | 688 | | |
692 | 689 | | |
693 | 690 | | |
| |||
697 | 694 | | |
698 | 695 | | |
699 | 696 | | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
700 | 700 | | |
701 | 701 | | |
702 | 702 | | |
| |||
0 commit comments