fix(bin): refuse merges without verified green checks (land of upstream #1614) - #48
Merged
Merged
Conversation
kunchenguid#1614) Ports upstream PR kunchenguid#1614 onto this fork's trunk. Nothing here is redesigned: the guard, its refusal wording, the --allow-unverified override, the merge_verification=/merge_verified_head= metadata keys, and the crew-state mapping changes are upstream's as written. Provenance: upstream PR kunchenguid#1614 head commit e3e4b47 its base c8edff3 landed onto 3611e49 (sbracewell64/firstmate main) The two trunks diverged at upstream kunchenguid#1495, so the diff did not apply cleanly. Resolutions, all of them fork-versus-upstream divergence rather than changes to what kunchenguid#1614 does: bin/fm-pr-merge.sh - this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps, which upstream has no equivalent of. The record resolution stays, and verification is placed between it and the recording step, so upstream's property still holds exactly: a head the guard refuses leaves no pr= recorded and no merge poll armed. META is bound to whichever record the task actually has, so the verification metadata write addresses it unchanged. tests/fm-pr-merge.test.sh - upstream's file is the base, with this fork's six released-task cases and their fixtures re-added. Their gh mocks now answer the verification read as well as the forge-view read. test_missing_meta_refuses_before_merge exists on both trunks asserting opposite behavior: upstream refuses a task with no record before any forge lookup, while this fork deliberately rebuilds that record from the pull request itself. The fork's version of the case is kept, because that reconstruction is this trunk's behavior. AGENTS.md, docs/architecture.md, docs/scripts.md - upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting. Verified on this fork: fm-lint.sh clean, fm-doc-audience-check.sh ok, and tests/fm-pr-merge.test.sh (34), tests/fm-crew-state.test.sh (54) and tests/fm-pr-check-security.test.sh (41) all pass. Checked once against the live forge with the merge command mocked: the pre-change path issued a squash merge for a pull request with three failing check runs, and this one refused it, naming the head and the failing count, before arming anything.
This was referenced Aug 6, 2026
Closed
sbracewell64
added a commit
that referenced
this pull request
Aug 9, 2026
kunchenguid#1614) (#48) Ports upstream PR kunchenguid#1614 onto this fork's trunk. Nothing here is redesigned: the guard, its refusal wording, the --allow-unverified override, the merge_verification=/merge_verified_head= metadata keys, and the crew-state mapping changes are upstream's as written. Provenance: upstream PR kunchenguid#1614 head commit e3e4b47 its base c8edff3 landed onto 3611e49 (sbracewell64/firstmate main) The two trunks diverged at upstream kunchenguid#1495, so the diff did not apply cleanly. Resolutions, all of them fork-versus-upstream divergence rather than changes to what kunchenguid#1614 does: bin/fm-pr-merge.sh - this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps, which upstream has no equivalent of. The record resolution stays, and verification is placed between it and the recording step, so upstream's property still holds exactly: a head the guard refuses leaves no pr= recorded and no merge poll armed. META is bound to whichever record the task actually has, so the verification metadata write addresses it unchanged. tests/fm-pr-merge.test.sh - upstream's file is the base, with this fork's six released-task cases and their fixtures re-added. Their gh mocks now answer the verification read as well as the forge-view read. test_missing_meta_refuses_before_merge exists on both trunks asserting opposite behavior: upstream refuses a task with no record before any forge lookup, while this fork deliberately rebuilds that record from the pull request itself. The fork's version of the case is kept, because that reconstruction is this trunk's behavior. AGENTS.md, docs/architecture.md, docs/scripts.md - upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting. Verified on this fork: fm-lint.sh clean, fm-doc-audience-check.sh ok, and tests/fm-pr-merge.test.sh (34), tests/fm-crew-state.test.sh (54) and tests/fm-pr-check-security.test.sh (41) all pass. Checked once against the live forge with the merge command mocked: the pre-change path issued a squash merge for a pull request with three failing check runs, and this one refused it, naming the head and the failing count, before arming anything.
sbracewell64
added a commit
that referenced
this pull request
Aug 9, 2026
Squash-reconcile of the fork trunk (48 commits through ed376cf, fork PRs #8-#48 plus CI mirrors) rebased onto upstream main at 74230fc, resolving 72 conflicted files. The fork trunk carries: the fm-launch-lib.sh one-owner launch refactor, the slot-base/contribution-target task base contract (fm-task-base-lib.sh), the zero-budget model registry, fleet admission control stages 0/1, the wake-outcome ledger, the LoopSpec canonical representation, the research-approved-work corpus scanner, the 70% compaction doctrine, from-firstmate steer markers, the fleet launcher menu and Windows-to-WSL bridge, forge-verified merge gates, and the fleet-view per-argument cap fix. Conflict-resolution decisions a reviewer cannot see from the diff alone: - Where the fork carried an older in-flight import of upstream work (delivery contracts kunchenguid#1563, remote secondmate homes kunchenguid#1576, trace context kunchenguid#995, and every add/add remote-secondmate file), upstream's landed and further-evolved version wins outright; nothing fork-specific lived in those copies (verified blob-by-blob against upstream history). - Upstream's --relaunch lifecycle control plane and the fork's task base contract both survive: base derivation and the brief base-contract guard are gated to fresh spawns (RELAUNCH=0) because a relaunch reuses the recorded worktree and bases, and the trunk may have moved since. - Launch commands stay one-owner in bin/fm-launch-lib.sh: upstream's Muse Code adapter is ported into the library (template arm, model flag, effort mapping with max->ultra) instead of resurrecting the inline fm-spawn template, and fm-spawn's post-template FM_PI_HARNESS prefix is dropped because the library's pi templates carry the marker themselves. - Herdr presentation spaces keep upstream's 0.8.0-floor semantics (config off/on/empty, two-argument fm_backend_herdr_presentation_enabled) across spawn, config inheritance, docs, and tests. - fm-pr-check derives its per-task lock from state/<id>.meta explicitly so upstream's kunchenguid#1568 meta locking coexists with the fork's #34 landing records (fm_meta_lock_path rejects a .landing path). - tests/lib.sh keeps both the fork's identity-verified background-process reaper and upstream's fm_fake_version_tool fixture. - Merged prose follows upstream's X-mode -> Relay rename. Pre-existing on both parents, not introduced here: tests/fm-calm-pi-extension.test.sh fails under system Node 22 (ERR_UNKNOWN_FILE_EXTENSION), verified identical on the base commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sbracewell64
added a commit
that referenced
this pull request
Aug 9, 2026
kunchenguid#1614) (#48) Ports upstream PR kunchenguid#1614 onto this fork's trunk. Nothing here is redesigned: the guard, its refusal wording, the --allow-unverified override, the merge_verification=/merge_verified_head= metadata keys, and the crew-state mapping changes are upstream's as written. Provenance: upstream PR kunchenguid#1614 head commit e3e4b47 its base c8edff3 landed onto 3611e49 (sbracewell64/firstmate main) The two trunks diverged at upstream kunchenguid#1495, so the diff did not apply cleanly. Resolutions, all of them fork-versus-upstream divergence rather than changes to what kunchenguid#1614 does: bin/fm-pr-merge.sh - this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps, which upstream has no equivalent of. The record resolution stays, and verification is placed between it and the recording step, so upstream's property still holds exactly: a head the guard refuses leaves no pr= recorded and no merge poll armed. META is bound to whichever record the task actually has, so the verification metadata write addresses it unchanged. tests/fm-pr-merge.test.sh - upstream's file is the base, with this fork's six released-task cases and their fixtures re-added. Their gh mocks now answer the verification read as well as the forge-view read. test_missing_meta_refuses_before_merge exists on both trunks asserting opposite behavior: upstream refuses a task with no record before any forge lookup, while this fork deliberately rebuilds that record from the pull request itself. The fork's version of the case is kept, because that reconstruction is this trunk's behavior. AGENTS.md, docs/architecture.md, docs/scripts.md - upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting. Verified on this fork: fm-lint.sh clean, fm-doc-audience-check.sh ok, and tests/fm-pr-merge.test.sh (34), tests/fm-crew-state.test.sh (54) and tests/fm-pr-check-security.test.sh (41) all pass. Checked once against the live forge with the merge command mocked: the pre-change path issued a squash merge for a pull request with three failing check runs, and this one refused it, naming the head and the failing count, before arming anything.
sbracewell64
added a commit
that referenced
this pull request
Aug 10, 2026
kunchenguid#1614) (#48) Ports upstream PR kunchenguid#1614 onto this fork's trunk. Nothing here is redesigned: the guard, its refusal wording, the --allow-unverified override, the merge_verification=/merge_verified_head= metadata keys, and the crew-state mapping changes are upstream's as written. Provenance: upstream PR kunchenguid#1614 head commit e3e4b47 its base c8edff3 landed onto 3611e49 (sbracewell64/firstmate main) The two trunks diverged at upstream kunchenguid#1495, so the diff did not apply cleanly. Resolutions, all of them fork-versus-upstream divergence rather than changes to what kunchenguid#1614 does: bin/fm-pr-merge.sh - this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps, which upstream has no equivalent of. The record resolution stays, and verification is placed between it and the recording step, so upstream's property still holds exactly: a head the guard refuses leaves no pr= recorded and no merge poll armed. META is bound to whichever record the task actually has, so the verification metadata write addresses it unchanged. tests/fm-pr-merge.test.sh - upstream's file is the base, with this fork's six released-task cases and their fixtures re-added. Their gh mocks now answer the verification read as well as the forge-view read. test_missing_meta_refuses_before_merge exists on both trunks asserting opposite behavior: upstream refuses a task with no record before any forge lookup, while this fork deliberately rebuilds that record from the pull request itself. The fork's version of the case is kept, because that reconstruction is this trunk's behavior. AGENTS.md, docs/architecture.md, docs/scripts.md - upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting. Verified on this fork: fm-lint.sh clean, fm-doc-audience-check.sh ok, and tests/fm-pr-merge.test.sh (34), tests/fm-crew-state.test.sh (54) and tests/fm-pr-check-security.test.sh (41) all pass. Checked once against the live forge with the merge command mocked: the pre-change path issued a squash merge for a pull request with three failing check runs, and this one refused it, naming the head and the failing count, before arming anything.
sbracewell64
added a commit
that referenced
this pull request
Aug 11, 2026
kunchenguid#1614) (#48) Ports upstream PR kunchenguid#1614 onto this fork's trunk. Nothing here is redesigned: the guard, its refusal wording, the --allow-unverified override, the merge_verification=/merge_verified_head= metadata keys, and the crew-state mapping changes are upstream's as written. Provenance: upstream PR kunchenguid#1614 head commit e3e4b47 its base c8edff3 landed onto 3611e49 (sbracewell64/firstmate main) The two trunks diverged at upstream kunchenguid#1495, so the diff did not apply cleanly. Resolutions, all of them fork-versus-upstream divergence rather than changes to what kunchenguid#1614 does: bin/fm-pr-merge.sh - this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps, which upstream has no equivalent of. The record resolution stays, and verification is placed between it and the recording step, so upstream's property still holds exactly: a head the guard refuses leaves no pr= recorded and no merge poll armed. META is bound to whichever record the task actually has, so the verification metadata write addresses it unchanged. tests/fm-pr-merge.test.sh - upstream's file is the base, with this fork's six released-task cases and their fixtures re-added. Their gh mocks now answer the verification read as well as the forge-view read. test_missing_meta_refuses_before_merge exists on both trunks asserting opposite behavior: upstream refuses a task with no record before any forge lookup, while this fork deliberately rebuilds that record from the pull request itself. The fork's version of the case is kept, because that reconstruction is this trunk's behavior. AGENTS.md, docs/architecture.md, docs/scripts.md - upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting. Verified on this fork: fm-lint.sh clean, fm-doc-audience-check.sh ok, and tests/fm-pr-merge.test.sh (34), tests/fm-crew-state.test.sh (54) and tests/fm-pr-check-security.test.sh (41) all pass. Checked once against the live forge with the merge command mocked: the pre-change path issued a squash merge for a pull request with three failing check runs, and this one refused it, naming the head and the failing count, before arming anything.
sbracewell64
added a commit
that referenced
this pull request
Aug 11, 2026
kunchenguid#1614) (#48) Ports upstream PR kunchenguid#1614 onto this fork's trunk. Nothing here is redesigned: the guard, its refusal wording, the --allow-unverified override, the merge_verification=/merge_verified_head= metadata keys, and the crew-state mapping changes are upstream's as written. Provenance: upstream PR kunchenguid#1614 head commit e3e4b47 its base c8edff3 landed onto 3611e49 (sbracewell64/firstmate main) The two trunks diverged at upstream kunchenguid#1495, so the diff did not apply cleanly. Resolutions, all of them fork-versus-upstream divergence rather than changes to what kunchenguid#1614 does: bin/fm-pr-merge.sh - this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps, which upstream has no equivalent of. The record resolution stays, and verification is placed between it and the recording step, so upstream's property still holds exactly: a head the guard refuses leaves no pr= recorded and no merge poll armed. META is bound to whichever record the task actually has, so the verification metadata write addresses it unchanged. tests/fm-pr-merge.test.sh - upstream's file is the base, with this fork's six released-task cases and their fixtures re-added. Their gh mocks now answer the verification read as well as the forge-view read. test_missing_meta_refuses_before_merge exists on both trunks asserting opposite behavior: upstream refuses a task with no record before any forge lookup, while this fork deliberately rebuilds that record from the pull request itself. The fork's version of the case is kept, because that reconstruction is this trunk's behavior. AGENTS.md, docs/architecture.md, docs/scripts.md - upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting. Verified on this fork: fm-lint.sh clean, fm-doc-audience-check.sh ok, and tests/fm-pr-merge.test.sh (34), tests/fm-crew-state.test.sh (54) and tests/fm-pr-check-security.test.sh (41) all pass. Checked once against the live forge with the merge command mocked: the pre-change path issued a squash merge for a pull request with three failing check runs, and this one refused it, naming the head and the failing count, before arming anything.
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.
Lands upstream PR kunchenguid#1614 onto this fork's trunk.
Provenance
fix(bin): refuse merges without verified green checkse3e4b470fd8eff73ce581160dc94b223032eaad3c8edff36b8466ea0fe547d3abf4b8aa3304899863611e49(sbracewell64/firstmate main)Nothing is redesigned and nothing re-reviewed. The guard, its refusal wording, the
--allow-unverifiedoverride, themerge_verification=/merge_verified_head=metadata keys, and the crew-state mapping changes are upstream's as written.Why it did not apply cleanly
The two trunks diverged at upstream kunchenguid#1495. Every resolution below is fork-versus-upstream divergence, not a change to what kunchenguid#1614 does.
bin/fm-pr-merge.sh— this fork resolves a task's identity through either a live meta or the durable landing record a released task keeps; upstream has no equivalent. The record resolution stays, and verification is placed between it and the recording step, so upstream's property holds exactly: a head the guard refuses leaves nopr=recorded and no merge poll armed.METAis bound to whichever record the task actually has, so the verification metadata write is unchanged.tests/fm-pr-merge.test.sh— upstream's file is the base, with this fork's six released-task cases and fixtures re-added; theirghmocks now answer the verification read as well as the forge-view read.test_missing_meta_refuses_before_merge— exists on both trunks asserting opposite behavior. Upstream refuses a task with no record before any forge lookup; this fork deliberately rebuilds that record from the pull request itself. The fork's version is kept, because that reconstruction is this trunk's behavior.AGENTS.md,docs/architecture.md,docs/scripts.md— upstream's sentences folded into the fork's own text for the landing record, the task base references, and the merge poll's conflict reporting.Verification on this fork
bin/fm-lint.shclean;bin/fm-doc-audience-check.shok.tests/fm-pr-merge.test.sh34 pass,tests/fm-crew-state.test.sh54 pass,tests/fm-pr-check-security.test.sh41 pass.pr merge ... --squashand exited 0; this one refused, naming the head and the failing count, before arming anything.Expected red on this fork:
PR must be raised via no-mistakes(attestation gate, direct-PR delivery per the captain's authorization of 2026-08-04) andBehavior portable serial 2(fails on the fork trunk itself, inherited rather than introduced). No attestation marker is written or implied.Do not merge without the captain's word.