Skip to content
This repository was archived by the owner on Aug 25, 2026. It is now read-only.

feat(stow): adopt operational learning capture - #36

Merged
JTInventory merged 2 commits into
mainfrom
fm/adopt-upstream-stow-197-0702
Jul 3, 2026
Merged

JTInventory merged 2 commits into
mainfrom
fm/adopt-upstream-stow-197-0702

Conversation

@JTInventory

Copy link
Copy Markdown
Owner

Intent

Adopt only upstream owner PR kunchenguid#197's /stow operational-memory feature into the captain fork Firstmate repo starting from current JTInventory/firstmate:main. Replay the stow skill, data/learnings.md convention, bootstrap/read instructions, knowledge-routing table, and README/docs rows where they fit this fork. Preserve fork-specific delivery rules, especially PRs targeting JTInventory/firstmate, the no-mistakes PR target guard, and existing durable secondmate profile design. Do not broad-sync unrelated upstream commits, do not create data/learnings.md as a tracked file, do not add co-author lines, and do not merge.

What Changed

  • Added a /stow skill that lets firstmate capture durable, evidence-backed operational learnings into local memory notes.
  • Documented the new data/learnings.md convention in firstmate startup flow, project knowledge routing, and configuration docs.
  • Updated the public docs to describe local operational learnings as gitignored fleet state, without adding a tracked learnings file.

Risk Assessment

✅ Low: Captain, the change is limited to documentation and a new prompt skill, preserves the fork-specific no-mistakes PR target rules, and introduces no executable runtime path.

Testing

The provided baseline was already green; I also reran the full configured test command in this exact worktree, ran targeted guard/bootstrap/secondmate checks, captured a reviewer-visible CLI transcript for the /stow operator surface and routing rules, and confirmed the worktree was clean afterward. Overall result: pass.

Evidence: Stow operator-surface evidence
Stow operator-surface verification
worktree: /root/.no-mistakes/worktrees/76db9585a6d5/01KWJDXPG7VBZ901RSNN5503QT
head: 6e78a1b
branch-name: fm/adopt-upstream-stow-197-0702

$ sed -n "1,80p" .agents/skills/stow/SKILL.md
---
name: stow
description: Sweep the current session for uncaptured durable knowledge and file it to disk before a context reset. Use when the captain invokes /stow (e.g. "/stow", "stow what you've learned"), before a session reset or context compaction, or periodically to keep operational memory current.
user-invocable: true
---

# stow

Sweep this session for durable knowledge that only exists in conversation right now, and write it to the disk locations firstmate already reads on the next bootstrap.
The goal is a session that is safe to reset or destroy because everything durable has already been captured.

## What it does

1. **Sweep the session for uncaptured durable knowledge.**
   Read back over this conversation and look for:
   - Operational learnings: fleet-local facts and gotchas discovered while operating firstmate (a script's sharp edge, a harness quirk, a recurring false alarm and its real cause).
   - Captain preferences expressed in passing: a working-style or approval preference the captain stated conversationally rather than through `data/captain.md` directly.
   - Project-intrinsic facts discovered: build, test, release, or architecture facts about a project that belong in that project's own `AGENTS.md`.
   - Decisions made: a standing choice the captain made this session that should outlive it.
   - Undone next steps: anything left open that has not yet been filed as backlog work.

2. **Route each finding using AGENTS.md's knowledge-routing table.**
   AGENTS.md (section 6, "Knowledge routing") is the single source of truth for where each kind of knowledge belongs.
   Read that table and route each finding there instead of re-deriving the mapping here.

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.
   - 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).
   - 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.
   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.

5. **Report to the captain.**
   Summarize, in plain outcome language (section 9): what was stowed and where, what was filed to the backlog, and whether the session is now safe to reset or destroy - i.e. whether every durable finding from this sweep now lives on disk rather than only in this conversation.
   If something could not be captured yet (for example, project-intrinsic knowledge waiting on a crewmate to land it), say so explicitly rather than reporting the session fully safe.

## Scope exclusion: no skill storage

`/stow` must **never** store, create, or edit a skill as a destination for any finding.
There is no "graduate this to a skill" move in this skill's routing.
This is a deliberate, standing exclusion, not an oversight: repo skills cannot yet distinguish knowledge that is fleet-local to this captain's home from knowledge generalizable to every firstmate user, so writing learnings into skills would silently leak fleet-local material into shared, tracked material (or vice versa).
That namespace problem is unresolved and deliberately deferred.
Until it is resolved, route generalizable knowledge to the shared `AGENTS.md` (or other shared, tracked material) via the pipeline, and fleet-local knowledge to `data/`, never to a skill.

$ awk "/### Knowledge routing/{flag=1} flag{print} /## 7\. Task lifecycle/{if(flag){exit}}" AGENTS.md
### Knowledge routing

Route each piece of durable knowledge to its most specific home:

| Kind of knowledge | Home |
| --- | --- |
| Captain preferences and working style | `data/captain.md` |
| 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` |
| 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) |
| Investigation findings | scout reports at `data/<id>/report.md` |

When the captain invokes `/stow`, load the `stow` skill.
It sweeps the current session for uncaptured durable knowledge, routes findings with this table, files undone next steps to the backlog, and reports whether the session is safe to reset.

**Delivery mode (choose at add).** `<mode>` is how a finished change reaches `main`, picked per project when you add it and recorded in the registry line (`fm-project-mode.sh` parses it; `fm-spawn` records it into each task's meta):

- `no-mistakes` (default; `[...]` may be omitted) - full pipeline -> PR -> captain merge. Highest assurance.
- `direct-PR` - push + open a PR via `gh-axi`, no pipeline -> captain merge.
- `local-only` - local branch, no remote, no PR; firstmate reviews the diff, the captain approves, firstmate merges to local `main` (section 7).

Orthogonal to mode is an optional `+yolo` flag (`[direct-PR +yolo]`), default off and **not recommended**: with `yolo` on, firstmate makes the approval decisions itself instead of asking the captain (section 7). When the captain adds a project without saying, default to `no-mistakes` with yolo off; only set a faster mode or `+yolo` on the captain's explicit say-so.

**Clone existing:** `git clone <url> projects/<name>`, add its registry line with the chosen mode, then initialize only if the mode is `no-mistakes`.

**Create new:** for `no-mistakes` and `direct-PR` modes a new project needs a GitHub repo first (they push to an `origin` remote); a `local-only` project needs no remote at all - a purely local git repo is fine.
Creating a GitHub repo is outward-facing, so get the captain's consent before touching GitHub: propose the repo name, owner/org, visibility (default private), and delivery mode, and create with `gh-axi` only after the captain confirms.
Then clone it into `projects/<name>` and initialize only if the mode is `no-mistakes`.
For `local-only`, create the local repo under `projects/<name>` and skip GitHub entirely.

**Initialize (`no-mistakes` mode only):**

`` `sh
cd projects/<name> && no-mistakes init && no-mistakes doctor
`` `

`no-mistakes init` sets up the local gate: a bare repo plus post-receive hook, the `no-mistakes` git remote, and a database record for the repo (it needs an `origin` remote).
It does **not** vendor any skill into the project - the no-mistakes skill is user-level now, available to every crewmate without a per-project copy.
So init produces nothing to commit; it is a sanctioned exception to the never-write rule (section 1) only in that it runs git remote/config setup inside the project.
Touch nothing else.
`direct-PR` and `local-only` projects skip init entirely - they do not run the pipeline (`local-only` has no remote at all).

If `no-mistakes doctor` reports problems, fix the environment (auth, daemon) before dispatching work to that project.

## 7. Task lifecycle

$ rg -n "/stow|data/learnings.md|no-mistakes PR target|secondmate-profile" README.md docs/architecture.md docs/configuration.md AGENTS.md
AGENTS.md:54:For this captain-owned Firstmate checkout, the no-mistakes PR target is `JTInventory/firstmate`.
AGENTS.md:79:config/secondmate-profile.json  model/effort axes the PRIMARY uses when launching SECONDMATE agents; LOCAL, gitignored; example `{"model":"gpt-5.5","effort":"high"}`. Missing file, omitted keys, or `"default"` values preserve default model/effort behavior. Explicit `--model` or `--effort` on `fm-spawn.sh --secondmate` wins. NOT inherited into secondmate homes; use inherited `config/crew-dispatch.json` for a secondmate home's own future crewmate/scout defaults
AGENTS.md:127:Because `config/` is gitignored this is a separate, primary-authoritative copy independent of the tracked-files fast-forward: it re-converges every live home whether or not its tracked files advanced, and it touches only the declared inheritable items (never `config/secondmate-harness` or `config/secondmate-profile.json`).
AGENTS.md:146:- `SECONDMATE_PROFILE: invalid config/secondmate-profile.json - <reason>` - the optional primary-local secondmate launch profile failed validation; fix or remove it before launching or respawning secondmates because `fm-spawn.sh --secondmate` refuses invalid profiles.
AGENTS.md:168:Then read `data/learnings.md` if present, to load fleet-local operational facts and gotchas this home has captured.
AGENTS.md:251:`config/secondmate-profile.json` is the primary-local model/effort companion for that launch harness, for example `{"model":"gpt-5.5","effort":"high"}`.
AGENTS.md:256:The split is durable: every secondmate respawn (recovery, `/updatefirstmate`, restart) re-resolves from `config/secondmate-harness` and re-reads `config/secondmate-profile.json`, so it survives restarts without relying on operator memory.
AGENTS.md:258:`config/crew-dispatch.json`, `config/crew-harness`, and `config/backlog-backend` are inherited; `config/secondmate-harness` and `config/secondmate-profile.json` are not.
AGENTS.md:265:The mechanism is generic over a single declared list (`fm-config-inherit-lib.sh`), primary-authoritative (re-pushed every convergence, mirroring absence), and easy to extend; `config/secondmate-harness` is deliberately excluded because secondmates never spawn secondmates, and `config/secondmate-profile.json` is excluded because it controls only primary-to-secondmate launches.
AGENTS.md:301:All truth lives in tmux, state files, data/backlog.md, data/captain.md, data/learnings.md, data/secondmates.md, persistent secondmate homes, and treehouse; your conversation memory is a cache.
AGENTS.md:374:| Fleet-local operational facts and gotchas | `data/learnings.md` |
AGENTS.md:379:When the captain invokes `/stow`, load the `stow` skill.
README.md:119:Secondmate launch can use a separate local `config/secondmate-harness`, plus a primary-local `config/secondmate-profile.json` for durable model and effort defaults.
README.md:143:| `/stow`            | Sweep the session for uncaptured durable knowledge, route each finding to its disk home per AGENTS.md, file undone next steps to the backlog, and report what is now safe to reset |
docs/configuration.md:30:## Operational learnings (data/learnings.md)
docs/configuration.md:32:Fleet-local operational facts and gotchas live locally in `data/learnings.md`; it is gitignored and read right after `data/captain.md` during bootstrap.
docs/configuration.md:65:`config/secondmate-profile.json` is the separate local, gitignored model/effort profile for those primary-to-secondmate launches, for example `{"model":"gpt-5.5","effort":"high"}`.
docs/configuration.md:73:`config/secondmate-profile.json` is not inherited either; use inherited `config/crew-dispatch.json` for a secondmate home's own future crewmate and scout defaults.
docs/configuration.md:82:Secondmate spawns are exempt and still resolve through `config/secondmate-harness`, then apply any primary-local `config/secondmate-profile.json` model or effort defaults.
docs/configuration.md:95:When `config/crew-dispatch.json` or `config/secondmate-profile.json` exists, bootstrap also requires `jq` for JSON validation.
docs/configuration.md:96:Malformed `config/secondmate-profile.json`, a non-object top level, non-string axes, an empty model, or an effort outside `default|low|medium|high|xhigh|max` is reported as `SECONDMATE_PROFILE: invalid config/secondmate-profile.json - ...`.
docs/architecture.md:93:That propagation is primary-authoritative, re-runs even when tracked files were already current, mirrors absence when the primary clears the value, and deliberately never copies `config/secondmate-harness` or `config/secondmate-profile.json`.
docs/architecture.md:102:`config/secondmate-profile.json` controls only the primary's secondmate launch model and effort axes, so a primary can durably pair `config/secondmate-harness=codex` with `{"model":"gpt-5.5","effort":"high"}` without relying on operator memory.
docs/architecture.md:107:`config/secondmate-harness` and `config/secondmate-profile.json` are primary-local and are not inherited into secondmate homes.
docs/architecture.md:153:`/stow` sweeps the current session for durable knowledge that only exists in conversation and routes each finding to the most specific disk home.
docs/architecture.md:154: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.
docs/architecture.md:155:Generalizable firstmate knowledge goes to shared tracked docs through the normal PR pipeline; `/stow` deliberately never stores findings in skills.
docs/architecture.md:174:Fleet state lives in tmux, no-mistakes run records, status event logs, local markdown under `data/` including `data/captain.md` and `data/learnings.md`, and persistent secondmate homes.
docs/architecture.md:175:Use `/stow` before an intentional reset when the conversation may hold durable knowledge that has not yet been written to disk; after that, the next firstmate session can reconcile and carry on.

$ git check-ignore -v data/learnings.md
.gitignore:3:data/	data/learnings.md

$ git ls-files --error-unmatch data/learnings.md
error: pathspec 'data/learnings.md' did not match any file(s) known to git
Did you forget to 'git add'?

$ bash bin/fm-no-mistakes-pr-target-guard.sh
ok: PR target repo jtinventory/firstmate verified

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • bash bin/fm-no-mistakes-pr-target-guard.sh || exit 1; command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
  • Provided baseline already ran successfully: bash bin/fm-no-mistakes-pr-target-guard.sh || exit 1; command -v tmux &gt;/dev/null || { echo &#34;tmux is required for e2e tests&#34; &gt;&amp;2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo &#34;== $t ==&#34;; bash &#34;$t&#34; || rc=1; done; exit &#34;$rc&#34;
  • bash bin/fm-no-mistakes-pr-target-guard.sh
  • command -v tmux >/dev/null; tmux -V
  • bash tests/fm-no-mistakes-pr-target-guard.test.sh
  • bash tests/fm-secondmate-harness.test.sh
  • bash tests/fm-bootstrap.test.sh
  • Reran full configured command: bash bin/fm-no-mistakes-pr-target-guard.sh || exit 1; command -v tmux &gt;/dev/null || { echo &#34;tmux is required for e2e tests&#34; &gt;&amp;2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo &#34;== $t ==&#34;; bash &#34;$t&#34; || rc=1; done; exit &#34;$rc&#34;
  • Generated reviewer evidence with sed, awk, rg, git check-ignore, git ls-files --error-unmatch data/learnings.md, and bash bin/fm-no-mistakes-pr-target-guard.sh into /tmp/no-mistakes-evidence/01KWJDXPG7VBZ901RSNN5503QT/stow-operator-surface.txt
  • git status --short
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@JTInventory
JTInventory merged commit 04810bd into main Jul 3, 2026
4 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant