Repository navigation
[Fix] 자동화 판정이 PR 전체 이력 대신 열린 PR과 claim 브랜치별 PR만 받도록 시한폭탄 제거 - #994
Conversation
닫힘·병합 PR 5000건 이력, 열린 PR 목록 상한 도달, workflow의 --state all 전수 조회 금지를 실패 테스트로 먼저 고정한다.
collect-automation-prs.mjs가 열린 PR 전체(상한 도달 시 실패)와 git ls-remote로 아는 claim 브랜치별 PR(전 상태)만 모은다. workflow 9개의 판정·재확인 13곳이 gh pr list --state all --limit 1000 대신 이를 쓰고, 등록·ITX 승격·원천 재확인 판정의 잘림 검사는 열린 PR 개수에만 적용한다.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
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 |
AquilaXk
left a comment
There was a problem hiding this comment.
Actionable comments posted: 2
🎯 Linked issue & acceptance criteria audit
- Linked issue: #993 [Fix] Remove the 1000-entry PR history dependency from automation decisions
- Goal summary: Decisions get open PRs plus per claim branch PRs, so history length is irrelevant.
- Acceptance criteria verified: 4/4
| ID | Acceptance criterion | Status | Evidence |
|---|---|---|---|
| AC-1 | Collector merges open PRs and per branch PRs and survives 5000 history entries | PASS | tools/ci/collect-automation-prs.mjs |
| AC-2 | Open PR count at the cap fails in the collector and in the three decisions | PASS | tools/ci/decide-itx-current-promotion.mjs |
| AC-3 | All 13 call sites use the collector and no unbounded all state list remains | PASS | tools/ci/automation-pr-list-bounded.test.mjs |
| AC-4 | ITX closed check is kept only for CLOSED PRs whose branch remains | PASS | tools/ci/collect-automation-prs.test.mjs |
🛡️ Adversarial audit evidence
- Falsifiability verified: Yes (Mutating the truncation check and three open count caps turned tests RED.)
- Hollow assertions detected: 0
- Production backdoors detected: 0
- Ground-truth sources verified:
Consumer code of all ten decisions read against the branch scoped listLive run of the collector against AquilaXk/easysubway-data with the real ls-remote outputTargeted tests: 70 of 70 passed on the PR head
- Mutation testing evidence:
probe-falsifiability on collect-automation-prs.mjs line 54 and on the open count caps in the ITX, reverification and registration decisions: all mutants killed, no survivors.
🤖 Prompt for all review comments with AI agents
Could we verify each finding against the current code and keep only those that
still apply? Could we make the smallest validated fix and briefly note why any
finding no longer applies?
Inline comments:
- `@tools/ci/collect-automation-prs.mjs:67-75`
Could the collector log the branch count with its summary line, and fail with a
named code once the count passes a generous bound, so runaway branch growth shows
up as a signal instead of a slow run?
- `@tools/ci/collect-automation-prs.test.mjs:126-139`
Could this file add two cases through the collector and decision together: a
CLOSED claim PR with its branch present expects ITX_PROMOTION_PR_CLOSED, and a
CLOSED PR whose branch is absent expects a normal WAIT or COLLECT result?
---
Outside diff comments:
None.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Aquila CLI invocation with repository CLAUDE.md, PR template and issue 993 text
Review profile: ASSERTIVE
Plan: Aquila fallback
Run ID: N/A (Aquila fallback)
Review source: Aquila CLI
Repository visibility: public GitHub repository
Trigger:
Discovery review requested for the current change set of this pull request
Base:
main@48c66420e11fd9e422e2dc9ebb32b2de63e44ca5
Head:
fix/bound-automation-pr-lists-993@062f1a7ba6c6d08d24cee86f01c83da435553ff4
Command:
node scripts/compile-review-payload.mjs input.json --output payload-1.json
📥 Commits
Reviewing files changed in this pull request between:
- Base:
48c66420e11fd9e422e2dc9ebb32b2de63e44ca5 - Head:
062f1a7ba6c6d08d24cee86f01c83da435553ff4
📒 Files selected for processing (2)
tools/ci/collect-automation-prs.mjstools/ci/collect-automation-prs.test.mjs
📜 Review details
리뷰 F1: 브랜치가 남은 CLOSED 승격 PR은 ITX_PROMOTION_PR_CLOSED, 브랜치가 지워진 CLOSED PR은 정상 진행임을 수집기+판정 통합 테스트로 고정한다. 리뷰 F2: claim 브랜치가 50개를 넘으면 AUTOMATION_CLAIM_BRANCH_LIMIT로 gh 호출 전에 실패하고, 조회한 브랜치 수를 로그에 남긴다.
|
No description provided. |
|
No description provided. |
|



Related issue
Closes #993
Refs #870
Refs #969
Summary
gh pr list --state all --limit 1000으로 PR 전체 이력을 받는다. 자동화가 매일 PR을 열어 이력은 계속 쌓이고(지금 612건), 1000건에 닿는 순간 등록·ITX 승격·원천 재확인 판정은*_LIST_TRUNCATED로 영구 실패하고, 나머지 판정(topology·KRIC·서울·광주·후보 갱신·파생 재결속·재확인)은 오래된 병합 PR이 잘린 목록으로 조용히 오판한다. [CI] P7D 원천 재확인 recipe(S2~S9)를 만료 전 무인 workflow로 자동화 (#969 남은 단계 1) #987 리뷰 F1(run 목록 상한)과 같은 종류의 시한폭탄이다.열린 PR 전체(상한 도달 시 실패 유지) +판정이 보는 claim 브랜치별 PR(전 상태)만 받는다. 이력이 5000건이어도 판정 결과가 같다.Changes
tools/ci/collect-automation-prs.mjs(신규): 열린 PR(--state open --limit N, N건에 닿으면AUTOMATION_PR_LIST_TRUNCATED)과git ls-remote출력의 브랜치별 PR(--state all --head <branch> --limit 100, 100건에 닿으면 같은 실패)을 번호 기준으로 합쳐 JSON으로 쓴다. claim 브랜치가 50개를 넘으면 gh 호출 전에AUTOMATION_CLAIM_BRANCH_LIMIT로 실패하고, 조회한 브랜치 수를 로그(branch_lookups)에 남긴다. gh 실패·목록 아님·형식 오류·잘못된 인자는 대체 없이 실패한다.tools/ci/decide-capital-topology-registration.mjs·decide-itx-current-promotion.mjs·decide-source-reverification.mjs: 잘림 검사(*_LIST_TRUNCATED)를 목록 길이가 아니라 열린 PR 개수에만 적용. 입력 형식과 나머지 분기는 그대로다.current-capital-topology-refresh.yml:50,current-capital-topology-registration.yml:80·:242,itx-current-promotion.yml:72,kric-current-facility-refresh.yml:55,nationwide-candidate-refresh.yml:61·:180,retained-gwangju-timetable-refresh.yml:41,seoul-current-accessibility-refresh.yml:46,source-derivative-rebinding.yml:53·:146,source-reverification.yml:48·:174):gh pr list --state all --limit 1000줄을 지우고, 이미 하던git ls-remote를 먼저 받은 뒤 그 출력을--refs로 수집기를 호출한다(순서만 PR 목록 → ls-remote에서 ls-remote → PR 목록으로 바뀐다). 출력 파일 이름·판정 호출 인자는 그대로다.${{ }}식은 run에 쓰지 않았다.collect-automation-prs.test.mjs·automation-pr-list-bounded.test.mjs(전수), 세 판정 테스트에 5000건 이력 케이스, workflow 계약 6개 갱신.data-test-ownership.json에data993등록.판정별 전후
decide-capital-topology-registrationREGISTRATION_LIST_TRUNCATEDdecide-itx-current-promotionITX_PROMOTION_LIST_TRUNCATED, 이력의 모든 CLOSED 승격 PR이ITX_PROMOTION_PR_CLOSEDPR_CLOSED는 브랜치가 남은 CLOSED PR에만(아래 참고)decide-source-reverificationREVERIFICATION_LIST_TRUNCATEDautomation/*브랜치별 PR. 잘림은 열린 PR에만.classifyClaims는 원래 claim 브랜치 키라 동일decide-derivative-rebinding,decide-nationwide-candidate-refreshcleanupBranches·pendingLedgerWriters가 claim 키automation/*브랜치별 PR. 결과 동일, 잘림 없음decide-current-capital-topology-refresh,decide-current-kric-facility-refresh,decide-current-seoul-accessibility-refresh,classifyRetainedGwangjuRefreshDeliveryledger-writers-idle(재확인 4곳)pendingLedgerWriters가 claim 키automation/*브랜치별 PR. 결과 동일Scope
Included
Excluded
ci.yml(PR #990이 automerge 대기 중이라 건드리지 않았다).automerge-queue.yml(--state open --label automerge목록),refresh-open-pr-age·열린 PR 목록 호출(--state open),automation-pr-recreate.mjs(닫힌 PR 최근 100건 표본,overflow: return, 잘림 실패 없음, 이력 길이 무관). 전수 테스트가 이 둘만 허용 목록으로 둔다.Ownership / dependencies
ci.yml)은 겹치지 않는다.data-test-ownership.json은 병합 시점에 다른 PR과 맞춘다.Contract & Compatibility
gh pr list(open·--head)만 쓴다. hubapi-catalog는 공공 데이터 원천용이라 해당 없음("카탈로그에 없음"). 실측:gh pr list --state all --head <branch> --limit 100은 같은 JSON 필드를 돌려주고 없는 브랜치는[]다.closed는 이력의 모든 CLOSED 승격 PR을 세던 것이라 한 번이라도 닫히면(브랜치가 지워졌어도) 영구 실패했다. 이후에는 브랜치가 남은 CLOSED PR만 이상(ITX_PROMOTION_PR_CLOSED)이다. 뒤처진 PR을 닫고 브랜치를 지운 뒤 다시 만드는automation-pr-recreate경로와 맞는다. 다른 판정은 원래 claim 키라 차이가 없다.Version impact
Product gate impact
Provenance impact
Version decision
Verification
573edaea2):node --test tools/ci/collect-automation-prs.test.mjs tools/ci/automation-pr-list-bounded.test.mjs tools/ci/decide-capital-topology-registration.test.mjs tools/ci/decide-itx-current-promotion.test.mjs tools/ci/decide-source-reverification.test.mjs→tests 61, pass 55, fail 6(수집기 모듈 없음ERR_MODULE_NOT_FOUND, 세 판정의 5000건 이력 케이스 3건, 전수 계약 2건). GREEN(커밋062f1a7ba): 같은 명령fail 0. 리뷰 F1·F2 반영(커밋fb5bc02dc): 수집기 테스트 12건(수집기+ITX 판정 통합 2건 추가, 브랜치 수 상한 1건 추가). 수집기가 브랜치 없는 CLOSED PR을 돌려주도록 변조(열린 목록을--state all로)하면 통합 테스트 포함 5건이 red가 됨을 확인하고 되돌렸다. 예전 방식이 실제로 틀린다는 증명은 수집기 테스트가 한다: 닫힘·병합 5000건에서--state all --limit 1000목록은 오래된 claim 병합 PR을 놓쳐 ITX 판정이 고아 브랜치로 실패하고, 수집기 목록은WAIT로 같은 결과를 낸다.node --test tools/ci/*.test.mjs→tests 639, pass 638, fail 1. 실패 1건은stage-local-mobile-fixture.test.mjs로,origin/main에서도 같은 명령이 같은 이유(apply-itx-topology-to-bundled-pack.mjs --derive-fixture실패, 로컬 mobile fixture 부재)로 실패한다(이 변경과 무관, CI는 fixture를 staging한다).automerge-queue.test.mjs(YAML block scalar 들여쓰기 계약) 29건 통과.node tools/ci/data-test-discovery.mjs verifyexit 0.actionlint .github/workflows/*.ymlexit 0.node tools/ci/check-documentation-fragment-sync.mjs --base origin/main통과(등록 resource 변경 없음). 실제 저장소 대상 수집기 실행:automation pull requests: open=2 branch_lookups=1 total=2(리뷰 반영 전 출력은claims=1), 열린 PR 상한 2로 줄이면AUTOMATION_PR_LIST_TRUNCATED: open pull request list reached its limit 2.fb5bc02dc전부 success: Data contracts 집계(shard 1~4·mobile-v19 포함, 같은 run), SonarCloud Code Analysis pass, CodeQL 3종 pass.Automation PR gates는 자동화 PR 전용이라 skipping.gh는 인자 배열로 호출하고(셸 없음) 브랜치 이름은 형식을 검증한다.Not run
stage-local-mobile-fixture.test.mjsorigin/main에서도 로컬 환경(mobile fixture 부재)으로 실패하는 기존 상태이며 CI에서 fixture를 staging해 돈다.Data contracts.Risk
AUTOMATION_PR_*코드로 step을 실패시켜 기존 실패 보고([Fix] 원천 갱신 workflow 실패를 이슈로 드러내고 광주 보관 시간표 갱신에 수동 실행 경로 추가 #926)로 드러난다. 대체 값은 없다.Rollout / Recovery
automation pull requests: open=N branch_lookups=M total=K한 줄과 기존 판정 출력.--state all --limit 1000호출로 돌아간다(이력 1000건 전까지는 동일).Review focus
closed의미 변화(브랜치가 지워진 CLOSED PR을 더는 세지 않음)가 의도에 맞는지.Checklist