Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 14 additions & 5 deletions .agents/skills/stow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,26 @@ The goal is a session that is safe to reset or destroy because everything durabl

3. **Write within firstmate's existing write boundaries.**
This skill does not grant any new write permission; it only prompts firstmate to use the boundaries that already exist (AGENTS.md section 1):
- Captain preferences and fleet-local operational facts: hand-write directly, to `data/captain.md` and `data/learnings.md` respectively.
`data/learnings.md` may not exist yet; create it on first learning, in the same dated, evidence-backed, curated style as `data/captain.md` - rewrite and prune stale or superseded entries rather than appending forever.
- Captain preferences and fleet-local operational facts: hand-write directly, to `data/captain.md` and `data/learnings.md` respectively, using inspect-then-update every time.
Before writing, inspect the destination, find the existing bullet or section the finding duplicates or supersedes, and rewrite it in place rather than adding a new trailing entry.
`data/learnings.md` may not exist yet; create it on first learning, in the same dated, evidence-backed, curated style as `data/captain.md`.
- Project-intrinsic knowledge: never hand-write a project's `AGENTS.md`.
Route it through a normal ship task so a crewmate records it via `bin/fm-ensure-agents-md.sh` and commits it through that project's delivery pipeline, exactly as section 6 describes.
If the fleet is live, delegate this to a crewmate rather than doing it inline.
- Knowledge generalizable to every firstmate user: this repo's own `AGENTS.md` (or other shared, tracked material), shipped through the normal branch -> no-mistakes -> PR -> captain-merge pipeline for this repo (section 1), never hand-committed straight to `main`.
- Task-scoped notes: append to the relevant backlog item's notes with `tasks-axi update <id> --append "<note>"`, or hand-edit `data/backlog.md` per the active backend (section 10).
- Task-scoped notes: inspect the relevant backlog item with `tasks-axi show <id> --full`, judge whether the new note is new, duplicate, superseding, or obsolete, then write a considered replacement body with `tasks-axi update <id> --body-file <path>`.
When the replacement intentionally supersedes prior state that should remain recoverable, add `--archive-body` to that update command so the prior body stays recoverable without copying it into the replacement.
Never append.
If hand-editing `data/backlog.md` per the active backend, make the same inspect-then-update edit in place.
- Undone next steps: file each as a queued backlog item (section 10), with `blocked-by` recorded if it genuinely depends on something else.

4. **Curate, don't just append.**
When a finding overlaps or supersedes something already on disk, prefer rewriting or pruning the existing entry over piling on a new one.
4. **Curate with inspect-then-update.**
Every write starts by reading the current destination and deciding how the finding changes what is already there.
Use this checklist before writing:
- Which existing bullet, section, or task body does this supersede?
- Can this be a one-sentence rewrite instead of a new entry?
- Should an older bullet or note be deleted, retired, or archived because it is now obsolete?
When a finding overlaps or supersedes something already on disk, rewrite or prune the existing entry instead of piling on a new one.
Graduation moves are limited to exactly three: promote a learning to the shared `AGENTS.md` via PR, fold it into `data/captain.md`, or delete a stale entry.
Do not invent other graduation paths.

Expand Down
20 changes: 11 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ config/cmux-socket-password optional cmux control-socket password; LOCAL, gitig
config/x-mode.env generated X-mode watcher cadence; LOCAL, gitignored; source before arming watcher when present
data/ personal fleet records; LOCAL, gitignored as a whole
backlog.md task queue, dependencies, history
captain.md captain's curated personal preferences and working style; LOCAL, gitignored, and canonical even if harness memory mirrors it
learnings.md fleet-local operational facts and gotchas; LOCAL, gitignored; dated, evidence-backed, curated - rewrite and prune rather than append forever, the same contract as captain.md; created lazily, absent until this home has a learning to store
captain.md captain's personal preferences and working style; LOCAL, gitignored, canonical even if harness memory mirrors it, and updated with inspect-then-update
learnings.md fleet-local operational facts and gotchas; LOCAL, gitignored; dated, evidence-backed, curated, and updated with inspect-then-update - rewrite and prune rather than append forever, the same contract as captain.md; created lazily, absent until this home has a learning to store
projects.md thin fleet navigation registry; firstmate-private, parsed by fm-project-mode.sh (section 6)
secondmates.md secondmate routing table; firstmate-private, maintained by fm-home-seed.sh (section 6)
<id>/brief.md per-task crewmate brief, or per-secondmate charter brief when kind=secondmate
Expand Down Expand Up @@ -140,6 +140,7 @@ It composes today's `fm-lock.sh`, `fm-bootstrap.sh`, and `fm-wake-drain.sh` - ca
Do not separately run `bin/fm-bootstrap.sh`, `bin/fm-lock.sh`, or `bin/fm-wake-drain.sh`, and do not separately read `data/projects.md`, `data/secondmates.md`, `data/captain.md`, `data/learnings.md`, `data/backlog.md`, or any `state/*.meta` afterward - they were just printed in full, and re-reading them defeats the entire point of collapsing session start into one command.
Do not bulk-read `state/*.status` afterward either: the digest printed bounded tails with full log paths for targeted follow-up when older wake-event history is actually needed.
Re-read a file only if the digest flagged it `ABSENT` (then rebuild or create it per the guidance in this section and section 6), its contents looked unparseable or corrupt, or an individual full status log is needed for older wake-event history.
This read-once rule does not block a targeted current-state read immediately before a workflow writes one of these files, such as `/stow`'s inspect-then-update pass or a backlog backend mutation.
Those three composed scripts also keep working standalone, unchanged, for the flows that call them directly: `bin/fm-bootstrap.sh install <tools>` after consent, `/updatefirstmate`, the afk daemon, and existing tests.

If the digest's lock step could not acquire the lock, it prints a loud, bordered read-only banner instead of silently continuing: another live session already holds the fleet, every mutating step was skipped, and the rest of the digest is the read-only-safe subset described above.
Expand All @@ -164,7 +165,7 @@ Otherwise it prints one line per problem or capability fact; handle each:
- `MISSING: <tool> (install: <command>)` - list the missing tools to the captain with a one-line purpose each plus the printed install commands, wait for consent (one approval may cover the list), then run `bin/fm-bootstrap.sh install <approved tools...>`.
For `treehouse`, this also covers an installed version whose `treehouse get` lacks `--lease`; treat it as an upgrade request.
For `no-mistakes`, this also covers an installed version older than 1.31.2, because crewmate validation briefs delegate gate mechanics to no-mistakes' version-matched guidance.
For `tasks-axi`, this also covers an installed build whose `tasks-axi --version` is older than 0.1.1; `config/backlog-backend=manual` only suppresses the `TASKS_AXI: available` capability line, not this missing-tool report.
For `tasks-axi`, this also covers an installed build whose `tasks-axi --version` is older than 0.1.1 or whose `tasks-axi update --help` lacks `--archive-body`; `config/backlog-backend=manual` only suppresses the `TASKS_AXI: available` capability line, not this missing-tool report.
For `quota-axi`, bootstrap requires it because crew-dispatch `quota-balanced` may call it; `bin/fm-dispatch-select.sh` still degrades at runtime when quota data is unavailable.
- `NEEDS_GH_AUTH` - ask the captain to run `! gh auth login` (interactive; you cannot run it for them).
- `TANGLE: <remediation>` - the primary checkout is stranded on a feature branch instead of its default branch; section 8 explains why this guard exists and what it protects.
Expand All @@ -181,7 +182,7 @@ Otherwise it prints one line per problem or capability fact; handle each:
- `SECONDMATE_LIVENESS: secondmate <id>: already-live|respawned|skipped: <reason>|respawn failed: <reason>` - the session-start liveness sweep checked a live secondmate's recorded endpoint for a real agent process.
Treat `already-live` and `respawned` as handled; investigate `skipped` or `respawn failed` because that secondmate is not guaranteed live.
- `TASKS_AXI: available` - a default-backend capability fact, not a problem; record it silently and use section 10 for backlog mutations.
It prints only when `config/backlog-backend` is absent or set to `tasks-axi` and the compatibility probe accepts `tasks-axi --version` as 0.1.1 or newer.
It prints only when `config/backlog-backend` is absent or set to `tasks-axi` and the compatibility probe accepts `tasks-axi --version` as 0.1.1 or newer plus `tasks-axi update --help` exposing `--archive-body`.
If the backend is not opted out and `tasks-axi` is missing or incompatible, bootstrap reports `MISSING: tasks-axi (install: npm install -g tasks-axi)` but still falls back to hand-editing and never blocks work.
If `config/backlog-backend=manual`, bootstrap hand-edits and does not suggest installing `tasks-axi`.
- `NUDGE_SECONDMATES: fm-<id>...` - the secondmate sweep fast-forwarded one or more *running* secondmate homes to firstmate's current version and their instruction surface (`AGENTS.md`, `bin/`, or `.agents/skills/`) actually changed; send a one-line re-read nudge with `FM_HOME=<this-firstmate-home> bin/fm-send.sh <id> 'firstmate was updated to the latest - please re-read your AGENTS.md to pick up the new instructions.'` unless `FM_HOME` is already set to the active firstmate home.
Expand Down Expand Up @@ -411,11 +412,11 @@ Route each piece of durable knowledge to its most specific home:

| Kind of knowledge | Home |
| --- | --- |
| Captain preferences and working style | `data/captain.md` |
| Captain preferences and working style | `data/captain.md`, inspected first and rewritten or pruned in place |
| Project-intrinsic knowledge | that project's own `AGENTS.md`, via normal crewmate delivery, never hand-written by firstmate |
| Fleet-local operational facts and gotchas | `data/learnings.md` |
| Fleet-local operational facts and gotchas | `data/learnings.md`, inspected first and rewritten or pruned in place |
| Knowledge generalizable to every firstmate user | the shared `AGENTS.md`, shipped via PR through the pipeline |
| Task-scoped notes | backlog item notes (`tasks-axi update <id> --append "<note>"`, or hand-edit per the active backend) |
| Task-scoped notes | backlog item notes, inspect first with `tasks-axi show <id> --full`, then replace the body with `tasks-axi update <id> --body-file <path>`, adding `--archive-body` when superseded prior state should remain recoverable, or hand-edit per the active backend |
| Investigation findings | scout reports at `data/<id>/report.md` |

When the captain invokes `/stow`, load the `stow` skill.
Expand Down Expand Up @@ -830,7 +831,7 @@ Re-evaluate Queued on every teardown and every heartbeat: anything whose blocker
A tracked `.tasks.toml` at this repo root pins the default `tasks-axi` markdown backend to `data/backlog.md`, with `done_keep = 10` and an archive at `data/done-archive.md`.
The local, gitignored `config/backlog-backend` file is the explicit opt-out knob.
Absent or `tasks-axi` means use the default tasks-axi backend; `manual` means force hand-editing even when `tasks-axi` is installed.
Compatible means the shared bootstrap probe accepts `tasks-axi --version` as 0.1.1 or newer.
Compatible means the shared bootstrap probe accepts `tasks-axi --version` as 0.1.1 or newer and `tasks-axi update --help` exposes `--archive-body`.
When the default backend is selected and compatible `tasks-axi` is on PATH, firstmate mutates the backlog through its verbs instead of hand-editing, with secondmate handoffs still going through the validated helper described in section 6.
When the default backend is selected but `tasks-axi` is missing or incompatible, bootstrap reports it through the normal `MISSING:` consent flow in `docs/configuration.md` "Toolchain", and every firstmate home falls back to hand-editing `data/backlog.md` exactly as this section describes until it is installed.
When `config/backlog-backend=manual`, every firstmate home hand-edits; bootstrap still requires compatible `tasks-axi` on `PATH` but does not print `TASKS_AXI: available`.
Expand All @@ -846,7 +847,8 @@ Map firstmate's real backlog operations to the approved commands:
- File an item: `tasks-axi add <id> "<one line>" --kind <ship|scout> --repo <name>`, plus `--start` for immediate dispatch (In flight) or the default queue placement, and `--blocked-by <id>` (repeatable) when it waits on another task.
- Start an existing queued item: `tasks-axi start <id>` before dispatching work from Queued, after checking that blockers are gone and any time/date gate has arrived.
- Move a finished task to Done: `tasks-axi done <id> --pr <url>` for a PR-based ship, `--report <path>` for a scout, or `--note "local main"` for a local-only merge.
- Append a status note: `tasks-axi update <id> --append "<note>"`; replace fields with `--title`, `--body`, or `--body-file <path>`.
- Update task notes: inspect first with `tasks-axi show <id> --full`, then replace the considered body with `tasks-axi update <id> --body-file <path>`.
Add `--archive-body` to that update command when superseding prior state should remain recoverable.
- Manage dependencies: `tasks-axi block <id> --by <other>` and `tasks-axi unblock <id> --by <other>`, then `tasks-axi ready` to list queued work with no unresolved blockers.
This is a dependency check only; future-dated items still stay queued until their date arrives.
- Read an item's full notes: `tasks-axi show <id> --full`.
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ See the [no-mistakes quick start](https://kunchenguid.github.io/no-mistakes/star
`.agents/skills/` holds agent-loaded skills that assume a live firstmate home and carry `metadata.internal: true` so installers such as [skills.sh](https://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.toml` is tracked `tasks-axi` config for `data/backlog.md`; compatible `tasks-axi` is the default backend for routine backlog mutations.
Compatible means version 0.1.1 or newer and `tasks-axi update --help` exposing `--archive-body`.
A local `config/backlog-backend=manual` opt-out forces hand-editing and stays gitignored.
A local `config/backend` file explicitly overrides runtime auto-detection for new task endpoints and stays gitignored; spawn-supported values are `tmux` plus experimental `herdr`, `zellij`, `orca`, and `cmux`, while `codex-app` is documented only in `docs/codex-app-backend.md`.
It does not make `data/` tracked.
Expand Down
5 changes: 3 additions & 2 deletions bin/fm-bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@
# no-mistakes is also MISSING when its installed version is older than
# 1.31.2.
# tasks-axi and quota-axi are required bootstrap tools (same class as
# lavish-axi). tasks-axi is also version-gated (0.1.1+); an installed
# but incompatible build reports MISSING like no-mistakes. When
# lavish-axi). tasks-axi is also version and feature gated (0.1.1+
# with update --archive-body); an installed but incompatible build
# reports MISSING like no-mistakes. When
# config/backlog-backend is not manual and tasks-axi is compatible,
# bootstrap prints TASKS_AXI: available. quota-axi is required because
# crew-dispatch quota-balanced may call it; fm-dispatch-select.sh still
Expand Down
19 changes: 15 additions & 4 deletions bin/fm-tasks-axi-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# Shared tasks-axi backend selection and compatibility probe for bootstrap and
# teardown.
# Usage: . bin/fm-tasks-axi-lib.sh
# Compatible means tasks-axi --version reports 0.1.1 or newer.
# Compatible means tasks-axi --version reports 0.1.1 or newer and
# `tasks-axi update --help` exposes --archive-body for recoverable note rewrites.
# `config/backlog-backend=manual` opts out of tasks-axi backlog mutations;
# absent or any other value keeps the default tasks-axi backend path, falling
# back to manual mutation when the tool is not compatible.
Expand All @@ -25,12 +26,22 @@ fm_tasks_axi_compatible() {
minor=${rest%% *}
patch=${rest##* }

[ "$major" -gt 0 ] && return 0
[ "$major" -eq 0 ] && [ "$minor" -gt 1 ] && return 0
[ "$major" -eq 0 ] && [ "$minor" -eq 1 ] && [ "$patch" -ge 1 ] && return 0
if [ "$major" -gt 0 ] ||
{ [ "$major" -eq 0 ] && [ "$minor" -gt 1 ]; } ||
{ [ "$major" -eq 0 ] && [ "$minor" -eq 1 ] && [ "$patch" -ge 1 ]; }; then
fm_tasks_axi_update_has_archive_body
return $?
fi
return 1
}

fm_tasks_axi_update_has_archive_body() {
local output
command -v tasks-axi >/dev/null 2>&1 || return 1
output=$(tasks-axi update --help 2>&1) || return 1
printf '%s\n' "$output" | grep -F -- '--archive-body' >/dev/null
}

fm_backlog_backend_value() {
local config_dir=$1 backend_file value
backend_file="$config_dir/backlog-backend"
Expand Down
2 changes: 2 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ The full ownership rule - what is project-intrinsic versus fleet-private, and ho

`/stow` sweeps the current session for durable knowledge that only exists in conversation and routes each finding to the most specific disk home.
Captain preferences go to `data/captain.md`, fleet-local operational facts and gotchas go to `data/learnings.md`, project-intrinsic knowledge goes through normal crewmate delivery into that project's committed `AGENTS.md`, and task-scoped notes or undone next steps go to the backlog.
Memory writes use inspect-then-update: read the current destination first, then rewrite or prune matching bullets or notes in place instead of appending by default.
Task-scoped notes use `tasks-axi show <id> --full` followed by `tasks-axi update <id> --body-file <path>`, adding `--archive-body` when the prior body should remain recoverable.
Generalizable firstmate knowledge goes to shared tracked docs through the normal PR pipeline; the firstmate-internal `/stow` deliberately never stores findings in either skill directory.

## Local clones stay fresh
Expand Down
2 changes: 1 addition & 1 deletion docs/cmux-backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Prerequisites:

- The cmux app itself, installed from [cmux.com](https://cmux.com) or `brew install --cask cmux`, version 0.64.17 or newer.
- `jq`, required to parse cmux's JSON output: `brew install jq` (or your platform's package manager).
- The same universal requirements as tmux (a verified crew harness, git with GitHub auth, node, treehouse, no-mistakes, gh-axi, chrome-devtools-axi, lavish-axi, tasks-axi 0.1.1 or newer, and quota-axi); treehouse still provides the worktree, cmux only provides the session.
- The same universal requirements as tmux (a verified crew harness, git with GitHub auth, node, treehouse, no-mistakes, gh-axi, chrome-devtools-axi, lavish-axi, tasks-axi 0.1.1 or newer with `update --archive-body`, and quota-axi); treehouse still provides the worktree, cmux only provides the session.
- The cmux CLI binary is not guaranteed to be on `PATH` after a plain app install (see "CLI is not on PATH by default" below) - the adapter falls back to the well-known bundle path automatically, so this is not a blocker, just something to be aware of if you want to run `cmux` yourself from a shell.

**One-time socket access setup (required, not optional):** cmux's control socket defaults to `automation.socketControlMode: "cmuxOnly"`, which rejects any CLI process not spawned inside cmux itself - firstmate always drives cmux from an external shell, so this must be changed before `backend=cmux` can work at all.
Expand Down
Loading