fix(bin): gate no-mistakes done-line check on the line's own URL, not recorded pr= - #7
Merged
Merged
Conversation
Nine ship workers in two days reported done at "committed, gates green"
without ever starting /no-mistakes, including three that carried an explicit
capitalized DEFINITION OF DONE paragraph and still stopped short, so prose
alone cannot close this gap.
- fm-dod-lib.sh: make invoking /no-mistakes the literal next step after the
implementation commit instead of something the worker waits for firstmate
to instruct; there is exactly one done state left (CI green with a PR).
- fm-status-append.sh (new): guarded status-append helper that a
mode=no-mistakes ship brief now routes its status report through; it
refuses a done: line until state/<id>.meta records a validated pr=
(bin/fm-pr-check.sh), printing the required next step instead. Every
other mode, kind, and status verb passes through exactly like a bare
echo.
- fm-crew-state.sh: a mode=no-mistakes ship task with no run ever attributed
and no recorded pr= now reads as parked ("implementation complete,
pipeline not started"), never done, so a heartbeat or absorb read is not
fooled by the same premature done line.
…ed status-append helper
…tus-report command
…art 3 of the intent) reclassifies a mode=no-mistakes/kind=ship child's `done:` status line as `parked` when its meta lacks a validated `pr=`. The pre-existing (untouched by this PR) test `test_nonprogressing_child_states_are_explicit` in tests/fm-bearings-snapshot.test.sh had a "done" child fixture with mode=no-mistakes and no pr=, intended to test unrelated "terminal state despite in-flight backlog" detection. That fixture now correctly reclassifies as parked instead of terminal done, breaking the test's terminal_in_flight assertion (which expected both done and failed to be flagged as terminal). Both failing checks (Behavior portable serial 2, Stock macOS Bash snapshot compatibility) failed for this identical reason - confirmed via CI logs, each showing exactly one failing subtest matching this exact test/assertion. Fix: added `pr=https://github.com/sample/sample/pull/1` to that fixture's done.meta, mirroring the pattern the PR's own new test (test_no_run_no_mistakes_done_with_pr_reports_done) establishes - a validated pr= is what keeps a no-mistakes ship task's done: line genuinely terminal. This preserves the original test's unrelated purpose and assertions while representing a truly-completed child per the new mechanical rule. Verified locally: tests/fm-bearings-snapshot.test.sh now passes 42/42 under both stock macOS /bin/bash 3.2 and default bash (previously failing subtest now passes); tests/fm-crew-state.test.sh passes 76/76; tests/fm-fleet-snapshot-view.test.sh (15/15) and the public-followup bash-3.2 regression (1/1) still pass; bin/fm-lint.sh is clean. Also reproduced the exact CI shard (portable-serial-2of4) locally and confirmed the fix resolves the reported failure (only pre-existing environment-related noise from missing local tooling remained, unrelated to CI which showed failed=1 matching this single issue)
…ot meta
fm-status-append.sh required state/<id>.meta's pr= to already be recorded
before allowing a done: line, but firstmate only writes pr= (via
fm-pr-check.sh) after seeing the worker's own done: PR <url> checks green
report - so the guard could never be satisfied by a legitimate first report
and refused every real completion, including this task's own.
Gate on the line's own content instead: a done: line on a mode=no-mistakes
ship task is accepted only when it names a real http(s) URL, matching the
DOD's one prescribed final-done shape; anything else (including the retired
"done: {summary}" wording) is still refused. Also fixes the pipeline's own
promoted-worker regression test, which built its "URL" with sed-style
backslash-escaped slashes that bash's parameter substitution left as literal
backslash characters rather than a real https:// prefix - it only passed
under the old meta-only check, which never looked at the line's content.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Follow-up fix on top of the done-drift PR: fm-status-append.sh's guard required state/.meta's pr= to already be recorded before allowing a done: line, but firstmate only writes pr= (via fm-pr-check.sh) after seeing the worker's own done: PR checks green report, so the guard could never be satisfied by a legitimate first report and refused every real completion. Gate on the line's own content instead: accept a done: line on a mode=no-mistakes ship task only when it names a real http(s) URL (the DOD's one prescribed final-done shape), refusing everything else including the retired done: {summary} wording. Also fixes the pipeline's own promoted-worker regression test in tests/fm-task-delivery.test.sh, whose sed-style backslash-escaped test URL was left as literal backslash characters by bash parameter substitution rather than a real https:// prefix, so it only passed under the old meta-only check. Update tests/fm-status-append.test.sh to match the corrected behavior and add coverage proving a recorded pr= does not exempt a URL-less done line.
What Changed
bin/fm-status-append.sh, a guarded status-append helper that only refuses adone:line on amode=no-mistakesship task when the line itself names no realhttp(s)://URL (rejecting the retireddone: {summary}wording), instead of requiring apr=that firstmate can't have written yet at that point.bin/fm-dod-lib.shgainsfm_status_report_line/fm_status_report_guard_notehelpers that render the correct status-report command per mode, consumed by bothbin/fm-brief.sh(fresh briefs) andbin/fm-promote.sh(promoted scouts), so a promoted no-mistakes worker gets the same guarded command as a briefed one.bin/fm-crew-state.shreclassifies a no-mistakes ship task's unattributeddone:status line asparked(not terminal done) when no validatedpr=is recorded, prompting a run of/no-mistakesinstead of reporting false completion.tests/fm-task-delivery.test.sh(its test URL was left as literal backslash characters instead of a realhttps://URL, masking a check that only passed under the old meta-only guard); updatetests/fm-bearings-snapshot.test.sh's done fixture and addtests/fm-status-append.test.shplus newtests/fm-crew-state.test.shcoverage proving a recordedpr=does not exempt a URL-less done line.Risk Assessment
✅ Low: The commit correctly fixes the identified bug (gating on meta pr= made the guard unsatisfiable for a legitimate first report), is internally consistent across fm-brief.sh, fm-dod-lib.sh, fm-status-append.sh, fm-promote.sh (via the shared helper), docs, and tests, and the regression test's backslash-escaping bug is genuinely fixed; the only gap found is a minor substring-match looseness with no realistic exploitation path given the guard's purpose (a mechanical backstop against a cooperative LLM worker's known bad phrasings, not an adversarial boundary).
Testing
Both targeted test files (fm-status-append.test.sh and fm-task-delivery.test.sh) pass in full under the target commit, and I independently reproduced the pre-fix bug (a legitimate first done report with a real PR URL was wrongly refused because meta's pr= wasn't recorded yet) and confirmed the fix resolves it end-to-end by running the pre-fix and post-fix versions of fm-status-append.sh side by side against identical inputs; I also reproduced the sed-style backslash-escape defect in the old promoted-worker test and confirmed it would have failed under the new content-based gate, validating that the test correction in this commit is a genuine regression fix rather than a tautological source-grep. No issues found.
Evidence: fm-status-append.test.sh full run (9/9 pass)
Evidence: Repro: pre-fix code refuses a legitimate first done report naming a real PR URL (the exact bug the intent describes)
Evidence: Repro: old test's sed-style backslash-escaped URL produces literal backslashes, which the new content-based gate correctly rejects
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
bin/fm-status-append.sh:54- The gate accepts any done: line containing the bare substring "http://" or "https://" anywhere, with nothing required after it (e.g. "done: http://" or "done: see https:// for context" both pass). This is a looser check than "names a real http(s) URL" as stated in the comment and commit message. In practice this only matters against a cooperative LLM worker deliberately trying to game the exact prescribed DOD wording, not an adversarial input, so the risk is low, but a minimal tightening (e.g. requiring at least one non-whitespace character after the scheme, such as*http[s]://?*) would make the check match its own documented contract exactly.✅ **Test** - passed
✅ No issues found.
bash tests/fm-status-append.test.sh (9/9 pass, including the two new tests test_refuses_the_old_dod_summary_wording and test_recorded_pr_does_not_exempt_a_urlless_done_line)bash tests/fm-task-delivery.test.sh (11/11 pass, including test_promoted worker guarded exactly like a fresh brief's)Manual repro: extracted bin/fm-status-append.sh@23f58af (pre-fix) into /tmp and ran it against a fresh state/<id>.meta with kind=ship, mode=no-mistakes, no pr= - confirmed adone: PR https://github.com/x/y/pull/9 checks greenline was wrongly refused (exit 1)Manual repro: ran the same scenario against bin/fm-status-append.sh@fd34cfe (fixed) - confirmed the same line is now accepted (exit 0) and appended verbatim to the status fileManual repro: reconstructed the old test's bash parameter-substitution replacement string in isolation and showed it yields literal backslash characters ('https:\/\/...'), then fed that malformed string to the new gate and confirmed it is correctly refused - validating why the test needed the unescaped-URL fix✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.