Skip to content

fix(codeql): recover reruns after missing dispatch verdict - #1902

Open
seonghobae wants to merge 55 commits into
mainfrom
fix/codeql-rerun-missing-verdict-redispatch
Open

fix(codeql): recover reruns after missing dispatch verdict#1902
seonghobae wants to merge 55 commits into
mainfrom
fix/codeql-rerun-missing-verdict-redispatch

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Root causes

The required CodeQL PR workflow treated run_attempt as proof that an earlier attempt dispatched. That is false after pre-runner cancellation. Terminal statuses and fallback receipts also lacked complete pagination, current target/base/run/source binding, unique evidence-complete producer selection, and preserved-SARIF proof. Later review exposed interacting liveness failures: independently scheduled matrix shards could adopt different live base SHAs; run-wide settlement could not combine an authenticated predecessor receipt with current direct evidence; and a protected-base advance after attempt capture had no automated recovery path.

Current canonical scope

  • exact head: ebf054e67f7dbeb7c9b8d0f90e2bc1c151471a2b
  • exact tree: 03a9ebd2ffc3504e52028499402b703394b5430e
  • protected base: main@7fd571dbcdbae6acf29d8f4ee704d7ba6297e4db
  • ancestry: ordinary non-force child of concurrent gate-proof head 7ca416ee…
  • lifecycle: Ready is review admission only; hosted GREEN and qualifying independent review remain merge gates, not Ready prerequisites

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

  • Read complete paginated status, producer-run, job, and artifact evidence.
  • Validate every matching producer candidate through exact run/workflow/source/title/actor/language/gate/SARIF/artifact evidence before requiring exactly one evidence-complete result.
  • Bind dispatch payload, handler title, receipts, and direct evidence to target repository, PR, live head, attempt base ref/SHA, required run, and immutable producer workflow source.
  • Capture one validated live base SHA before matrix expansion. Shards consume that immutable attempt snapshot and fail closed if it becomes stale.
  • When the coordinator proves the same base ref has advanced, bind a new attempt to the freshly validated base, emit rerun_mode=all, require the complete terminal matrix map, and request the exact required run's whole-run rerun endpoint. Unchanged-base recovery remains failed-job-only.
  • Re-authenticate predecessor receipts through exact run metadata, immutable source ancestry, terminal language result, exactly one state-consistent SARIF gate step, successful SARIF preservation, and an unexpired exact-attempt artifact. The shard and coordinator receipt consumers enforce the same boundary.
  • Treat target base A, producer source S, and handler runtime T as separate identities. Admit only T == S or immutable compare evidence that S is the merge-base ancestor of newer T.
  • Admit known App identities and the narrow self-repository github-actions[bot] fallback only through the same exact evidence boundary.
  • Keep matrix scans at actions: read; one non-matrix settlement job alone owns actions: write.
  • Preserve all exact failed compatibility jobs for settlement while scanning only languages without an authenticated verdict.
  • Require successful SARIF preservation before terminal publication or settlement; when status POST is forbidden, allow only fully authenticated current-run scan and unexpired-artifact evidence.

ADR-0025, doctoring, CHANGELOG, the product/technical Gap baseline, and executable shell contracts record the problem, constraints, rejected alternatives, evidence, failure scenes, effects, and follow-up.

Concurrent and successor delta preservation

The current tree preserves the concurrent 7ca416ee… predecessor gate-proof delta and extends its state-consistency contract to every receipt consumer. Draft PR #2039 remains open until hosted equivalence is observed; no predecessor evidence is transferred.

Exact-tree verification

RED reproduced 13 base-recovery/rerun-mode/gate-proof failures; an additional coordinator gate-mismatch RED was then added and repaired.

  • exact-head two-workflow focused contracts: 129 passed in 107.53s
  • full repository: 3079 passed, 1 skipped, 21 subtests passed in 308.37s
  • statement coverage: 13194/13194; branch coverage: 5330/5330; total 100%
  • public-doc coverage: 100%
  • python -m compileall -q scripts tests: PASS
  • git diff --check: clean
  • local actionlint: unavailable; fresh hosted validation remains a merge gate

Admission and prohibitions

The current source finding about post-capture base advance is repaired on exact head ebf054e67f7dbeb7c9b8d0f90e2bc1c151471a2b. If fresh head/base/review inspection shows no new substantive source finding, Ready may be restored solely to admit independent review. Pending hosted Checks and qualifying independent review remain later merge gates and are not approval or completion.

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.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: f5a88e4e-17a9-4b1c-ba3a-724b56063112

📥 Commits

Reviewing files that changed from the base of the PR and between 8c4fd55 and ebf054e.

📒 Files selected for processing (12)
  • .github/workflows/codeql-pr.yml
  • .github/workflows/codeql-scan-dispatch.yml
  • CHANGELOG.md
  • docs/adr/0025-codeql-required-workflow-dispatch-architecture.md
  • docs/doctoring/codeql-live-base-terminal-boundary.md
  • docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md
  • docs/doctoring/codeql-sarif-publication-boundary.md
  • docs/product-technical-gap-baseline.md
  • tests/test_codeql_pr_rerun_recovery_contract.py
  • tests/test_codeql_pr_workflow_contract.py
  • tests/test_codeql_scan_dispatch_workflow_contract.py
  • tests/test_scheduler_and_codeql_dispatch_runner_image_contract.py
📝 Walkthrough

Walkthrough

CodeQL 재실행은 run_attempt 대신 인증된 terminal verdict와 live PR 신원을 사용합니다. 상태 조회는 모든 페이지를 확인합니다. 중앙 dispatch는 SARIF 보존이 성공한 경우에만 terminal 상태를 게시하고 required job을 재실행합니다.

Changes

CodeQL 재실행 복구

Layer / File(s) Summary
Live PR 신원 검증과 전체 상태 조회
.github/workflows/codeql-pr.yml, tests/test_codeql_pr_workflow_contract.py
dispatch 단계가 live PR의 base 저장소, ref, SHA를 이벤트 값과 비교합니다. 커밋 상태 조회는 --paginate --slurp로 전체 페이지를 읽습니다. 잘못된 base와 두 번째 페이지의 verdict를 테스트합니다.
증거 기반 재디스패치 계약
docs/adr/0025-codeql-required-workflow-dispatch-architecture.md, docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md, docs/doctoring/codeql-live-base-terminal-boundary.md, tests/test_codeql_pr_rerun_recovery_contract.py
run_attempt 검사를 제거하고 인증된 terminal verdict가 없을 때 정확한 PR, head, job, language 샤드를 재디스패치합니다. verdict=pending, payload, 상태 페이지네이션을 회귀 테스트로 검증합니다.

SARIF 게시 경계

Layer / File(s) Summary
SARIF 보존 후 terminal 상태 게시
.github/workflows/codeql-scan-dispatch.yml, docs/doctoring/codeql-sarif-publication-boundary.md, tests/test_codeql_scan_dispatch_workflow_contract.py
SARIF 업로드 단계에 sarif_upload id와 if-no-files-found: error를 추가합니다. 업로드 outcome이 success가 아니면 terminal 상태 게시와 exact-job wake-up을 중단합니다. 성공, 실패, 건너뜀, 취소 결과를 테스트합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟡 Moderate · up to 8c4fd

A stale same-head CodeQL verdict could be reused after the PR base changes, potentially completing the required workflow without a verdict for the current scan context. Resolve the status provenance gap before merge.

Sequence Diagram(s)

sequenceDiagram
  participant AnalyzeHead
  participant GitHubPRAPI
  participant GitHubStatusesAPI
  participant CodeQLScanDispatch
  participant SARIFArtifactStore
  AnalyzeHead->>GitHubPRAPI: live PR base와 head 조회
  AnalyzeHead->>GitHubStatusesAPI: 전체 commit statuses 조회
  GitHubStatusesAPI-->>AnalyzeHead: terminal verdict 또는 없음
  AnalyzeHead->>CodeQLScanDispatch: verdict가 없으면 CodeQL 샤드 디스패치
  CodeQLScanDispatch->>SARIFArtifactStore: SARIF evidence 업로드
  SARIFArtifactStore-->>CodeQLScanDispatch: sarif_upload outcome 반환
  CodeQLScanDispatch->>GitHubStatusesAPI: 성공한 경우에만 terminal 상태 게시
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 92.31% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 3 files. (6 skipped: 6 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 CodeQL 디스패치 verdict 누락 후 재실행을 복구하는 핵심 변경을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/codeql-rerun-missing-verdict-redispatch

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.

Copy link
Copy Markdown
Contributor Author

Exact-head verification sweep for e47de34288fba93b990a39031503c3e59caeb680: Python Security 33953038123, SAST Semgrep 33953038106, CodeQL PR 33953038159, and Security Scan 33953038143 are all still queued. CodeQL detect job 101271230246 has not executed yet. There are no submitted reviews and no review threads. Protected .github/main remains 6d7fbebec8aec31d88a30a36e71ca5b3925d241d, so no intervening base delta has been adopted yet.

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.

Copy link
Copy Markdown
Contributor Author

Non-force restack completed on protected main@71dd84d40576281a6218f622d685d13c6b2f5e7b as merge descendant db15e4c516e3eedc6fe41ed5a298857529f0aac0. The intervening main commit #1883 changed admission-controller/audit/scheduler code and tests only; #1902 changes only codeql-pr.yml, its focused rerun regression, and its doctoring trace, so the combined tree preserves both deltas without destructive rebase or force-push. Live PR metadata now reports mergeable=true.

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 codeql-dispatch/actions and codeql-dispatch/python verdicts.

Copy link
Copy Markdown
Contributor Author

Fresh owner-head adoption: protected main advanced again to 27d7331cc4e0ae73f2d10122e9f2a8f437c90641 via #1907 after the previous restack. That intervening delta is AGENTS/CLAUDE verification guidance and does not overlap #1902's CodeQL workflow/test/doctoring files. I adopted it with another normal two-parent descendant, 96919601105239c0b035534bbe8961563d113f42, preserving the #1902 blobs exactly and updating the branch with force=false.

Keep Draft. This restack does not address the still-stale ADR 0025 and predecessor checks/reviews do not transfer. Require all evidence on 9691960... before any merge.

Copy link
Copy Markdown
Contributor Author

Additional unchanged-head consumer evidence for this owner defect, 2026-09-05:

ContextualWisdomLab/codec-carver#520@08d1c3ca20e3e41a703ac9e5c5aea6f702962d2d has CI 33905349122, fuzz 33905349153, Security Scan 33905349127, and SAST 33905348978 terminal success, but required CodeQL PR 33905348976 failed solely in both compatibility jobs after successful current-head dispatch requests. Python job 101188835268 and actions job 101188835300 each reached Fail closed without a current-head CodeQL dispatch verdict and then waited roughly three hours before failing. Detect job 101128928869 was successful and checked out the exact target head. This is not a codec-carver source/test failure.

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 codeql-dispatch/<language> verdict within its observation horizon and fails closed.

GREEN acceptance remains central: after #1902's recovery semantics land on protected .github, rerun this unchanged codec-carver head and require authenticated terminal codeql-dispatch/python and codeql-dispatch/actions verdicts bound to 08d1c3ca..., without leaf no-op commits, synthetic status, timeout widening as a substitute for missing dispatch authority, or gate weakening. Consumer #520 stays Draft.

Copy link
Copy Markdown
Contributor Author

Fresh protected-main sweep found main@f2f91b806122ed233e3a0e2a325246077c2e15e4, 14 protected-main commits ahead of the prior merge-base and no path overlap with this PR's four-file delta. I adopted that intervening tree through normal two-parent descendant 059933143561513039cabbf911460e1056dbba7a (parents: prior PR head 510e3378f2fc30129debc776f4a187474f5ff6fa + protected main@f2f91b806122ed233e3a0e2a325246077c2e15e4), with no force push, destructive rebase, or delta loss. Fresh compare is ahead 8 / behind 0 and still changes only .github/workflows/codeql-pr.yml, ADR 0025, the recovery doctoring note, and tests/test_codeql_pr_rerun_recovery_contract.py.

This comment supersedes the PR body's older current-head/base sentence. Exact development head is now 059933143561513039cabbf911460e1056dbba7a on protected main@f2f91b806122ed233e3a0e2a325246077c2e15e4. Fresh exact-head Security Scan 33982957907, Python Security 33982957915, CodeQL PR 33982957904, and SAST Semgrep 33982957893 are queued; reviews=0 and review threads=0. Keep Draft and do not merge until one unchanged head has terminal required gates and qualifying independent approval.

Copy link
Copy Markdown
Contributor Author

Fresh canonical-owner verification from AIP consumer lane:

CodeQL PR run 33982957904 on exact head 059933143561513039cabbf911460e1056dbba7a is now terminal failure, but the observed step sequence matches the intended pending-dispatch protocol rather than the old run_attempt != 1 defect. Detect job 101351344454 succeeded. Both actions job 101361129333 and python job 101361129362 successfully executed Request current-head CodeQL scan dispatch and then intentionally failed Release runner or enforce current-head CodeQL verdict while no terminal verdict existed.

The corresponding trusted opencode-agent[bot] repository-dispatch runs exist for the same exact PR/head: 33990372949 (created 20:31:37Z) and 33990538096 (created 20:34:56Z). Both are currently queued. Therefore do not repair this by weakening the pending failure or synthesizing a status. Acceptance remains: each queued dispatch must run on canonical main, publish authenticated terminal codeql-dispatch/<language> for exact head/job identity, and rerun only the exact failed shard. If those dispatches later terminate without publishing/rerunning, that is the next causal owner-path finding.

Copy link
Copy Markdown
Contributor Author

/opencode

Current owner-path head is 059933143561513039cabbf911460e1056dbba7a, but protected main has advanced to d9eb9f79b6ce66c1225c26be385ae814d87d9aca. Compare is diverged: this PR is ahead 8 / behind 1 from merge base f2f91b806122ed233e3a0e2a325246077c2e15e4.

Read and adopt the intervening protected-main delta as a normal descendant; do not force-push or destructively rebase. The intervening merged #1943 changes CHANGELOG.md, scripts/ci/contextual_orchestrator_review_launcher.py, and tests/test_contextual_orchestrator_review_runtime_preflight.py. This PR's own delta remains .github/workflows/codeql-pr.yml, ADR 0025, the rerun-recovery doctoring note, and tests/test_codeql_pr_rerun_recovery_contract.py. Inspect the actual files and resolve any real overlap rather than assuming a race.

Preserve the evidence-driven recovery contract: run_attempt is metadata, not a dispatch receipt; when an exact-head shard has no authenticated terminal verdict, bounded redispatch remains allowed and the shard stays pending until the trusted central handler posts its verdict. Do not synthesize success, weaken required checks, substitute a provider, or add a leaf workaround.

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.

Copy link
Copy Markdown
Contributor Author

Non-force protected-main adoption completed.

New exact head: 2d4624a3998baf79944d2a76b2a3367946b0d923 with parents 059933143561513039cabbf911460e1056dbba7a and protected main@d9eb9f79b6ce66c1225c26be385ae814d87d9aca. The result tree was built from the protected-main tree plus the exact four blobs owned by this PR, so the intervening #1943 sidecar/CHANGELOG/runtime-preflight changes are retained. Fresh compare from protected main is ahead 9 / behind 0 and the net PR delta is still only .github/workflows/codeql-pr.yml, ADR 0025, docs/doctoring/codeql-rerun-pre-runner-cancellation-recovery.md, and tests/test_codeql_pr_rerun_recovery_contract.py.

No force update or destructive rebase was used. Exact-head SAST 33994885321, CodeQL PR 33994885323, Python Security 33994885341, and Security Scan 33994885405 are queued, so this descendant is not GREEN and the PR remains Draft. The previous 059933… workflow results are predecessor evidence only.

Copy link
Copy Markdown
Contributor Author

Fresh LineageWeave downstream canary for the rerun-recovery contract: ContextualWisdomLab/LineageWeave#914@61ed3a3712d252e3c179a71d297c52f05e1bac20, required CodeQL run 33979627116. Attempt 1 detected languages successfully; python job 101357239026 (and the javascript-typescript/actions siblings) revalidated the live exact head, found no authenticated codeql-dispatch/<language> terminal status, obtained OIDC/app token, POSTed the codeql-scan repository_dispatch successfully, wrote verdict=pending, then intentionally failed to release the runner. Current exact-head commit statuses still contain no codeql-dispatch/python, /javascript-typescript, or /actions terminal verdict. Tests 33979633195, Security 33979627218, and SAST 33979627205 are success, so the CodeQL handoff is the remaining central required-workflow evidence lane (independent PR approval is separately absent). This consumer cannot safely use a manual rerun while protected central codeql-pr.yml retains the RUN_ATTEMPT != 1 veto: absent a trusted terminal status, attempt 2 would fail before redispatch. Please keep #914 as a post-integration unchanged-head canary for #1902; no leaf no-op commit, synthetic status, predecessor evidence transfer, or gate weakening is requested.

seonghobae pushed a commit that referenced this pull request Sep 6, 2026
…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

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact head e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e after the non-force adoption of protected main@efb8926923de45245338159a489a1b227e81945f. Focus on whether later-attempt recovery can redispatch only when no authenticated exact-head terminal verdict exists, without weakening OIDC/app-token validation, creator/status ownership, per-language isolation, pending fail-closed behavior, or concurrency. Also verify that the two-parent adoption preserved all intervening main changes and the PR remains limited to its four owned paths.

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

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.md

Length 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 tests

Length 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.py

Length 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 || true

Length of output: 47536


@seonghobae Review complete for e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e.

Finding

  • Medium — Paginate the authenticated status lookup before redispatch.
    .github/workflows/codeql-pr.yml Line 204 calls GET /commits/${PR_HEAD_SHA}/statuses without --paginate or an explicit page size. The workflow treats an empty first response page as proof that no authenticated terminal codeql-dispatch/<language> verdict exists. A busy commit can have more statuses than the API default response page. An older authenticated terminal verdict can then be omitted, and a later attempt can redispatch despite an existing verdict. Use a paginated lookup, then filter the complete status history for the trusted creator and language context.

The rest of the requested controls remain present after inspection:

  • The change removes only the RUN_ATTEMPT != 1 veto.
  • The caller retains live PR-head validation, run/job validation, OIDC exchange, app-token exchange, one-language dispatch, and verdict=pending fail-closed behavior.
  • The handler retains actor and sender authorization, live metadata validation, exact run/job/language validation, terminal status publication, and exact failed-job rerun validation.
  • The handler concurrency group remains scoped to target repository, PR number, and language.
  • e72ae30e3e989396b8cfdd1d850f7db1f45c6a7e is a two-parent descendant of the specified protected-main commit.
  • The merge tree differs from protected main@efb8926923de45245338159a489a1b227e81945f only in the four owned paths. No intervening protected-main path was lost.

I did not execute repository tests in this inspection environment.

You are interacting with an AI system.

Copy link
Copy Markdown
Contributor Author

Ready-for-review restored at exact event 2026-09-08T07:07:41Z on unchanged head e07e8fd50378ed0d73fa33bacb7a647f832cd578 / tree 7e55de0ef9f8df78e5eb18c98019afa044f5bd68 after resolving the two repaired, outdated review threads. PR body ancestry wording was corrected at 2026-09-08T07:07:54Z without a source or head change.

Fresh state before transition: protected base main@7fd571db…, behind 0, mergeable, no unresolved substantive source finding. Ready is review admission only. Exact-head hosted GREEN and qualifying independent review remain merge gates; no approval, auto-merge, bypass, manual rerun, empty push, or force update was performed.

@seonghobae
seonghobae marked this pull request as draft September 8, 2026 07:12

Copy link
Copy Markdown
Contributor Author

Draft transition at 2026-09-08T07:12:57Z on unchanged head e07e8fd50378ed0d73fa33bacb7a647f832cd578. Fresh successor audit of #2039 found two still-valid test-contract deltas: explicit empty producer evidence must not silently acquire defaults, and OpenCode App receipts need the same malformed run-metadata matrix already exercised for the narrow self-repository fallback. The canonical source behavior remains GREEN; Draft now records incomplete successor carryover until these exact tests are integrated. No rerun, empty push, approval, auto-merge, bypass, or force update was used.

Copy link
Copy Markdown
Contributor Author

Canonical successor integration complete at exact head 723d1c368b459ce5646d5ebc91ce9546bbe5fc70 / tree f372d1e4217ff0423f76688d3fe5cc23bc48970d, parent e07e8fd50378ed0d73fa33bacb7a647f832cd578.

Review of Draft #2039 identified two valid test-only semantics not yet explicit in the canonical writer: (1) explicit empty producer jobs/artifacts must not acquire fixture defaults, and (2) App identity never substitutes for exact producer-run metadata. Both are now integrated. RED reproduced empty-evidence defaulting; the event/path/head/repository/actor/triggering-actor substitution matrix is fail-closed on the production path. Other #2039 deltas are already carried by equal or stronger canonical failure-state, malformed-evidence, pagination, and receipt-identity cases.

Exact-tree GREEN: focused two-workflow contracts 111 passed; full repository 3061 passed, 1 skipped, 21 subtests; statement/branch/public-doc coverage 100%; Python compile and diff check clean. Local actionlint is unavailable, so hosted validation remains authoritative.

Protected-base comparison is 49 ahead / 0 behind; PR remains mergeable; unresolved review threads are 0. This is source/contract evidence only, not approval or hosted GREEN. Ready may be restored solely for current-head review admission after a final live-state check. No auto-merge, bypass, force update, empty push, or manual rerun.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e07e8fd503

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/codeql-scan-dispatch.yml Outdated
Comment thread .github/workflows/codeql-pr.yml Outdated

Copy link
Copy Markdown
Contributor Author

Current-head RCA checkpoint — 723d1c368b459ce5646d5ebc91ce9546bbe5fc70

  • Exact GitHub blobs independently execute 62/62 required-workflow contracts and 49/49 dispatch-handler contracts.
  • Both new P1 findings are source-valid and share one convergence boundary: mixed predecessor/current receipts plus base movement cannot be repaired independently.
  • Acceptance requires executable cases for (1) one predecessor-authenticated terminal language plus one current pending language and (2) base advancement between shard admissions, with either one attempt-wide base or an authenticated whole-run invalidation path.

The PR remains Draft; neither thread was resolved. I did not overlap the active writer with a partial source change.

Copy link
Copy Markdown
Contributor Author

Fresh live canary from fast-mlsirm should be folded into this canonical CodeQL rerun-recovery lane, not repaired in the leaf.

Protected central authority is still main@7fd571dbcdbae6acf29d8f4ee704d7ba6297e4db (#2028), so these runs exercise the predecessor production topology while #1902 is Draft:

  1. fast-mlsirm#1738@f1a67806c271ad175cff5284b23c1c2d76aa9614, required run 34032362487: both compatibility receivers settled/fail before coordinator job 101959593555 successfully dispatched exact-head CodeQL evidence.
  2. I then tested the apparent operator recovery path after dispatch. Re-running a single failed receiver job is not a reliable convergence primitive under GitHub job-rerun dependency closure:

No leaf source/no-op commits were used. This evidence strengthens the existing single-settlement design requirement: convergence needs to be intrinsic to the workflow, not depend on manually choosing one failed matrix job. The #1902 RED/GREEN set should cover a post-dispatch rerun attempt where GitHub re-materializes sibling matrix jobs but not the coordinator, and prove the attempt cannot leave any required language shard permanently failed merely because a sibling settles before the requested rerun acquires a runner.

This appears compatible with your current P1 findings rather than a competing lane: authenticate predecessor-handler receipts across mixed-matrix settlement, and bind one attempt to one base SHA. Please preserve exact repo/PR/live-base/head/language/required-run/source/SARIF/artifact binding and fail closed.

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-head integration review for 855f0173aae53620f68322e3b218c022fe1c4eed.

The non-force merge preserves RED 48baf18c11e4d942748b33cf7c94e15fe7fde7bb and the 723d1c368b459ce5646d5ebc91ce9546bbe5fc70 repair. Shard and coordinator admission now validate the live repository/ref/head and bind newly issued context/title/payload evidence to the fresh live base SHA; the old event-base receipt cannot match. Both status consumers also validate every candidate and normalize by (run_id,state), accepting a verdict only when exactly one evidence-complete producer remains. The earlier base-advance and first-complete-status-order findings are therefore resolved on this exact head.

This does not open merge admission. Two separate current-source P1 threads remain unresolved: run-wide settlement cannot yet authenticate a terminal predecessor-handler receipt for an already-complete language, and independently admitted matrix shards can bind different live base SHAs within one required attempt. The PR should remain Draft until both receive executable RED→GREEN repair.

Hosted evidence for this exact SHA is non-terminal: CodeQL 34201420308 is pending; Runtime Quality 34201420253, SAST 34201420286, Security Scan 34201420237, and Python Security 34201420195 are queued. No predecessor result is promoted.

Copy link
Copy Markdown
Contributor Author

Exact-head repair is now integrated at 87228f918ff17cd1e7216ed8d5a37bd1de4d93db (tree 2e80fd0474632ff52a3813c21503f2e95e5a5785) by an ordinary two-parent, non-force reconciliation of concurrent head 855f0173… and repair commit 2b60f0ef….

This resolves both current P1 findings in source:

  • PRRT_kwDOS_C14s6gIutt: detect-languages captures one validated live base before matrix expansion; all shards and the coordinator consume that attempt-wide SHA and reject any later base advance. A failed-only rerun therefore cannot combine siblings from bases A and B.
  • PRRT_kwDOS_C14s6gIutq: settlement re-authenticates predecessor receipts using the exact bound title/context, run/workflow/source ancestry, App actors, terminal language result, successful SARIF preservation, and one unexpired exact-attempt artifact before combining the unique receipt with current direct evidence.

The concurrent RED/test delta and product Gap entry are preserved. A contradictory per-shard live-base success expectation was converted to an explicit fail-closed regression under the stronger attempt-wide invariant.

Exact-tree GREEN: focused 118 passed; full 3068 passed, 1 skipped, 21 subtests; statement 13194/13194 and branch 5330/5330 coverage; public-doc 100%; Python compile and diff check clean. Local actionlint is unavailable, so hosted validation remains a merge gate.

Protected base comparison is 53 ahead / 0 behind, mergeable. This evidence is review admission only, not approval or merge authorization. No manual rerun, empty push, auto-merge, self-approval, bypass, or force update was used.

@seonghobae
seonghobae marked this pull request as ready for review September 8, 2026 08:18

Copy link
Copy Markdown
Contributor Author

Exact-head review finding for 87228f918ff17cd1e7216ed8d5a37bd1de4d93db.

The two earlier P1 paths are materially addressed, and the exact blobs pass the two focused workflow suites (118 passed in 109.88s). A new fail-closed gap remains in receipt_evidence_proven():

  • The predecessor job filter binds the language job's terminal conclusion and the successful Preserve CodeQL SARIF evidence step, but it never requires exactly one Enforce CodeQL Medium+ SARIF gate step with a conclusion consistent with the receipt state.
  • Live-shaped RED test_dispatch_settlement_rejects_predecessor_without_language_gate supplies an exact source-bound predecessor run, matching success status, successful preservation step, and unexpired exact artifact, but omits the gate step. Expected: settlement waits and does not wake. Actual: the script prints Re-ran the exact failed CodeQL language jobs... and calls rerun-failed-jobs (1 failed test).
  • Add the missing gate proof and negative missing/duplicate/mismatched-gate fixtures before resolving the predecessor-receipt thread.

A separate liveness condition also remains in the attempt-wide base repair. detect-languages captures the base once and succeeds; if the base advances afterward, shards/coordinator fail against the captured SHA. The only automated wake path still POSTs rerun-failed-jobs, which cannot refresh the already-successful capture job/output. The same required run can therefore remain pinned to the old base indefinitely. Either restart the whole workflow attempt on this condition or bind a refreshable attempt identity whose consumers converge without mixing bases; add a behavioral base-advance→recovery fixture, not only a rejection assertion.

These are source findings, not hosted-check or approval evidence. Keep Draft until RED→GREEN and fresh exact-head review.

@seonghobae
seonghobae marked this pull request as draft September 8, 2026 08:21

Copy link
Copy Markdown
Contributor Author

Ready-for-review admission was restored at 2026-09-08T08:18:29Z on unchanged exact head 87228f918ff17cd1e7216ed8d5a37bd1de4d93db / base 7fd571dbcdbae6acf29d8f4ee704d7ba6297e4db. Immediately before transition: mergeable, 53 ahead / 0 behind, unresolved threads 0, no remaining concrete current-source finding. The Ready event cancelled the earlier push runs and registered fresh same-head hosted gates: CodeQL PR 34203791363 pending; Python Security 34203791227, Security Scan 34203791206, and SAST Semgrep 34203791274 queued. None is promoted to GREEN. Ready is review admission only; hosted terminal GREEN and qualifying independent review remain merge gates. No manual rerun, empty push, approval, auto-merge, bypass, or force update was used.

Copy link
Copy Markdown
Contributor Author

Current-head coordination for 855f0173aae53620f68322e3b218c022fe1c4eed: the earlier base-advance deadlock and duplicate evidence-complete status ordering are present with tests, but two current P1 contracts remain unresolved in exact source. (1) codeql-scan-dispatch.yml still accepts evidence receipts only when target_url == PRODUCER_RUN_ID, so an authenticated predecessor receipt cannot participate in mixed predecessor/current settlement. (2) CodeQL shards and coordinator still independently bind PR_BASE_SHA from separate live reads, allowing one attempt to span base A/B instead of sharing one immutable run-level base snapshot. New leaf evidence: #2005 CodeQL 34190638093 had one pending shard and an actions rerun with no authenticated terminal verdict; #2007 CodeQL 34197136206 dispatched both languages but both required shards remained pending without wake/settlement. Their Ready events have now created replacement same-head runs 34202089945 and 34202091140; neither predecessor failure nor replacement state is transferred as GREEN. Traceability also needs correction: cited RED 0e363d614e81a7191fdb5f9b75356ca4b8d2e881 is not reachable through GitHub (422 No commit found), so publish a reachable remote RED commit or label it explicitly local-only. Please keep Draft and repair the two interacting contracts test-first at the canonical owner; no consumer-side bypass or broad status allowlist is acceptable.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87228f918f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/codeql-pr.yml Outdated

Copy link
Copy Markdown
Contributor Author

Exact-head gate-proof repair integrated at 7ca416ee7bb8dba75855980c0ebeb748666cf100 / tree 62708f94dda37fc64cf80d110f3c0e769ab2ce1f as an ordinary child of 87228f918ff17cd1e7216ed8d5a37bd1de4d93db.

TDD evidence:

  • RED: missing, duplicate-success, and success-receipt/failure-gate predecessor fixtures all woke the failed required jobs instead of failing closed (3 failed).
  • GREEN: settlement now requires exactly one Enforce CodeQL Medium+ SARIF gate step whose conclusion matches the terminal receipt state, in addition to the existing run/source/job/preservation/artifact evidence.
  • Exact candidate suites: 121 passed in 101.54s.
  • Remote exact blobs match the tested blobs: workflow db19b43c…, contract test 3fd4dc36….
  • Protected-main comparison: 54 ahead / 0 behind; branch update used force=false.

The independent whole-attempt base-advance recovery finding remains open, so this PR stays Draft. Fresh hosted runs 34204995343, 34204995406, 34204995513, 34204995437, and 34204995397 are queued and are not GREEN evidence.

Copy link
Copy Markdown
Contributor Author

Exact-head repair for the current post-capture base-advance finding is now published at ebf054e67f7dbeb7c9b8d0f90e2bc1c151471a2b (tree 03a9ebd2ffc3504e52028499402b703394b5430e), an ordinary non-force child of concurrent gate-proof head 7ca416ee….

The coordinator now proves the live base ref, adopts the fresh live base SHA, emits rerun_mode=all, requires the complete terminal matrix job map, and asks GitHub for a whole-run rerun of the exact required run. Unchanged-base recovery remains failed mode and uses only rerun-failed-jobs. Shards keep the attempt-wide capture invariant and still fail closed on stale snapshots. The handler validates both modes before mutation and requires a newer exact attempt for every required language.

The concurrent predecessor-gate repair is preserved and strengthened: shard, coordinator, and handler receipt readers now require exactly one successful SARIF-preservation step and exactly one gate step whose conclusion matches success|failure|error.

RED reproduced 13 failures, followed by one separate coordinator gate-mismatch RED. Exact-tree GREEN: focused 129 passed in 107.53s; full repository 3079 passed, 1 skipped, 21 subtests passed in 308.37s; statement 13194/13194, branch 5330/5330, total coverage 100%; public-doc 100%; compileall PASS; diff check clean. Local actionlint is unavailable, so hosted validation remains a merge gate.

This resolves top-level finding #5581711833 and inline review comment #3955891530 at the source level. The PR remains Draft pending a fresh exact-head/base/review/thread admission check; Ready, if restored, is review admission only and does not authorize approval, auto-merge, bypass, empty push, or manual rerun.

@seonghobae
seonghobae marked this pull request as ready for review September 8, 2026 08:57

Copy link
Copy Markdown
Contributor Author

Ready-for-review admission was restored at 2026-09-08T08:57:34Z on unchanged exact head ebf054e67f7dbeb7c9b8d0f90e2bc1c151471a2b / protected base 7fd571dbcdbae6acf29d8f4ee704d7ba6297e4db.

Immediately before transition: 55 ahead / 0 behind, mergeable, 12 changed paths, unresolved review threads 0, and no newer substantive current-source finding after repair evidence #5582176132. The prior inline P1 thread is resolved against this head. Ready is independent-review admission only; it is not approval or merge evidence.

The Ready event cancelled the prior push-triggered hosted runs and registered fresh same-head gates: Python Security 34207344460 queued, Security Scan 34207344467 queued, SAST Semgrep 34207344436 pending, CodeQL PR 34207344514 pending. Agent Review Runtime Quality CI 34207159185 remains queued. None is promoted to GREEN.

No auto-merge, approval, protection bypass, empty push, manual rerun, force update, or stale-head evidence transfer was performed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: medium Normal-priority or P2 work status: needs-review Open pull request requiring current-head review or checks type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant