Skip to content

task: the close-evidence line named the wrong evidence (DIVE-2184)#249

Open
lodar wants to merge 1 commit into
mainfrom
dive-2184-close-evidence-message
Open

task: the close-evidence line named the wrong evidence (DIVE-2184)#249
lodar wants to merge 1 commit into
mainfrom
dive-2184-close-evidence-message

Conversation

@lodar

@lodar lodar commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

The merge gate's accepting branch claims ancestry and a delegated push. Both are false for a squash-merged PR — and DIVE-2102 closed exactly that way (PR #248dfd3d306, head 62e1a83 not an ancestor of main).

Both predictions about this were wrong, which is why the mechanism was measured before touching it. I predicted the gate cannot be satisfied by a squash-merge (blocking). olivia predicted it passes when it should block (permissive). Neither: it accepted for a correct reason and described it falsely. The accepting variable is set by _gate_branch_ident_on_main (attribution — a commit on main whose SUBJECT names the ident, DIVE-2120); _gate_branch_ancestry was demoted and accepts nothing.

Measured rather than inferred: removing the attribution stub from the suite's own ancestor scenario makes the gate refuse (rc=5) with the ancestry stub still set.

The new message states what was measured and claims neither route, because attribution cannot distinguish a delegated push from a squash-merged PR — a squash rewrites the sha, so both look identical to a subject scan.

The test was asserting the message, not the mechanism. The pre-existing arm set both an ancestry stub and an attribution stub, then asserted *ANCESTOR* appeared — green because the message lied. That is how the wording survived DIVE-2120. Corrected, plus an arm that fails if the ancestry claim returns.

31/0 on the ancestry suite. task_deliver_merge_gate_unit's 2 reds are pre-existing (identical on pristine origin/main; DIVE-2114).

🤖 Generated with Claude Code

The merge gate's accepting branch prints "branch X is an ANCESTOR of main — its
commits are all on main (no PR needed; delegated push, DIVE-2101)". Both halves
are false for a squash-merged PR, and DIVE-2102 closed exactly that way: PR #248
squashed to dfd3d30, and its head 62e1a83 is not an ancestor of main at all.

BOTH PREDICTIONS ABOUT THIS WERE WRONG, which is why the mechanism was worth
measuring before touching it. I predicted the gate CANNOT be satisfied by a
squash-merge (blocking). olivia predicted it passes when it should block
(permissive). Neither: the gate accepted for a CORRECT reason and DESCRIBED it
falsely. The variable feeding that branch is set by _gate_branch_ident_on_main —
attribution, a commit on main whose SUBJECT names the ident (DIVE-2120) — while
_gate_branch_ancestry was demoted and now accepts nothing.

Measured, not inferred: removing the attribution stub from the suite's own
ancestor scenario makes the gate REFUSE (rc=5, "NO commit reachable from it
names ANC-1"), with the ancestry stub still set. Ancestry accepts nothing alone.

So the fix is the message and the fossil variable name (_banc, from when ancestry
WAS the criterion). The new text states what was measured and claims neither
route, because attribution genuinely cannot tell a delegated push from a
squash-merged PR — a squash rewrites the sha, so both look identical to a subject
scan. The comment directly above the warn already demanded it "say WHICH evidence
closed it"; it named the wrong one.

AND THE TEST WAS ASSERTING THE MESSAGE, NOT THE MECHANISM. The pre-existing arm
set BOTH an ancestry stub and an attribution stub, then asserted *ANCESTOR*
appeared in the output — so it was green precisely because the message lied. That
is how the wording survived the DIVE-2120 semantics change. Corrected to assert
the evidence that actually accepts, plus an arm that fails if the ancestry claim
returns.

One of my own new arms was wrong the same way and caught by its own run: it
grepped the bare words "delegated push", which fire on the corrected text's
DISCLAIMER ("a delegated push and a squash-merged PR are indistinguishable").
Now matches the claim string, not the words.

31/0 on the ancestry suite. task_deliver_merge_gate_unit's 2 reds are
pre-existing (identical on pristine origin/main; DIVE-2114).
@lodar

lodar commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Second instance, caught live 20 minutes after this PR opened — and it is stronger evidence than the DIVE-2102 case this PR was written from, because here the branch does not exist at all.

Closing DIVE-1925 just now emitted:

warn: DIVE-1925: branch 'dive-1925-zero-downtime-deploy' is an ANCESTOR of main in
lodar/5dive-api — its commits are all on main (no PR needed; delegated push, DIVE-2101).
done=merged-to-main satisfied.

Every load-bearing clause is false:

  • "is an ANCESTOR of main" — it closed on attribution. The squash commit is 53121d81, subject DIVE-1925: zero-downtime API deploys via systemd socket activation (#32).
  • "no PR needed" — it landed via PR cli: token-burn audit — heartbeat fresh-default off + haiku Explore (DIVE-1210) #32, which the subject literally names.
  • "delegated push" — nobody pushed to main; it was a squash merge.
  • "branch '...' is"--delete-branch removed it on merge. The message asserts a present-tense property of a ref that no longer exists.

That last one matters for the fix: the message names the branch as the subject of the claim, and the branch is exactly the thing attribution deliberately stopped depending on (DIVE-2120 moved the search to main precisely because a merged-and-deleted branch was byte-identical to one that never existed). So the wording is a leftover from the mechanism that was replaced.

This is also a different repo (lodar/5dive-api, not 5dive-ai/5dive), so it is not specific to one project's merge style — it is every squash-merged PR in every repo we close against.

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