문제
noema-review.yml의 repository_dispatch 재시도는 중앙 ContextualWisdomLab/.github에서 실행되면서 client_payload.target_repository로 sibling 저장소를 가리킵니다. 이때 ${{ github.token }}은 중앙 .github 저장소 범위에 머무르므로 다음 target API를 읽거나 취소할 권한이 없습니다.
repos/{target_repository}/actions/runs
repos/{target_repository}/pulls/{pr_number}
repos/{target_repository}/actions/runs/{run_id}/cancel
현재 #1797의 cancel-superseded-noema-runs가 repository_dispatch를 포함하면서 GH_TOKEN: ${{ github.token }}을 사용하므로, sibling retry cleanup은 실질적으로 동작하지 않습니다. 같은 결함은 #1661의 독립 리뷰에서도 확인됐습니다.
경계
- native/required
pull_request_target cleanup은 target 저장소의 github.token을 사용합니다.
- 중앙
repository_dispatch가 sibling 저장소를 조작하려면 해당 target에 제한된 GitHub App 설치 토큰 또는 OIDC 교환 토큰을 사용해야 합니다.
- PAT fallback은 현재 Noema credential 정책과 동일한 fail-closed 순서를 따르되, 원문 token을 로그·출력·artifact에 남기지 않습니다.
- cleanup token에는 target repository의
actions: write, pull_requests: read, metadata: read만 부여합니다. 리뷰 게시용 권한과 분리합니다.
- target repository·PR 번호·expected head는 토큰 발급과 첫 API 호출 전에 다시 검증합니다.
TDD 수용 기준
- 중앙
.github의 github.token으로 sibling repository Actions API를 호출하려는 현행 경로를 RED fixture로 고정합니다.
repository_dispatch cleanup은 target repository-scoped token이 없으면 성공한 척 건너뛰지 않고 typed non-success를 남깁니다.
- GitHub App 경로는 target 한 저장소에만
actions: write, pull_requests: read, metadata: read를 요청합니다.
- OIDC 경로는 target repository를 token exchange request에 포함하고 반환 token을 mask합니다.
- native
pull_request_target은 불필요한 cross-repository app token을 만들지 않습니다.
- live PR head가
EXPECTED_HEAD_SHA와 다르면 취소 API를 호출하지 않습니다.
- 같은 PR의 이전 Noema run만 취소하고 다른 PR·다른 저장소·release/deploy/migration run은 보존합니다.
- rate limit·network·malformed response는 wrong cancellation보다 fail-closed를 우선하며 구체적인 typed telemetry를 남깁니다.
queue: max와 별개로, cleanup job은 review job의 concurrency group 밖에 유지합니다.
- source-fix workflow를 쓴 경우 exact-head GREEN과 같은 commit에서 제거합니다.
Stack
협업
여유가 있는 로컬 세션은 이 이슈를 독립 stack으로 맡아 RED 로그, exact head, 발급된 token의 권한 receipt, 취소 대상/비대상 fixture, GREEN 결과를 남겨 주십시오.
기다리는 동안 다른 로컬 세션에게 지속적으로 지시 받아 도우세요. 계속 묻고 계속 피드백하고 계속 지원하세요. 더 주도적이고 더 적극적으로요.
문제
noema-review.yml의repository_dispatch재시도는 중앙ContextualWisdomLab/.github에서 실행되면서client_payload.target_repository로 sibling 저장소를 가리킵니다. 이때${{ github.token }}은 중앙.github저장소 범위에 머무르므로 다음 target API를 읽거나 취소할 권한이 없습니다.현재 #1797의
cancel-superseded-noema-runs가repository_dispatch를 포함하면서GH_TOKEN: ${{ github.token }}을 사용하므로, sibling retry cleanup은 실질적으로 동작하지 않습니다. 같은 결함은 #1661의 독립 리뷰에서도 확인됐습니다.경계
pull_request_targetcleanup은 target 저장소의github.token을 사용합니다.repository_dispatch가 sibling 저장소를 조작하려면 해당 target에 제한된 GitHub App 설치 토큰 또는 OIDC 교환 토큰을 사용해야 합니다.actions: write,pull_requests: read,metadata: read만 부여합니다. 리뷰 게시용 권한과 분리합니다.TDD 수용 기준
.github의github.token으로 sibling repository Actions API를 호출하려는 현행 경로를 RED fixture로 고정합니다.repository_dispatchcleanup은 target repository-scoped token이 없으면 성공한 척 건너뛰지 않고 typed non-success를 남깁니다.actions: write,pull_requests: read,metadata: read를 요청합니다.pull_request_target은 불필요한 cross-repository app token을 만들지 않습니다.EXPECTED_HEAD_SHA와 다르면 취소 API를 호출하지 않습니다.queue: max와 별개로, cleanup job은 review job의 concurrency group 밖에 유지합니다.Stack
repository_dispatchcleanup credential 및 실행 계약협업
여유가 있는 로컬 세션은 이 이슈를 독립 stack으로 맡아 RED 로그, exact head, 발급된 token의 권한 receipt, 취소 대상/비대상 fixture, GREEN 결과를 남겨 주십시오.