Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
8089f44
fix(spawn): isolate docker-compose project names per worktree
Jul 5, 2026
7ea1904
no-mistakes(test): waiting for background test run to complete
Jul 5, 2026
73a1564
no-mistakes(test): fix(tests): make herdr fake CLI counter race-safe …
Jul 5, 2026
88a3976
no-mistakes(document): docs: document per-worktree docker-compose pro…
Jul 5, 2026
d513347
no-mistakes(document): docs already fully synced; added missing docke…
Jul 5, 2026
929b003
no-mistakes(lint): Fix unused $out variable flagged by shellcheck in …
Jul 5, 2026
dac1eaf
feat(spawn): auto-compact claude crewmates around 200k tokens
Jul 10, 2026
10b1606
no-mistakes(test): fix environment-fragile test failures (jq, git, ha…
Jul 10, 2026
e700616
feat(spawn): raise claude auto-compact window to 300000
Jul 11, 2026
38efa4a
fix(teardown): recognize work fast-forwarded into local main as landed
Jul 11, 2026
20a04c5
test(teardown): drop stale git-2.38 skip gate for content-in-default …
Jul 11, 2026
e05d340
feat(dispatch): add model/effort tiers and mechanical quality guardrails
Jul 9, 2026
84ab44e
no-mistakes(review): scope risk-tripwire brief scan, narrow bin path,…
Jul 9, 2026
b6f3a5d
no-mistakes(review): harden risk-tripwire scans and mechanically wire…
Jul 9, 2026
067e68a
no-mistakes(review): make risk-tripwire grep portable, give tier-guar…
Jul 9, 2026
beedf6d
no-mistakes(review): set exec bit on new tests, fix ultracode marker doc
Jul 10, 2026
6321c62
no-mistakes(test): fix jq/git-version and test-env portability in fai…
Jul 10, 2026
3c4f4dd
no-mistakes(document): sync docs with new resource-tiering guardrail …
Jul 10, 2026
906522a
no-mistakes(review): exclude herdr-lab brief block from risk-tripwire…
Jul 10, 2026
590bfa7
no-mistakes(review): clean up orphan .ultracode state marker on teardown
Jul 10, 2026
d07b141
no-mistakes(review): stop tiering guardrails passing silently when di…
Jul 10, 2026
1367b36
no-mistakes(review): pass ultracode through dispatch, tighten tiering…
Jul 10, 2026
d9a2749
no-mistakes(test): skip handoff tests on incompatible tasks-axi; fix …
Jul 10, 2026
76003fa
no-mistakes: apply CI fixes
Jul 10, 2026
766f38c
fix(teardown): check both origin and local ref for landed content
Jul 11, 2026
98f9c97
feat: auto-sync live NAS deployments after a landed ship task
Jul 12, 2026
e286ecc
no-mistakes(review): docs: document fm-nas-deploy-sync.sh script and …
Jul 12, 2026
db5569e
no-mistakes(review): Sandbox teardown tests' NAS deploy sync lookup file
Jul 12, 2026
a7da1a1
no-mistakes(review): Aggregate pm2 cluster status and stub NAS sync i…
Jul 12, 2026
effd1a4
no-mistakes(review): Bound NAS deploy sync git/fs calls with a timeout
Jul 12, 2026
8d32567
no-mistakes(review): Guard NAS sync fetch race, document timeout knob…
Jul 12, 2026
0641830
no-mistakes(test): placeholder - awaiting background test run completion
Jul 12, 2026
8f11fc1
no-mistakes(document): Synced AGENTS.md and docs/architecture.md/cmux…
Jul 12, 2026
f1e06df
feat: surface failed critical systemd services at bootstrap
Jul 13, 2026
39ccd34
keep firstmate repo in sync with upstream template
Jul 14, 2026
60b3008
clarify /updatefirstmate converges to the fork, not the upstream temp…
Jul 14, 2026
c809323
fix(turnend-guard): poll for a re-arming watcher before blocking
Jul 15, 2026
451c974
no-mistakes(test): fix stale packed-refs-lock recovery and backlog-ha…
Jul 15, 2026
0a3cdbe
no-mistakes(test): Waiting on full test suite run to verify fm-afk-la…
Jul 15, 2026
604df17
no-mistakes(document): Sync docs/configuration.md and docs/turnend-gu…
Jul 15, 2026
bfe2cc0
checkpoint: recover uncommitted work after captain/crew crash
Jul 15, 2026
b316b30
fix: suppress SC2016 for the deliberate single-quoted verify-tier bri…
Jul 15, 2026
a08ff3e
fix: reclaim leaked tmp roots in secondmate test suites
Jul 15, 2026
75123c4
fix: read no-break-space composer padding as empty
Jul 15, 2026
199e12e
no-mistakes(review): bound local-merge push; prune stale test gates
Jul 15, 2026
edbbf18
fix: scope fm-merge-local.sh auto-push to firstmate's own repo
Jul 15, 2026
67230e0
no-mistakes(review): will report after background lint completes
Jul 16, 2026
a7d95e1
no-mistakes(document): Synced docs for fm-teardown --force NAS-sync s…
Jul 16, 2026
bf2afe3
feat(watch): surface autodeploy-log failures on the periodic sweep
Jul 15, 2026
8faceec
feat(bootstrap): add session-start check for autodeploy-log failures
Jul 15, 2026
2a01aac
fix(watch): bound autodeploy log reads with a timeout
Jul 15, 2026
ca52250
feat(bootstrap): warn when autodeploy alerting is inert; document kno…
Jul 16, 2026
c45491b
docs: correct autodeploy log-format attribution
Jul 16, 2026
67e3337
fix(decision-hold): only require tasks-axi in verify() when decision …
Jul 17, 2026
e18e48c
fix: hard-timeout watcher crew-state reads
Jul 15, 2026
e8e45af
no-mistakes(review): fix: exclude 0 from valid FM_CREW_STATE_NM_TIMEO…
Jul 16, 2026
dec2d6d
no-mistakes(review): test: add zero-timeout regression coverage for h…
Jul 16, 2026
2478e4e
no-mistakes(review): fix: reject all-zero-padded timeout values, not …
Jul 16, 2026
cb9c5dc
fix(watch): honor a declared pause over an orphaned run-step for an e…
Jul 17, 2026
47f9f40
no-mistakes(document): docs: note verify()'s conditional tasks-axi re…
Jul 17, 2026
5fb0cc6
no-mistakes: apply CI fixes
Jul 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .agents/skills/bootstrap-diagnostics/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: bootstrap-diagnostics
description: >-
Agent-only handling playbook for session-start bootstrap diagnostics.
Use whenever the session-start digest's bootstrap section prints an actionable diagnostic line - MISSING, MISSING_MANUAL, BACKEND_INVALID, NEEDS_GH_AUTH, TANGLE, CREW_DISPATCH invalid, FLEET_SYNC, PR_CHECK_MIGRATION, SECONDMATE_SYNC, SECONDMATE_LIVENESS, NUDGE_SECONDMATES, or FMX - or when a standalone bin/fm-bootstrap.sh run prints one of those lines.
Use whenever the session-start digest's bootstrap section prints an actionable diagnostic line - MISSING, MISSING_MANUAL, BACKEND_INVALID, NEEDS_GH_AUTH, TANGLE, CREW_DISPATCH invalid, FLEET_SYNC, PR_CHECK_MIGRATION, SECONDMATE_SYNC, SECONDMATE_LIVENESS, NUDGE_SECONDMATES, FMX, SERVICE_FAILED, AUTODEPLOY_FAILED, AUTODEPLOY_INERT, or UPSTREAM_DRIFT - or when a standalone bin/fm-bootstrap.sh run prints one of those lines.
A silent bootstrap section, or a BOOTSTRAP_INFO fact, means no skill load.
user-invocable: false
metadata:
Expand Down Expand Up @@ -50,3 +50,17 @@ When any diagnostic needs captain attention, report the plain consequence and re
Inspect the reason, keep the pending marker under `state/.secondmate-nudge-pending/` intact, and rerun session start after the endpoint or metadata issue is fixed so bootstrap can retry the exact same marked send.
- `FMX: X mode on ...` / `FMX: X mode off ...` - bootstrap confirmed or removed the local X-mode poll artifacts (`docs/configuration.md` "X mode (.env)").
Only when a running watcher needs the cadence transition applied immediately, restart the home-scoped watcher through the emitted harness supervision protocol; bootstrap deliberately never restarts the watcher itself.
- `SERVICE_FAILED: <unit> - failed since <timestamp>` - a systemd unit named in the optional local `config/critical-services` file is in the failed state (`docs/configuration.md` "Critical service watch"); a pure read-only detection (`systemctl is-failed`, no root), so a read-only session still surfaces it.
Report it to the captain in plain language; never restart the unit yourself - a unit that failed may be unsafe to restart without knowing why.
An absent or empty config file, a host without `systemctl`, or no failed unit all print nothing.
- `AUTODEPLOY_FAILED: <label> - <last line>` - the last line of a status log named in the optional local `config/autodeploy-logs` file reports failure (`bin/fm-watch.sh`'s `autodeploy_scan` owns the failure convention; `bin/fm-bootstrap.sh`'s `autodeploy_logs_check` is its session-start counterpart, a pure read-only detection that catches a deploy that failed while no watcher was armed to sweep it).
Tell the captain plainly that the live deploy for `<label>` is failing, relaying the log line; firstmate never touches the deploy itself.
An absent or empty config file, a missing or transiently unreadable log (a NAS hiccup), or a healthy last line all print nothing.
- `AUTODEPLOY_INERT: config/autodeploy-logs is set but no timeout mechanism (timeout, gtimeout, or perl) is on PATH; autodeploy-alert checks cannot run` - the host has none of the three mechanisms `fm-autodeploy-lib.sh`'s `fm_autodeploy_read_last_line` needs to bound a log read, so every autodeploy check silently no-ops on both the bootstrap check and the watcher's periodic sweep.
Tell the captain plainly that autodeploy alerting is disabled on this host until `timeout` (coreutils), `gtimeout` (macOS via Homebrew's coreutils), or `perl` is installed; this is a one-time-per-session capability gap, not a deploy failure.
- `UPSTREAM_DRIFT: local main is <ahead> ahead / <behind> behind upstream/main, last reconciled <days>d ago (<date>)` - the always-on FYI variant: firstmate's OWN repo tracking how far it has drifted from its read-only upstream template (`kunchenguid/firstmate`, the `upstream` remote after the remote swap).
It prints every session; record it silently like any capability fact and take no action while the wording stays FYI.
It only reports - the network fetch that refreshes the ref runs in the locked fleet-sync sweep, and reconciling upstream is never a bootstrap side effect.
- `UPSTREAM_DRIFT: this repo's upstream sync needs attention - ...` - the escalated variant (local main more than ~30 commits behind `upstream/main`, or the merge-base older than 10 days).
Surface it to the captain in plain outcome language and, on their go-ahead, dispatch a deliberately-reviewed firstmate-repo reconciliation ship task - fetch `upstream`, merge it into local `main`, resolve conflicts, and land local-only (`AGENTS.md` section 1) - the same shape that reconciled the divergence before.
Never automate the merge; keeping the gap small also keeps the pipeline's opportunistic upstream PR's diff clean (`AGENTS.md` section 1).
7 changes: 7 additions & 0 deletions .agents/skills/harness-adapters/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ Its broader dark-TRUECOLOR placeholder handling and dark-theme tradeoff are docu
That styled capture is internal to the boolean detector only.
`fm-peek` and every other human or LLM-facing capture path stays plain `tmux capture-pane` with no escape codes.

**Auto-compaction fact (verified 2026-07-09, Claude Code 2.1.206; shipped constant raised to 300000 2026-07-11).**
`bin/fm-spawn.sh` launches every claude crewmate and secondmate with `CLAUDE_CODE_AUTO_COMPACT_WINDOW=300000`, scoped the same way as `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false` above, so these separately-launched processes auto-compact around 300k tokens the way the primary already does via its own `.claude/settings.local.json` (which they never inherit).
The var is read once at process startup and is capped at the model's real context window, so it can only lower the effective trigger, never raise it past the real ceiling: `min(300000, window)` is `300000` once `window` exceeds it, but a no-op (stays at `window`) below that.
This is not a universal guarantee for every possible future model choice - a differently-configured account/model capped at the plain ~200k window would see no change - but it is true for the window tier crew actually runs on today: `--model sonnet` on this account, the standard crewmate spawn, resolves to the ~1M-context beta, well above 300000.
Verified live in a tmux pane at the original 200000 value (the mechanism is unchanged, only the shipped constant moved to 300000): `claude --model sonnet` on this account resolves to a ~967k-token auto-compact window with no override (`/context` reported `Auto-compact window: 967k tokens`, i.e. the 1M-context beta, not the 200k a plain Sonnet window would imply); relaunched with `CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000` set, `/context` reported `39.5k/200k tokens (20%)` and `Auto-compact window: 200k tokens` - the window pinned to the override as expected.
This is why the primary's own two-var form (`CLAUDE_CODE_AUTO_COMPACT_WINDOW=1000000` + `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=20`) is not copied here: that pair assumes a 1M window, and would silently cap a smaller-window model/account combination to a far more aggressive trigger.

**Primary-session guard fact (verified 2026-07-04, Claude Code 2.1.201; preserved 2026-07-08, Claude Code 2.1.204).**
This is separate from the per-task crewmate turn-end hook above (that one just `touch`es a marker file in a task's own `.claude/settings.local.json`).
The firstmate PRIMARY's own `.claude/settings.json` registers `bin/fm-turnend-guard.sh` as a Stop hook, and exiting with status 2 plus stderr reliably forces the model to continue.
Expand Down
3 changes: 3 additions & 0 deletions .agents/skills/updatefirstmate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ It never forces, never creates a merge commit, never stashes, and advances a tar
A tracked-files fast-forward leaves the gitignored operational dirs (data/, state/, config/, projects/, .no-mistakes/) untouched, so a secondmate's in-flight work is never disrupted.
This touches only the firstmate repo and its own worktrees, never anything under `projects/`.

Post-swap, this pull follows `origin`, which is the captain's fork, so `/updatefirstmate` converges the whole fleet onto that fork and does nothing on the primary checkout, which is itself the source every fork tracks.
It deliberately never reaches for the read-only `upstream` template: folding template improvements into local `main` is a separate, reviewed reconciliation ship task, the one the `UPSTREAM_DRIFT:` bootstrap diagnostic surfaces, and it never rides in on a self-update.

## What it does

1. **Run the updater:**
Expand Down
46 changes: 46 additions & 0 deletions .agents/skills/verify-trivial/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: verify-trivial
description: >-
Agent-only Light verification tier for a task dispatched at the trivial (haiku/low) model/effort tier.
Use when authoring or filling in a Light-tier brief's Task section (a brief scaffolded with `bin/fm-brief.sh --light-verify`), when working a task whose brief points here, or when reviewing such a task's done report before PR-ready.
Cites `verify-rigorously` for the AC bar, its 3 verification shapes, its pass/fail matrix, and its "what wasn't verified" footer; layers 3 deltas on top: a cap of 3 acceptance criteria instead of an uncapped set, a 3-attempt cap-out that escalates the task's tier rather than failing it outright, and a mandatory side-effect confidence gate before shipping.
user-invocable: false
metadata:
internal: true
---

# verify-trivial

Light verification tier for a task dispatched at the trivial (haiku/low) model/effort tier (see `AGENTS.md` section 7's escalation-trigger paragraph).
Such a task is scaffolded with `bin/fm-brief.sh --light-verify`; its brief points here instead of the default, uncapped verification workflow.

## Cite, don't copy

Load `verify-rigorously` and apply it in full: named observable pass/fail acceptance criteria, one of its 3 verification shapes per criterion, the criterion x shape pass/fail matrix, and the closing "what wasn't verified" footer.
This skill does not restate that contract - `verify-rigorously` is its sole owner.
Everything below is a delta on top of it that applies only to a Light-tier task.

## Delta 1: cap acceptance criteria at 3

Name at most 3 acceptance criteria, not verify-rigorously's uncapped set.
A trivial-tier task is scoped small enough by definition (`bin/fm-tier-guard.sh`'s envelope: at most 2 changed files, at most 30 changed lines) that 3 observable criteria should describe "done" completely.
If the task genuinely needs more than 3 to state what done means, that is itself a signal the task has outgrown the trivial tier: report it per Delta 2 instead of naming a 4th criterion.

## Delta 2: a 3-attempt cap-out escalates, it does not fail

verify-rigorously's own 3-attempt cap says: stop and report what's failing, what was tried, and the likely cause.
On the Light tier, that report is not a terminal failure - it is a request to escalate the task off this tier.
Append `needs-decision: {criterion} failed verification after 3 attempts, requesting escalation to a heavier tier` (or `blocked:` if the same obstacle recurred, per the brief's own rule for that case) and stop; do not report `failed:` for a cap-out alone.
Firstmate escalates the task's model/effort in place per `AGENTS.md` section 7's escalation-trigger paragraph, exactly as a `bin/fm-tier-guard.sh` envelope escalation would, and the task continues under the ordinary uncapped `verify-rigorously` workflow from there.
Never drop the task back to the Light tier afterward - this mirrors section 7's "never silently de-escalate for the rest of that task's life."

## Delta 3: mandatory side-effect confidence gate before shipping

Before reporting `done:` (ship tasks) or writing the report (scout tasks), state explicitly, in one line, whether the change has any side effects outside the files it touches - a shared config default, a migration, a public interface, a cross-task or cross-project coupling - and your confidence in that assessment.
An unstated "no side effects" is not the same as a stated one: silence here is exactly the gap verify-rigorously's own footer warns against, so this gate is mandatory even when the answer is "none found."
If confidence is anything less than high, that uncertainty is itself grounds for a Delta 2 escalation rather than shipping on the Light tier.

## Wiring this tier's no-mistakes validation

For a no-mistakes-mode ship task on this tier, firstmate's validation trigger skips the document step (`no-mistakes axi run --skip=document`): the side-effect confidence gate above already covers what that step would otherwise catch at this tier's scale.
This is firstmate's own action at Validate time (`AGENTS.md` section 7), not something the crewmate invokes itself.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ config/backlog-backend
config/backend
config/x-mode.env
config/cmux-socket-password
config/autodeploy-logs
config/wedge-alarm
config/critical-services
Loading