Skip to content

fix(OMN-17875): omnibase_core auto-merge arms with the org PAT so dev push workflows fire - #1646

Merged
jonahgabriel merged 1 commit into
devfrom
jonah/omn-17875-OmniNode-ai/omnibase_core-automerge-pat
Sep 4, 2026
Merged

jonahgabriel merged 1 commit into
devfrom
jonah/omn-17875-OmniNode-ai/omnibase_core-automerge-pat

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Closes OMN-17875 (AC4 — the omnibase_core sibling port).

Port of omnibase_infra#3178 (merged 2026-09-04T12:32:53Z, b71159f3e0b1fb59a26c593fa4be2f78118ff51c), which root-caused this defect on the sibling repo. Same change, same rationale, re-measured against this repo's own live data.

Finding — measured here, 2026-09-04T15:20–15:25Z

auto-merge.yml armed gh pr merge --auto with the default workflow token. GitHub completes an armed auto-merge as the identity that armed it, and fires no push event for commits authored by that default token (documented Actions-recursion prevention). Every push-on-dev workflow was therefore skipped on every PR that landed through this job.

Query, over the 30 most recently merged dev PRs (#1613–#1645):

gh api "repos/OmniNode-ai/omnibase_core/actions/runs?head_sha=<full-40-char-oid>&event=push" --jq .total_count
Commit PR Merged by push-event runs
1bd884e57 #1645 app/github-actions 0
5d6da6f50 #1640 app/github-actions 0
dbdb93a2c #1639 app/github-actions 0
38d4ba830 #1638 app/github-actions 0
f338525bf #1635 app/github-actions 0
fc20d0869 #1633 app/github-actions 0
d191ffb22 #1643 jonahgabriel 12
a3c3184e0 #1634 jonahgabriel 14
4edb9e596 #1632 jonahgabriel 12
cccbdbbfe #1628 jonahgabriel 12

Totals over that window: 20 bot merges, all 20 with zero dev-branch push runs; 10 jonahgabriel merges, all 12–14.

Two of the bot merges (31e44e9db #1621, 9b8b5704b #1615) report total_count: 2, but those two runs are Release + Propagate config across downstream repos on head_branch v0.47.1 / v0.47.0 with actor jonahgabriel — tag pushes that happen to share the commit, not dev-branch pushes. Dev-branch suppression is 20 of 20.

Measurement gotcha worth recording: head_sha must be the full 40-char oid. An abbreviated SHA matches nothing and returns a false total_count: 0 — that false zero initially made those two look like clean bot merges. The 12–14 counts on the human merges are the positive control that makes the real zeros evidence of absence rather than a broken query (CLAUDE.md rule 16).

What was skipped

Push-on-dev workflows in this repo: ci.yml, security-scan.yml, cross-repo-validation.yml, precommit-parity-gate.yml, receipt-honesty.yml, omni-standards-compliance.yml, check-db-ownership.yml, check-handshake.yml, check-llm-refs-drift.yml, validator-fsm-handler-drift.yml, validator-no-plugin-daemon-classes.yml, validator-runtime-profiles.yml, plus propagate-config.yml (push, path-filtered, no branch filter).

release.yml is not in the skipped set here: its only push trigger is tags: ['v[0-9]*.[0-9]*.[0-9]*'] with no branches: key, so a dev merge never fires it regardless of merger identity. (This corrects the ticket body's "check its trigger" note for this repo, matching the same correction #3178 made for infra.)

Mechanism, and why not an App token

A GitHub App installation token is not a substitute. The OMN-16373 controlled probe (2026-08-22, branch test/omn16373-suppression-probe-1, since deleted) isolated the identities against a push-triggered marker workflow:

  • CONTROL, ambient jonahgabriel auth: commit fd534b2a → marker workflow FIRED (run 32562988366, event=push, conclusion=success).
  • APP TOKEN, onexbot-occ-writer[bot]: commit 38ffe1f4 on the same branch → marker workflow did NOT fire; zero event=push runs at that head SHA.

omninode_infra/.github/workflows/auto-merge.yml is the precedent — it kept the org PAT for exactly this property (OMN-15769, re-affirmed by OMN-16373) and its dev merges have never suffered this suppression.

Exact changes

.github/workflows/auto-merge.yml (+109/−2):

Step Job Was Now
Resolve PR number and author without checkout pre-check default workflow token unchanged — read-only (gh pr view / gh api reads), creates no commit, so the suppression mechanism cannot apply
Enable auto-merge auto-merge default workflow token secrets.CROSS_REPO_PAT — this is the step that arms the merge
Enqueue armed PR and verify it entered the queue auto-merge default workflow token secrets.CROSS_REPO_PAT — mutates merge state twice: gh pr update-branch pushes a merge commit onto the PR head branch, and enqueuePullRequest hands the merge to a queue

Plus a header comment block carrying the measurements above, the OMN-16373 probe result, and an explicit "do not modernise this back to the default token or an App token" instruction, citing OMN-17875 / OMN-16373.

No new credential is minted. CROSS_REPO_PAT is an existing org secret with visibility: all — readback 2026-09-04T15:19Z, gh api orgs/OmniNode-ai/actions/secrets/CROSS_REPO_PAT → {"name":"CROSS_REPO_PAT","created_at":"2026-03-03T19:03:03Z","visibility":"all"}. This repo already consumes it in ci.yml, release.yml, propagate-config.yml, publish-downstream-pin-bump.yml, cr-thread-gate.yml, cr-thread-gate-caller.yml and dependency-cascade.yml.

No fallback expression was added. A fallback to the default token would restore the defect silently on any run where the PAT is unavailable — precisely the invisible-failure shape this ticket exists to remove.

Precondition verified before porting: gh api repos/OmniNode-ai/omnibase_core --jq .allow_auto_merge → true, squash only, default_branch: dev. So the arming step is live here (not the known-red unconditional---auto defect that affects the repos where auto-merge is disabled).

Enforcement (CLAUDE.md rule 5)

This repo already had a policy test pinning this workflow — tests/unit/validation/test_auto_merge_workflow_shape.py — so rather than adding a second file that could drift from it (infra had none and needed a new one), the 7 new assertions are appended there, keeping one home for auto-merge.yml shape:

  • both mutating steps carry secrets.CROSS_REPO_PAT (parametrized, 2 cases);
  • neither has a fallback to the default token (parametrized, 2 cases);
  • the read-only pre-check resolve step stays on the default token and performs no mutating verb;
  • no App-token mint step is introduced;
  • the header keeps its OMN-17875 / OMN-16373 citations.

Negative control (rule 16 — a passing test is not evidence until it is shown to bite): reverting both tokens produces 4 failed, 13 passed; the fix in place produces 17 passed.

Local verification

  • uv run pytest tests/unit/validation/test_auto_merge_workflow_shape.py -q → 17 passed (10 pre-existing + 7 new)
  • Adjacent policy tests tests/unit/validation/test_validator_github_token_env_reads.py + tests/ci/test_workflow_uses_refs_resolve.py → 31 passed
  • uv run ruff format / uv run ruff check → clean
  • pre-commit full hook set on commit → all passed
  • Governed pre-push impacted-test selector (escalated to full suite) → 1901 passed in 293.63s, [prepush-smart-tests] impacted tests passed; allowing push.

mypy --strict reports 9 errors in the test file, all of them pre-existing on origin/dev (identical count and lines against the unmodified file) and all in the pre-existing helpers, none in the appended block. tests/ is explicitly outside this repo's gated mypy scope — the mypy-type-check hook is files: ^src/omnibase_core/.*\.py$ with exclude: ^(tests/|...). Nothing was suppressed to achieve that.

Expected: this PR's own merge will still fire no push workflows

This PR will be armed and merged by the current, unfixed job — a workflow's pull_request / check_suite run uses the base-branch definition, not the PR's, so the version of auto-merge.yml doing the arming is the one on dev. This merge commit will therefore show 0 push-event runs, exactly like the 20 bot merges tabulated above. That is expected, it is the defect being fixed, and it is not a regression introduced here. Record it as the last suppressed merge on this repo; every merge after it should be non-zero.

First post-merge verification

  1. gh api "repos/OmniNode-ai/omnibase_core/actions/runs?head_sha=<next-merge-sha>&event=push" --jq .total_count → expected non-zero (12–14, matching the human-merge baseline), where the same query on every bot merge before this PR returned 0.
  2. gh api repos/OmniNode-ai/omnibase_core/pulls/<next-pr> --jq .merged_by.login should read jonahgabriel (the PAT owner, a User) rather than github-actions[bot].

Scope

omnibase_core only. No src/ code is touched — this changes CI workflow arming credentials and their policy test. The remaining AC4 siblings (omniclaude — claimed by a peer lane, omnimarket, omnimemory, onex_change_control, omnidash) stay on the ticket. No boot code is touched, so the codex-owned staging boot tickets are unaffected.

Evidence-Ticket: OMN-17875
Evidence-Source: OCC#8211

…push workflows fire

auto-merge.yml armed 'gh pr merge --auto' with the default workflow token.
GitHub completes an armed auto-merge as the identity that armed it, and fires
no push event for commits authored by that default token, so every
push-on-dev workflow was skipped on every PR that landed through this job.

Measured 2026-09-04T15:20-15:25Z over the 30 most recently merged dev PRs
(#1613-#1645), via
  gh api "repos/OmniNode-ai/omnibase_core/actions/runs?head_sha=<full-oid>&event=push" --jq .total_count
all 20 bot merges had 0 dev-branch push runs; all 10 jonahgabriel merges had
12-14. The human counts are the positive control that makes those zeros
evidence of absence rather than a broken query.

Swap the two merge-state-mutating steps to secrets.CROSS_REPO_PAT (existing
org secret, visibility=all, already consumed by seven workflows in this repo).
The read-only pre-check resolve step stays on the default token: it creates no
commit. No fallback expression, which would restore the defect silently.

Port of omnibase_infra#3178.
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Measured note for whoever verifies this after it lands — one field behaves differently here than the doctrine text predicts, and it is not a contradiction of the fix.

This PR was armed by the current, unfixed job on dev (as predicted in the body): Auto-Merge run 33894440462, job Enable Auto-Merge, 16:22:49Z→16:23:00Z, log line auto-merge enabled (squash): at 16:22:56Z — that step runs under the default workflow token on dev today.

But gh pr view 1646 --json autoMergeRequest reports enabledBy: jonahgabriel, is_bot: false, enabledAt: 2026-09-04T16:22:55Z — i.e. GitHub attributes the enablement to the run’s triggering actor, not to the arming credential. The repo-registry note in omni_home/CLAUDE.md says default-token arming makes both enabledBy and mergedBy read github-actions[bot]; that is accurate for mergedBy but not for enabledBy on this repo.

So verify on mergedBy, not enabledBy. mergedBy is the field that actually tracked the suppression in the measurement: all 20 suppressed merges read merged_by.login = app/github-actions, all 10 firing merges read jonahgabriel.

Expected on this PR’s own merge commit, unchanged: merged_by.login = app/github-actions and total_count = 0 push runs — the last suppressed merge on this repo. Every merge after it should read jonahgabriel with 12–14.

Current state: 129 checks pass. The two still pending are CI Summary and OCC Companion Merged Gate (OMN-15214), both waiting on companion OCC#8211, which is blocked by a fleet-wide condition unrelated to this change (see OMN-14445 — the platform-leads review tripwire went from 1 to 2 members at ~15:41Z today and now fails closed on every open OCC PR: 8208, 8209, 8210, 8211, 8212). Auto-merge is armed on both this PR and OCC#8211, so both land as soon as that clears. Nothing here was bypassed.

jonahgabriel pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 4, 2026
…#8211)

* evidence: OCC companion pass 1 for OmniNode-ai/omnibase_core#1646

* evidence: OCC companion self-bind for #8211

---------

Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
@jonahgabriel
jonahgabriel merged commit 334d088 into dev Sep 4, 2026
213 of 215 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-17875-OmniNode-ai/omnibase_core-automerge-pat branch September 4, 2026 17:57
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