Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0ae14af
ci: gate GitHub workflows with pinned actionlint (#2517)
kunchenguid Aug 17, 2026
ac55d39
fix: install pinned lint tools across supported platforms (#2546)
kunchenguid Aug 17, 2026
312871d
docs: reconcile test-evidence docs with store_in_repo: true (#2548)
kunchenguid Aug 17, 2026
64d61ae
docs: clarify test evidence branch storage (#2549)
kunchenguid Aug 17, 2026
d023c45
docs: hint that live scouts may host their own Lavish review loop (#2…
kunchenguid Aug 18, 2026
d843712
fix(bin): report remote secondmate delivery and state truthfully (#2570)
kunchenguid Aug 18, 2026
d9ee8ea
feat: adopt spendPriority for quota dispatch (#2574)
kunchenguid Aug 18, 2026
862c532
docs: add GROK_BOT.md Grok Bot system prompt (#2590)
kunchenguid Aug 18, 2026
9d2ad81
docs: update GROK_BOT.md nautical terms and self-improvement (#2592)
kunchenguid Aug 18, 2026
f758e51
doc: Update language in GROK_BOT.md for clarity
kunchenguid Aug 18, 2026
ed66b85
fix(bin): preserve inactive reconciliation scan progress (#2595)
kunchenguid Aug 18, 2026
63362d2
doc: Revise Firstmate delegation and communication guidelines
kunchenguid Aug 18, 2026
03bb1d8
doc: Update work delegation and secret management instructions
kunchenguid Aug 18, 2026
c54c448
test(procevent): make the process-event suite's detached-runner asser…
kunchenguid Aug 19, 2026
7f5255a
fix: preserve pending replies and defer remote reposts (#2618)
kunchenguid Aug 19, 2026
b57c4d6
fix(bin): honor declared pauses in busy-pane wedge checks (#2619)
kunchenguid Aug 19, 2026
02ecdfe
sync: merge upstream kunchenguid/firstmate main (16 commits)
knowttl Aug 19, 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
3 changes: 2 additions & 1 deletion .agents/skills/firstmate-coding-guidelines/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ Run `bin/fm-doc-audience-check.sh`; it enforces classification, README setup rou
- Plain dash `-`, never an em dash.
- Never add an agent name as a commit co-author.
- `bin/*.sh` and `bin/backends/*.sh` must pass `shellcheck`.
- Run `bin/fm-lint.sh` before treating a script change as done; it is the single owner of the lint definition (file set, config, and pinned shellcheck version) that CI and the no-mistakes pre-push gate both invoke, and it refuses to run under any other shellcheck version.
- Run `bin/fm-lint.sh` before treating a script change as done; it is the single owner of the lint definition (file set, config, pinned shellcheck version, and pinned actionlint workflow lint) that CI and the no-mistakes pre-push gate both invoke, and it refuses to run under any other version of either linter.
- When a task names a specific tool, implement the work with that tool, or explicitly flag the substitution and its new dependency footprint for review before shipping.
- Colocate tests with the existing pattern in `tests/`, name them `<subject>.test.sh`, and extend an existing script rather than inventing a new runner.
- Tests must exercise behavior through an executable or public interface and must never assert implementation-source bytes, including through parsers, regexes, snapshots, or indirect wrappers.
- A maintainer-verification record under `docs/verification/` records active empirical facts, not assumptions or task chronology.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/process-event-sources/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Firstmate registers a source, keeps working, and is woken when that process comp
## Arming a source

Use the adapter, not the generic runner, for a real source.
For an Atelier review artifact:
For an Atelier review artifact firstmate owns (a live investigating scout should host its own loop):

```sh
bin/fm-procevent-atelier.sh arm <artifact.html>
Expand Down
140 changes: 72 additions & 68 deletions .agents/skills/quota-array-dispatch/SKILL.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .agents/skills/stuck-crewmate-recovery/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The target window's harness is recorded as `harness=` in `state/<id>.meta`.
This procedure covers ordinary `kind=ship` and `kind=scout` direct reports.
Load `secondmate-provisioning` instead for `kind=secondmate` recovery.

For a REMOTE secondmate, `fm-crew-state`'s `unknown`/`worktree gone` and `fm-send`'s `remote send failed`/`delivery unconfirmed` verdicts are unreliable and routinely false-negative; do not conclude the mate is dead or the send failed from those alone, confirm against the actual remote pane first.
For a REMOTE secondmate, `fm-crew-state` and `fm-peek` read the actual remote endpoint over `fm-on.sh`, and `fm-send` reports a delivered-with-pending-confirmation steer as delivered (their headers own the contracts); an `unknown-remote` read or unreachable-host failure means the remote state could not be read, never that the mate is dead or the send failed.
Recover a genuinely stuck remote mate only through `bin/fm-spawn.sh <id> --secondmate`, never raw herdr pane close/kill surgery, which strands the endpoint binding.

Treat the digest's endpoint result as a presence signal, not proof that the task's work or validation run is gone.
Expand Down
28 changes: 25 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ permissions:

jobs:
lint:
name: Lint shell scripts
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
Expand All @@ -20,8 +20,15 @@ jobs:
set -eu
bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
# Single owner of the lint definition (file set + config + version). Do not
# re-spell the shellcheck command here; keep CI and the pre-push gate on it.
- name: Install pinned actionlint
run: |
set -eu
bin/fm-install-actionlint.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
# Single owner of the lint definition (shell file set, config, version,
# and GitHub workflow lint). Do not re-spell the checks here; keep CI
# and the pre-push gate on this script so a self-broken ci.yml still
# fails locally before merge.
- run: bin/fm-lint.sh

# Deterministic proof that portable parallel shards + portable serial + Herdr
Expand Down Expand Up @@ -52,6 +59,11 @@ jobs:
set -eu
bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Install pinned actionlint
run: |
set -eu
bin/fm-install-actionlint.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Install tasks-axi
run: |
set -eu
Expand Down Expand Up @@ -84,6 +96,11 @@ jobs:
set -eu
bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Install pinned actionlint
run: |
set -eu
bin/fm-install-actionlint.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Install tasks-axi
run: |
set -eu
Expand Down Expand Up @@ -130,6 +147,11 @@ jobs:
set -eu
bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Install pinned actionlint
run: |
set -eu
bin/fm-install-actionlint.sh "$RUNNER_TEMP/bin"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Require tmux for e2e tests
run: |
set -eu
Expand Down
8 changes: 5 additions & 3 deletions .no-mistakes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ document:

# Pin lint to the same owner CI runs instead of leaving it to no-mistakes'
# default handling, which does not invoke the repository's canonical lint gate.
# `bin/fm-lint.sh` owns the complete lint definition and
# `bin/fm-lint.sh` owns the complete lint definition, including GitHub workflow
# lint via pinned actionlint in `bin/fm-lint-workflows.sh`, and
# `.github/workflows/ci.yml` invokes it directly, with parity asserted by
# `tests/fm-lint.test.sh`.
# `tests/fm-lint.test.sh` and `tests/fm-lint-workflows.test.sh`.
#
# Do not set commands.test to a complete tests/*.test.sh walk. Local no-mistakes
# Test is intent-targeted validation of whether the change meets its brief;
Expand All @@ -36,7 +37,8 @@ document:
commands:
lint: 'bin/fm-lint.sh'

# Store test evidence in this repo so it is committed alongside the change instead of kept in a temp dir.
# Publish each run's test evidence to the orphan no-mistakes/evidence branch linked from the PR.
# The evidence is not committed to the feature or default branch.
test:
evidence:
store_in_repo: true
9 changes: 5 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,16 @@ If static `config/crew-harness` or `config/secondmate-harness` names an unverifi
`docs/configuration.md` owns dispatch-profile and runtime-backend schemas, `bin/fm-harness.sh` owns static resolution, and `bin/fm-spawn.sh` owns launch flags and fail-closed validation.
When dispatch profiles exist, consult them at every crewmate or scout intake and pass the resolved concrete profile required by `fm-spawn`.
Routing precedence is an explicit per-task captain override, then the best-fit configured rule, then the configured default, then the static crewmate harness.
Firstmate alone resolves a matched profile array: run `quota-axi --json` at that intake, evaluate every configured candidate against that current output, and choose with inspectable effective headroom and usable runway, using pace and reserve only later when needed.
Account for every candidate with the catalog evidence, provider relationship, applicable quota and authentication facts, remaining uncertainty, fit and reasoning class, and the headroom, runway, and later pace or reserve evidence used in selection; never omit a candidate, guess, fall back silently, or call the result quota-informed without them.
Firstmate alone resolves a matched profile array: begin with `quota-axi`'s default TOON at that intake, using the skill's narrow TOON-then-`--json` fallback only for genuine ambiguity, evaluate every configured candidate against that current output, and choose with inspectable `spendPriority` as the one quota-perspective ranker after the skill's eligibility, reasoning-class, and runway-feasibility gates.
Account for every candidate with the catalog evidence, provider relationship, applicable quota and authentication facts, remaining uncertainty, fit and reasoning class, and the spendPriority and runway evidence used in selection; never omit a candidate, guess, fall back silently, or call the result quota-informed without them.
Establish model support and provider family from that harness's own authoritative catalog, then read `quota-axi` at the granularity the vendor actually supplies: provider-level or all-model evidence applies to every model established in that family, and a named-model window bounds only that model.
Missing model-level quota, a missing authentication source, unmeasurable headroom, or unmodeled authentication is disclosed uncertainty that keeps a candidate eligible, never a credential or login escalation.
Only concrete contradictory evidence blocks a candidate, such as an authoritative catalog proving the model unsupported or proof that the credential selected for that surface is unusable; never infer a credential store, provider family, or quota mapping from a harness, model, or source name, and never launch another harness's CLI to judge a candidate.
Preserve malformed profile configuration as an actionable error rather than selecting around it.
When every candidate is tight, preserve the captain's strongest-reasoning class rather than silently downgrading it solely to conserve quota; stop and report the tight choice if that class cannot proceed.
Break genuine evidence ties without array-order or harness bias.
`quota-axi` owns how model or product windows relate to bounding account windows and remains data-only.
Load `quota-array-dispatch` before choosing among a matched profile array; that skill is the single owner of the completion-aware selection procedure.
Load `quota-array-dispatch` before choosing among a matched profile array; that skill is the single owner of the TOON-first spendPriority selection procedure.
The generic effort fallback and its precedence are owned by `harness-adapters`: explicit captain and standing configured effort win; otherwise use low for well-understood explicit work, xhigh for ambiguous investigation or design, intermediate levels proportionally, and never max without explicit captain preference.
Do not add model-specific versions of that policy.

Expand Down Expand Up @@ -373,6 +373,7 @@ Retire one only on an explicit captain or main-firstmate decision, after loading
A completed scout must leave a self-contained report before its scratch worktree can be discarded; read and relay its findings, record the report as the Done artifact, and re-evaluate the queue.
A report may recommend implementation but does not authorize it.
Before treating the investigation or any visual review as complete, load `decision-hold-lifecycle`; teardown enforces that shared completion gate.
When a scout's deliverable is a visual artifact the captain will iterate on, prefer keeping that scout alive to host its own Atelier loop rather than tearing it down and mediating from firstmate, so the scout keeps its investigation context and the captain iterates in one continuous session.
When implementation is separately authorized, promote the existing scout through `bin/fm-promote.sh` rather than creating a duplicate task.
The promoted worker must inventory scratch state, return to a clean default-branch base, carry over only intended fix changes, create the ship branch, and follow the project's selected delivery path while leaving scratch commits and debug edits behind and turning a reproduced bug into the regression test.

Expand Down Expand Up @@ -524,7 +525,7 @@ These skills are not captain-invocable; load them only at their precise triggers
- `bootstrap-diagnostics` - load whenever the session-start digest's bootstrap or network-checks section prints an actionable diagnostic line (`MISSING:`, `MISSING_MANUAL:`, `BACKEND_INVALID:`, `NEEDS_GH_AUTH`, `TANGLE:`, `STARTUP_MEMORY_BUDGET:`, `CREW_DISPATCH: invalid`, `FLEET_SYNC:`, `NETWORK_CHECKS:`, `PR_CHECK_MIGRATION:`, `SECONDMATE_SYNC:`, `SECONDMATE_LIVENESS:`, `SECONDMATE_HANDOFF:`, `NUDGE_SECONDMATES:`, or `FMX:`); silence and `BOOTSTRAP_INFO:` need no load.
- `diagnostic-reasoning` - load before scoping a reported bug and before acting on a diagnostic report.
- `ask-user-authority` - load before deciding any ask-user finding, regardless of the project's `yolo` posture.
- `quota-array-dispatch` - load before choosing among a matched crew-dispatch profile array from current quota-axi output.
- `quota-array-dispatch` - load before choosing among a matched crew-dispatch profile array from current quota-axi default TOON.
- `harness-adapters` - load before spawning or recovering a crewmate or secondmate, handling a trust dialog, sending a harness-specific skill invocation, interrupting or exiting an agent, resuming an exited agent, or verifying a new harness adapter.
- `firstmate-orca` - load before switching to Orca, spawning or supervising Orca-backed work, smoke-testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata.
- `project-management` - load before adding, creating, removing, or initializing a project.
Expand Down
13 changes: 8 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ See the [no-mistakes quick start](https://kunchenguid.github.io/no-mistakes/star
- Helper scripts in `bin/` are plain bash.
Each starts with a usage header comment; keep it accurate when you change behavior.
Test scripts and helpers in `tests/` are plain bash too.
`bin/fm-lint.sh` must pass: it is the single owner of the lint definition (the shellcheck file set, config, and pinned shellcheck version), and both CI and the no-mistakes pre-push gate run it, so local and CI can never diverge.
It pins one exact shellcheck version and refuses to run under any other; print it with `bin/fm-lint.sh --required-version` and install that build locally.
`bin/fm-lint.sh` must pass: it is the single owner of the lint definition (the shellcheck file set, config, pinned shellcheck version, and pinned actionlint workflow lint), and both CI and the no-mistakes pre-push gate run it, so local and CI can never diverge.
A malformed `.github/workflows/*.yml`, including a self-broken `ci.yml`, fails that local lint path before merge because a broken workflow cannot report its own breakage.
It pins one exact shellcheck version and one exact actionlint version and refuses to run under any other.
Print the shellcheck pin with `bin/fm-lint.sh --required-version` and the actionlint pin with `bin/fm-lint-workflows.sh --required-version`.
Use `bin/fm-install-shellcheck.sh` and `bin/fm-install-actionlint.sh` to install those exact builds locally; each installer's header owns its destination usage and supported platforms.
- Harness-adapter ownership spans detection in `bin/fm-harness.sh`, launch and hook mechanics in `bin/fm-spawn.sh`, semantic busy sources and trust gates in `bin/fm-busy-lib.sh`, delivery-only rendered guards in `bin/fm-composer-lib.sh`, cleanup in `bin/fm-teardown.sh`, and facts in `.agents/skills/harness-adapters/SKILL.md`; the `firstmate-coding-guidelines` skill owns the validation policy for checks that depend on those harnesses.
- Changes to runtime session backends (`bin/fm-backend.sh`, `bin/backends/`, and the scripts that dispatch through them) keep current setup and limits in the relevant backend guide and active empirical evidence in [`docs/verification/runtime-backends.md`](docs/verification/runtime-backends.md).
- [`docs/documentation-audiences.md`](docs/documentation-audiences.md) and its machine-consumed inventory own prose classification; run `bin/fm-doc-audience-check.sh` after documentation changes.
Expand All @@ -64,15 +67,15 @@ A crewmate picking up such a brief should load the skill even if the brief preda
When supervising live crewmates, keep firstmate's own long validation or build commands in the background so watcher wakes can still be handled.
Crewmate validation follows the installed no-mistakes version's SKILL.md and live `axi` help instead of duplicating gate mechanics in firstmate docs.
Firstmate's wrapper still matters: crewmates route every `ask-user` finding to firstmate, which applies the authority contract in `AGENTS.md`, and crewmates avoid `--yes` because it would bypass that check and any required captain escalation.
Local `.no-mistakes/` state and test evidence stay out of this repo; `.no-mistakes.yaml` keeps evidence in a temp directory and pins the gate's lint command to `bin/fm-lint.sh`, matching the Linux CI lint job.
`.no-mistakes.yaml` publishes test evidence to the orphan `no-mistakes/evidence` branch, which shares no history with code branches, and pins the gate's lint command to `bin/fm-lint.sh`, matching the Linux CI lint job.
Local no-mistakes Test is intent-targeted and must not re-run every `tests/*.test.sh`; `.github/workflows/ci.yml` owns the broad behavior suite plus platform-specific compatibility lanes.
That is firstmate-specific; do not commit `.no-mistakes/evidence/` here even when another no-mistakes-managed target project keeps committed PR evidence.
The pipeline publishes that evidence itself, so never hand-commit `.no-mistakes/` paths onto a feature branch; CI rejects them as tracked personal fleet paths.

Check and test the toolbelt before pushing:

```sh
while IFS= read -r script; do /bin/bash -n "$script" || exit; done < <(bin/fm-lint.sh --list-files) # syntax-check the shell surface fm-lint.sh will cover (changed files locally, full set in CI/on main)
bin/fm-lint.sh # lint that same surface; the single owner CI and the no-mistakes gate both run, full set in CI
bin/fm-lint.sh # lint that shell surface plus GitHub workflows via pinned actionlint; the single owner CI and the no-mistakes gate both run
bin/fm-test-run.sh tests/<subject>.test.sh # one script (primary local focus path, timed)
bin/fm-test-run.sh --family pure-contract-unit # ordinary family-scoped local path (serial, timed)
bin/fm-test-run.sh --changed # conservative changed-file-informed set (never silent full suite)
Expand Down
Loading
Loading