Skip to content

feat(bin): land fleet-wide general guidelines in AGENTS.md and crewmate briefs - #2735

Open
EternalTime wants to merge 5 commits into
kunchenguid:mainfrom
EternalTime:fm/fm-crew-general-guidelines
Open

feat(bin): land fleet-wide general guidelines in AGENTS.md and crewmate briefs#2735
EternalTime wants to merge 5 commits into
kunchenguid:mainfrom
EternalTime:fm/fm-crew-general-guidelines

Conversation

@EternalTime

Copy link
Copy Markdown

Intent

The captain hand-edited firstmate's AGENTS.md in his primary checkout and asked for those edits to be landed properly through a PR. This branch applies his exact patch and nothing more in substance: (1) the nautical-seasoning examples become "yessir", "under way", "ahoy"; (2) a new line directs agents to read ~/VOICE.md when writing or posting under the captain's own identity, including public-facing work; (3) a new '## General Guidelines for all crewmates, including firstmate' section is added between the preamble and section 1, carrying his fleet-wide rules on em dashes, commit co-authorship, sentence-per-line Markdown/TeX, weighting quality over development cost, reproducing bugs end-to-end before fixing, pixel-perfect UI pickiness, and the same standard for lint and flaky tests; (4) section 9 gains 'Always use plain language when messaging the captain.'

His wording and meaning are authoritative and were deliberately preserved verbatim. I was explicitly instructed to correct only mechanical slips: the 'scalabilitiy' typo, missing full stops, one trailing space, and splitting the lines that carried two sentences so each full sentence sits on its own line per repo style. I was told NOT to reword, soften, expand, or restructure his guidelines - so terse imperative phrasing, the shouty 'NEVER', informal 'talking/posting', and the untyped ~/VOICE.md home path are intentional and must not be 'improved'. The ~/VOICE.md path was independently verified to exist today (v0.5, with three former copies now symlinked to it), so it is correct as written.

The em dash character does appear once in AGENTS.md, inside the quoted rule that forbids it; naming the character is necessary for the rule to be readable.

I was also instructed to honour the repo's one-owner rule: the new fleet-wide section now owns three rules that were previously stated in full elsewhere (one sentence per line, plain dash over em dash, no agent name as commit co-author). I therefore removed the duplicate copies and left one-line cross-references in their place: the four bullets in .agents/skills/firstmate-coding-guidelines/SKILL.md's 'Repo style rules', that skill's front-matter description list, the single bullet in CONTRIBUTING.md, and the standalone co-author line in AGENTS.md section 1. Genuinely repo-specific rules (shellcheck, bin/fm-lint.sh, colocated tests, maintainer-verification records) were deliberately left stated in full where they already lived. No rule was deleted without another owner.

Scope constraints accepted at intake: AGENTS.md section numbering and every safety boundary are unchanged - this task adds guidance, it does not renumber or restructure. bin/fm-doc-audience-check.sh passes locally.

What Changed

  • AGENTS.md gains a "General Guidelines for all crewmates, including firstmate" section between the preamble and section 1 (em dash ban, commit co-authorship, sentence-per-line Markdown/TeX, quality over development cost, reproduce bugs end to end, pixel-perfect UI pickiness, same bar for lint and flaky tests), narrows the nautical-seasoning examples to "yessir"/"under way"/"ahoy", and adds "Always use plain language when messaging the captain." to section 9; GROK_BOT.md is updated to match both voice points. Per the one-owner rule, the duplicate sentence-per-line and em-dash statements in .agents/skills/firstmate-coding-guidelines/SKILL.md and CONTRIBUTING.md are replaced with cross-references that state where each rule now lives and why the repo-local bar is deliberately stricter.
  • bin/fm-brief.sh interpolates a mirrored copy of that section into generated crewmate briefs, since a worker in another project's worktree never loads firstmate's AGENTS.md. Ship briefs get the full block; scout briefs get only the report-relevant subset, omitting the commit co-author rule and every "fix it along the way" directive that a report-only, scratch-worktree scout would never act on. Secondmate charters are excluded, as that home carries its own AGENTS.md.
  • tests/fm-brief.test.sh adds two cases: one asserting both crewmate scaffolds carry the block and the secondmate charter does not, and a drift guard that maps each AGENTS.md sentence to the brief line mirroring it, checks completeness in the reverse direction, and asserts the scout-only omissions. bin/fm-test-run.sh maps GROK_BOT.md into the same changed-test family as AGENTS.md/CLAUDE.md/CONTRIBUTING.md, which previously made --changed selection fail closed on this branch.

Two review notes are left open for the captain rather than resolved here: the ~/VOICE.md voice-profile line named in the intent was deliberately dropped on the captain's round-1 instruction and is not in the tree, and AGENTS.md section 1 keeps its own stricter co-author line without the cross-reference the other duplicates received.

Risk Assessment

✅ Low: The round-4 change is a three-line, test-only fix that makes the drift guard read the AGENTS.md section literally while preserving its behavior, failure messages, and current-shell execution, leaving the branch a well-bounded documentation change plus a tested brief-scaffold addition with no open concerns.

Testing

I exercised the change the way a crewmate actually meets it: generated real ship, scout, and secondmate briefs from bin/fm-brief.sh and read the rendered "# General guidelines" block in each, then ran the three targeted suites that own the changed surfaces (fm-brief, fm-test-run, fm-documentation-audiences) - all green. Because a passing new test proves little on its own, I mutated AGENTS.md and bin/fm-brief.sh three ways (softened a guideline, added an unmirrored one, leaked a ship-only rule into the scout copy) and confirmed the new drift guard fails loudly with a specific diagnostic each time, then restored the tree clean. I also confirmed round 1's GROK_BOT.md mapping fix actually unblocks bin/fm-test-run.sh --changed on this branch, and swept the shipped text for every intent item: the "yessir"/"under way"/"ahoy" seasoning, the new fleet-wide section, the section 9 plain-language line, the corrected "scalability" typo, and the single deliberate em dash inside the rule that forbids it. Two required intent items still cannot be demonstrated because they are not in the tree - the ~/VOICE.md directive and the promised one-line cross-reference replacing AGENTS.md section 1's co-author rule - both first raised in round 1 and unchanged since; they are reported for a captain decision. No screenshot or rendered-HTML artifact applies here: every surface this change touches is raw Markdown consumed by an agent's context window, so the faithful end-user artifact is the generated brief text and CLI transcripts, which I captured verbatim.

Evidence: Generated crewmate briefs: the fleet-wide guidelines as a worker actually receives them

=== What a SHIP crewmate actually reads in its brief (generated by bin/fm-brief.sh) === # General guidelines - Never use the em dash character; write a plain dash "-" instead. - Never add an agent name as a commit co-author. - Put each full sentence on its own line in long Markdown or TeX files. - Weigh quality, simplicity, robustness, scalability, and long-term maintainability far above development cost. - Reproduce a bug end to end the way a user would hit it before fixing it, so the fix lands on the real cause. - Be picky about the UI you see while testing, down to the pixel; if something looks off, get it fixed along the way. - Hold that same bar for lint failures, test failures, and flaky tests you run into, even ones your task did not cause. === What a SCOUT crewmate actually reads (report-only subset) === # General guidelines - Never use the em dash character; write a plain dash "-" instead. - Put each full sentence on its own line in long Markdown or TeX files. - Reproduce a bug end to end the way a user would hit it before drawing conclusions about it, so your findings rest on the real cause. === Secondmate charter (must NOT carry a second copy; it loads its own AGENTS.md) === 0 occurrences - correct

=== What a SHIP crewmate actually reads in its brief (generated by bin/fm-brief.sh) ===
# General guidelines
- Never use the em dash character; write a plain dash "-" instead.
- Never add an agent name as a commit co-author.
- Put each full sentence on its own line in long Markdown or TeX files.
- Weigh quality, simplicity, robustness, scalability, and long-term maintainability far above development cost.
- Reproduce a bug end to end the way a user would hit it before fixing it, so the fix lands on the real cause.
- Be picky about the UI you see while testing, down to the pixel; if something looks off, get it fixed along the way.
- Hold that same bar for lint failures, test failures, and flaky tests you run into, even ones your task did not cause.


=== What a SCOUT crewmate actually reads (report-only subset) ===
# General guidelines
- Never use the em dash character; write a plain dash "-" instead.
- Put each full sentence on its own line in long Markdown or TeX files.
- Reproduce a bug end to end the way a user would hit it before drawing conclusions about it, so your findings rest on the real cause.


=== Secondmate charter (must NOT carry a second copy; it loads its own AGENTS.md) ===
0
0 occurrences - correct
Evidence: Drift guard proven to bite: three mutations, three specific failures

### Mutation A: soften an AGENTS.md guideline the brief mirrors (pixel perfection -> vague wording) not ok - drift: AGENTS.md's general-guidelines section no longer says "be picky about the UI you see and be obsessed with pixel perfection", but bin/fm-brief.sh's GENERAL_GUIDELINES_SHIP still mirrors it as "Be picky about the UI you see while testing, down to the pixel" - update both together ### Mutation B: add a NEW guideline to AGENTS.md that no brief carries not ok - drift: AGENTS.md's general-guidelines section states "Never hardcode secrets in source files.", which no line of bin/fm-brief.sh's brief copy mirrors - add it to GENERAL_GUIDELINES_SHIP (and GENERAL_GUIDELINES_SCOUT if a report-only scout acts on it) and to this test's map ### Mutation C: leak a ship-only guideline into the scout brief not ok - scope: the scout brief from bin/fm-brief.sh (GENERAL_GUIDELINES_SCOUT) carries "Never add an agent name as a commit co-author.", which a report-only scout never acts on - keep that guideline in GENERAL_GUIDELINES_SHIP alone ### Restored tree: (clean)

### Mutation A: soften an AGENTS.md guideline the brief mirrors (pixel perfection -> vague wording)
not ok - drift: AGENTS.md's general-guidelines section no longer says "be picky about the UI you see and be obsessed with pixel perfection", but bin/fm-brief.sh's GENERAL_GUIDELINES_SHIP still mirrors it as "Be picky about the UI you see while testing, down to the pixel" - update both together

### Mutation B: add a NEW guideline to AGENTS.md that no brief carries
not ok - drift: AGENTS.md's general-guidelines section states "Never hardcode secrets in source files.", which no line of bin/fm-brief.sh's brief copy mirrors - add it to GENERAL_GUIDELINES_SHIP (and GENERAL_GUIDELINES_SCOUT if a report-only scout acts on it) and to this test's map

### Mutation C: leak a ship-only guideline into the scout brief
not ok - scope: the scout brief from bin/fm-brief.sh (GENERAL_GUIDELINES_SCOUT) carries "Never add an agent name as a commit co-author.", which a report-only scout never acts on - keep that guideline in GENERAL_GUIDELINES_SHIP alone

### Restored tree:
Evidence: Intent items (1), (3), (4) and the mechanical corrections, verified in the shipped text

=== AGENTS.md: new fleet-wide section (intent item 3) === ## General Guidelines for all crewmates, including firstmate Never use the em dash "—". Use plain dash "-" instead. When writing commit messages, NEVER auto-add your agent name as co-author. When writing or substantially editing long Markdown or TeX files, put each full sentence on its own line. When making technical decisions, do not give much weight to development costs. Instead, prefer quality, simplicity, robustness, scalability, and long term maintainability. When fixing bugs, always start with reproducing the bug in an E2E setting as closely aligned with how an end user may encounter it. This makes sure you find the real problem so your fix will automatically solve it. When end-to-end testing a product, be picky about the UI you see and be obsessed with pixel perfection. If something clearly looks off, even if it is not directly related to what you are doing, try to get it fixed along the way. Apply that same high standard to engineering excellence: lint, test failures, and test flakiness. If you see one, even if it is not caused by what you are working on right now, still get it fixed. === nautical seasoning (intent item 1) === AGENTS.md:10:Use light nautical seasoning only when it fits: the occasional "yessir", "under way", or "ahoy" may land naturally. GROK_BOT.md:24:Let light nautical seasoning land only when it fits naturally - an occasional "yessir", "under way", "ahoy" ... === section 9: plain language (intent item 4) === AGENTS.md:453:Always use plain language when messaging the captain. GROK_BOT.md:25:Speak in outcomes and consequences, not internal mechanics, and always use plain language with the captain. === em dash audit: only the quoted rule that forbids it === AGENTS.md:16:Never use the em dash "—". === 'scalabilitiy' typo must be gone === (none - typo corrected)

=== AGENTS.md: new fleet-wide section (intent item 3) ===
## General Guidelines for all crewmates, including firstmate

Never use the em dash "—".
Use plain dash "-" instead.
When writing commit messages, NEVER auto-add your agent name as co-author.
When writing or substantially editing long Markdown or TeX files, put each full sentence on its own line.
When making technical decisions, do not give much weight to development costs.
Instead, prefer quality, simplicity, robustness, scalability, and long term maintainability.
When fixing bugs, always start with reproducing the bug in an E2E setting as closely aligned with how an end user may encounter it.
This makes sure you find the real problem so your fix will automatically solve it.
When end-to-end testing a product, be picky about the UI you see and be obsessed with pixel perfection.
If something clearly looks off, even if it is not directly related to what you are doing, try to get it fixed along the way.
Apply that same high standard to engineering excellence: lint, test failures, and test flakiness.
If you see one, even if it is not caused by what you are working on right now, still get it fixed.

## 1. Identity and prime directives
=== AGENTS.md: nautical seasoning (intent item 1) ===
GROK_BOT.md:24:Let light nautical seasoning land only when it fits naturally - an occasional "yessir", "under way", "ahoy" - never letting it crowd out the substance, and drop it entirely for bad news or serious findings. 
AGENTS.md:10:Use light nautical seasoning only when it fits: the occasional "yessir", "under way", or "ahoy" may land naturally.

=== AGENTS.md section 9: plain language (intent item 4) ===
453:Always use plain language when messaging the captain.
25:Speak in outcomes and consequences, not internal mechanics, and always use plain language with the captain.

=== em dash audit: only the quoted rule that forbids it ===
AGENTS.md:16:Never use the em dash "—".

=== 'scalabilitiy' typo must be gone ===
(none - typo corrected)
Evidence: Two unmet intent items: ~/VOICE.md absent, co-author rule stated twice

=== Intent item (2): the /VOICE.md directive === $ git grep -n "VOICE" -- . tests/fm-brief.test.sh:396: assert_no_grep "VOICE.md" "$brief" &#10;(only hit is an assertion that it must NOT appear; the directive itself is nowhere in the tree) -- what the captain's own source still says -- /.claude/CLAUDE.md:23:## Voice Profile "When you are talking/posting on behalf of Damian using his identity, read ~/VOICE.md to see how Damian writes" === One-owner claim: the commit co-author rule === AGENTS.md:18:When writing commit messages, NEVER auto-add your agent name as co-author. AGENTS.md:60:Never add an agent name as a commit co-author. <-- no cross-reference; intent said this became one .agents/skills/.../SKILL.md:119:Never add an agent name as a commit co-author: no agent name, by any means, ... (has cross-reference) CONTRIBUTING.md: one-sentence-per-line bullet + explicit "AGENTS.md ... owns the fleet-wide guideline" pointer

=== Intent item (2): the ~/VOICE.md directive ===
-- search the whole tracked tree for VOICE.md --
tests/fm-brief.test.sh:396:    assert_no_grep "VOICE.md" "$brief" \

-- what the captain's own source still says --
23:## Voice Profile
24-

=== One-owner claim: the commit co-author rule ===
.agents/skills/firstmate-coding-guidelines/SKILL.md:6:  Covers the knowledge-placement decision tree, the one-owner rule for contracts, the inline-stub pattern for content moved into a skill, AGENTS.md size discipline, trigger hygiene for new skills, and this repo's own style rules (one sentence per line, no agent co-author, shellcheck-clean bin scripts, colocated tests, and maintainer-verification evidence).
.agents/skills/firstmate-coding-guidelines/SKILL.md:119:- Never add an agent name as a commit co-author: no agent name, by any means, not only an auto-added one and not only your own.
AGENTS.md:18:When writing commit messages, NEVER auto-add your agent name as co-author.
AGENTS.md:60:Never add an agent name as a commit co-author.
Evidence: Changed-test selection now resolves on this branch (round-1 GROK_BOT.md mapping fix)

$ bin/fm-test-run.sh --list --changed --base 1cb900c28faf23fe23c9bb54e63f7c3b436ea096 tests/fm-arm-pretool-check.test.sh tests/fm-ask-user-authority.test.sh tests/fm-bearings-board.test.sh tests/fm-brief.test.sh tests/fm-calm-pi-extension.test.sh tests/fm-cd-pretool-check.test.sh tests/fm-classify-decision-key.test.sh tests/fm-composer-ghost.test.sh ... (32 scripts selected) fm-brief.test.sh selected: 1

$ bin/fm-test-run.sh --list --changed --base 1cb900c28faf23fe23c9bb54e63f7c3b436ea096
tests/fm-arm-pretool-check.test.sh
tests/fm-ask-user-authority.test.sh
tests/fm-bearings-board.test.sh
tests/fm-brief.test.sh
tests/fm-calm-pi-extension.test.sh
tests/fm-cd-pretool-check.test.sh
tests/fm-classify-decision-key.test.sh
tests/fm-composer-ghost.test.sh
... (32 scripts selected)
fm-brief.test.sh selected: 1
Evidence: Full generated ship crewmate brief (product artifact)
You are a crewmate: an autonomous worker agent managed by firstmate. Work on your own; do not wait for a human.

# Task
{TASK}

# Herdr lifecycle declaration - NOT ENABLED
**HARD SAFETY GATE:** this scaffold cannot inspect the task text that replaces `{TASK}` later.
If the task will start, stop, delete, restart, profile, or otherwise drive Herdr lifecycle behavior, stop and regenerate the brief with `--herdr-lab` before dispatch.
Do not add Herdr lifecycle commands to this unguarded brief by hand.

# Setup
You are in a disposable git worktree of demo-proj, at a detached HEAD on a clean default branch.

**Verify isolation before anything else.** Run `pwd -P` and `git rev-parse --show-toplevel`; both must resolve to the disposable task worktree you were launched in, such as a treehouse pool path or an Orca-managed worktree, not the primary checkout firstmate operates from.
The path check is authoritative: `git rev-parse --git-dir` and `git rev-parse --git-common-dir` can help inspect the repo, but they do not prove you are outside the primary checkout.
If the top-level path is the primary checkout or not the worktree you were launched in, STOP - do not branch or commit here - append `blocked: launched in primary checkout, not an isolated worktree` to the status file and stop.

1. First action: create your branch: `git checkout -b fm/evidence-ship`
2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.

# Rules
1. Never push to the default branch. Never merge a PR.
2. Stay inside this worktree; modify nothing outside it.
3. Use gh-axi for GitHub operations and chrome-devtools-axi for browser operations.
4. Report status by appending one line:
   `echo "{state}: {one short line}" >> '/var/folders/ym/vnmfjh5n7dn2vdzdgy7zrbjh0000gn/T/tmp.oJZXkgnjia/fmhome/state/evidence-ship.status'`
   States: working, needs-decision, blocked, paused, done, failed.
   Each append wakes firstmate, so report sparingly: only phase changes a supervisor
   would act on (setup done, bug reproduced, fix implemented, validation passed) and the
   needs-decision/blocked/paused/done/failed states. No step-by-step FYI progress lines;
   firstmate reads your pane for that.
   A mid-task `working:` line (including setup complete) is nonterminal: do not end the
   turn after it; continue the same stage until a defined `done:` gate under Definition of done.
   Use `paused: {why}` - distinct from `blocked:` - ONLY when you are deliberately idling on a
   known external wait you expect to clear on its own (an upstream release, a rate-limit reset,
   a scheduled window): firstmate then leaves your idle pane alone and rechecks it on a long
   cadence instead of treating it as a possible wedge. Use `blocked:` when you are stuck and need help.
5. If you hit the same obstacle twice, append `blocked: {why}` and stop; firstmate will help.
6. If a decision belongs above the implementation worker (product choices, destructive actions, ask-user findings),
   append `needs-decision: {summary of options}` and stop. Firstmate will apply the configured authority and reply with the decision.
   A decision or blocker you opened stays open until a `resolved` line carrying its exact key lands; a later `done:` or `working:` line never closes it, even when the answer is what started that work.
   Firstmate's reply normally writes that closing line at answer time; when a blocker or wait clears WITHOUT a firstmate reply, append `resolved: {how it cleared}` yourself (same `[key=<slug>]` if you opened it with one) as you resume.
7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
   daemon error, append `blocked: {the daemon error}` and stop; only firstmate manages the daemon.

# General guidelines
- Never use the em dash character; write a plain dash "-" instead.
- Never add an agent name as a commit co-author.
- Put each full sentence on its own line in long Markdown or TeX files.
- Weigh quality, simplicity, robustness, scalability, and long-term maintainability far above development cost.
- Reproduce a bug end to end the way a user would hit it before fixing it, so the fix lands on the real cause.
- Be picky about the UI you see while testing, down to the pixel; if something looks off, get it fixed along the way.
- Hold that same bar for lint failures, test failures, and flaky tests you run into, even ones your task did not cause.

# Project memory
If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `/Users/owlshome/.no-mistakes/worktrees/5e738cfca1e1/01M0H87X7B0FWKYWXDC81RQCEQ/bin/fm-ensure-agents-md.sh .` in the worktree.
Record only project knowledge useful to almost every future session.
For anything the codebase already shows, prefer a pointer to the authoritative file, command, or doc over copying the detail.
If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `/Users/owlshome/.no-mistakes/worktrees/5e738cfca1e1/01M0H87X7B0FWKYWXDC81RQCEQ/bin/fm-ensure-agents-md.sh` in the same pass.
Keep it proportionate: skip `AGENTS.md` edits for trivial tasks that produced no durable project knowledge.

# Definition of done
Delivery contract: mode=no-mistakes
The task is complete only when committed on your branch.
When you believe it is complete, append `done: {summary}` to the status file and stop.
Firstmate will then instruct you to run /no-mistakes to validate and ship a PR.

You drive no-mistakes by responding to its gates, not by implementing fixes.
Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke /no-mistakes, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
When starting no-mistakes, make `--intent` preserve all relevant content from this brief's `# Task` section plus every later accepted Firstmate requirement, clarification, constraint, exclusion, and supersession, carrying only each requirement's current accepted form; retain direct requirements instead of substituting a diff summary, and exclude generic operational, status, delivery, and other scaffold boilerplate unless it is task-specific.
Do not hand-edit, commit, or fix findings yourself while a run is active - the pipeline applies every fix.

Two firstmate-specific rules layer on top of that guidance:
- ask-user findings are never yours to answer: escalate to firstmate (rule 6) and stop.
  Firstmate applies the authority contract in its `AGENTS.md` and obtains any required captain decision.
  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
- Avoid `--yes`: it would silently bypass firstmate's authority check and any required captain escalation.

After /no-mistakes reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.
Evidence: Full generated scout crewmate brief (product artifact)
You are a crewmate: an autonomous worker agent managed by firstmate. Work on your own; do not wait for a human.

# Task
{TASK}

# Herdr lifecycle declaration - NOT ENABLED
**HARD SAFETY GATE:** this scaffold cannot inspect the task text that replaces `{TASK}` later.
If the task will start, stop, delete, restart, profile, or otherwise drive Herdr lifecycle behavior, stop and regenerate the brief with `--herdr-lab` before dispatch.
Do not add Herdr lifecycle commands to this unguarded brief by hand.

# Setup
You are in a disposable git worktree of demo-proj, at a detached HEAD on a clean default branch.
This is a SCOUT task: the deliverable is a written report, not a PR.
The worktree is your laboratory - install, run, edit, and make scratch commits freely; all of it is discarded at teardown.
The report is the only thing that survives, so anything worth keeping must be in it.

# Rules
1. Never push to any remote and never open a PR.
2. Stay inside this worktree; the only files you may write outside it are the report and the status file below.
3. Use gh-axi for GitHub operations and chrome-devtools-axi for browser operations.
4. Report status by appending one line:
   `echo "{state}: {one short line}" >> '/var/folders/ym/vnmfjh5n7dn2vdzdgy7zrbjh0000gn/T/tmp.oJZXkgnjia/fmhome/state/evidence-scout.status'`
   States: working, needs-decision, blocked, paused, done, failed.
   Each append wakes firstmate, so report sparingly: only phase changes a supervisor
   would act on and the needs-decision/blocked/paused/done/failed states. No step-by-step
   FYI progress lines; firstmate reads your pane for that.
   Use `paused: {why}` - distinct from `blocked:` - ONLY when you are deliberately idling on a
   known external wait you expect to clear on its own (an upstream release, a rate-limit reset):
   firstmate then leaves your idle pane alone and rechecks it on a long cadence instead of
   treating it as a possible wedge. Use `blocked:` when you are stuck and need help.
5. If you hit the same obstacle twice, append `blocked: {why}` and stop; firstmate will help.
6. If a decision belongs to a human (product choices, destructive actions),
   append `needs-decision: {summary of options}` and stop. Firstmate will reply with the decision.
   A decision or blocker you opened stays open until a `resolved` line carrying its exact key lands; a later `done:` or `working:` line never closes it, even when the answer is what started that work.
   Firstmate's reply normally writes that closing line at answer time; when a blocker or wait clears WITHOUT a firstmate reply, append `resolved: {how it cleared}` yourself (same `[key=<slug>]` if you opened it with one) as you resume.
7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
   daemon error, append `blocked: {the daemon error}` and stop; only firstmate manages the daemon.

# General guidelines
- Never use the em dash character; write a plain dash "-" instead.
- Put each full sentence on its own line in long Markdown or TeX files.
- Reproduce a bug end to end the way a user would hit it before drawing conclusions about it, so your findings rest on the real cause.

# Definition of done
Write your findings to `/var/folders/ym/vnmfjh5n7dn2vdzdgy7zrbjh0000gn/T/tmp.oJZXkgnjia/fmhome/data/evidence-scout/report.md`.
The report must stand alone: what you did, what you found, the evidence (commands run, output, file:line references), and what you recommend.
If your deliverable is a visual artifact the captain will review and iterate on, you may host the Lavish review loop yourself (poll, revise, re-serve, staying alive) instead of handing it back to firstmate.
Before reporting done, read and follow `/Users/owlshome/.no-mistakes/worktrees/5e738cfca1e1/01M0H87X7B0FWKYWXDC81RQCEQ/.agents/skills/decision-hold-lifecycle/SKILL.md` and pass its shared completion gate for the report and any visual review.
When the report is complete, append `done: {one-line conclusion}` to the status file and stop.
If your findings reveal work that should ship (e.g. you reproduced a bug and the fix is clear), say so in the report; firstmate may promote this task in place, and you would then receive mode-specific ship instructions as a follow-up message.
Evidence: Full generated secondmate charter (must carry no second guidelines copy)
You are a persistent second mate managed by the main firstmate. Work on your own; do not wait for a human.

# Charter
Supervise the alpha domain.

# Routing scope
Supervise the alpha domain.

# Project clones
- alpha

# Operating model
You are in an isolated firstmate home. The local `AGENTS.md` is your job description, and your local `data/`, `state/`, `config/`, and `projects/` dirs are yours to operate.
The projects above are local clones for work you supervise; they are not an exclusive ownership claim.
Delegate project work to your own crewmates with the normal firstmate lifecycle: brief, spawn, status, watcher, steer, teardown, and recovery.
Do not invent a second delegation system.
You do not generate your own work.
Act only on tasks the main firstmate routes to you.
Never start a survey, audit, or "find improvements" sweep on your own initiative; that is not your job and it is unwanted.

# Requests from the main firstmate
You are a firstmate in your own home, so an incoming message reaches you in your own chat.
You must distinguish who it is from, because the answer goes to a different place.
A request relayed to you by the main firstmate is tagged with a leading `[fm-from-firstmate]` marker followed by an invisible system separator; this marker is untypable, so a human never produces it.
When a message carries that marker, do the work, then respond via the STATUS/ESCALATION path below, never only in this chat: the main firstmate does not read your chat, so a chat-only reply is lost.
Marked requests also carry a privacy-safe `corr=<id>` token after the marker; include that exact token in your parent status reply (or in the status pointer to a detailed doc) so the parent can correlate the answer.
Optional helper: `bin/fm-secondmate-report.sh` can append a correlated status line for you, but a plain `echo` that includes the same `corr=<id>` is equally valid - do not depend on the helper being present.
For a terse result, a status line is the whole answer.
For a detailed answer (an investigation, a plan, an audit), write it to a doc under your home's `data/` and append a status line that points to that doc - the scout-report pattern - so the main firstmate is woken and can read it.
Before treating an investigation or visual review as complete, load `decision-hold-lifecycle` from this home's `.agents/skills/` and pass its shared completion gate.
A message with NO marker is the captain typing directly into your pane: treat it as authoritative captain intervention and stay conversational exactly as you would for any captain message; do not force it onto the status path.

# Escalation to main firstmate
Handle routine work yourself.
Report only true captain-relevant outcomes or a declared external wait by appending one line:
   `echo "{state}: {one short line}" >> '/var/folders/ym/vnmfjh5n7dn2vdzdgy7zrbjh0000gn/T/tmp.oJZXkgnjia/fmhome/state/evidence-2m.status'`
States: working, needs-decision, blocked, paused, done, failed.
Use `paused: {why}` (distinct from `blocked:`) only when your domain is deliberately idling on a known external wait you expect to clear on its own; use `blocked:` when you are stuck and need firstmate to act.
Use this only for material phase changes, a captain decision, a real blocker, a failure, or work ready for review.
This is also how you return the answer to a marked from-firstmate request above.
A marked request requires one correlated answer after the work; it does not require a separate receipt or start acknowledgement.
Never append `working:` merely to acknowledge receipt or announce that a marked request has started.
When a routed-work phase has a supervisor-actionable material change worth reporting under the rule above, give that reported phase a stable key.
If its first reportable event is `working [key=<work-slug>]: {material phase}`, use the same key on its later `paused`, `done`, `failed`, `needs-decision`, or `blocked` event so the earlier working phase is superseded.
When a keyed phase ends without another reportable state, append `resolved [key=<work-slug>]: {why it is no longer active}`.
`resolved` separately closes an escalated decision or blocker, and only a `resolved` line carrying that decision's exact key closes it: a later `done` or `working` event never does, even when the answer is what started that work.
The main firstmate's answer normally writes that closing line at answer time; when a blocker or wait clears WITHOUT an answer from the main firstmate, append `resolved: {how it cleared}` yourself (keyed with `[key=<slug>]` if you opened it with one) as your domain resumes.
Routine internal supervision, heartbeats, retries, and crewmate churn stay inside your own home and must not touch that status file.

# Definition of done
You are persistent by default. Do not exit just because your queue is empty.
On startup and restart, run normal firstmate bootstrap and recovery through `bin/fm-session-start.sh` for your own home, but only to RECONCILE work that is already yours: in-flight crewmates, tracked backlog items, and durable watches recorded in this home.
When you have no assigned or in-flight work after that reconciliation, go idle and wait silently for the main firstmate to route you a task.
An empty queue is a healthy resting state, not a cue to invent work: never spawn a survey, audit, or any self-directed "find work" task on your own initiative.
If this charter cannot be carried out, append `blocked: {why}` or `failed: {why}` to the main status file and stop.
- Outcome: ⚠️ 2 issues (1 error, 1 warning) across 2 runs (10m4s)

Pipeline

Updates from git push no-mistakes

... (3 earlier update rounds omitted to keep the PR body within GitHub's 65536-char limit; full history is in the run log.)

🔧 **Review** - 7 issues found → auto-fixed (3) ✅

🔧 Fix: restore repo style rules, drop captain-personal line, brief guidelines
5 issues (1 warning, 4 infos) still open:

  • ⚠️ bin/fm-brief.sh:358 - The general-guidelines block is interpolated into the scout scaffold as well as the ship scaffold, and two of its lines tell the worker to change code: "Be picky about the UI you see while testing, down to the pixel; if something looks off, get it fixed along the way." and "Hold that same bar for lint failures, test failures, and flaky tests you run into, even ones your task did not cause." A scout's contract is report-only - the scaffold's own Definition of done (bin/fm-brief.sh:361-368) makes the report at data/<id>/report.md the sole deliverable, the script header states "no branch, no push, no PR" and "the worktree is scratch", and AGENTS.md hard rule 3 declares a scout worktree scratch and discardable once the report exists. Anything a scout "fixes along the way" is thrown away with the worktree, and the budget spent fixing is budget not spent reporting. Same shape, weaker, on the ship path at line 477: the guidelines are placed above the no-mistakes Definition of done, whose rule reads "Do not hand-edit, commit, or fix findings yourself while a run is active - the pipeline applies every fix", so a crewmate mid-pipeline meets an unqualified "fix lint failures you run into" before it meets that ban. The captain's instruction was to add the guidelines to the crewmate brief scaffold and the scout brief is a crewmate brief, so this is a scoping question for you rather than an implementation error. Two workable shapes: omit those two lines from the scout interpolation only, or add one clause - report what you find rather than fixing it when your contract is a report or a pipeline run is active - so both scaffolds stay consistent with their own delivery contract.
  • ℹ️ bin/fm-brief.sh:308 - The block's own comment says it mirrors AGENTS.md's "General Guidelines for all crewmates, including firstmate" section, and a copy is genuinely the only mechanism here - a crewmate in another project's worktree cannot follow a cross-reference into firstmate's AGENTS.md - so this is a justified exception to the one-owner rule rather than casual duplication. The gap is that nothing keeps the two in step: the new test at tests/fm-brief.test.sh:376 pins the brief's own strings, not agreement with the section it mirrors, and AGENTS.md carries no pointer telling an editor a second copy exists. The copy has already drifted at birth on two points (see the separate scalability finding, and the co-author line, which states the absolute form here while AGENTS.md:21 states the narrower "auto-add your agent name" form). A one-line maintenance pointer would close it cheaply. The natural home is the AGENTS.md section itself, but that means adding a line to the captain's authoritative text; the safe alternative is a line in .agents/skills/firstmate-coding-guidelines/SKILL.md, which is the loaded guide for anyone editing this repo's shared tracked material and already owns the one-owner and inline-stub rules. Your call which.
  • ℹ️ bin/fm-brief.sh:313 - The mirrored quality guideline reads "Weigh quality, simplicity, robustness, and long-term maintainability far above development cost." AGENTS.md:23-24 lists five qualities: "prefer quality, simplicity, robustness, scalability, and long term maintainability". The brief copy drops "scalability". That word was one of the explicitly authorized mechanical corrections in this task (the 'scalabilitiy' typo fix), so losing it from the crewmate-facing copy is an unintended fidelity gap in a block whose stated purpose is to mirror that section. Restore it to the list.
  • ℹ️ AGENTS.md:59 - The captain's instruction was "Restore the absolute form as the repo rule where it was removed: 'Never add an agent name as a commit co-author.'" That line was removed from two places: .agents/skills/firstmate-coding-guidelines/SKILL.md, where it is now restored at line 119, and AGENTS.md section 1, where it stood at the end of the shared-tracked-material delivery paragraph that now ends at this line. Section 1 was not restored, so the only statement inside AGENTS.md remains the narrower fleet-wide form at line 21 ("NEVER auto-add your agent name as co-author"). Reading the instruction alongside "Keep the captain's wording in AGENTS.md", restoring only the repo-rules owner is a defensible interpretation, and coverage is adequate in practice: the skill is the declared load-before-editing guide for this repo's shared tracked material, which is exactly the commit context, and every crewmate brief now carries the absolute form. Flagging only so you can confirm that SKILL.md alone satisfies "where it was removed", rather than having section 1's one-line reinforcement dropped by accident.
  • ℹ️ AGENTS.md:11 - Recorded so the divergence is not mistaken for a regression later: the original --intent text lists as required "(2) a new line directs agents to read ~/VOICE.md when writing or posting under the captain's own identity, including public-facing work", and both of those lines are now absent from AGENTS.md. This is not a contradiction to resolve - it is the captain's explicit round-1 decision ("Remove the captain-personal line from AGENTS.md entirely. Delete both the name and the ~/VOICE.md path. Do NOT replace it with a generic pointer, a placeholder, or a config-file reference"), which supersedes that clause of the intent. The removal is complete and clean: no placeholder was left, and tests/fm-brief.test.sh:410 asserts no generated brief leaks the instruction either. The one thing not verifiable from this branch is the other half of that decision - the instruction moving wholesale into firstmate's private captain-preferences file, which per AGENTS.md:95 and docs/configuration.md:139-141 is data/captain.md, gitignored and therefore outside this diff. Worth confirming firstmate has actually recorded it there, since otherwise the guidance is simply gone. No action needed on this branch.

🔧 Fix: split scout brief guidelines, add AGENTS.md drift guard
1 warning still open:

  • ⚠️ tests/fm-brief.test.sh:493 - The completeness loop iterates the AGENTS.md section through an unquoted heredoc:

    done <<EOF
    $section
    EOF

An unquoted heredoc performs command substitution, parameter expansion, and backslash processing on its body, so the test does not read the section literally - it evaluates it. The General Guidelines section happens to contain no backtick, $, or backslash today (I checked AGENTS.md:19-30), so the guard passes correctly right now; the hazard is that this test's entire purpose is to fire when someone edits that section. AGENTS.md uses backticks constantly for paths and commands, so a plausible future fleet-wide guideline - "Run bin/fm-lint.sh before treating a script change as done" - would make the test shell out and run bin/fm-lint.sh while building the line it was supposed to compare, and $FOO in a guideline would silently expand to empty and then fail the claimed-by-a-map-row check with a confusing message.

The pipe-into-while form is the wrong fix here: tests/lib.sh:44-47 defines fail() as printf plus exit 1, so running the loop in a subshell would turn a real drift failure into a silently ignored one. Two forms keep the loop in the current shell and read the text literally: write the section to a file next to the map (agents_general_guidelines_section &gt; &#34;$TMP_ROOT/general-guidelines-section.txt&#34; and done &lt; &#34;$TMP_ROOT/general-guidelines-section.txt&#34;), which matches how write_general_guidelines_map already feeds the other loop, or use bash process substitution (done &lt; &lt;(agents_general_guidelines_section)). The file form is the closer fit to the file's existing pattern.

🔧 Fix: read AGENTS.md section literally in brief drift guard
✅ Re-checked - no issues remain.

⚠️ **Test** - 2 issues (1 error, 1 warning)
  • 🚨 AGENTS.md:14 - Intent item (2) is not in the landed change: the line directing agents to read ~/VOICE.md when writing or posting under the captain's own identity is absent from AGENTS.md and from every other tracked file. Commit 2725ed2 ("drop captain-personal line") removed it. The captain's own source still carries it as ## Voice Profile -> "When you are talking/posting on behalf of Damian using his identity, read ~/VOICE.md to see how Damian writes", and the intent states the path was independently verified to exist (it does: /Users/owlshome/VOICE.md, 39650 bytes). I cannot produce evidence for a required intent item that is not present, so the captain needs to decide whether to restore the line or amend the intent.
  • ⚠️ AGENTS.md:60 - The one-owner claim in the intent does not match the tree for the commit co-author rule. The intent says the standalone co-author line in AGENTS.md section 1 was replaced by a one-line cross-reference, but AGENTS.md now states the rule twice with no pointer between them: line 18 ("When writing commit messages, NEVER auto-add your agent name as co-author.") in the new fleet-wide section and line 60 ("Never add an agent name as a commit co-author.") in section 1. The SKILL.md and CONTRIBUTING.md duplicates were given explicit cross-references explaining why they are deliberately stricter; the AGENTS.md section 1 copy was not, so it reads as an unowned duplicate rather than an intentional narrower rule.
  • ⚠️ bin/fm-test-run.sh:991 - bin/fm-test-run.sh --changed failed closed on this branch with "no changed-test mapping for source path: GROK_BOT.md", because the branch is the first to touch GROK_BOT.md and the changed-file table had no entry for it. This makes the repo's documented targeted-test selection (bin/fm-test-run.sh --changed --base origin/main) unusable for anyone working this branch. I added GROK_BOT.md to the same mapping case as AGENTS.md/CLAUDE.md/CONTRIBUTING.md, which is the class of file it belongs to; selection now resolves to 32 pure-contract-unit scripts and tests/fm-test-run.test.sh (which owns the fail-closed-on-unmapped contract) still passes.
  • bin/fm-test-run.sh tests/fm-brief.test.sh - 22 assertions including the two new ones (crewmate briefs carry the fleet-wide general guidelines, ship and scout guideline copies track the AGENTS.md section they mirror)
  • bin/fm-test-run.sh tests/fm-documentation-audiences.test.sh tests/fm-ensure-agents-md.test.sh - doc classification/owner-pointer and AGENTS.md scaffolding contracts
  • bin/fm-test-run.sh tests/fm-test-run.test.sh - re-run after my changed-file mapping fix, covers the fail-closed-on-unmapped-source contract
  • bin/fm-doc-audience-check.sh - the repo's documentation contract check the intent claims passes locally (ok surfaces=69 local_links=256)
  • Manual end-user artifact generation: FM_HOME=&lt;tmp&gt; bin/fm-brief.sh &lt;id&gt; demo-proj --mode no-mistakes, --scout, and --secondmate alpha, then read the rendered brief.md for each
  • Drift-guard negative check A: deleted "do not give much weight to development costs" from the AGENTS.md section and confirmed tests/fm-brief.test.sh fails with an actionable drift message
  • Drift-guard negative check B: added an unmirrored guideline to the AGENTS.md section and confirmed the completeness direction of the guard fails
  • Drift-guard negative check C: leaked the ship-only pixel-perfection guideline into GENERAL_GUIDELINES_SCOUT in bin/fm-brief.sh and confirmed the scope assertion fails
  • Fidelity diff of the landed AGENTS.md section against the captain's ~/.claude/CLAUDE.md "## General Guidelines" source, normalising only the four declared mechanical fixes
  • bin/fm-test-run.sh --list --changed --base 1cb900c - before (died on GROK_BOT.md) and after the mapping fix

🔧 Fix: map GROK_BOT.md in changed-test selection table
2 issues (1 error, 1 warning) still open:

  • 🚨 AGENTS.md:14 - Required intent item (2) is still absent from the tree, so I cannot produce evidence for it. git grep VOICE over all tracked files returns exactly one hit - tests/fm-brief.test.sh:396, an assertion that the string must NOT appear in a generated brief. There is no line anywhere in AGENTS.md (or any other tracked file) directing agents to read ~/VOICE.md when writing or posting under the captain's own identity. Commit 0277a4f added the captain's section, and commit 2725ed2 ("drop captain-personal line") removed the voice-profile directive; dc825c3 then added a test that locks its absence in. The captain's own source still carries it (~/.claude/CLAUDE.md, "## Voice Profile" -> "When you are talking/posting on behalf of Damian using his identity, read ~/VOICE.md to see how Damian writes"), and the intent states the path was independently verified to exist. This was raised in round 1 and is unchanged at the target commit, so the captain needs to decide: restore the line (and drop or invert the brief assertion that forbids it), or amend the intent to record that the voice-profile directive is deliberately fleet-local and not landed here.
  • ⚠️ AGENTS.md:60 - The intent's one-owner claim - that the standalone co-author line in AGENTS.md section 1 was replaced by a one-line cross-reference - does not hold at the target commit, so I could not demonstrate it. AGENTS.md states the rule twice with no pointer between the two: line 18 ("When writing commit messages, NEVER auto-add your agent name as co-author.") in the new fleet-wide section, and line 60 ("Never add an agent name as a commit co-author.") in section 1. Commit 0277a4f did remove line 60 as the intent describes; the later review commit dc825c3 re-added it verbatim, without the cross-reference the intent promised. The other two duplicates were handled as described - SKILL.md:119 and CONTRIBUTING.md carry explicit "deliberately stricter / owned fleet-wide by AGENTS.md" cross-references - which makes the untouched AGENTS.md section 1 copy read as an unowned duplicate rather than an intentional narrower rule. The captain should decide whether section 1 keeps its own stricter statement (with a cross-reference like SKILL.md's) or defers to the fleet-wide section.
  • bash tests/fm-brief.test.sh - full colocated suite for the changed script, including the two new cases test_briefs_carry_fleet_general_guidelines and test_brief_guidelines_track_agents_md_section (22 checks, all pass)
  • bash tests/fm-test-run.test.sh - owns the fail-closed-on-unmapped-source contract touched by the round-1 GROK_BOT.md mapping fix (all pass)
  • bash tests/fm-documentation-audiences.test.sh - prose classification and owner-pointer guard for the changed AGENTS.md / CONTRIBUTING.md / SKILL.md surfaces (all pass)
  • Manual end-to-end brief generation: FM_HOME=&lt;tmp&gt; bin/fm-brief.sh evidence-ship demo-proj --mode no-mistakes, ... evidence-scout demo-proj --scout, and FM_SECONDMATE_CHARTER=... ... evidence-2m --secondmate alpha, then read the resulting brief.md files - the actual text a crewmate loads
  • Mutation test A: softened "be picky about the UI ... pixel perfection" in AGENTS.md, confirmed the drift guard fails with a named-sentence diagnostic, restored the file
  • Mutation test B: added an unmirrored guideline ("Never hardcode secrets in source files.") to the AGENTS.md section, confirmed the reverse-completeness check fails, restored the file
  • Mutation test C: leaked the ship-only co-author guideline into GENERAL_GUIDELINES_SCOUT in bin/fm-brief.sh, confirmed the scope check fails, restored via git checkout --
  • bin/fm-test-run.sh --list --changed --base 1cb900c - confirms the branch's changed-file set now resolves (32 scripts, including tests/fm-brief.test.sh) instead of failing closed on GROK_BOT.md
  • Intent conformance sweep over the shipped text: nautical-seasoning examples in AGENTS.md:10 and GROK_BOT.md:24, section 9 plain-language line at AGENTS.md:453 and its GROK_BOT.md:25 counterpart, grep -rn &#39;—&#39; em-dash audit, grep -rn scalabilitiy typo check, and git grep VOICE / grep -rn co-author for the two open items
  • git status --porcelain - worktree left clean, no transient artifacts
⚠️ **Document** - 1 info
  • ℹ️ bin/fm-supervise-daemon.sh:654 - Follow-up, deliberately out of scope here: the new AGENTS.md rule "Never use the em dash" is contradicted by 8 pre-existing em dashes the branch does not touch. Three are runtime strings the captain actually reads - bin/fm-supervise-daemon.sh:654 (supervisor escalate message), :924 (wedge display-message), :1426 (pane auto-discovery warning) - and five are code comments: bin/fm-supervise-daemon.sh:2, :413, :436 and bin/fm-tmux-lib.sh:2, :218. Two test occurrences (tests/fm-daemon.test.sh:1116 comment, tests/fm-public-followup.test.sh:210 multibyte fixture) are also present; the fixture is intentional. I left all of them alone: the runtime strings are executable behavior this phase must not change, and fixing only the comments would leave the captain-facing output still violating the rule. Worth one small follow-up change that sweeps comments and strings together. The single em dash in AGENTS.md:16 is correct as written - it is inside the quoted rule that forbids the character.
🔧 **Lint** - 1 issue found → auto-fixed ✅
  • ⚠️ linter found issues (exit code 127)

🔧 Fix: lint clean; no code changes needed
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

Land the captain's edits: refreshed nautical-seasoning examples, a pointer
to ~/VOICE.md when writing under his identity, a new general-guidelines
section for all crewmates, and a plain-language rule in section 9.

Give the sentence-per-line, plain-dash, and no-agent-co-author rules a
single owner in that new section, replacing the copies in the coding
guidelines skill, CONTRIBUTING.md, and section 1 with cross-references.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant