opencode-review-dispatch.yml의 메타데이터 검증이 큐 대기 시간 때문에 실패합니다. 대기가 길수록 실패율이 오르고, 실패가 재시도를 부르고, 재시도가 대기를 늘리는 자기강화 구조입니다.
#1927·#1929(낡은 인가 변수)와 독립된 원인이고, 그쪽을 고쳐도 남습니다. 수정 대상이 설정 값이 아니라 검증 의미론이라 별건으로 올립니다.
측정
opencode-review-dispatch.yml의 실패 run 중 actor=github-actions[bot]인 것(= 인가를 통과하는 신원) 44건 전수를 의존 순서로 재분류했습니다. 스텝을 run 간에 합산하면 하류 캐스케이드가 중복 계산되므로, validate-pr-metadata → coverage-source-tree → coverage-evidence → opencode-review에서 처음 실패한 job을 근본 원인으로 잡았습니다.
16 validate-pr-metadata | Bind workflow inputs... 36%
14 coverage-evidence | Measure test and docstring 32% ← #1883 이 해소
6 opencode-review | Wake exact-head required... 14%
8 나머지 (각 1~2건)
최대 원인 16건을 ##[endgroup] 이후의 실행 출력만 읽어 다시 갈랐습니다. 그 앞은 스크립트 소스 에코라 모든 에러 문구를 포함하고 있어서 어떤 가설이든 확증됩니다.
9 repository_dispatch metadata does not match the live pull request: base_sha
3 rejected closed, missing, or malformed live metadata (state=closed)
4 repository_dispatch authorization rejected (#1927/#1929)
12/16이 큐 지연의 결과입니다.
실제 로그
Authorized repository_dispatch actor=github-actions[bot] sender=github-actions[bot] ← 인가 통과
##[error]... does not match the live pull request: base_sha.
supplied_base=main/76969152... live_base=main/5d55a31e...
supplied_head=...fd964d24 live_head=...fd964d24 ← head 는 일치
head는 맞고 base만 어긋납니다. 디스패치는 보낸 시점의 base SHA를 싣는데, 큐에서 기다리는 동안 main이 전진합니다. state=closed 3건도 검증 도달 시점에 PR이 이미 닫힌 것이라 같은 기전입니다.
드리프트가 사실상 확정적입니다
오늘 origin/main의 시간당 커밋 수입니다.
09시 2 · 10시 2 · 11시 6 · 13시 5 · 14시 6 · 17시 11 · 18시 3 · 19시 1
그리고 실측된 완주 실행 하나가 **총 15시간 37분, 그중 실제 계산 약 73초(대기 99.87%)**였습니다. 시간당 1~11회 움직이는 브랜치에서 15시간을 기다리면 base가 안 움직일 확률은 사실상 0입니다.
핵심: 이 검사는 데이터 의존이 아니라 staleness 정책입니다
opencode-review-dispatch.yml의 실제 데이터 경로입니다.
:186 검증 [ "$SUPPLIED_BASE_SHA" = "$live_base_sha" ] || mismatches+=("base_sha") ← 불일치면 exit 1
:199 출력 printf 'base_sha=%s\n' "$live_base_sha" ← live 를 내보냄
:295 소비 PR_BASE_SHA: ${{ needs.validate-pr-metadata.outputs.base_sha }}
:332 git -C "$fetch_dir" checkout --detach "$PR_BASE_SHA"
SUPPLIED_BASE_SHA는 비교에만 쓰이고 버려집니다. 하류가 실제로 체크아웃하는 값은 live_base_sha입니다. 즉 supplied와 live가 달라도 파이프라인은 live로 정상 동작합니다.
동등성 요구가 지키는 것은 "디스패치 시점과 검증 시점 사이에 base가 안 움직였다"는 보장이고, 현재 조건에서 그 보장은 거의 항상 거짓입니다.
head_sha는 다릅니다. :188에서 같은 방식으로 비교하지만, 그건 "이 리뷰가 디스패치된 바로 그 커밋을 대상으로 한다"는 exact-head 규율의 근간입니다. head는 엄격히 유지되어야 합니다.
판단이 필요한 지점
base_sha 동등성을 푸는 것이 기술적으로 안전하다는 것까지가 측정으로 말할 수 있는 전부입니다. 남는 질문은 설계입니다.
- base 드리프트를 허용하면 coverage가 디스패치 당시와 다른 base에서 측정됩니다. 그 차이가 판정에 영향을 주는지는 이 리포의 커버리지 계약이 정할 문제입니다.
- 대안으로 허용 범위(예: live base가 supplied base의 후손이면 통과)를 두면 보장을 완전히 버리지 않고 드리프트를 흡수할 수 있습니다.
어느 쪽이든 신뢰 경계에 관한 결정이라 근거만 올립니다.
재현
R=repos/ContextualWisdomLab/.github/actions
gh api "$R/workflows/opencode-review-dispatch.yml/runs?status=failure&per_page=100" \
--jq '.workflow_runs[] | select(.actor.login=="github-actions[bot]") | .id'
# 각 run 에 대해 validate-pr-metadata job 의 로그에서 ##[endgroup] 이후만 읽을 것.
# 그 앞은 스크립트 소스 에코이며 모든 에러 문구를 포함한다.
관련: #1927, #1929, #1925, #1883
opencode-review-dispatch.yml의 메타데이터 검증이 큐 대기 시간 때문에 실패합니다. 대기가 길수록 실패율이 오르고, 실패가 재시도를 부르고, 재시도가 대기를 늘리는 자기강화 구조입니다.#1927·#1929(낡은 인가 변수)와 독립된 원인이고, 그쪽을 고쳐도 남습니다. 수정 대상이 설정 값이 아니라 검증 의미론이라 별건으로 올립니다.측정
opencode-review-dispatch.yml의 실패 run 중actor=github-actions[bot]인 것(= 인가를 통과하는 신원) 44건 전수를 의존 순서로 재분류했습니다. 스텝을 run 간에 합산하면 하류 캐스케이드가 중복 계산되므로,validate-pr-metadata → coverage-source-tree → coverage-evidence → opencode-review에서 처음 실패한 job을 근본 원인으로 잡았습니다.최대 원인 16건을
##[endgroup]이후의 실행 출력만 읽어 다시 갈랐습니다. 그 앞은 스크립트 소스 에코라 모든 에러 문구를 포함하고 있어서 어떤 가설이든 확증됩니다.12/16이 큐 지연의 결과입니다.
실제 로그
head는 맞고 base만 어긋납니다. 디스패치는 보낸 시점의 base SHA를 싣는데, 큐에서 기다리는 동안
main이 전진합니다.state=closed3건도 검증 도달 시점에 PR이 이미 닫힌 것이라 같은 기전입니다.드리프트가 사실상 확정적입니다
오늘
origin/main의 시간당 커밋 수입니다.그리고 실측된 완주 실행 하나가 **총 15시간 37분, 그중 실제 계산 약 73초(대기 99.87%)**였습니다. 시간당 1~11회 움직이는 브랜치에서 15시간을 기다리면 base가 안 움직일 확률은 사실상 0입니다.
핵심: 이 검사는 데이터 의존이 아니라 staleness 정책입니다
opencode-review-dispatch.yml의 실제 데이터 경로입니다.SUPPLIED_BASE_SHA는 비교에만 쓰이고 버려집니다. 하류가 실제로 체크아웃하는 값은live_base_sha입니다. 즉 supplied와 live가 달라도 파이프라인은 live로 정상 동작합니다.동등성 요구가 지키는 것은 "디스패치 시점과 검증 시점 사이에 base가 안 움직였다"는 보장이고, 현재 조건에서 그 보장은 거의 항상 거짓입니다.
head_sha는 다릅니다.:188에서 같은 방식으로 비교하지만, 그건 "이 리뷰가 디스패치된 바로 그 커밋을 대상으로 한다"는 exact-head 규율의 근간입니다. head는 엄격히 유지되어야 합니다.판단이 필요한 지점
base_sha동등성을 푸는 것이 기술적으로 안전하다는 것까지가 측정으로 말할 수 있는 전부입니다. 남는 질문은 설계입니다.어느 쪽이든 신뢰 경계에 관한 결정이라 근거만 올립니다.
재현
관련: #1927, #1929, #1925, #1883