Skip to content

fix: require configured git identity in worker briefs - #264

Merged
dnth merged 1 commit into
mainfrom
fm/fm-brief-commit-identity
Oct 20, 2026
Merged

dnth merged 1 commit into
mainfrom
fm/fm-brief-commit-identity

Conversation

@dnth

@dnth dnth commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Intent

Add one rule line to the ship-brief scaffold generated by bin/fm-brief.sh, in the Rules section shared by every ship delivery mode: commit only with the repository's configured git identity, and never override the author or committer (no git -c user.name=.../user.email, no --author, no GIT_AUTHOR_*/GIT_COMMITTER_* environment variables, no agent names as authors or co-authors). Reason: a worker commit in insourcedata/superfk-aceh PR 980 (b4e98eb9) carried author firstmate-crewmate firstmate-crewmate@local; nothing in firstmate sets that identity, the worker overrode it. AGENTS.md already forbids agent co-authors; make the identity rule explicit to workers. Keep it one concise line fitting the scaffold style; do not restructure the brief. Update any test that pins scaffold text or rule numbering. Scout and secondmate scaffolds stay unchanged unless they also tell workers to commit, in which case they get the same line. Acceptance: each ship mode (no-mistakes, direct-PR, local-only) brief contains the rule once; scout/secondmate unchanged except as above; existing bin/ checks pass and the PR body shows the rendered rule line.

What Changed

  • Add rule 8 to all ship delivery modes and scout briefs: Commit only with the repository's configured git identity: never override the author or committer via git -c user.name=/user.email, --author, GIT_AUTHOR_*/GIT_COMMITTER_* environment variables, or an agent name as author or co-author.
  • Add regression coverage checking that the rule appears exactly once in no-mistakes, direct-PR, local-only, and scout briefs, and remains absent from secondmate charters.

Risk Assessment

✅ Low: The change adds the required identity rule to the shared ship scaffold and commit-capable scout scaffold, leaves secondmate output unchanged, and introduces no unrelated behavior.

Testing

Selected behavioral checks and live CLI generation passed. Output comparisons confirmed only the intended rule was added, with secondmate output unchanged. Evidence includes generated Markdown and CLI transcripts; no GUI surface applies. PR-body publication and broad regression remain with their assigned outer phases.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Generate a no-mistakes ship brief: Rules contains the complete identity restriction once ✅ pass live Live CLI transcript and base-output comparisons
Generate a direct-PR ship brief: Rules contains the complete identity restriction once ✅ pass live Live CLI transcript and base-output comparisons
Generate a local-only ship brief: Rules contains the complete identity restriction once ✅ pass live Live CLI transcript and base-output comparisons
Generate a scout brief: scratch commits remain permitted with the same identity rule once ✅ pass live Live CLI transcript and base-output comparisons
Generate a secondmate charter: output remains byte-identical to base ✅ pass live Live CLI transcript and base-output comparisons
Enable orchestration or Herdr-lab scaffolding: the identity rule remains present exactly once ✅ pass live Live CLI transcript and base-output comparisons
Repeat scaffolding for an existing task: generation refuses and preserves the existing brief ✅ pass live Live CLI transcript and base-output comparisons
Evidence: Live CLI transcript and base-output comparisons
$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check demo --mode no-mistakes
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (ship, mode=no-mistakes; replace {TASK} and every {ACCEPTANCE CRITERION})

Generated Rules entry (exactly once):
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
All other generated bytes match base.

Repeated scaffold refused without altering the existing brief:
error: ship task already exists
error: could not atomically scaffold ship task: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check

$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check demo --mode direct-PR
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (ship, mode=direct-PR; replace {TASK} and every {ACCEPTANCE CRITERION})

Generated Rules entry (exactly once):
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
All other generated bytes match base.

Repeated scaffold refused without altering the existing brief:
error: ship task already exists
error: could not atomically scaffold ship task: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check

$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check demo --mode local-only
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (ship, mode=local-only; replace {TASK} and every {ACCEPTANCE CRITERION})

Generated Rules entry (exactly once):
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
All other generated bytes match base.

Repeated scaffold refused without altering the existing brief:
error: ship task already exists
error: could not atomically scaffold ship task: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check

$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check demo --scout
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (scout; replace {TASK})

Generated Rules entry (exactly once):
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
All other generated bytes match base.

Repeated scaffold refused without altering the existing brief:
error: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md already exists

$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check --secondmate demo
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (secondmate charter)

Secondmate generated charter is byte-identical to base.

Repeated scaffold refused without altering the existing brief:
error: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md already exists

$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check demo --mode direct-PR --orchestrate
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (ship, mode=direct-PR; replace {TASK} and every {ACCEPTANCE CRITERION})

Generated Rules entry (exactly once):
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
All other generated bytes match base.

Repeated scaffold refused without altering the existing brief:
error: ship task already exists
error: could not atomically scaffold ship task: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check

$ FM_HOME=<isolated-worktree-home> bin/fm-brief.sh identity-check demo --mode local-only --herdr-lab
scaffolded: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/brief.md (ship, mode=local-only; replace {TASK} and every {ACCEPTANCE CRITERION})

Generated Rules entry (exactly once):
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
All other generated bytes match base.

Repeated scaffold refused without altering the existing brief:
error: ship task already exists
error: could not atomically scaffold ship task: ~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check
Evidence: Generated ship brief with rendered identity rule
You are a crewmate: an autonomous worker agent managed by firstmate. Work on your own; do not wait for a human.

# Task
{TASK}

# Acceptance criteria
- AC1: {ACCEPTANCE CRITERION}

# Herdr lifecycle declaration - NOT ENABLED
**HARD SAFETY GATE:** this scaffold cannot inspect the task text filled in above.
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, 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/identity-check`
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}" >> '~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/state/identity-check.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.
   Whenever a turn ends while the task's board row is still in flight, the last status line
   must be terminal (`done:`, `failed:`, `needs-decision:`, `blocked:`) or `paused:`,
   landing within 600s of turn-end - never end on silence or a bare `working:`.
   Firstmate's watcher escalates a pane left idle past that bound with its row still in
   flight as `idle-with-open-work`. A `done:` is the delivery claim and must name the
   artifact the Definition of done requires; completion recording and teardown refuse a
   `done:` that carries none.
   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 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.
8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.

# Firstmate instruction inbox
Firstmate steers you through durable message files in '~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/state/identity-check.inbox'.
When a terminal message says an instruction is waiting there - and at any natural checkpoint when you are unsure - list '~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/state/identity-check.inbox'/*.msg, read and act on each message in numeric order, then acknowledge each handled message by moving it: `mv '~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/state/identity-check.inbox'/NNN.msg '~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/state/identity-check.inbox'/handled/`.
The move IS the acknowledgement: without it firstmate rings again and eventually treats you as stuck. An empty or absent inbox needs no action.

# Delegating read-only scouting
When the task benefits from bounded read-only scouting - mapping files, tracing call paths, gathering evidence, or broad pattern searches - delegate that scouting to native subagents instead of grinding through it solo.
On OMP, `omp agents unpack` ships the `scout`/`task`/`reviewer`/`security-reviewer`/`sonic` subagents; `scout` is read-only, `@smol`, and built for parallel search - prefer it for this work.
On other harnesses, use the read-only subagent surface the harness provides; where it provides none, do the scouting yourself.
Subagents scout only: keep every edit, verification run, and evidence receipt in your own main trajectory. You stay accountable for integrating and verifying their output and for recording the receipts your deliverable requires.

# Project memory
If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/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 `~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/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.

# Acceptance evidence
Before reporting implementation complete, record at least one compact receipt for every acceptance criterion with `~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/bin/fm-receipt.sh identity-check <criterion> <type> <summary> <result> --outcome <success|failure|negative|zero|skipped|empty|placeholder|weak|accepted-blocked> [options]`.
Only `--outcome success` evidences a criterion; `accepted-blocked` requires a non-empty `--captain-exception "<text>"` (the date plus the captain's own words or the board key that holds them) and accounts for the criterion without evidencing it; every other structured outcome records an unevidenced negative or inconclusive result.
A task with any accepted-blocked criterion is never auto-merged; state those criteria and their exception references plainly in the PR description.
Run `~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/bin/fm-receipt-check.sh identity-check` and do not append `done:` unless its JSON status is `complete`.
The latest receipt per criterion decides it: when a finding or a later test shows a criterion unsatisfied, record a `--outcome failure` receipt for it, fix, and record a fresh `--outcome success`.
Receipts establish that you accounted for every declared criterion; they certify nothing about review, CI, No-Mistakes completion, or merge readiness, so keep summaries and results compact and point to commands or artifacts when useful.
When a cited artifact lives inside this scratch worktree (for example `.qa/evidence/<run_id>/report.json`), copy it into `~/.no-mistakes/worktrees/dd71c22cc6d7/01M5BC21BWN9R6387C8KTJNPNB/.phase-test/home/data/identity-check/artifacts/` (gitignored, survives teardown) before `done:` and cite the copied path; worktree-relative paths die with the worktree.

# Definition of done
Delivery contract: mode=no-mistakes
The task is complete only when committed on your branch and every declared acceptance criterion has a receipt.
When you believe it is complete, append `done: {summary}` to the status file and stop.
Firstmate will then start full No-Mistakes validation on this worker.

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; fix ordinary findings only after Firstmate directs the supported abort and branch-custody return sequence, and when a finding shows a criterion unsatisfied, record its failure receipt before the fix and a fresh success after it.
Firstmate's PR-ready helper reads No-Mistakes' own status for your run - branch, PR URL, full head SHA, and outcome - so never push foreign commits over the pipeline's head.

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.
  Report each parked gate as `needs-decision [key=nm-<run>-<step>]: ask-user findings=<id1>,<id2>,...` naming every ask-user finding id the gate presents; PR registration and done acceptance refuse any recorded ask-user resolution that lacks a matching firstmate `resolved [key=nm-<run>-<step>]` record.
  Firstmate applies `ask-user-authority` 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` to the status file and stop. You are finished.
The `done:` line must carry the PR URL - it is the delivery artifact - and PR registration and teardown refuse a `done:` that names none.

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.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Generate a no-mistakes ship brief: Rules contains the complete identity restriction once ✅ pass live Live CLI transcript and base-output comparisons
Generate a direct-PR ship brief: Rules contains the complete identity restriction once ✅ pass live Live CLI transcript and base-output comparisons
Generate a local-only ship brief: Rules contains the complete identity restriction once ✅ pass live Live CLI transcript and base-output comparisons
Generate a scout brief: scratch commits remain permitted with the same identity rule once ✅ pass live Live CLI transcript and base-output comparisons
Generate a secondmate charter: output remains byte-identical to base ✅ pass live Live CLI transcript and base-output comparisons
Enable orchestration or Herdr-lab scaffolding: the identity rule remains present exactly once ✅ pass live Live CLI transcript and base-output comparisons
Repeat scaffolding for an existing task: generation refuses and preserves the existing brief ✅ pass live Live CLI transcript and base-output comparisons
  • Ran seven selected executable-interface checks from tests/fm-brief.test.sh, covering ship modes, mode validation, delivery flags, orchestration, identity rules, scout and secondmate generation.
  • Ran python3 .phase-test/drive.py to invoke base and target scaffold CLIs in an isolated worktree-local FM_HOME across seven configurations, compare generated outputs, and retry existing tasks.
  • Saved generated briefs and CLI evidence; removed disposable drivers and data; verified git status --short was empty.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Ship and scout scaffolds now tell the worker to commit only with the repository's configured git identity and never override the author or committer, so a worker cannot leak an agent identity into a delivered commit. Secondmate charters are unchanged because they do not instruct commits.

Rendered rule line (ship scaffolds, Rule 8):

    8. Commit only with the repository's configured git identity: never override the author or committer via `git -c user.name=`/`user.email`, `--author`, `GIT_AUTHOR_*`/`GIT_COMMITTER_*` environment variables, or an agent name as author or co-author.
@dnth
dnth merged commit 3d910ef into main Oct 20, 2026
18 checks passed
@dnth
dnth deleted the fm/fm-brief-commit-identity branch October 20, 2026 03:50
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