fix(spawn): refuse a stale no-mistakes delivery target before it can push #7
Loading…
Reference in a new issue
No description provided.
Delete branch "fm/wlg-nm-target-defect"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happened
no-mistakesstores a repository push target independent of git remotes, captured at run creation and held in its ownstate.sqlite.wishlist-galore's clone had
originpointing at the GitHub mirror instead of Forgejo. I corrected the clone, its linked worktrees, and the tool's bare mirror, verified all three withgit remote -v, and reported it fixed.It was not fixed. Two pipelines pushed branches and opened a pull request on GitHub afterwards, against the captain's Forgejo-only rule. Then a brand-new run still captured GitHub with every git remote correct — reproducible, not a fluke. The tool's own
eject+initrebuilt the record and fixed it.What this adds
bin/fm-spawn.shnow compares the stored no-mistakes delivery target against the project'soriginbefore spawning a no-mistakes ship task, and refuses on a mismatch rather than warning.Two refusal cases, both fail-closed:
originremote → refuse.state.sqlite, orsqlite3unavailable → refuse before an unverified pipeline can push, rather than assuming the target is fine.The diagnostic names the repair (
no-mistakes doctor, thenno-mistakes init) instead of leaving the operator to work it out.The decision worth understanding
The check deliberately does not rely on
git remote -v. That is precisely the evidence that lied: every remote was correct while the tool still pushed to GitHub. A guard reading only the remotes would have passed the exact situation it exists to catch.tests/fm-spawn-nm-target.test.shreproduces that shape directly — Forgejo origin, GitHub still recorded in the tool's database — and asserts the refusal. That is the case that actually occurred, not a synthetic one.The lesson, recorded rather than just fixed
"I fixed the configuration" and "the system now behaves correctly" are different claims requiring different evidence. A correct setting proves nothing about a process already running against the old one. That gap cost two mirror violations and an hour, and the guard exists so the next person does not repay it.
Scope
Deliberately small — a guard, not a subsystem. No
no-mistakesinternals touched, nostate.sqlitewritten, no daemon restarted; it serves every lane on this machine.Note
Shipped
direct-PRrather than through the full pipeline. My judgement was that a small internal tooling guard does not warrant it — flagged to the captain as a rigor reduction that is theirs to overrule.