Skip to content

fix(OMN-20978): several merged change-control companions for one PR resolve to the latest merged - #1956

Merged
jonahgabriel merged 2 commits into
devfrom
jonah/omn-20978-latest-merged-companion
Oct 11, 2026
Merged

jonahgabriel merged 2 commits into
devfrom
jonah/omn-20978-latest-merged-companion

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

OMN-20978

Cause

select_merged_companion (OMN-18338) refused whenever two or more MERGED change-control companions named one product PR, and resolve_evidence_source_from_record turned that refusal into a retryable wait that can never resolve, because merged records do not change. A PR whose head moves after its first companion merged gets a second companion, and from then on occ-preflight / eligibility, the companion-merged gate in CI Summary and the receipt-gate probe all wait to their deadline and fail. Observed on omniclaude#2661 at head 6305f9576: OCC#13596 (bound head ad7cb80, merged 2026-10-10T19:00:36Z) and OCC#13675 (bound head 9aaf535, merged 2026-10-11T14:15:02Z). Because occ-preflight checks this script out at core-ref dev, the defect is live for every repository.

Fix

When several distinct merged companions name the PR, the one merged last into their shared base is cited. The change-control branch is squash-only and linear, so that merge commit has every earlier companion's merge commit as an ancestor. A receipt-gate checkout at it, or the occ-preflight durable tip that contains it, therefore carries every record the earlier companions did, and choosing it cannot hide evidence. The candidate read adds mergedAt,baseRefName to the one gh pr list call it already makes, and the three consumers share the resolver, so no extra API calls are made.

Shapes the rule cannot order still fail closed with an ambiguous detail: a missing, unparseable or timezone-less merge time, candidates merged into different or unreadable bases, and two candidates tied on the latest time. Open, closed-unmerged and other-PR records are excluded before ordering, as before. The result cap of 50 and the unreadable-lookup refusal are unchanged.

Verification

  • RED on dev: the new tests, run against the dev pre-image of the script (git checkout origin/dev -- scripts/ci/check_occ_companion_merged.py), gave 17 failed and 1 passed.
  • GREEN: tests/unit/scripts/ci/test_check_occ_companion_merged.py plus tests/ci/test_companion_side_binding_omn18338.py gave 97 passed. The neighbouring occ-preflight-wait, receipt-gate-shape and contract-compliance binding suites gave 138 passed.
  • ruff format and check clean, mypy --strict clean on the script, and the commit and push pre-commit hooks passed.
  • AC1 (-k multiple_merged) and AC2 (-k other_pr) are covered by the new test class. AC3 (occ-preflight / eligibility passes on omniclaude#2661) is verified by a rerun after this lands on dev.

Lab: not runtime-affecting (CI gate script only, no runtime image or compose input changes), so there is no lab lane to exercise. Instead I replayed the real omniclaude#2661 records through the fixed resolver. Merge times were read from the onex_change_control canonical clone: da751e72 (#13596) at 2026-10-10T19:00:36Z and 211f3f25 (#13675) at 2026-10-11T14:15:02Z. git merge-base --is-ancestor da751e72 211f3f25 exits 0, and the resolver returns OCC#13675.

Unblocks omniclaude#2661, the gh shim commit-object gateway that lets lanes commit change-control receipts again. It also unblocks any other PR that has two merged companions.

Evidence-Ticket: OMN-20978
Evidence-Source: OCC#13693

…esolve to the latest merged

select_merged_companion refused whenever two merged companions named one product PR, so a PR whose head moved after its first companion merged waited on a record that could never change (omniclaude#2661: OCC#13596 and OCC#13675). The companion merged last into the shared base is now cited: the change-control branch is squash-only and linear, so its merge commit carries every earlier companion's records. Missing or unparseable merge times, split bases and tied latest times still fail closed as ambiguous.
@jonahgabriel
jonahgabriel requested a review from a team as a code owner October 11, 2026 19:27
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Oct 11, 2026
…omnibase_core#1956

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 452f11a53c6151c1f151a7e0e8e4786e150c56e8.
@jonahgabriel
jonahgabriel enabled auto-merge (squash) October 11, 2026 19:28
jonahgabriel pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Oct 11, 2026
…base_core (#13693)

* evidence(OMN-20978, OMN-20940): author OCC companion for OmniNode-ai/omnibase_core#1956

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 452f11a53c6151c1f151a7e0e8e4786e150c56e8.

* evidence(OMN-20978, OMN-20940): self-bind OCC#13693 + rebind contract_sha256

---------

Co-authored-by: omnimarket-bot <bot@omninode.ai>
…idence / dod-verify verifies it

Cause: repo-evidence / dod-verify refused on head 452f11a with 'pull request
cites OMN-20978 but carries no contracts/OMN-20978.yaml'; the OCC path
admitted, so the shadow comparison failed as unclassified_difference and
CI Summary failed closed on that L4 external context.

Fix: the in-repo contract binds AC1 (-k multiple_merged), AC2 (-k other_pr)
and AC3 (the gate passes on the latest of two merged companions, the
omniclaude#2661 shape) to this PR's own tests. node_dod_verify reports all
three verified at the head tree and all three failed at the merge base
60ce70d.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant