Repository navigation
ci(OMN-20708): the branch claim check can read the lab node's work-ledger check - #2715
Merged
Merged
Conversation
The reusable workflow gains a claim_source input with values file (default) and work-ledger. With work-ledger, the job reads the check "branch-claim / work-ledger" posted on the pull request head by the GitHub App onexbot-occ-writer (omnimarket's node_branch_claim_check_effect, omnimarket#3547). It opens no database connection and checks out no ledger. The job waits up to 900 seconds (input lab_check_wait_seconds). This change is the earlier draft omniclaude#2608 rebased onto dev. The folded branch-claim-gate.yml no longer exists, so its wiring is now in ci.yml. The caller branch-claim-check.yml names claim_source: file explicitly and gains checks: read. It stays on file until a completed lab check is visible on an omniclaude pull request head; none was visible on omniclaude#2708, #2710, #2711 or #2672 on 2026-10-13. tests/scripts/test_branch_claim_check_workflow.py runs the reader's own Bash with a fake gh and real jq. It no longer skips when jq is missing; it fails. New named cases: ledger_absent_passes, work_ledger_source_runs_no_ledger_step, claimed_elsewhere_refused, branch_claim_check_workflow_is_wired. The test is a named step "Branch-claim check workflow reader (OMN-20708)" of the Branch Claim Gate job in ci.yml, and a check-only pre-commit hook branch-claim-check-workflow. The Branch Claim Gate path filter now names the caller, the test and .pre-commit-config.yaml. contracts/OMN-20708.yaml added with three acceptance criteria and their dod_evidence. 38 tests in the file pass. Not changed: scripts/branch_claim.py, the pre-push hook, required-checks.yaml, branch protection.
jonahgabriel
enabled auto-merge (squash)
October 13, 2026 12:04
Contributor
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Findings
Gate semantics (pilot phase)
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
The CI check "Tests (Split 2/2)" failed on head 822752b at tests/workflows/test_blocking_validation_workflows.py::test_filter_is_the_original_trigger[branch-claim-gate]. The PR widened the Branch Claim Gate path filter in ci.yml with three paths: tests/scripts/test_branch_claim_check_workflow.py, .github/workflows/branch-claim-check.yml, and .pre-commit-config.yaml. This commit adds those three paths to the test's FOLDED_JOBS entry for branch-claim-gate, in the filter's order. The Hostile Reviewer gate blocked on one finding agreed by two voters: that the lab check outcome is spoofable via the check-runs API. This commit adds a comment above the "Read the lab branch-claim check for this head" step in branch-claim-check-reusable.yml stating the trust boundary: GitHub sets a check run's app from the creating token, so only the named App's installation token can publish a run the step accepts; GITHUB_TOKEN publishes as github-actions. The comment also notes jq @uri escapes & = # in the check name. No behaviour change in the workflow. Focused tests: 71 passed in test_blocking_validation_workflows.py (branch-claim/folded selection), 38 passed in test_branch_claim_check_workflow.py.
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.
Summary
Ticket OMN-20708. Repo omniclaude. This PR rebases the earlier draft omniclaude#2608 onto dev and adds the wiring that draft lacked. The reusable workflow .github/workflows/branch-claim-check-reusable.yml gains a claim_source input: file (default, the existing markdown-ledger path, every store step gated on it) or work-ledger.
Behaviour
With work-ledger the job reads the check "branch-claim / work-ledger" posted on the PR head by omnimarket's node_branch_claim_check_effect (omnimarket#3547), which reads omninode_internal.work_ledger_rows on the lab. Only runs from the GitHub App onexbot-occ-writer are trusted; the latest completed one wins. The job waits up to 900 seconds (input lab_check_wait_seconds), polling every 20 seconds. The first summary line must match "branch-claim-outcome: ...". A missing check, a garbled line or a did-not-run outcome fails with "THE CHECK DID NOT RUN" in both modes. held-elsewhere and fence-behind fail only in refuse mode. unidentified warns. held-by-pusher, unclaimed and no-ticket pass. The job opens no database connection and checks out no ledger.
unclaimed stays clean on purpose, as in tests/scripts/test_branch_claim.py::test_unclaimed_is_clean and as the lab node reports it (a success conclusion). The plan unit's wording "refuses an unclaimed branch" is therefore met by the held-elsewhere and fence-behind refusal in refuse mode, not by refusing a ticket with no claim row.
Folded gate: branch-claim-gate.yml no longer exists on dev, so the earlier draft's edit to it is replaced by ci.yml wiring. The Branch Claim Gate job in ci.yml gets a named step "Branch-claim check workflow reader (OMN-20708)" running tests/scripts/test_branch_claim_check_workflow.py. Its path filter now names the caller, the test and .pre-commit-config.yaml. A check-only pre-commit hook branch-claim-check-workflow runs the same file. Branch Claim Gate is not on the CI Summary soft allowlist, so a red there fails the required CI Summary context. The test no longer skips when jq is missing; it fails. contracts/OMN-20708.yaml added with AC1 (no ledger step runs with work-ledger, and an unheld branch passes with no ledger present), AC2 (held-elsewhere and fence-behind refused in refuse mode; an absent, pending, foreign-app, garbled or did-not-run lab check never passes), AC3 (wired).
Not done here
The caller .github/workflows/branch-claim-check.yml names claim_source: file explicitly (and has checks: read). It is not flipped to work-ledger. On 2026-10-13 none of omniclaude#2708, #2710, #2711 or #2672 carried a "branch-claim / work-ledger" check, so flipping now would make every omniclaude PR wait 900 seconds and fail. The flip is the one claim_source line, to be made once a completed lab check from the writer App is visible on an omniclaude PR head. Removing the file path and its inputs is a later change. required-checks.yaml and branch protection are not touched, so the branch-claim-check context is still not a required context; that is for the operator.
Tests
tests/scripts/test_branch_claim_check_workflow.py has 38 passing cases. Named selections: -k ledger_absent_passes, -k work_ledger_source_runs_no_ledger_step, -k claimed_elsewhere_refused, -k branch_claim_check_workflow_is_wired. With the base (dev d6a31b6) versions of branch-claim-check-reusable.yml, branch-claim-check.yml, ci.yml and .pre-commit-config.yaml restored, those four selections give 2 failed and 3 errors; restored to this branch's versions all pass.
Lab: host=h200 lane=omn20708-3d38 sha=822752b04a8b90aa5fc34b858be4f776a60910f2 command=onex_lab_run.py --via bus --repo omniclaude --ref jonah/omn-20708-branch-claim-work-ledger -- uv run pytest tests/scripts/test_branch_claim_check_workflow.py tests/scripts/test_branch_claim.py tests/scripts/test_branch_claim_hook.py tests/test_ci_full_suite_ignores.py tests/ci/test_ci_summary_gate.py -q --no-cov -p no:randomly; work unit lw-6051a454648d4238; observed 300 passed in 20.80s, exit 0.