Skip to content

fix(bin): refuse merges without verified green checks (land of upstream #1614) - #48

Merged
sbracewell64 merged 1 commit into
mainfrom
fm/merge-path-verifies-no-ci-green
Aug 6, 2026
Merged

fix(bin): refuse merges without verified green checks (land of upstream #1614)#48
sbracewell64 merged 1 commit into
mainfrom
fm/merge-path-verifies-no-ci-green

Conversation

@sbracewell64

Copy link
Copy Markdown
Owner

Lands upstream PR kunchenguid#1614 onto this fork's trunk.

Provenance

Upstream PR kunchenguid/firstmate#1614fix(bin): refuse merges without verified green checks
Exact commit ported e3e4b470fd8eff73ce581160dc94b223032eaad3
Its base upstream c8edff36b8466ea0fe547d3abf4b8aa330489986
Landed onto 3611e49 (sbracewell64/firstmate main)

Nothing is redesigned and nothing re-reviewed. 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.

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 no pr= recorded and no merge poll armed. META is 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; 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; 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.sh clean; bin/fm-doc-audience-check.sh ok.
  • tests/fm-pr-merge.test.sh 34 pass, tests/fm-crew-state.test.sh 54 pass, tests/fm-pr-check-security.test.sh 41 pass.
  • Checked once against the live forge with the merge command mocked, on a pull request with three genuinely failing check runs: the pre-change path issued pr merge ... --squash and 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) and Behavior 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.

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.
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