Thanks for wanting to contribute. One rule up front:
Human-authored pull requests targeting main must be raised through no-mistakes.
We require this to reduce the maintainer's burden of reviewing and merging contributions.
no-mistakes puts a local git proxy in front of your real remote.
Pushing through it runs an AI-driven review/test/lint pipeline in an isolated worktree, forwards the push upstream only after every check passes, and opens a clean PR automatically.
A GitHub Actions check (Require no-mistakes) runs on PRs targeting main and fails if the body is missing the deterministic signature that no-mistakes writes.
The generated ## Pipeline section must contain Updates from [git push no-mistakes](https://github.com/kunchenguid/no-mistakes) exactly; prose that merely says the checks passed is not a substitute for that machine-verifiable marker.
Dependency bots are exempt so their automation keeps working, but regular contributor PRs without the signature will not be reviewed or merged.
-
Fork the repo, then clone the parent repo or set your local
originback to the parent ([email protected]:kunchenguid/firstmate.git). -
Create a branch and make your changes.
-
Initialize the gate with your fork as the push target:
no-mistakes init --fork-url [email protected]:<you>/firstmate.git(firstmate expects no-mistakes v1.31.2+; without a fork, plainno-mistakes initstill works for maintainers with push access). -
Commit your changes.
-
Push through the gate instead of pushing to
origin:git push no-mistakes
-
Run
no-mistakesto attach to the pipeline, watch findings, authorize auto-fixes, and review ask-user findings as needed. Follow the installed no-mistakes version's SKILL.md and liveaxihelp for gate mechanics. -
Once the pipeline passes, it pushes the branch to your fork and opens the PR against the parent repo for you.
See the no-mistakes quick start for the full first-run walkthrough.
- This repo is a template for running a firstmate orchestrator agent.
AGENTS.mdis the agent's main job description and names when to load bundled firstmate skills;CLAUDE.mdis a symlink to it, and.claude/skillsis a symlink to.agents/skills. - Only shared material is tracked:
AGENTS.md,README.md,CONTRIBUTING.md,.tasks.toml,.github/workflows/,bin/,.agents/skills/,skills/, and provider-neutral components undertools/..agents/skills/holds agent-loaded skills that assume a live firstmate home and carrymetadata.internal: trueso installers such as skills.sh hide them from discovery;skills/holds standalone, installer-facing public skills with no firstmate dependency (see the README's "Two-tier skill layout"). Everything personal to one captain's fleet (.env,data/,state/,config/,projects/,.no-mistakes/) is gitignored; never commit it. The root.tasks.tomlis trackedtasks-axiconfig fordata/backlog.md; compatibletasks-axiis the default backend for routine backlog mutations, with the compatibility definition owned bydocs/configuration.md("Backlog backend"). A localconfig/backlog-backend=manualopt-out forces firstmate's routine backlog updates to hand-editing and stays gitignored; validated secondmate handoffs still delegate throughtasks-axi mv. A localconfig/backendfile explicitly overrides runtime auto-detection for new task endpoints and stays gitignored; spawn-supported values aretmuxplus experimentalherdr,zellij,orca, andcmux, whilecodex-appis documented only indocs/codex-app-backend.md. It does not makedata/tracked. - 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 intests/are plain bash too.bin/fm-lint.shmust 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 withbin/fm-lint.sh --required-versionand install that build locally. - Changes to harness adapters (detection in
bin/fm-harness.sh, launch and hook mechanics inbin/fm-spawn.sh, busy signatures inbin/fm-watch.shandbin/fm-tmux-lib.sh, cleanup inbin/fm-teardown.sh, and facts in.agents/skills/harness-adapters/SKILL.md) must be verified empirically against the real harness, never written from documentation alone. - Changes to runtime session backends (
bin/fm-backend.sh,bin/backends/, and the scripts that dispatch through them) need empirical adapter notes in the relevant backend guide:docs/tmux-backend.md,docs/herdr-backend.md,docs/zellij-backend.md,docs/orca-backend.md,docs/cmux-backend.md, ordocs/codex-app-backend.mdfor blocked Codex App transport work. - In Markdown, put each full sentence on its own line.
README.mdstays a concise overview plus pointers: it never carries a wall of inline detail. Route detail to the most specificdocs/file (architecture, configuration, or a backend guide) and link to it instead.
Changes to the shared tracked material listed under "Repo conventions" ship through the no-mistakes pipeline on a feature branch and require an explicit merge approval.
Before making any such change, load the agent-only firstmate-coding-guidelines skill (.agents/skills/firstmate-coding-guidelines/SKILL.md).
It has the knowledge-placement rules that keep AGENTS.md from regrowing after each diet pass.
There is no reliable way for bin/fm-brief.sh's scaffold to detect that a task's repo is firstmate itself, so firstmate adds this skill's load line to firstmate-repo briefs by hand.
A crewmate picking up such a brief should load the skill even if the brief predates this instruction.
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: ask-user findings route to the captain through firstmate, and crewmates avoid --yes because it silently resolves captain-owned decisions without 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 shell and Agent Fleet source checks to their matching CI commands.
That is firstmate-specific; do not commit .no-mistakes/evidence/ here even when another no-mistakes-managed target project keeps committed PR evidence.
Check and test the toolbelt before pushing:
for script in bin/*.sh bin/backends/*.sh; do bash -n "$script"; done # syntax-check the toolbelt
bin/fm-lint.sh # lint the toolbelt and behavior tests; the single owner CI and the no-mistakes gate both run
for test_script in tests/*.test.sh; do case "$test_script" in tests/fm-afk-launch.test.sh|tests/fm-backend-autodetect-smoke.test.sh|tests/fm-backend-herdr-workspace-per-home-e2e.test.sh) continue ;; esac; bash "$test_script"; done # behavior tests safe for a developer checkout
[ "$(readlink CLAUDE.md)" = "AGENTS.md" ]
[ "$(readlink .claude/skills)" = "../.agents/skills" ]
tmp=$(mktemp -d) && printf 'done: smoke\n' > "$tmp/smoke.status" && FM_STATE_OVERRIDE="$tmp" FM_SIGNAL_GRACE=1 FM_POLL=1 FM_HEARTBEAT=999999 bin/fm-watch-arm.sh # watcher re-arm smoke test (prints arm status, then an actionable signal)Agent Fleet is independently packaged under tools/agent-fleet and requires Python 3.11 or newer plus uv.
Run the complete locked verification in tools/agent-fleet/RELEASING.md before pushing; that document also owns versioning, tagging, and clean-install verification.
Discover behavior-test entrypoints by listing tests/*.test.sh and run one directly to focus on a subject; partition wrappers source their matching tests/*-suite.sh implementation.
When triaging a red behavior shard, use its begin and end markers to identify each failing script: the shard continues through its complete assignment and records every exit code before the final Behavior tests job verifies the executed union.
Reproduce with the exclusion-aware local loop to see every safe failure at once before concluding which ones are real.
Reproduce in a checkout whose origin is the repository's https URL, as CI's own checkout is: the secondmate network-authority fixtures assert that the product pins the resolved address of the origin host, and a checkout whose origin is a local filesystem path has no host to pin, so those cases refuse for a reason that exists only locally.
Run the suites from a checkout sitting on its default branch, not from a task-branch worktree - the worktree-tangle guard fires and several secondmate suites require the default branch, which produces more failures that are pure local artifacts.
Do not run tests/fm-afk-launch.test.sh, tests/fm-backend-autodetect-smoke.test.sh, or tests/fm-backend-herdr-workspace-per-home-e2e.test.sh on a developer checkout: they act on the DEFAULT Herdr workspace where the live crewmate fleet runs and can destroy other agents' unlanded work.
CI runs them safely only because its runner is disposable and carries no fleet.
Use bin/fm-brief.sh --herdr-lab for these suites; it owns the isolation contract requiring a never-default lab session, a trailing --session on every Herdr call, guarded teardown, and a before/after fleet-state tripwire.
Other tests that need a real optional backend, an explicit opt-in, or an ambient toolchain capability (real zellij/cmux smoke tests, the live Pi regression, the Pi TypeScript-extension checks when node cannot import .ts modules directly) skip themselves and print the tool or environment gate needed to enable them.
Open an issue, or talk to me on Discord.