fix(codeql): recover reruns after missing dispatch verdict - #1902
fix(codeql): recover reruns after missing dispatch verdict#1902seonghobae wants to merge 82 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true📝 WalkthroughWalkthroughCodeQL 재실행은 ChangesCodeQL 디스패치와 정산
Priority: ➖ Normal — Impact reflects medium issue severity. Estimated code review effort: 5 (Critical) | ~120 minutes Severity of issue fixed: Medium Merge Risk: 🟡 Moderate · up to Important receipt-authentication and pagination paths are not independently protected by the changed contract tests. Strengthen those tests before merging to reduce the risk of silently breaking CodeQL settlement. Sequence Diagram(s)sequenceDiagram
participant AnalyzeHead
participant PRAPI
participant StatusAPI
participant Coordinator
participant ScanDispatch
participant Settlement
AnalyzeHead->>PRAPI: live head/base 조회
AnalyzeHead->>StatusAPI: base-bound verdict 조회
Coordinator->>StatusAPI: pending language evidence 조회
Coordinator->>ScanDispatch: pending matrix와 failed job map dispatch
ScanDispatch->>StatusAPI: terminal receipt 게시
Settlement->>StatusAPI: receipt와 direct evidence 검증
Settlement->>ScanDispatch: exact run 또는 failed jobs 재실행
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Exact-head verification sweep for Accordingly the executable test-first regression and minimal source repair remain a development candidate, not hosted GREEN or merge-ready evidence. ADR 0025 is still Proposed and its attempt-one/attempt-two prose must be reconciled before this Draft can advance; do not mark it Accepted merely because the recovery defect is understood. |
|
Non-force restack completed on protected Keep Draft: ADR 0025 still describes the older "attempt one dispatch / attempt two verdict read" sequence and must be made code-current before merge, and this restacked exact head still needs its own full test/coverage/docstring/workflow/security/review evidence. After ordinary protected integration, acceptance remains rerunning unchanged accounting-platform #49 and observing authenticated terminal |
|
Fresh owner-head adoption: protected Keep Draft. This restack does not address the still-stale ADR 0025 and predecessor checks/reviews do not transfer. Require all evidence on |
|
Additional unchanged-head consumer evidence for this owner defect, 2026-09-05:
Owner RED: a consumer can obtain runner assignment and successfully request the exact-head CodeQL scan, yet the compatibility workflow never receives an authenticated terminal GREEN acceptance remains central: after #1902's recovery semantics land on protected |
|
Fresh protected-main sweep found This comment supersedes the PR body's older current-head/base sentence. Exact development head is now |
|
Fresh canonical-owner verification from AIP consumer lane:
The corresponding trusted |
|
/opencode Current owner-path head is Read and adopt the intervening protected-main delta as a normal descendant; do not force-push or destructively rebase. The intervening merged #1943 changes Preserve the evidence-driven recovery contract: After the non-force adoption, run the focused rerun-recovery contracts plus complete central workflow tests/security/coverage/docstring gates on the new exact head, then update the PR body to the new protected-main parent and exact evidence. Keep Draft until those gates and independent review are terminal. |
|
Non-force protected-main adoption completed. New exact head: No force update or destructive rebase was used. Exact-head SAST |
|
Fresh LineageWeave downstream canary for the rerun-recovery contract: |
…scape a line-leading #1939 The 22:20Z paragraph of signature 3 still counted #1902's green job as a noema-review success; it was a draft skip with a 1 s verdict step, as the stage-level tally further down already says. Wrap the line-leading #1939 reference in inline code (MD018). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BV96rXhqoR3tYZ9AeAVur4
|
@coderabbitai review Please review exact head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
head_expected='e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e'
base='efb8926923de45245338159a489a1b227e81945f'
echo '== HEAD and parents =='
git rev-parse HEAD
git show -s --format='%H%nparents: %P%nsubject: %s' "$head_expected"
echo '== Parent ancestry =='
git merge-base --is-ancestor "$base" "$head_expected" && echo "base-is-ancestor=true"
git diff-tree --no-commit-id --name-status -r "$head_expected"
echo '== Changed paths relative to protected main =='
git diff --name-status "$base" "$head_expected"
echo '== Intervening main changes preserved by merge result =='
git diff --name-status "${head_expected}^1" "$base"
echo '== Four target path blob IDs: base vs head =='
for path in \
'.github/workflows/codeql-pr.yml' \
'docs/adr/0025-codeql-pr-rerun-recovery.md' \
'docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md' \
'tests/test_codeql_pr_rerun_recovery_contract.py'
do
printf '%s\n' "$path"
git rev-parse "$base:$path" 2>&1 || true
git rev-parse "$head_expected:$path" 2>&1 || true
done
echo '== Candidate files =='
fd -a 'codeql-pr.yml|0025.*codeql|codeql-rerun-pre-runner|test_codeql_pr_rerun_recovery_contract.py' . \
-E .git -E node_modules -E dist -E build
echo '== Workflow outline / security-sensitive snippets =='
rg -n -C 6 \
'run_attempt|codeql-dispatch|repository_dispatch|id-token|ACTIONS_ID_TOKEN_REQUEST|create-github-app-token|concurrency|verdict|creator|statuses|sha|head_sha|language|pending|fail.closed|dispatch' \
.github/workflows/codeql-pr.yml
echo '== Focused regression and doctoring/ADR =='
cat -n tests/test_codeql_pr_rerun_recovery_contract.py
printf '\n== ADR ==\n'
cat -n docs/adr/0025-codeql-pr-rerun-recovery.md
printf '\n== Doctoring ==\n'
cat -n docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.mdLength of output: 24265 🏁 Script executed: #!/bin/bash
set -euo pipefail
head='e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e'
prior='2d4624a3998baf79944d2a76b2a3367946b0d923'
base='efb8926923de45245338159a489a1b227e81945f'
echo '== Exact owned diff against protected main =='
git diff --find-renames --find-copies --stat "$base" "$head"
git diff --find-renames --find-copies -- .github/workflows/codeql-pr.yml "$base" "$head"
echo '== PR-owned changes relative to prior PR parent =='
git diff --name-status "$prior" "$head"
git diff -- .github/workflows/codeql-pr.yml \
docs/adr/0025-codeql-required-workflow-dispatch-architecture.md \
docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md \
tests/test_codeql_pr_rerun_recovery_contract.py \
"$prior" "$head"
echo '== Merge tree agreement with protected main outside owned paths =='
python3 - <<'PY'
import subprocess
head = 'e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e'
base = 'efb8926923de45245338159a489a1b227e81945f'
owned = {
'.github/workflows/codeql-pr.yml',
'docs/adr/0025-codeql-required-workflow-dispatch-architecture.md',
'docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md',
'tests/test_codeql_pr_rerun_recovery_contract.py',
}
def entries(rev):
raw = subprocess.check_output(['git', 'ls-tree', '-r', '-z', rev])
return {
item.split(b'\t', 1)[1].decode(): item.split(b'\t', 1)[0].decode().split()[2]
for item in raw.split(b'\0') if item
}
h, b = entries(head), entries(base)
unexpected = sorted(
p for p in set(h) | set(b)
if p not in owned and h.get(p) != b.get(p)
)
print('unexpected-path-count=' + str(len(unexpected)))
print('\n'.join(unexpected))
PY
echo '== Corrected ADR and doctoring note =='
cat -n docs/adr/0025-codeql-required-workflow-dispatch-architecture.md
cat -n docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md
echo '== CodeQL handler candidates =='
fd -a -i 'codeql*' .github tests -E .git -E node_modules -E dist -E build
echo '== Handler workflow references =='
rg -n -C 5 'codeql-scan|codeql-dispatch|required_run_id|required_job_id|required_language|repository_dispatch|concurrency|createCommitStatus|statuses' \
.github/workflows testsLength of output: 202709 🏁 Script executed: #!/bin/bash
set -euo pipefail
head='e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e'
prior='2d4624a3998baf79944d2a76b2a3367946b0d923'
base='efb8926923de45245338159a489a1b227e81945f'
echo '== Compact merge and scope verification =='
git show -s --format='head=%H%nparents=%P' "$head"
printf 'merge-base='; git merge-base "$prior" "$base"
printf 'base..head paths:\n'; git diff --name-status "$base" "$head"
python3 - <<'PY'
import subprocess
head='e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e'
base='efb8926923de45245338159a489a1b227e81945f'
owned=frozenset((
'.github/workflows/codeql-pr.yml',
'docs/adr/0025-codeql-required-workflow-dispatch-architecture.md',
'docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md',
'tests/test_codeql_pr_rerun_recovery_contract.py',
))
def tree(ref):
return {line.split('\t',1)[1]:line.split()[2]
for line in subprocess.check_output(['git','ls-tree','-r',ref],text=True).splitlines()}
left,right=tree(head),tree(base)
print('non-owned tree differences:', [p for p in sorted(set(left)|set(right)) if p not in owned and left.get(p)!=right.get(p)])
PY
echo '== Exact workflow delta =='
git diff --unified=30 "$prior" "$head" -- .github/workflows/codeql-pr.yml
echo '== ADR delta =='
git diff --unified=12 "$prior" "$head" -- docs/adr/0025-codeql-required-workflow-dispatch-architecture.md
echo '== CodeQL handler structure =='
cat -n .github/workflows/codeql-scan-dispatch.yml | sed -n '1,460p'
echo '== CodeQL-specific test inventory =='
fd -a -i '*codeql*' tests .github/workflows -E .git | sort
echo '== CodeQL-specific assertions =='
rg -n -C 3 'codeql-scan|codeql-dispatch|required_run_id|required_job_id|required_language|RUN_ATTEMPT|OIDC|concurrency|rerun-failed-jobs|statuses' \
tests/test_code_scanning_required_workflow_contract.py \
tests/test_codeql_pr_rerun_recovery_contract.py \
tests/test_required_workflow_queue_contract.py \
tests/test_scheduler_and_codeql_dispatch_runner_image_contract.pyLength of output: 28847 🏁 Script executed: #!/bin/bash
set -euo pipefail
head='e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e'
base='efb8926923de45245338159a489a1b227e81945f'
echo '== Workflow diff from protected main =='
git diff --unified=25 "$base" "$head" -- .github/workflows/codeql-pr.yml
echo '== ADR diff from protected main =='
git diff --unified=20 "$base" "$head" -- docs/adr/0025-codeql-required-workflow-dispatch-architecture.md
echo '== Recovery test and doctoring additions =='
git diff --unified=8 "$base" "$head" -- \
tests/test_codeql_pr_rerun_recovery_contract.py \
docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md
echo '== Handler status publication and exact rerun tail =='
cat -n .github/workflows/codeql-scan-dispatch.yml | sed -n '407,620p'
echo '== CodeQL tests and targeted contract references =='
fd -a -i '.*codeql.*' tests .github/workflows -E .git | sort
rg -n -C 4 'codeql-scan|codeql-dispatch|required_run_id|required_job_id|required_language|rerun-failed-jobs|RUN_ATTEMPT' \
tests/test_code_scanning_required_workflow_contract.py \
tests/test_codeql_pr_rerun_recovery_contract.py \
tests/test_required_workflow_queue_contract.py \
tests/test_scheduler_and_codeql_dispatch_runner_image_contract.py \
2>/dev/null || trueLength of output: 47536
Finding
The rest of the requested controls remain present after inspection:
I did not execute repository tests in this inspection environment. You are interacting with an AI system. |
|
Current exact handler delta map after the new #2040 P1 review:
All three touch the handler contract and tests; none currently contains the other two complete deltas. Before #1902 producer migration, build a normal non-force descendant that preserves all three and add conflict/dual-representation plus two-language HTTP-403 ordering fixtures. Keep #1902 Draft and preserve every branch until the union is exact-head GREEN; no predecessor check transfer or simple closure. |
|
Orgmetra consumer canary #63 remains exact Fresh owner inventory now observes this PR at |
|
Independent exact-head verification for
The owner dependency is #2040. It has implemented one attempt-level settlement, but current head |
Exact canary — run-wide wake race after successful scan (2026-09-08)Canonical owner live head is
Acceptance belongs here: the sole settlement owner must collect all terminal language results and wake the required run/jobs without per-language concurrent rerun POSTs. A running attempt must not strand another successful language. Bind the settlement to exact repository/PR/head/base/required-run plus the complete failed-job map, and exercise the Actions-success/Python-success overlapping-wake schedule in a RED→GREEN hosted canary. Do not turn HTTP 403 into success without proving that every required language will consume its authenticated terminal receipt. |
|
Current exact-head checkpoint: |
|
Canonical handler contract coordination for current producer head #2040 advanced with RED This producer still builds Required successor repair after #2040 lands: send the full detected settlement matrix matching every exact required job, update RED/GREEN fixtures and ADR/doctoring claims, non-force restack, then regenerate producer → protected-handler → exact required-run evidence. Existing base/head/source/run/job/SARIF checks must remain intact. #1902 correctly remains Draft; no branch mutation or predecessor evidence transfer was performed here. |
|
Canonical handler checkpoint — 2026-09-08
|
|
Owner base correction — 2026-09-08 Canonical handler |
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head review at c8d7caa0d699cec0200815fdfbca8bc0b2f7a4ec: no new source finding in the focused delta. RED 940242dfc80169fcac84286fb17b1f58fa6f5ce3 proves that a mixed terminal/pending attempt previously dispatched only the pending language while retaining both failed job IDs. GREEN c8d7caa0d699cec0200815fdfbca8bc0b2f7a4ec derives rerun_matrix from the complete exact failed-job map and rejects a non-bijective wake envelope before credential acquisition. This preserves receipt-based all-terminal suppression and the production provenance/credential checks. Exact remote tree 9e51d259a832af0f7ea31a4ffc9b792a040f07c9 matches the independently tested local tree: CodeQL workflow contracts 76 passed; full GITHUB_ACTIONS=true python -W error -m pytest -q 3089 passed, 1 skipped, 21 subtests; git diff --check clean. Hosted exact-head Checks and qualifying independent approval remain merge gates.
|
Test-first run-wide wake repair is now published on the canonical branch by an ordinary fast-forward (
The PR remains Draft/Proposed. Fresh hosted Checks, the protected-handler prerequisite chain, and qualifying independent approval are not inherited from |
|
Fresh consumer evidence confirms the just-repaired mixed-language wake contract. On #2002 exact head, required CodeQL run |
|
Dependency handoff from #2040: current #2040 head |
|
Complete successor carryover update: #2040 now contains exact #1902 head This carries #1902's base/head/run/workflow/actor/job/gate/SARIF/artifact/creator-bound producer and recovery contracts into the same successor as the protected handler. The previously proposed head-only compatibility status was rejected; the combined successor publishes only Exact-tree verification on |
|
Fresh downstream reproduction for canonical recovery at current #1902 head
Both exact product heads have all other hosted policy/security/test workflows GREEN, so this is central recovery behavior, not product analysis failure. Acceptance remains: one run-wide settlement owner must consume the complete failed-job map after authenticated terminal receipts publish and rerun the exact required jobs without cross-language wake races, preserving repository/PR/head/live-base/required-run identity. No downstream bypass or blind full rerun. |
|
Canonical handler prerequisite advanced by ordinary child #2040@ |
|
Successor checkpoint — 2026-09-09 Canonical combined owner #2040 advanced by ordinary child |
Root causes
The required
CodeQL PRworkflow treatedrun_attemptas proof that a cancelled pre-runner attempt dispatched. Terminal status and direct fallback paths also lacked complete pagination, exact target/base/run/source/SARIF binding, and unique evidence-complete producer settlement. Review then exposed coupled liveness and authority gaps across attempt-wide base capture, predecessor receipts, App validation, protected-base advances during handler execution, and ambiguous complete producers.Current canonical scope
9f065583b367df7608ec2bb57ba9337f3926f8fea3b3cc17b0cee93877f1f8814f65243349ef92a7main@7fd571dbcdbae6acf29d8f4ee704d7ba6297e4db3c8da485…Scheduler/Strix deltas formerly mixed into this history remain carried by successor #1999 and are not reintroduced. Cross-repository credential authority remains the separate #1929 boundary.
Exact-bound repair
repository_dispatch.client_payloadwithin GitHub's ten-property limit. Exact run34214980549failed after OIDC/App-token success with HTTP 422 because eleven properties were sent. RED310e9e60.../ run34217639402reproduced11 <= 10; the successor groups mode plus exact failed-job identities underrerun_requestwhile the receiver retains legacy compatibility for already queued dispatches.ahead, behind 0, and the old SHA as exact base/merge base; restart the exact required run in whole-attempt mode. Retarget, rewrite, divergence, stale head, malformed compare, or unverifiable ancestry fails closed.actions: read; one non-matrix settlement alone ownsactions: write.ADR-0025, CHANGELOG, doctoring, the product/technical Gap baseline, and executable shell contracts record the decision and failure scenes.
Concurrent and successor delta preservation
The tree preserves the concurrent
7ca416ee…, late-base REDb9245808…, and late-window repair3c8da485…deltas. Draft PR #2039 remains open until hosted equivalence is observed; no predecessor evidence is transferred.Exact-tree verification
3 failed; GREEN:3 passed62 passed in 43.36s3086 passed, 1 skipped, 21 subtests passed in 284.54s100%100%compileall: PASSgit diff --check: cleanactionlint: unavailable; fresh hosted workflow validation remains a merge gateCurrent hosted blocker (exact head)
At
9f065583b367df7608ec2bb57ba9337f3926f8fe, Security, SAST, Python Security, Runtime Quality, OpenCode, Noema, and Strix checks are successful. CodeQL run 34225089444 dispatched successfully but both compatibility shards terminated FAILURE because the protected handler still predates the nested envelope and one-attempt settlement repair. All source review threads are resolved; no qualifying current-head approval exists.Canonical sequence: ordinarily merge the backward-compatible handler-only prerequisite #2040 after its own exact-head gates, then non-force restack this PR and regenerate terminal dispatch/wake evidence.
Admission and prohibitions
The payload-cardinality source repair, receipt-only self-repository fixture, complete direct-evidence pagination assertion, and ADR heading repair are present on this exact tree; fresh hosted GREEN and current review are still required. Draft preserves the valid delta while the protected-consumer prerequisite is incomplete. Fresh exact-head hosted Checks and a qualifying independent review remain merge gates, and no predecessor result is promoted.
No synthetic status, self-approval, auto-merge authorization, administrator bypass, force update, destructive rebase, mutable-branch consumption, predecessor evidence transfer, empty retrigger commit, manual rerun, or allowlist weakening is authorized.
Summary by CodeRabbit
개선 사항
문서