Skip to content

fix(codeql): serialize exact dispatch wakeups - #2056

Open
seonghobae wants to merge 6 commits into
fix/codeql-wake-sibling-rerun-racefrom
codex/codeql-atomic-wake-20260909
Open

fix(codeql): serialize exact dispatch wakeups#2056
seonghobae wants to merge 6 commits into
fix/codeql-wake-sibling-rerun-racefrom
codex/codeql-atomic-wake-20260909

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Root cause

Concurrent language shards independently woke failed jobs in one CodeQL required-workflow run. The first wake reactivated the run; a sibling wake then received GitHub HTTP 403 (workflow run already running) and could leave that sibling's failed verdict unchanged.

Change

This PR is stacked on #2051. That predecessor moves wake responsibility after the complete scan matrix and binds terminal evidence to the exact PR, head, base ref, base SHA, and required run. This successor tightens the atomic wake: it requires the supplied job ids to equal the run's complete failed-job set before one rerun-failed-jobs call. A terminal scan failure also reaches the wake so the required check reflects the real failure; cancellation remains excluded because it has no complete evidence.

Exact-head evidence

  • Head: 69ae472562c93cc17674af5e2085a58947d3fab8
  • Base: fix(codeql): coordinate failed-job wake once #2051 558693e0333e48012beea142f739bc634b0674a7
  • Focused workflow contracts: 52 passed in 16.46s
  • Full suite: 3000 passed, 1 skipped, 21 subtests passed in 170.92s
  • actionlint .github/workflows/codeql-pr.yml .github/workflows/codeql-scan-dispatch.yml: passed
  • git diff --check: passed

Verification boundary

repository_dispatch executes the protected default-branch workflow, not this open PR's branch version. Fixture-backed tests prove the branch contract; a fresh default-branch dispatch after protected integration remains required runtime evidence. No manual branch-selected workflow or security bypass was added. Earlier reviews target stale heads and are not current acceptance evidence.

Scope

Nine files relative to #2051: owner workflow, regression contracts, ADR/doctoring/gap baseline, changelog, and reusable agent know-how. No consumer workflow or secret changed.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 80a56d18-0e26-4fea-a367-d6b99399a019

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head product diff. Coverage is a separate gate.

Changed files

  • .github/workflows/codeql-scan-dispatch.yml — GitHub Actions review job
  • AGENTS.md — repository behavior
  • CHANGELOG.md — repository behavior
  • CLAUDE.md — repository behavior
  • docs/doctoring/codeql-dispatch-multi-language-wake-race.md — operator or user guidance
  • tests/test_codeql_scan_dispatch_workflow_contract.py — regression suite

Changed behavior

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: codeql-scan-dispatch.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: codeql-scan-dispatch.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: AGENTS.md"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: AGENTS.md"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: CHANGELOG.md"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: CHANGELOG.md"]
  R3 --> V3["required checks"]
  Evidence --> S4["Repository file: CLAUDE.md"]
  S4 --> I4["repository behavior"]
  I4 --> R4["Review risk: Repository file: CLAUDE.md"]
  R4 --> V4["required checks"]
  Evidence --> S5["Docs: codeql-dispatch-multi-language-wake-race.md"]
  S5 --> I5["operator or user guidance"]
  I5 --> R5["Review risk: Docs: codeql-dispatch-multi-language-wake-race.md"]
  R5 --> V5["docs review"]
  Evidence --> S6["Test: test_codeql_scan_dispatch_workflow_contract.py"]
  S6 --> I6["regression suite"]
  I6 --> R6["Review risk: Test: test_codeql_scan_dispatch_workflow_contract.py"]
  R6 --> V6["targeted test run"]
Loading

Findings

No source-backed product finding is synthesized from the coverage gate. A coverage miss belongs in the status comment.

  • Head SHA: 75ca862da09729361b52183b4345987fc0112911
  • Workflow run: 34323731752
  • Workflow attempt: 1
  • Coverage gate: failure

Review outcome

Coverage is a gate, not the review. This body reviews the changed product files.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: codeql-scan-dispatch.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: codeql-scan-dispatch.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: AGENTS.md"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: AGENTS.md"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: CHANGELOG.md"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: CHANGELOG.md"]
  R3 --> V3["required checks"]
  Evidence --> S4["Repository file: CLAUDE.md"]
  S4 --> I4["repository behavior"]
  I4 --> R4["Review risk: Repository file: CLAUDE.md"]
  R4 --> V4["required checks"]
  Evidence --> S5["Docs: codeql-dispatch-multi-language-wake-race.md"]
  S5 --> I5["operator or user guidance"]
  I5 --> R5["Review risk: Docs: codeql-dispatch-multi-language-wake-race.md"]
  R5 --> V5["docs review"]
  Evidence --> S6["Test: test_codeql_scan_dispatch_workflow_contract.py"]
  S6 --> I6["regression suite"]
  I6 --> R6["Review risk: Test: test_codeql_scan_dispatch_workflow_contract.py"]
  R6 --> V6["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

…deql-atomic-wake-20260909

Signed-off-by: Seongho Bae <me@seonghobae.me>

# Conflicts:
#	.github/workflows/codeql-scan-dispatch.yml
#	AGENTS.md
#	CLAUDE.md
#	tests/test_codeql_scan_dispatch_workflow_contract.py
…om/ContextualWisdomLab/.github into codex/codeql-atomic-wake-20260909

Signed-off-by: Seongho Bae <me@seonghobae.me>

# Conflicts:
#	docs/adr/0025-codeql-required-workflow-dispatch-architecture.md
@seonghobae
seonghobae changed the base branch from main to fix/codeql-wake-sibling-rerun-race September 9, 2026 08:13
@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head visual inspection and review request

  • Head: 78717d74e014039f4db9d6e0a805fb19387b826f
  • Base: fix/codeql-wake-sibling-rerun-race (fix(codeql): coordinate failed-job wake once #2051)
  • Actual browser: Microsoft Edge, 1897×953, GitHub PR conversation, default locale
  • Inspected: stack banner/base branch, 4 commits, 9 changed files, exact-head evidence, verification boundary, and scope
  • Result: headings, long SHA/commands, links, spacing, contrast, wrapping, sidebar, and vertical scrolling rendered without clipping, overlap, horizontal overflow, or unreadable text
  • Boundary: GitHub's “Able to merge” display is not protected-main acceptance; hosted exact-head checks and independent review are still pending.

The existing OpenCode review is stale because it names head 75ca862da09729361b52183b4345987fc0112911.

@cwl-noema-review @opencode-agent review exact head 78717d74e014039f4db9d6e0a805fb19387b826f.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode reviewed the current-head mergeability evidence and changed-file flow before approval, then found merge conflicts on the affected path.

Findings

1. HIGH Merge Conflict Guidance - Resolve the PR branch against the latest base branch

  • Problem: GitHub reports mergeStateStatus DIRTY for this pull request.
  • Root cause: Branch codex/codeql-atomic-wake-20260909 cannot be merged cleanly into fix/codeql-wake-sibling-rerun-race; the changed-file flow below shows which review/runtime path is blocked by the conflict.
  • Fix: Merge or rebase the latest fix/codeql-wake-sibling-rerun-race into codex/codeql-atomic-wake-20260909, resolve conflict markers in the PR branch, rerun the focused checks, and push the same branch.
  • Repair commands:
gh pr checkout 2056 --repo ContextualWisdomLab/.github
git fetch origin fix/codeql-wake-sibling-rerun-race
git merge --no-ff origin/fix/codeql-wake-sibling-rerun-race  # or: git rebase origin/fix/codeql-wake-sibling-rerun-race
git status --short
# resolve files, then git add <resolved-files>
# merge path: git commit
# rebase path: git rebase --continue
git push origin HEAD:codex/codeql-atomic-wake-20260909
# rebase path only: git push --force-with-lease origin HEAD:codex/codeql-atomic-wake-20260909
  • Regression test: Keep OpenCode approval gated on mergeability so model-output failures cannot approve a conflicted PR.

Merge Conflict Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: codeql-scan-dispatch.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: AGENTS.md"]
  S2 --> I2["repository behavior"]
  I2 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V2["required checks"]
  Evidence --> S3["Repository file: CHANGELOG.md"]
  S3 --> I3["repository behavior"]
  I3 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V3["required checks"]
  Evidence --> S4["Repository file: CLAUDE.md"]
  S4 --> I4["repository behavior"]
  I4 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V4["required checks"]
  Evidence --> S5["Docs: 0025-codeql-required-workflow-dispatch-architecture.md (4 files)"]
  S5 --> I5["operator or user guidance"]
  I5 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V5["docs review"]
  Evidence --> S6["Test: test_codeql_scan_dispatch_workflow_contract.py"]
  S6 --> I6["regression suite"]
  I6 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V6["targeted test run"]
Loading
  • Result: REQUEST_CHANGES
  • Reason: mergeStateStatus is DIRTY; mergeable is CONFLICTING.
  • Head SHA: 78717d74e014039f4db9d6e0a805fb19387b826f
  • Workflow run: 34328413232
  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: codeql-scan-dispatch.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: AGENTS.md"]
  S2 --> I2["repository behavior"]
  I2 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V2["required checks"]
  Evidence --> S3["Repository file: CHANGELOG.md"]
  S3 --> I3["repository behavior"]
  I3 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V3["required checks"]
  Evidence --> S4["Repository file: CLAUDE.md"]
  S4 --> I4["repository behavior"]
  I4 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V4["required checks"]
  Evidence --> S5["Docs: 0025-codeql-required-workflow-dispatch-architecture.md (4 files)"]
  S5 --> I5["operator or user guidance"]
  I5 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V5["docs review"]
  Evidence --> S6["Test: test_codeql_scan_dispatch_workflow_contract.py"]
  S6 --> I6["regression suite"]
  I6 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V6["targeted test run"]
Loading

@cwl-noema-review cwl-noema-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noema LLM review

The PR changes the wake condition from needs.scan.result != 'cancelled' to needs.scan.result == 'success' at .github/workflows/codeql-scan-dispatch.yml:522. This narrows the wake trigger so that a skipped, failed, or otherwise non-successful scan matrix will never wake the required workflow, which can leave a failed CodeQL required run unrewoken and therefore block a PR without producing the expected evidence. The failed-job-set comparison also only matches jobs where the bound language passes a strict regex and integer filter, so a legitimately failed CodeQL job whose binding does not satisfy this filter will be rejected and the run will never be rerun. These are concrete behavioral regressions that need tests and narrowed conditions before approval.

Reviewed changed lines

  • .github/workflows/codeql-scan-dispatch.yml:522 (LEFT): Old condition needs.scan.result != 'cancelled' wakes the required workflow even when a scan shard has concluded with success, failure, or skipped states.
  • .github/workflows/codeql-scan-dispatch.yml:522 (RIGHT): New condition needs.scan.result == 'success' suppresses the exact wake when any shard is skipped or failed, which can leave a failed required CodeQL run without its authorized rerun.
  • .github/workflows/codeql-scan-dispatch.yml:599 (RIGHT): select((.language | type) == "string") filters language identity into the expected failed set, but if the authenticated CodeQL binding contains a failed job whose language is not a matching string, the exact-set comparison will reject the run without rerunning.

Adversarial validation

  • .github/workflows/codeql-scan-dispatch.yml:522 (RIGHT) confirmed: The exact wake runs only when the whole scan matrix concludes as success. — Hardcoded condition && needs.scan.result == 'success' at changed line 522 directly gates the wake coordinator.
  • .github/workflows/codeql-scan-dispatch.yml:599 (RIGHT) confirmed: The failed-job-set comparison reruns every failed CodeQL job bound by the production payload. — The right-side jq filter select((.language | type) == "string") and test("^[a-z0-9-]+$") at changed lines 599-600 constrain the expected set.
  • Residual risk: A skipped or canceled scan shard after the matrix completes can now suppress the only authorized wake path, leaving a failed required CodeQL run uncorrected. The failed-job-set identity check can also reject a valid run when any bound job record omits a string language or when an earlier fixtureless GH API response changes pagination shape.

Findings

  • [high] .github/workflows/codeql-scan-dispatch.yml:522 (RIGHT): Changing needs.scan.result != 'cancelled' to needs.scan.result == 'success' suppresses the wake whenever any scan shard completes as failed or skipped. Since the wake coordinator is the only authorization for rerunning a failed required CodeQL job, this can leave a failing PR unrewoken and break the exact-wake contract.
  • [medium] .github/workflows/codeql-scan-dispatch.yml:599 (RIGHT): The expected failed-job identifier set is assembled by selecting only string, lowercase-alphanumeric-hyphen languages and numeric job ids. A valid failed CodeQL binding that does not satisfy these filters will cause the observed/expected set comparison to fail closed without issuing the rerun.
  • Result: REQUEST_CHANGES
  • Head SHA: 78717d74e014039f4db9d6e0a805fb19387b826f
  • Reviewer credential: noema-review-github-app-refresh
  • Actor: cwl-noema-review[bot]

…ce' into HEAD

Signed-off-by: Seongho Bae <me@seonghobae.me>

# Conflicts:
#	docs/doctoring/codeql-partial-shard-wake-duplicate-dispatch.md
#	tests/test_codeql_scan_dispatch_workflow_contract.py
@seonghobae

Copy link
Copy Markdown
Contributor Author

최신 owner base 승계

#2056을 #2051 exact base 558693e0333e48012beea142f739bc634b0674a7에 non-force merge해 current head를 153abe9c753f4821670f79b5a055652b5b2a845d로 갱신했습니다.

  • 보존한 fix(codeql): serialize exact dispatch wakeups #2056 delta: 모든 scan shard 성공 뒤 exact required run의 전체 failed-job 집합을 supplied binding과 정확히 대조하고 rerun-failed-jobs를 한 번만 호출
  • 승계한 fix(codeql): coordinate failed-job wake once #2051 delta: terminal dispatch evidence와 wake를 base ref + base SHA + required run에 결속하고 head-only status는 관측용으로 제한
  • 충돌: doctoring 1곳, contract test 1곳; 두 계약을 함께 보존해 해결
  • GREEN: 관련 52 tests, actionlint, diff check
  • 전체 merge-result: 3000 passed, 1 skipped, 21 subtests (169.82s)

이전 head 78717d74…의 Checks와 리뷰는 current-head acceptance가 아닙니다. 새 hosted Checks와 독립 리뷰를 요청합니다.

@cwl-noema-review @opencode-agent review exact head 153abe9c753f4821670f79b5a055652b5b2a845d

Signed-off-by: Seongho Bae <me@seonghobae.me>
@seonghobae

Copy link
Copy Markdown
Contributor Author

exact-head 재검증

대상 head는 69ae472562c93cc17674af5e2085a58947d3fab8입니다.

  • Noema의 stale-head 지적 중 terminal scan failure가 wake에서 누락되는 경로는 현재 코드에도 유효해 수정했습니다. needs.scan.result != 'cancelled'로 exact success/failure는 required check에 반영하고, 불완전한 cancellation만 제외합니다.
  • language/job 필터 지적은 앞선 canonical payload validation과 CodeQL language allowlist가 보장하는 동일 계약이라 완화하지 않았습니다. malformed binding은 계속 fail closed입니다.
  • 관련 52 tests, actionlint, diff check, 전체 3000 passed, 1 skipped, 21 subtests가 통과했습니다.
  • 실제 Edge 1897×953에서 수정 전 본문의 stale head/test 수치를 발견해 본문을 고친 뒤 재촬영·재검사했습니다. 새 head/base, 긴 SHA/명령, 링크, 정렬, 간격, 대비, 글꼴, 줄바꿈, 잘림, 겹침, 가로 스크롤, sidebar를 확인했고 남은 시각 결함은 없습니다.
  • 최종 캡처: /Users/seonghobae/.codex/visualizations/2026/09/04/01a06aac-7183-7910-aa64-48e0ae87d955/pr-2056-exact-head-69ae4725-1897x953-final.jpg

기존 OpenCode/Noema 리뷰는 78717d74… 대상이라 현재 head 승인 근거가 아닙니다. current-head Checks와 독립 리뷰를 다시 요청합니다.

@cwl-noema-review @opencode-agent review exact head 69ae472562c93cc17674af5e2085a58947d3fab8

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