Skip to content

fix(brief): 把 no-mistakes 的完成判据钉到管线产出的 PR,而不是裸提交 - #10

Merged
onyx-space merged 6 commits into
mainfrom
fm/fm-brief-bare-done-without-pipeline
Sep 11, 2026
Merged

onyx-space merged 6 commits into
mainfrom
fm/fm-brief-bare-done-without-pipeline

Conversation

@onyx-space

@onyx-space onyx-space commented Sep 11, 2026 •

Copy link
Copy Markdown
Owner

摘要

治本:mode=no-mistakes 的 worker 反复把"已提交"当成"已完成" —— 当天一天内就抓到 3 次:fm-brief-pr-discipline(runs_on_current_branch: 0)、glitter-pr-ci-status(报告里写"等 /no-mistakes 开 PR"就收尾了)、pi-remote-catalog-freshness-gate-local-fix("fix committed on branch … ready for the run"就声明 done)。三次都是只提交、没跑管线、没开 PR,每次都要 MAIN 花一轮去追。

队列里本来就有这条(fm-brief-bare-done-without-pipeline):worker brief 需要把"什么才算完成"钉死,不要指望 worker 自己记住。

本 PR 让 bin/fm-brief.sh 生成的 ship brief 在 mode=no-mistakes 下无法再被误读为"提交即完成"。该 brief 的 Definition of done 由单一 owner bin/fm-dod-lib.sh 渲染,普通 ship brief 与 promoted scout 两条交付路径共用同一份契约。

改了什么

  • 重写 bin/fm-dod-lib.sh 里 mode=no-mistakes 的 Definition of done:把管线 push 并开出的 PR写为完成信号,明确写出 commit / 干净分支 / "ready for the run" 都不是完成;唯一完成声明钉死为 done: PR {url} checks green,且必须是状态日志的最后一行。
  • brief 现在把"跑管线"变成 worker 提交后的自己的步骤,并使用与 harness 无关的技能调用形态(删掉了 harness 专属的 /no-mistakes 斜杠写法);同一分支已有 run 时禁止再起第二个 run;run 进行中收到 firstmate 的技能投递只当作催办(reattach + poll);因"已 run 在跑"被拒时改为跟随管线自己的 status,而不是报 blocked;补充首次运行的 no-mistakes doctor / no-mistakes init 步骤。direct-PR 契约的措辞改为 "Do NOT start the no-mistakes pipeline"。
  • AGENTS.md 记录 bin/fm-dod-lib.sh 是各 delivery mode Definition of done 的单一 owner;tests/fm-brief.test.sh 与 tests/fm-task-delivery.test.sh 钉住新的完成信号、其唯一 claim 形态、以及与 direct-PR / local-only 的隔离。

风险评估

✅ 低:改动只重写 worker 面向的契约文本(单一 owner bin/fm-dod-lib.sh,并同步 AGENTS.md)及其回归断言,不触碰任何可执行逻辑;已验证每一种 mode 生成的 brief 都渲染出预期契约,且没有消费方回归。

验证

在隔离的临时 home 里搭起真实的 firstmate 脚本,端到端驱动改过的 Definition of done:用真实的 bin/fm-brief.sh 生成 no-mistakes / direct-PR / local-only 三种 brief;直接从 bin/fm-dod-lib.sh 渲染 fm_dod_block 并与生成的 brief 逐字 diff(一致);跑真实的 bin/fm-promote.sh promotion 路径并 diff 它产出给 promoted worker 的 ship-instructions(一致);两个聚焦套件(tests/fm-brief.test.sh、tests/fm-task-delivery.test.sh)通过。证据是 evidence 目录里粘贴的真实命令输出。

4 个场景中 3 个现场驱动通过,1 个如实记为未驱动:

场景 结果 现场驱动
mode=no-mistakes 的 worker 只提交、不开管线 PR 时不判完成:生成的 Definition of done 把管线 PR 写成完成信号,并明确 commit 不是完成 ✅ 通过 是
worker 能用自己 harness 的形态启动管线:生成的 no-mistakes brief 里没有写死的斜杠调用,具体形态交给 harness-adapters;promoted-scout 交付文本同样如此 ✅ 通过 是
防重复 / 管线所有权规则拒绝第二个或非所有者的 worker 冒充同一管线 PR ⏸️ 未现场驱动 否
非管线 worker 不被回归:direct-PR brief 仍在自开的 PR 上完成,local-only brief 仍在就绪分支上完成,两者都不携带 no-mistakes 的 claim ✅ 通过 是

未驱动那条的原因:本仓没有"拒绝第二次/非所有者启动"的运行时守卫 —— bin/fm-nm-run-lib.sh 里的 run 归属判定是只读的,真正的拒绝发生在外部 no-mistakes CLI,本步骤无法在仓内执行。

下方 English 折叠里是以上叙述的英文原文;再往下的证据块与 Pipeline 段是机器输出(日志转录、自检报告),按原文保留。

English ## Intent

治本:mode=no-mistakes 的 worker 反复把"已提交"当成"已完成"——今天一天内就抓到 3 次:fm-brief-pr-discipline(runs_on_current_branch: 0)、glitter-pr-ci-status(报告里写"等 /no-mistakes 开 PR"就收尾了)、pi-remote-catalog-freshness-gate-local-fix("fix committed on branch … ready for the run"就声明 done)。三次都是只提交、没跑管线、没开 PR,每次都要 MAIN 花一轮去追。

队列里本来就有这条(fm-brief-bare-done-without-pipeline):worker brief 需要把"什么才算完成"钉死,不要指望 worker 自己记住。

What Changed

  • Reworked the mode=no-mistakes definition of done in bin/fm-dod-lib.sh: the pipeline-pushed PR is now named as the completion signal, a commit/clean branch/"ready for the run" is explicitly stated not to be one, and the single completion claim is pinned to done: PR {url} checks green as the last line of the status log.
  • The brief now makes running the pipeline the worker's own post-commit step in a harness-agnostic skill-invocation form (with the harness-specific /no-mistakes slash form removed), forbids starting a second validation run while one is active on the branch, treats a mid-run firstmate skill delivery as a nudge to reattach and poll, routes an already-active-run refusal to the pipeline's own status instead of a blocked report, and adds the first-run no-mistakes doctor / no-mistakes init step. The direct-PR contract wording becomes "Do NOT start the no-mistakes pipeline".
  • AGENTS.md records bin/fm-dod-lib.sh as the single owner of delivery-mode definitions of done, and tests/fm-brief.test.sh plus tests/fm-task-delivery.test.sh pin the new completion signal, its single claim shape, and the separation from the direct-PR and local-only modes.

Risk Assessment

✅ Low: The change only rewrites worker-facing contract prose (single owner bin/fm-dod-lib.sh, aligned AGENTS.md) plus its regression pins, touches no executable logic, and I verified the emitted briefs for every mode render the intended contract with no consumer regressions.

Testing

I stood up the real firstmate scripts in isolated temp homes and drove the changed Definition of done end to end: generated the no-mistakes, direct-PR, and local-only briefs with the real bin/fm-brief.sh, rendered fm_dod_block directly from bin/fm-dod-lib.sh and diffed it against the generated brief (identical), ran the real bin/fm-promote.sh promotion path and diffed its ship-instructions DoD against the brief (identical), and fed the prescribed completion line through the real bin/fm-crew-state.sh reader, which classified the pinned done: PR <url> checks green (and the same claim with head and CI appended) as done while a commit-only claim stayed working. Targeted tests for the brief, the promotion delivery path, and the crew-state reader all pass. The only scenario I could not drive is the actual refusal of a second or non-owning start, which lives in the external no-mistakes CLI rather than in this repo; it is reported untested as a residual. Overall the pinned-completion intent is demonstrated on the real generated and delivered artifacts.

  • Live validation: ✅ go - 3 of 4 scenarios driven live against the product
Scenario Result Live Evidence
A mode=no-mistakes worker that commits but opens no pipeline PR is not treated as complete: the generated Definition of done names the pipeline PR as the completion signal and says a commit is not one… ✅ pass live Real bin/fm-brief.sh no-mistakes brief (artifacts/brief-no-mistakes-definition-of-done.txt) states 'Completion for mode=no-mistakes is a PR the no-mistakes pipeline pushed and opened, never a commit.'…
A worker can start the pipeline in its own harness's form: the generated no-mistakes brief carries no hard-coded slash invocation, defers the exact form to harness-adapters, and the promoted-scout del… ✅ pass live brief-surface-checks.txt: 0 occurrences of '/no-mistakes' and 0 unverifiable ownership claims in the generated no-mistakes brief; the harness-agnostic start sentence is present. Real promotion via bin…
Anti-duplication and pipeline-ownership rules reject a second or non-owning worker claiming the same pipeline PR. ⏸️ untested no This repo has no runtime guard that refuses a second or non-owning start; run attribution in bin/fm-nm-run-lib.sh is read-only and the refusal lives in the external no-mistakes CLI, which cannot be ex…
Non-pipeline workers are not regressed: the direct-PR brief still completes on its own opened PR and the local-only brief still completes on the ready branch, and neither receives the no-mistakes cont… ✅ pass live Real bin/fm-brief.sh direct-PR and local-only briefs keep their own signals ('done: PR {url}' and 'done: ready in branch fm/live-local-only') and 'The task is complete only when committed on your bran…
Evidence: Generated no-mistakes Definition of done (real bin/fm-brief.sh output)

Source: Generated no-mistakes Definition of done (real bin/fm-brief.sh output)

# Definition of done
Delivery contract: mode=no-mistakes
**Completion for mode=no-mistakes is a PR the no-mistakes pipeline pushed and opened, never a commit.**
A commit, a clean branch, or "ready for the run" is NOT completion; stopping there leaves the task unfinished and firstmate has to chase it.
The one completion claim is `done: PR {url} checks green`, written with the PR's full `https://` URL once the run reports CI green.
Running the pipeline belongs to this task, not to a later instruction: once your implementation is committed, start this task's no-mistakes pipeline yourself in your own harness's skill-invocation form, and keep driving its gates until that green result or a terminal failure.
The exact skill-invocation form is harness-specific and owned by `harness-adapters`; when you are unsure of it, state the action in natural language and proceed.
Never start a second validation run while one is already active on this branch.
Treat a firstmate delivery of this task's no-mistakes skill that arrives mid-run as a nudge to reattach and poll, not as a second start.
If a start is refused because a run is already active on this branch, follow the pipeline's own status and help lines instead of reporting the task blocked.
First run in a repo the pipeline has never seen: run `no-mistakes doctor`, then `no-mistakes init` if it reports the repo is not initialized here, before the first run.
Write the completion line as the pinned claim first, then the validated head commit and the CI result on that same line, leaving the claim itself intact.
The completion line is the LAST line in the status log: put any supplementary explanation before it, or in `data/<task-id>/`, never after it.

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 start the skill, 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, pass `--intent` as only this brief's `## Captain's intent` subsection plus any later words the captain actually said.
For a legacy brief with no such subsection, include only words explicitly labeled `Captain:`, `Captain's words:`, `Captain's ask:`, or `Captain's intent:`; never copy its mixed `# Task` wholesale. If it has no provenance-marked captain words, stop and ask firstmate instead of starting no-mistakes.
Do not include `## Firstmate spec`, later Firstmate build constraints, or your own decisions and tradeoffs.
The `--intent` string you pass must be self-sufficient: that string plus the codebase must let a reader reconstruct roughly the same specification, without depending on a separate report, a PR, or context that lives only in this conversation.
When the captain's intent refers to a report, decision, or PR ("do items 1, 2, 3, and 7 of the report"), write the substance of the referenced items into `--intent` in the captain's terms, not only the pointer; that substance is the captain's ask by reference, while Firstmate's build instructions and your own decisions still stay out.
This replaces the no-mistakes skill's advice to enrich `--intent` with decisions and tradeoffs; that advice does not apply to Firstmate-dispatched work.
Do not hand-edit, commit, or fix findings yourself while a run is active - the pipeline applies every fix.

One drive call blocks until the next gate or outcome, which routinely outlives what your harness lets a single command run: Claude Code kills a command at ten minutes maximum, while one fix round is capped around thirty minutes and up to three rounds chain.
So background the drive call and poll `no-mistakes axi status` from a separate call instead of sitting in one blocking hold your harness will kill.
Where a harness's own command limit is not established, assume it bounds commands and use that same background-and-poll shape.
A killed or timed-out call is never evidence the daemon died: the daemon accepts your response immediately and runs the round in the background, so the call was only ever waiting for a read while the run kept working.
Reattach and keep going rather than reporting the pipeline blocked; rule 7 owns the checks that decide when a pipeline block is real.

Two firstmate-specific rules layer on top of that guidance:
- ask-user findings are never yours to answer: escalate to firstmate using rule 6's ask-user format and stop.
  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.
- NEVER pass `--yes` (or `-y`) to `no-mistakes axi run` or `no-mistakes axi respond`. It is banned fleet-wide.
  It auto-resolves every gate including ask-user findings with no escalation, and answering your own ask-user finding is a hard rule violation.

After the pipeline 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: Generated direct-PR Definition of done (real bin/fm-brief.sh output)

Source: Generated direct-PR Definition of done (real bin/fm-brief.sh output)

# Definition of done
Delivery contract: mode=direct-PR
This task ships **direct-PR**: you raise the PR yourself, without the no-mistakes pipeline.
The task is complete only when committed on your branch.
When it is implemented and committed, push your branch and open a PR with `gh-axi`, then append `done: PR {url}` to the status file and stop.
Do NOT start the no-mistakes pipeline. The configured merge authority decides whether to merge the PR; firstmate relays the outcome.
Evidence: Generated local-only Definition of done (real bin/fm-brief.sh output)

Source: Generated local-only Definition of done (real bin/fm-brief.sh output)

# Definition of done
Delivery contract: mode=local-only
This task ships **local-only**: no remote, no PR, no pipeline.
The task is complete only when committed on your branch `fm/live-local-only`. Do NOT push, do NOT open a PR, do NOT merge.
Keep your branch a clean fast-forward onto the current default branch - if `main` has advanced, rebase onto it so the eventual merge stays a fast-forward.
When it is implemented and committed, append `done: ready in branch fm/live-local-only` to the status file and stop.
The configured merge authority approves the ready branch, then firstmate merges it into local `main` through the guarded fast-forward path.
Evidence: Promoted no-mistakes worker DoD from real bin/fm-promote.sh (ship-instructions.md)

Source: Promoted no-mistakes worker DoD from real bin/fm-promote.sh (ship-instructions.md)

# Definition of done
Delivery contract: mode=no-mistakes
**Completion for mode=no-mistakes is a PR the no-mistakes pipeline pushed and opened, never a commit.**
A commit, a clean branch, or "ready for the run" is NOT completion; stopping there leaves the task unfinished and firstmate has to chase it.
The one completion claim is `done: PR {url} checks green`, written with the PR's full `https://` URL once the run reports CI green.
Running the pipeline belongs to this task, not to a later instruction: once your implementation is committed, start this task's no-mistakes pipeline yourself in your own harness's skill-invocation form, and keep driving its gates until that green result or a terminal failure.
The exact skill-invocation form is harness-specific and owned by `harness-adapters`; when you are unsure of it, state the action in natural language and proceed.
Never start a second validation run while one is already active on this branch.
Treat a firstmate delivery of this task's no-mistakes skill that arrives mid-run as a nudge to reattach and poll, not as a second start.
If a start is refused because a run is already active on this branch, follow the pipeline's own status and help lines instead of reporting the task blocked.
First run in a repo the pipeline has never seen: run `no-mistakes doctor`, then `no-mistakes init` if it reports the repo is not initialized here, before the first run.
Write the completion line as the pinned claim first, then the validated head commit and the CI result on that same line, leaving the claim itself intact.
The completion line is the LAST line in the status log: put any supplementary explanation before it, or in `data/<task-id>/`, never after it.

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 start the skill, 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, pass `--intent` as only this brief's `## Captain's intent` subsection plus any later words the captain actually said.
For a legacy brief with no such subsection, include only words explicitly labeled `Captain:`, `Captain's words:`, `Captain's ask:`, or `Captain's intent:`; never copy its mixed `# Task` wholesale. If it has no provenance-marked captain words, stop and ask firstmate instead of starting no-mistakes.
Do not include `## Firstmate spec`, later Firstmate build constraints, or your own decisions and tradeoffs.
The `--intent` string you pass must be self-sufficient: that string plus the codebase must let a reader reconstruct roughly the same specification, without depending on a separate report, a PR, or context that lives only in this conversation.
When the captain's intent refers to a report, decision, or PR ("do items 1, 2, 3, and 7 of the report"), write the substance of the referenced items into `--intent` in the captain's terms, not only the pointer; that substance is the captain's ask by reference, while Firstmate's build instructions and your own decisions still stay out.
This replaces the no-mistakes skill's advice to enrich `--intent` with decisions and tradeoffs; that advice does not apply to Firstmate-dispatched work.
Do not hand-edit, commit, or fix findings yourself while a run is active - the pipeline applies every fix.

One drive call blocks until the next gate or outcome, which routinely outlives what your harness lets a single command run: Claude Code kills a command at ten minutes maximum, while one fix round is capped around thirty minutes and up to three rounds chain.
So background the drive call and poll `no-mistakes axi status` from a separate call instead of sitting in one blocking hold your harness will kill.
Where a harness's own command limit is not established, assume it bounds commands and use that same background-and-poll shape.
A killed or timed-out call is never evidence the daemon died: the daemon accepts your response immediately and runs the round in the background, so the call was only ever waiting for a read while the run kept working.
Reattach and keep going rather than reporting the pipeline blocked; rule 7 owns the checks that decide when a pipeline block is real.

Two firstmate-specific rules layer on top of that guidance:
- ask-user findings are never yours to answer: escalate to firstmate using rule 6's ask-user format and stop.
  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.
- NEVER pass `--yes` (or `-y`) to `no-mistakes axi run` or `no-mistakes axi respond`. It is banned fleet-wide.
  It auto-resolves every gate including ask-user findings with no escalation, and answering your own ask-user finding is a hard rule violation.

After the pipeline 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: Direct fm_dod_block output for all three modes (single owner in bin/fm-dod-lib.sh)

Source: Direct fm_dod_block output for all three modes (single owner in bin/fm-dod-lib.sh)

----- fm_dod_block no-mistakes -----
# Definition of done
Delivery contract: mode=no-mistakes
**Completion for mode=no-mistakes is a PR the no-mistakes pipeline pushed and opened, never a commit.**
A commit, a clean branch, or "ready for the run" is NOT completion; stopping there leaves the task unfinished and firstmate has to chase it.
The one completion claim is `done: PR {url} checks green`, written with the PR's full `https://` URL once the run reports CI green.
Running the pipeline belongs to this task, not to a later instruction: once your implementation is committed, start this task's no-mistakes pipeline yourself in your own harness's skill-invocation form, and keep driving its gates until that green result or a terminal failure.
The exact skill-invocation form is harness-specific and owned by `harness-adapters`; when you are unsure of it, state the action in natural language and proceed.
Never start a second validation run while one is already active on this branch.
Treat a firstmate delivery of this task's no-mistakes skill that arrives mid-run as a nudge to reattach and poll, not as a second start.
If a start is refused because a run is already active on this branch, follow the pipeline's own status and help lines instead of reporting the task blocked.
First run in a repo the pipeline has never seen: run `no-mistakes doctor`, then `no-mistakes init` if it reports the repo is not initialized here, before the first run.
Write the completion line as the pinned claim first, then the validated head commit and the CI result on that same line, leaving the claim itself intact.
The completion line is the LAST line in the status log: put any supplementary explanation before it, or in `data/<task-id>/`, never after it.

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 start the skill, 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, pass `--intent` as only this brief's `## Captain's intent` subsection plus any later words the captain actually said.
For a legacy brief with no such subsection, include only words explicitly labeled `Captain:`, `Captain's words:`, `Captain's ask:`, or `Captain's intent:`; never copy its mixed `# Task` wholesale. If it has no provenance-marked captain words, stop and ask firstmate instead of starting no-mistakes.
Do not include `## Firstmate spec`, later Firstmate build constraints, or your own decisions and tradeoffs.
The `--intent` string you pass must be self-sufficient: that string plus the codebase must let a reader reconstruct roughly the same specification, without depending on a separate report, a PR, or context that lives only in this conversation.
When the captain's intent refers to a report, decision, or PR ("do items 1, 2, 3, and 7 of the report"), write the substance of the referenced items into `--intent` in the captain's terms, not only the pointer; that substance is the captain's ask by reference, while Firstmate's build instructions and your own decisions still stay out.
This replaces the no-mistakes skill's advice to enrich `--intent` with decisions and tradeoffs; that advice does not apply to Firstmate-dispatched work.
Do not hand-edit, commit, or fix findings yourself while a run is active - the pipeline applies every fix.

One drive call blocks until the next gate or outcome, which routinely outlives what your harness lets a single command run: Claude Code kills a command at ten minutes maximum, while one fix round is capped around thirty minutes and up to three rounds chain.
So background the drive call and poll `no-mistakes axi status` from a separate call instead of sitting in one blocking hold your harness will kill.
Where a harness's own command limit is not established, assume it bounds commands and use that same background-and-poll shape.
A killed or timed-out call is never evidence the daemon died: the daemon accepts your response immediately and runs the round in the background, so the call was only ever waiting for a read while the run kept working.
Reattach and keep going rather than reporting the pipeline blocked; rule 7 owns the checks that decide when a pipeline block is real.

Two firstmate-specific rules layer on top of that guidance:
- ask-user findings are never yours to answer: escalate to firstmate using rule 6's ask-user format and stop.
  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.
- NEVER pass `--yes` (or `-y`) to `no-mistakes axi run` or `no-mistakes axi respond`. It is banned fleet-wide.
  It auto-resolves every gate including ask-user findings with no escalation, and answering your own ask-user finding is a hard rule violation.

After the pipeline 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.

----- fm_dod_block direct-PR -----
# Definition of done
Delivery contract: mode=direct-PR
This task ships **direct-PR**: you raise the PR yourself, without the no-mistakes pipeline.
The task is complete only when committed on your branch.
When it is implemented and committed, push your branch and open a PR with `gh-axi`, then append `done: PR {url}` to the status file and stop.
Do NOT start the no-mistakes pipeline. The configured merge authority decides whether to merge the PR; firstmate relays the outcome.

----- fm_dod_block local-only -----
# Definition of done
Delivery contract: mode=local-only
This task ships **local-only**: no remote, no PR, no pipeline.
The task is complete only when committed on your branch `fm/live-local-only`. Do NOT push, do NOT open a PR, do NOT merge.
Keep your branch a clean fast-forward onto the current default branch - if `main` has advanced, rebase onto it so the eventual merge stays a fast-forward.
When it is implemented and committed, append `done: ready in branch fm/live-local-only` to the status file and stop.
The configured merge authority approves the ready branch, then firstmate merges it into local `main` through the guarded fast-forward path.
Evidence: Real bin/fm-crew-state.sh classification of pinned, pinned+head+CI, and commit-only claims

Source: Real bin/fm-crew-state.sh classification of pinned, pinned+head+CI, and commit-only claims

pinned claim only (brief line 246/279)
  line: done: PR https://github.com/o/r/pull/9 checks green
  -> state: done · source: status-log · PR https://github.com/o/r/pull/9 checks green · run still monitoring PR
pinned claim + head + CI appended (brief line 233 shape)
  line: done: PR https://github.com/o/r/pull/9 checks green head deadbeef CI green
  -> state: done · source: status-log · PR https://github.com/o/r/pull/9 checks green head deadbeef CI green · run still monitoring PR
commit-only claim (the failure this change targets)
  line: done: fix committed on branch fm/feat-ci, ready for the run
  -> state: working · source: run-step · validating (running)
Evidence: Generated-brief surface checks: harness-agnostic start, no leakage into other modes, anti-duplication rules

Source: Generated-brief surface checks: harness-agnostic start, no leakage into other modes, anti-duplication rules

== generated brief paths ==
/tmp/fm-live2-eOH9dC/home/data/live-direct-PR/brief.md
/tmp/fm-live2-eOH9dC/home/data/live-local-only/brief.md
/tmp/fm-live2-eOH9dC/home/data/live-no-mistakes/brief.md

== harness-specific slash form in no-mistakes brief (expect 0) ==
0

== unverifiable ownership claims in no-mistakes brief (expect none) ==
(none)

== no-mistakes contract leaking into other modes (expect 0 0) ==
direct-PR: 0
local-only: 0

== mode-specific completion signals ==
When it is implemented and committed, push your branch and open a PR with `gh-axi`, then append `done: PR {url}` to the status file and stop.
When it is implemented and committed, append `done: ready in branch fm/live-local-only` to the status file and stop.
The one completion claim is `done: PR {url} checks green`, written with the PR's full `https://` URL once the run reports CI green.
After the pipeline 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.

== anti-duplication rules delivered in no-mistakes brief ==
112:Never start a second validation run while one is already active on this branch.
113:Treat a firstmate delivery of this task's no-mistakes skill that arrives mid-run as a nudge to reattach and poll, not as a second start.
114:If a start is refused because a run is already active on this branch, follow the pipeline's own status and help lines instead of reporting the task blocked.
Evidence: Targeted test run: tests/fm-brief.test.sh

Source: Targeted test run: tests/fm-brief.test.sh

ok - fm-brief: scaffolds leave the worker role scope to the launch boundary and keep the secondmate contract
ok - fm-brief.sh: bash -n succeeds
/private/var/folders/jq/t9r90khx6kzcw250jx08lw1r0000gn/T/fm-brief.EPqaez/heredoc-in-substitution.sh:2
ok - fm-brief.sh: no heredoc is nested inside a command substitution (Bash 3.2 parse-safe)
ok - fm-brief.sh: --help renders the complete header
ok - fm-brief.sh: no-mistakes/direct-PR/local-only briefs generate cleanly
ok - fm-brief.sh: ship --mode is required and closed-set validated
ok - fm-brief.sh: the explicit ship mode wins over the registered posture
ok - fm-brief.sh: --yolo and scout/secondmate --mode are refused, never silently dropped
ok - fm-brief.sh: faster paths use configured authority without stacked review
ok - fm-brief.sh: no-mistakes DOD keeps its apostrophe prose and bans --yes outright
ok - fm-brief.sh: no-mistakes completion is the pipeline PR, and the other modes stay distinct
ok - fm-brief.sh: no-mistakes ask-user findings use one event plus a verbatim snapshot
ok - fm-brief.sh: ship project-memory wording carries the AGENTS.md authoring bar
ok - fm-brief.sh: --herdr-lab emits the complete hard safety contract
ok - fm-brief.sh: --herdr-lab uses its quoted Firstmate-owned helper path
ok - fm-brief.sh: ship and scout scaffolds make omitted Herdr intent fail-visible
ok - fm-brief.sh: the documented {TASK} and {FIRSTMATE_SPEC} fills cannot corrupt the Herdr safety gate
ok - fm-brief.sh: Herdr lab contract covers scouts and rejects secondmate misuse
ok - fm-brief.sh: --no-projects scaffolds a project-less charter and guards misuse
ok - fm-brief.sh: marked requests avoid generic acknowledgements and preserve material reporting
ok - fm-brief.sh: relative directory inputs ignore CDPATH, render stable absolute charter paths, or fail loudly
ok - fm-brief.sh: custom pause verb renders in every scaffold
ok - fm-brief.sh: investigation and visual-review completions load the shared decision policy
ok - fm-brief.sh: worker briefs carry the CE workflow boundary section
ok - fm-brief.sh: PR-opening briefs point the worker at the pr-description skill
ok - fm-brief: every worker scaffold states the artifact-placement contract and the charter stays free of it
ok - fm-brief: scout and secondmate code paths still scaffold well-formed briefs
Evidence: Targeted test run: tests/fm-task-delivery.test.sh

Source: Targeted test run: tests/fm-task-delivery.test.sh

ok - fm-spawn: every legacy worker receives scoped role instructions without changing project or primary instructions
ok - fm-spawn: a ship spawn requires a valid explicit mode and yolo before anything is created
ok - fm-spawn: scout and secondmate spawns refuse ship delivery flags
ok - fm-spawn: the brief's recorded mode and the spawn's explicit mode must agree
ok - fm-spawn: a rigor downgrade against the registered posture is announced, never blocked
ok - fm-spawn: a scout spawn resolves no delivery posture from the registry
ok - fm-promote: promotion requires the delivery contract and records it exactly once
ok - fm-promote: a symlinked task record is refused and its target is left untouched
ok - fm-promote: a promoted worker receives the same mode-specific delivery contract a briefed one does
ok - fm-project-mode: the conditional policy is accepted, mapped for mechanical callers, and readable raw
ok - fm-spawn/fm-promote: leftover Task placeholders are refused until both subsections are filled
# all fm-task-delivery tests passed
Evidence: Targeted test run: tests/fm-crew-state.test.sh

Source: Targeted test run: tests/fm-crew-state.test.sh

ok - active run-step is authoritative
ok - stale needs-decision over active run is superseded
ok - stale blocked over active run is superseded
ok - daemon/timeout blocked claim over a live fixing run reads as run alive
ok - socket refusal or missing socket over a stale fixing run reports blocked
ok - socket refusal over a terminal attributed run reports blocked
ok - broken-pipe blocker over a live run keeps the plain superseded reading
ok - genuine daemon-down blocked line still reports blocked
ok - genuine parked run is not flagged superseded
ok - scalar gate parked run is not flagged superseded
ok - gate block parked run is not flagged superseded
ok - ci-ready status log beats monitoring run
ok - ci-monitoring run with checks already green surfaces done
ok - top-level ci status uses ci log green marker
ok - terminal no-checks ci-monitor marker surfaces done
ok - base-advance rearm after green stays working
ok - pending no-checks ci-monitor marker stays working
ok - ci-monitoring run with checks not yet green stays working
ok - a fresh issue after an earlier green reading is not masked
ok - stale checks-green status log does not mask CI relapse
ok - ci fixing is not overridden by an earlier green marker
ok - top-level fixing is not overridden by a stale ci running row
ok - top-level fixing is not overridden by a stale done log
ok - terminal passed run is authoritative
ok - terminal passed run with an open PR reads held-for-merge, never merged
ok - terminal passed run with a proven merge record reads PR merged
ok - an identity-mismatched merge record does not prove this PR merged
ok - the attributed run's PR identity outranks a stale task meta PR
ok - a passed run with no PR identity claims no merge and names no URL
ok - terminal failed run is authoritative
ok - orphaned ci monitor after green reads as held-for-merge done
ok - status-only failed orphaned ci monitor after green reads done
ok - genuinely failing CI keeps the failed verdict
ok - a second failed step disqualifies the orphaned-monitor reclassification
ok - cross-branch run is attributed via the real runs list
ok - socket refusal over a coarse active run reports blocked
ok - failed ledger record reads unknown only when the daemon is provably down
ok - cross-branch attribution picks the branch's most recent row
ok - a live run outranks a terminal run bound to the same worktree
ok - runs-list selection prefers a live row over a newer terminal one
ok - an unfetched live sibling outranks a terminal row at the worktree's exact commit
ok - two terminal rows keep the existing newest-first precedence
ok - an unclassifiable status row keeps the ledger's newest-first precedence
ok - a terminal run with no live sibling is unchanged
ok - coarse run does not probe another branch's ci log
ok - another branch's run is ignored, falls back
ok - no run + a busy semantic record reads working, attributed to its source
ok - a converted adapter never reads working from rendered footer text
ok - grok still reads working through its isolated rendered-tail fallback
ok - herdr's native busy verdict reads working with no record present
ok - a herdr CLI that fails to answer reads unknown/unreachable, never gone
ok - an alive endpoint whose scrollback read failed stays working
ok - a husk pane (agent gone) still reads gone for reclaim
ok - a mid-tool-call crew stays working because its record outranks herdr's generation state
ok - an idle record with idle agent_status stays not-busy (no regression for a human-blocked agent)
ok - no run + idle pane uses the status-log verb
ok - no run + idle pane parses keyed status syntax
ok - no run + idle pane on a paused: status reports state: paused with its reason
ok - no run + idle pane honors the configured paused verb
ok - a trailing resolved: event does not corrupt state render (idle stays idle)
ok - dead window ignores stale status log
ok - a tmux that fails to answer reads unknown/unreachable, never gone
ok - closed pane still reports a terminal run-step
ok - closed pane still reports an active run-step
ok - no timeout command uses perl bound
ok - scout skips the run lookup
ok - torn-down worktree is handled gracefully
ok - fm-crew-state remote: alive endpoint falls through to the routed status log
ok - fm-crew-state remote: an idle alive endpoint reads alive, never gone or dead
ok - fm-crew-state remote: an unreachable host reads unknown-remote, never gone or dead
ok - fm-crew-state remote: the remote host's own dead verdict is reported truthfully
ok - missing meta is handled gracefully
ok - crew_is_provably_working absorbs a validating crew found only via the runs-list fallback
ok - crew_is_provably_working still surfaces a genuinely stopped crew (safety property preserved)
ok - usage error exits 2
ok - historical same-branch rewritten head is not attributed as current
ok - active run with valid descendant fix head remains current
ok - local work advanced past run head invalidates attribution
ok - pipeline-owned active run binds without head equality and beats the failed row
ok - a genuinely failed run with no later run is not hidden
ok - coarse scan anchors the unresolvable active row instead of falling to an older one
ok - coarse scan with a mismatched anchor stays unknown and lets the pane answer
ok - the exemption requires branch_sync.state=pipeline_owned
ok - the exemption never applies to a terminal run
ok - missing run head falls back instead of matching by branch
ok - active fix round with an unfetched pipeline head reads working
ok - unanchored unverifiable active row is never attributed
ok - unresolvable terminal row never reads as current
ok - runs-list continuation attribution works when axi answers another branch
all fm-crew-state tests passed

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 - 3 of 4 scenarios driven live against the product
Scenario Result Live Evidence
A mode=no-mistakes worker that commits but opens no pipeline PR is not treated as complete: the generated Definition of done names the pipeline PR as the completion signal and says a commit is not one… ✅ pass live Real bin/fm-brief.sh no-mistakes brief (artifacts/brief-no-mistakes-definition-of-done.txt) states 'Completion for mode=no-mistakes is a PR the no-mistakes pipeline pushed and opened, never a commit.'…
A worker can start the pipeline in its own harness's form: the generated no-mistakes brief carries no hard-coded slash invocation, defers the exact form to harness-adapters, and the promoted-scout del… ✅ pass live brief-surface-checks.txt: 0 occurrences of '/no-mistakes' and 0 unverifiable ownership claims in the generated no-mistakes brief; the harness-agnostic start sentence is present. Real promotion via bin…
Anti-duplication and pipeline-ownership rules reject a second or non-owning worker claiming the same pipeline PR. ⏸️ untested no This repo has no runtime guard that refuses a second or non-owning start; run attribution in bin/fm-nm-run-lib.sh is read-only and the refusal lives in the external no-mistakes CLI, which cannot be ex…
Non-pipeline workers are not regressed: the direct-PR brief still completes on its own opened PR and the local-only brief still completes on the ready branch, and neither receives the no-mistakes cont… ✅ pass live Real bin/fm-brief.sh direct-PR and local-only briefs keep their own signals ('done: PR {url}' and 'done: ready in branch fm/live-local-only') and 'The task is complete only when committed on your bran…
  • FM_HOME=<tmp> ./bin/fm-brief.sh live-no-mistakes some-proj --mode no-mistakes (real generated brief)
  • FM_HOME=<tmp> ./bin/fm-brief.sh live-direct-PR some-proj --mode direct-PR (real generated brief)
  • FM_HOME=<tmp> ./bin/fm-brief.sh live-local-only some-proj --mode local-only (real generated brief)
  • . ./bin/fm-dod-lib.sh && fm_dod_block <mode> <id> for all three modes, diffed against the generated brief DoD
  • FM_HOME=<tmp> FM_STATE_OVERRIDE=<tmp>/state ./bin/fm-promote.sh live-promote-nm --mode no-mistakes --yolo off (real promotion), diffed ship-instructions.md DoD against the brief DoD
  • real bin/fm-crew-state.sh classification drive over three status lines: done: PR https://... checks green, that claim plus head and CI appended, and done: fix committed on branch fm/feat-ci, ready for the run
  • bash tests/fm-brief.test.sh (targeted; drives real bin/fm-brief.sh; new test_no_mistakes_completion_is_a_pr_not_a_commit passed)
  • bash tests/fm-task-delivery.test.sh (drives real bin/fm-promote.sh + bin/fm-brief.sh and compares both DoD blocks)
  • bash tests/fm-crew-state.test.sh (drives real bin/fm-crew-state.sh; ok - ci-ready status log beats monitoring run)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@onyx-space

Copy link
Copy Markdown
Owner Author

CI result for head 5b0b2a9

Not all checks are green. One check has no verdict:

  • Behavior portable parallel 1 — cancelled, no verdict. It was externally cancelled at the job's 10-minute limit on both attempts (first attempt 09:57:28Z→10:07:42Z, rerun 10:23Z→10:33Z). No job failure was reported.
  • Every other check on this head reports pass (Behavior portable parallel 2, Behavior portable serial 1-5, Behavior tests (Herdr), Behavior timing aggregate, Stock macOS Bash snapshot compatibility, Lint, PR must be raised via no-mistakes, Repo invariants, Test coverage guard).

This is a known CI flake tracked separately as fm-ci-behavior-parallel-job-timeout; it is unrelated to this change, and no code change, gate lowering, or check skipping was made for it. The no-mistakes run therefore finished as passed-with-override (a human approved past the cancelled check) rather than checks-passed — this PR is not claiming an all-green CI result.

@onyx-space onyx-space changed the title fix(brief): pin no-mistakes completion to the pipeline PR, not a commit fix(brief): 把 no-mistakes 的完成判据钉到管线产出的 PR,而不是裸提交 Sep 11, 2026
The no-mistakes Definition of done opened by declaring the task complete at
commit time and asking for `done: {summary}`, so workers read a commit as
delivery and stopped without ever running the pipeline; three tasks were
chased for it in one day. The block now opens by naming the pipeline's PR as
the only completion, says outright that a commit, a clean branch, or "ready
for the run" is not completion, makes running the pipeline the worker's own
step, states the first-run doctor/init step, requires the PR URL, head, and
CI result on completion, and keeps the completion claim as the last status
line. direct-PR and local-only keep their own distinct signals.

tests/fm-brief.test.sh pins the new no-mistakes wording, the absent
commit-is-complete sentence, and the mode separation.
@onyx-space
onyx-space force-pushed the fm/fm-brief-bare-done-without-pipeline branch from 5b0b2a9 to 0a8ba27 Compare September 11, 2026 22:09
@onyx-space onyx-space changed the title fix(brief): 把 no-mistakes 的完成判据钉到管线产出的 PR,而不是裸提交 fix(bin): pin no-mistakes delivery completion to the pipeline PR Sep 11, 2026
@onyx-space onyx-space changed the title fix(bin): pin no-mistakes delivery completion to the pipeline PR fix(brief): 把 no-mistakes 的完成判据钉到管线产出的 PR,而不是裸提交 Sep 11, 2026
@onyx-space
onyx-space merged commit acfe093 into main Sep 11, 2026
16 checks passed
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