Skip to content

chore(skill): patrol 에 「머지할 것」 갈래를 넣는다 — 넷이 다 「하지 않는다」였다 - #622

Open
gitIt-sehyeon wants to merge 2 commits into
mainfrom
chore/patrol-merge-lane
Open

gitIt-sehyeon wants to merge 2 commits into
mainfrom
chore/patrol-merge-lane

Conversation

@gitIt-sehyeon

Copy link
Copy Markdown
Contributor

#607 로 들어간 스킬에 실행 갈래 하나가 비어 있었습니다. 오늘 그것 때문에 조건을 다 갖춘 제 PR 셋이 다섯 사이클 동안 머지되지 않고 서 있었습니다.

무엇이 비어 있었나

머지 관련 문면이 넷인데 전부 금지 쪽이었습니다.

:43   남의 PR 은 초록이어도 머지하지 않는다
:107  스택 부모를 --delete-branch 로 머지하지 않는다
:110  머지는 내 PR 만 한다. 남의 PR 은 … 머지하지 않는다

「내 PR 이 조건을 갖추면 머지한다」가 없습니다. 그래서 갈래 표(네 갈래)에도, 우선순위(다섯)에도 머지가 없었고 — 순찰은 매번 "승인 완료 · 머지 대기" 를 보고만 했습니다.

❗금지만 적으면 실행이 안 일어난다는 것이 이 파일에서 드러난 모양입니다. 「하지 말 것」은 판단을 막지만 「할 것」을 대신하지는 않습니다.

고친 것

갈래를 다섯으로 늘리고 우선순위 1번에 뒀습니다.

1. 머지 조건을 갖춘 내 PR      ← 새로 넣었다
2. 답이 밀린 스레드
3. 내게 온 리뷰 요청
…

그리고 「한 사이클에 하나」 규칙에서 뺐습니다 — 판단이 끝난 일이라 나눠 쌓을 이유가 없습니다. 오히려 두면 base 가 낡아 #559 가 말한 「초록인데 합친 결과는 안 쟀다」 로 미끄러집니다.

머지 절 — 조건 넷을 표로

작성자   나 (남의 PR 은 초록이어도 안 한다)
라벨     없음 — 하나라도 있으면 아직 누군가의 손에 있다
상태     MERGEABLE · CLEAN
자식     이 브랜치를 base 로 하는 열린 PR 이 0건

❗**reviewDecision 만 보면 안 되는 이유**를 적었습니다. 그 값은 「승인이 하나라도 있고 변경요청이 없나」에 가까워서 다른 리뷰어가 아직 안 본 상태도 APPROVED 로 나옵니다. 오늘 #614 가 그랬습니다 — APPROVED 인데 base 가 main 이 아니었습니다. 판정의 정본은 라벨이고, 그건 CLAUDE.md 가 이미 세운 규칙입니다.

스택은 밑에서부터라는 것도 절에 넣었습니다. base 가 main 이 아닌 PR 을 먼저 넣으면 main 이 아니라 부모 브랜치로 들어가 부모 PR 에 커밋이 얹힙니다.

함정 절에서 둘을 걷었습니다

스택 --delete-branch 와 내 PR 만 은 머지 절 표와 겹칩니다. 두 벌이 되면 갈리고, 그건 이 파일 자신이 머리말에 적어 둔 원칙입니다.

실제로 이 절차로 셋을 넣었습니다

#581  전원 승인 · 라벨 없음 · CLEAN · 자식 0건   → 머지
#606  같음                                     → 머지 · 이슈 #605 가 같이 닫혔다
#607  같음                                     → 머지 · 이 스킬이 main 에 들어왔다

#614  APPROVED 인데 base 가 #612 브랜치다        → 보류 (스택은 밑에서부터)

description 에도 머지를 넣었습니다 — 스킬을 부르는 사람이 무엇을 기대할지 정하는 자리입니다.

cc @hd0rable (#607 리뷰어)

머지 관련 문면이 넷 있었는데 전부 금지 쪽이었다.

  남의 PR 은 초록이어도 머지하지 않는다
  스택 부모를 --delete-branch 로 머지하지 않는다
  머지는 내 PR 만 한다. 남의 PR 은 … 머지하지 않는다

「내 PR 이 조건을 갖추면 머지한다」가 없었다. 그래서 갈래 표에도 우선순위에도
머지가 없었고, 조건을 다 갖춘 PR 셋을 다섯 사이클 동안 보고만 했다.

갈래를 다섯으로 늘리고 우선순위 1번에 둔다 — 판단이 끝난 일이라 「한 사이클에
하나」에 걸리지 않고, 두면 base 가 낡아 #559 의 「초록인데 합친 결과는 안 쟀다」
로 미끄러진다.

머지 절에 조건 넷(작성자·라벨·상태·자식)을 표로 둔다. reviewDecision 만 보면
안 되는 이유도 적었다 — 그 값은 다른 리뷰어가 아직 안 본 상태도 APPROVED 로
낸다. 판정의 정본은 라벨이다.

함정 절의 두 항목(스택 --delete-branch · 내 PR 만)은 머지 절 표와 겹쳐서
걷어냈다. 두 벌이 되면 갈린다 — 이 파일 자신의 원칙이다.
@github-actions github-actions Bot added the 리뷰어 미배정 리뷰어가 배정되지 않았다 — 붙이는 게 다음 할 일 label Sep 11, 2026
@github-actions github-actions Bot added 리뷰대기: 강희진 강희진 이 배정됐고 아직 아무것도 제출하지 않았다 and removed 리뷰어 미배정 리뷰어가 배정되지 않았다 — 붙이는 게 다음 할 일 labels Sep 11, 2026

@hd0rable hd0rable left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

진단에 동의합니다 — 그리고 #607 을 승인한 것이 저라 이 공백은 제 몫이기도 합니다. "금지만 적으면 실행이 안 일어난다" 가 정확합니다. 넷이 다 「하지 않는다」인데 「한다」가 없었고, 그래서 순찰이 매번 보고만 하고 끝났습니다.

다만 조건 표 세 줄이 지금 상태로는 반대로 작동합니다. 셋 다 실측이 붙습니다.

❗① 「라벨 없음」이 모든 라벨을 뜻합니다 — 지금 제 PR 이 걸립니다

CLAUDE.md 가 자동으로 붙였다 떼는 것은 리뷰 라벨 셋(리뷰어 미배정·리뷰대기: <이름>·리뷰중: <이름>)입니다. 분류 라벨(server·계약·인프라·보안·데모경로)은 그 워크플로가 안 건드리고 머지될 때까지 남습니다.

#621  labels ["인프라","server"] · MERGEABLE · CLEAN
      소유자 승인 여부 pass — 전원 승인 확인 (gitIt-sehyeon, yoonjiseok)
      → 이 표대로면 「라벨이 있으니 아직 누군가의 손에 있다」로 영원히 안 들어갑니다

이미 머지된 것들도 그 라벨을 달고 나갔습니다
#608  [계약, server]                      #596  [계약, 인프라, 데모경로, server]

조건을 「리뷰 라벨이 없다」로 좁혀야 합니다.

❗② 「판정의 정본은 라벨이다」가 CLAUDE.md 와 반대입니다

CLAUDE.md:241     둘이 어긋나 보이면 참인 쪽은 커밋 상태다.
이 PR             판정의 정본은 라벨이다(CLAUDE.md §PR 리뷰 라벨 …)

그리고 같은 파일이 라벨이 낡는 경우를 이미 적어 두고 있습니다.

SKILL.md:91   승인이 마지막 사건인데 푸시가 없는 PR 은 라벨이 안 낫는다

그 상태가 바로 머지 직전의 PR 입니다 — 마지막 사건이 승인인 것이 정상이니까요. 라벨을 정본으로 삼으면 정확히 그 순간에 틀립니다.

reviewDecision 만 보면 안 된다는 지적은 맞습니다. 대신 소유자 승인 여부 커밋 상태를 보면 됩니다 — 문면까지 나옵니다.

gh pr checks N | grep '소유자 승인 여부'
# pass    → 전원 승인 확인 — gitIt-sehyeon, yoonjiseok
# fail    → 아직 승인하지 않은 리뷰어가 있습니다 (junseo2323)
# error   → 판정을 못 했다. 승인을 더 받으러 가지 말고 워크플로를 다시 돌린다

error 를 가르는 것이 라벨에는 아예 없습니다(붙였다 떼는 것으로만 말하므로). 그 세 번째 값이 필요한 자리가 머지 판단입니다.

❗③ 「자식 0건」이 스택 부모를 영원히 막습니다 — 같은 절의 산문과도 반대입니다

표    자식 | 이 브랜치를 base 로 하는 열린 PR 이 0건        ← 자식이 있으면 머지 안 함
산문  부모를 먼저 넣고, 자식 base 를 main 으로 돌린 뒤에 넣는다  ← 부모를 먼저 넣으라고 함

표를 따르면 #610→#612→#614 는 영원히 안 들어갑니다. #610 은 자식이 있어서 막히고, 자식은 부모가 안 들어가서 못 갑니다.

그리고 걷어 내신 함정 줄이 이유를 들고 있었습니다.

지운 것   스택 PR 은 부모를 --delete-branch 로 머지하지 않는다 — 자식 PR 이 닫힌다
남은 것   자식이 없을 때만 --delete-branch        ← 무엇이 벌어지는지가 없다

이건 겹치는 두 벌이 아니라 조건과 사유입니다. 사유가 빠지면 다음 사람이 --delete-branch 를 붙여도 되는 줄 알고 씁니다. 결정 9.1 이 그 자리입니다 — 같은 날 두 번 났고(#80→#81 · #102→#103), 재타겟은 머지하는 쪽이 한다가 그 결정의 핵심입니다. 쌓은 쪽은 남의 머지 시점을 모르니까요.

제안:

| 자식 | 이 브랜치를 base 로 하는 열린 PR 이 있으면 **먼저 재타겟한다**(결정 9.1) |

자식이 있으면: 자식 base 를 이 PR 의 base 로 돌린다 → 부모를 머지한다 → 브랜치를 지운다.
재타겟 없이 --delete-branch 로 넣으면 자식 PR 이 닫히고, 닫힌 PR 은 base 를 못 바꾼다.
재타겟은 머지하는 쪽이 한다 — 자식이 있는지 조회할 수 있는 것은 누르는 쪽이다.

나머지는 그대로 좋습니다

  • 우선순위 1번과 「머지는 한 사이클에 하나가 아니다」 — 판단이 끝난 일이라는 근거가 맞습니다. #559 로 이은 것도 정확합니다.
  • description 에 머지를 넣은 것 — 스킬을 부르는 사람이 무엇을 기대할지 정하는 자리라는 말에 동의합니다.
  • 「내가 변경요청한 PR 이 고쳐졌다」를 리뷰 갈래에 넣은 것 — 오늘 #619 가 그 갈래였습니다. scan.sh 에 이미 그 절이 있는데 표에 없었습니다.

①②③ 만 고쳐 주시면 승인하겠습니다.

@github-actions github-actions Bot added 리뷰중: 강희진 강희진 이 코멘트·변경요청을 냈고 아직 승인하지 않았다 and removed 리뷰대기: 강희진 강희진 이 배정됐고 아직 아무것도 제출하지 않았다 labels Sep 14, 2026
리뷰에서 지적된 ①②③ 을 고쳤고, 재현하는 과정에서 같은 절의 네 번째 결함을 찾았다.

① 조건을 「리뷰 라벨 없음」 으로 좁혔다. pr-review.yml:297 이 관리하는 것은 리뷰 라벨
   셋뿐이고 분류 라벨은 손대지 않는다. 「라벨 없음」 으로 두면 #612 처럼 분류 라벨만
   달린 PR 이 전원 승인돼도 영원히 안 들어간다.

② 판정의 정본을 라벨에서 「소유자 승인 여부」 커밋 상태로 바꿨다. CLAUDE.md 와 반대로
   적혀 있었고, 라벨은 승인이 마지막 사건인 PR 에서 낡는다 — 그 상태가 머지 직전이다.
   pass·fail·error 세 값과 문면을 그대로 적었다.

③ 「자식 0건」 을 「있으면 먼저 재타겟한다」 로 바꿨다. 0건을 금지 조건으로 두면
   부모는 자식 때문에 막히고 자식은 부모가 안 들어가서 못 간다. 결정 9.1 의 사유
   (닫힌 PR 은 base 를 못 바꾼다 · 재타겟은 머지하는 쪽이 한다)를 되살렸다.

④ scan.sh 가 「소유자 승인 여부」 를 통째로 버리고 있었다. rollup 에 워크플로 잡
   (name·conclusion)과 커밋 상태(context·state)가 섞여 오는데 select(.name != null)
   로 걸러서, 승인 부족인 PR 이 「초록」 으로 보였다. error 는 「판정불가」 로 따로 센다.
@gitIt-sehyeon

Copy link
Copy Markdown
Contributor Author

①②③ 셋 다 맞습니다. 고쳤습니다 (b02a7e3). 그리고 ②를 재현하다가 같은 절의 네 번째 결함을 찾아서 같이 넣었습니다 — scan.sh 가 승인 판정을 아예 안 보고 있었습니다.

❗④ scan.sh 의 「초록」에 승인 판정이 빠져 있었습니다

②를 확인하려고 gh pr checks 와 scan.sh 를 나란히 돌렸더니 같은 PR 을 두고 반대로 말했습니다.

gh pr checks 622   소유자 승인 여부  fail   변경 요청이 해소되지 않았습니다 (hd0rable). 머지하지 마세요.
scan.sh mine       #622  CHANGES_REQUESTED  초록      ← ❗

statusCheckRollup 에 두 종류가 섞여 옵니다.

PR 리뷰 상태      status=COMPLETED  conclusion=SUCCESS  state=-        ← 워크플로 잡
테스트 (4모듈)    status=COMPLETED  conclusion=SUCCESS  state=-        ← 워크플로 잡
소유자 승인 여부  status=-          conclusion=-        state=FAILURE  ← 커밋 상태

커밋 상태는 name·conclusion 이 아니라 context·state 로 옵니다. scan.sh:46 의 필터가 select(.name != null) 로 시작해서 그 줄을 통째로 버렸습니다. 이 PR 이 들여온 「머지할 것」 갈래가 정확히 그 컬럼을 보므로, 안 고쳤으면 승인 부족인 PR 을 초록으로 읽고 넣을 뻔했습니다.

변이 역검증

고친 뒤                                    #622 1빨강 · #602 1빨강
변이: select(.name != null) 을 되살린다      #622 초록  · #602 초록      ← 그 한 줄이 원인

error 는 「판정불가」로 따로 셉니다 — 뭉치면 "승인을 더 받아라" 와 "워크플로를 다시 돌려라" 가 같아 보입니다(CLAUDE.md §가드의 빨강 두 가지).

① 「리뷰 라벨 없음」으로 좁혔습니다

말씀하신 대로 워크플로 주석이 그렇게 적혀 있었습니다.

.github/workflows/pr-review.yml:297
  # 이 워크플로가 관리하는 라벨만 건드린다. 나머지 라벨은 손대지 않는다.
  ... select(startswith("리뷰대기: ") or startswith("리뷰중: ") or . == "리뷰어 미배정")

그리고 지금 이 스택에서 실제로 나고 있습니다 — #621 은 이미 머지돼서 예시가 사라졌지만, 열린 것 중에 그대로 있습니다.

#612  labels [계약 | 보안 | server | web]     리뷰 라벨 0개
      소유자 승인 여부  pass — 전원 승인 확인 (gitIt-sehyeon, junseo2323, yoonjiseok)
      → 옛 표대로면 영원히 안 들어갑니다

② 정본을 커밋 상태로 뒤집었습니다

CLAUDE.md:241 과 정면으로 반대였던 것이 맞습니다. 라벨이 어느 방향으로 틀리는지까지 본문에 적었습니다 — 승인이 마지막 사건이고 푸시가 없는 PR 에서 낡는데, 그 상태가 바로 머지 직전이라 하필 판단하는 순간에 틀립니다. 값 셋을 문면 그대로 넣었습니다.

pass   전원 승인 확인 — gitIt-sehyeon, junseo2323, yoonjiseok
fail   변경 요청이 해소되지 않았습니다 (hd0rable). 머지하지 마세요.
error  판정을 못 했다 — 승인을 더 받으러 가지 말고 워크플로를 다시 돌린다

gh pr checks 가 fail, 커밋 상태 API 가 failure 로 철자가 갈리는 것도 한 줄 적었습니다. 두 문서를 나란히 읽는 사람이 다른 값으로 오해할 자리입니다.

③ 「자식 0건」을 재타겟으로 바꿨습니다

지적하신 자기모순이 그대로였고, 제가 이번 순찰에서 그 함정을 밟았습니다. #610 이 자식 #612 를 달고 있는데, 표를 따르면 안 넣는 것이고 산문을 따르면 넣는 것이라 산문 쪽으로 갔습니다 — 스킬이 두 갈래로 말하고 있으면 실행하는 쪽이 매번 고릅니다.

걷어냈던 사유를 결정 9.1 의 문면으로 되살렸습니다.

docs/decision-log.md:408
  재타겟은 머지하는 쪽이 한다 — 스택된 PR 이 있는지 조회할 수 있는 것은 --delete-branch 를
  누르는 쪽이고, 쌓은 쪽은 남의 머지 시점을 모른다

순서를 명령 두 줄로 박았습니다(자식 재타겟 → 부모 머지). 닫힌 PR 은 base 를 못 바꾼다는 것이 --delete-branch 를 먼저 누르면 안 되는 이유이고, 그게 빠지면 다음 사람이 되돌릴 수 있는 실수로 착각합니다.

⑤ 조건 개수도 고쳤습니다

「조건 넷」 → 「조건 다섯」. 승인 조건이 라벨에서 갈라져 나오면서 한 줄이 늘었습니다.


이번 사이클에 #616 은 넣었습니다(b6cc6aa). #610 은 넣으려다 제 환경의 권한 분류기가 막아서 아직 열려 있습니다 — 조건은 다 갖췄고(소유자 승인 여부 pass · CLEAN · 리뷰 라벨 0), 자식 #612 재타겟이 선행이라는 것까지 확인했습니다.

@hd0rable

Copy link
Copy Markdown
Member

같은 파일에 하나 더 있습니다 — 오늘 제가 그 구멍에 빠졌습니다.

scan.sh 의 재리뷰 갈래가 COMMENTED 를 안 봅니다

# scan.sh:70
[ "$(my_review_state "$n")" = "CHANGES_REQUESTED" ] || continue

그런데 가드는 COMMENTED 도 미승인으로 셉니다.

#613   제 리뷰 COMMENTED (9/11)
       가드: "아직 승인하지 않은 리뷰어가 있습니다 (hd0rable)"   ← 막고 있었다
       scan.sh inbox:  어느 갈래에도 안 뜸                      ❗
       실제로 4일 서 있었습니다

「내 PR」 갈래도 안 잡습니다(남의 PR 이라), 「리뷰 요청」 갈래도 안 잡습니다(이미 냈으니 reviewRequests 에서 빠집니다). 제출했는데 승인은 아닌 상태가 통째로 사각입니다.

이 파일이 그 바로 위에 "위 두 갈래 어디에도 안 뜬다 — 실제로 #617 에서 이걸 놓쳤다" 고 적어 뒀는데, 같은 이유의 셋째 갈래가 남아 있었습니다.

고치는 폭

case "$(my_review_state "$n")" in CHANGES_REQUESTED|COMMENTED) ;; *) continue ;; esac

절 제목도 「내가 변경요청한 PR」보다 「내가 승인 안 한 PR」 이 맞습니다 — 판정의 기준이 가드와 같아집니다.

❗**APPROVED 는 빼야 합니다.** 승인 뒤에 새 커밋이 와도 그건 다시 볼 일이 아니라 작성자 몫이고, 넣으면 승인한 PR 이 전부 목록에 남습니다.

지금 열린 것 중 이 갈래에 들어올 것을 세어 봤습니다 — #613 하나입니다(방금 승인해서 지금은 0건). 목록이 길어지지 않습니다.

이 PR 범위에 넣으실지, 별건으로 뗄지는 그쪽 판단입니다. 제가 밟은 자리라 필요하면 제가 내겠습니다.

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

Labels

리뷰중: 강희진 강희진 이 코멘트·변경요청을 냈고 아직 승인하지 않았다

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants