완성된 글이 나흘 동안 작업 트리에 잠겨 있었다 — 발행 파이프라인 잔여물을 이어받는 구조
발행 직전까지 끝난 글 세 편이 작업 트리 안에서 96시간을 보냈습니다. 2026-09-04 낮에 politics-right·note·dev 세 사이트의 초안이 본문과 삽화까지 완성된 채 커밋 없이 남았고 그날의 자동 발행 실행은 wave2 를 발행하지 못한 채 끝났습니다. 왜, 언제 끝났는지는 기록에 남아 있지 않습니다. 남아 있는 것은 결과뿐입니다. 그 뒤 09-05 부터 09-08 아침까지 네 번의 정기 실행이 이 트리 셋을 매번 "건너뛴다"로 처리했고 세 사이트의 발행은 09-04 부터 09-07 까지 넉 날 연속 0편이었습니다. 잠긴 세 편이 풀린 것은 09-08 낮 12시 34분부터 13시 36분 사이였고 09-07 새벽에 잠긴 politics-left 초안은 같은 날 오전 11시 9분에 먼저 나왔습니다.
기술적 결함이 하나 더 있었습니다. 스킵을 알리는 통지는 보드(Paperclip) 한 곳에만 걸리게 돼 있었는데 그 보드가 같은 기간 404로 죽어 있었고 스킵을 알 수 있는 다른 경로인 디스코드에는 무엇을 못 적었는지가 아니라 "보드 기록 실패 6건"이라는 숫자만 갔습니다(문서에 남은 기록 기준). 스킵도 침묵하고 그 침묵을 알릴 통로도 침묵한 셈이라 이 구간의 설계를 고친 커밋 245f472는 "조용한 정지"라고 부릅니다. 이 글은 그 96시간을 만든 두 설계 — 잔여물을 건너뛰던 설계와, 건수만 옮기던 알림 설계 — 를 각각 무엇으로 바꿨는지의 기록입니다.
결론부터
바뀐 것은 두 갈래입니다. 트리를 여는 쪽과, 실패를 알리는 쪽입니다.
| 상황 | 예전 (2026-09-04~08 당시) | 지금 (09-08·09-11 수정 후) |
|---|---|---|
| 작업 트리에 잔여물이 있으면 | 종료 코드 2 — 그 사이트를 건너뛴다 | 종료 코드 3 — 이어받고, 남은 목록을 에이전트 프롬프트에 넣는다 |
| 보드 기록이 실패하면 | 디스코드에 "실패 N건" 숫자만 간다 | 못 남긴 내용 자체를 디스코드로 옮긴다 (앞의 3건) |
| 실행 카드를 아예 못 잡으면 | 옮기는 함수가 입구에서 조용히 돌아간다 | BOARD_DOWN — 이 경우에도 내용을 옮긴다 |
첫 번째 행의 변경이 96시간 감금의 재발을 막는 쪽이고(pipeline/worktree.sh:52-58) 둘째·셋째 행의 변경이 "고쳤는데도 두 번 더 조용했던" 09-09~11 의 재발을 막는 쪽입니다(pipeline/report.sh:28-101, FLOW.md:205-229). 세 행 다 공통된 방향이 하나 있습니다. 사람이 알아채야 하는 것을 코드가 알아채게 옮겼다는 것입니다. 잔여물은 사람이 발견할 때까지 기다리는 게 아니라 다음 실행이 이어받고 보고 채널의 실패는 건수가 아니라 유실된 내용으로 알립니다.
검증 방법도 함께 바뀌었습니다. 이 글의 마지막 절에서 다루지만 "고쳤다"고 믿었던 09-08 의 수정이 사흘 뒤에 또 조용해진 이유가 리허설이 밟지 않은 경우였기 때문에, 지금은 가짜 bun 으로 채널을 죽여 경우를 전부 밟는 검사가 붙어 있습니다.
완성된 초안이 나흘 동안 트리에 잠겨 있었다
09-08 오전 10시 10분 커밋 245f472의 메시지는 잔여물을 실측 목록으로 남깁니다. politics-left 이주노동자 글 14,998자에 SVG 4장과 커버, politics-right 예산안 글 11,522자, note 헬스체크 글 10,492자, dev Polars 글 14,753자 — 네 편 전부 "draft: true 로 멈춰 있었다"고 적습니다. 같은 메시지가 적는 "넷이 나흘간 한 편도 못 냈다"는 politics-left 를 포함한 과장입니다 — git 발행 기록 기준으로 0편이 이어진 것은 politics-right·note·dev 세 사이트이고 politics-left 는 09-05 07:48 과 09-06 07:19 에 발행돼 있습니다(아래 일자별 표와 같습니다). 나중에 만들어진 carry 프롬프트의 표현을 빌리면 "본문·삽화까지 끝나 있고 발행만 안 된 초안"이었습니다.
생성 시각과 발행 시각을 이으면 잠긴 시간이 나옵니다. 생성은 글 frontmatter 의 date(UTC 로 저장되므로 KST 로 환산), 발행은 main 브랜치 발행 커밋의 시각입니다. 이 글의 커밋 시각은 전부 author date, 그러니까 작업 트리에서 에이전트가 커밋을 만든 시각 기준입니다. cherry-pick 으로 main 에 얹히는 committer 시각은 별도로 존재합니다 — 09-04 wave1 세 편은 셋 다 13:18:22 에, 09-08 이어받기 네 편은 wt_integrate 일괄로 13:41:43 에 얹혔습니다. 앞선 헬스체크 글이 같은 커밋을 "13:18"로 적어 둔 것은 committer 기준이라 이 글과 표기가 갈립니다. 이 글의 "발행"은 이후로도 author date 기준이고 push·배포 시각은 커밋 메타데이터에 남지 않으므로 실제 공개는 이보다 늦을 수 있습니다.
| 초안 | 생성 (KST) | 발행 (KST) | 잠긴 시간 |
|---|---|---|---|
| politics-left 이주노동자 | 09-07 05:30 | 09-08 11:09 | 약 29시간 39분 |
| politics-right 예산안 | 09-04 12:46 | 09-08 12:34 | 약 96시간 |
| note 헬스체크 | 09-04 12:58 | 09-08 13:07 | 약 96시간 |
| dev Polars | 09-04 12:57 | 09-08 13:36 | 약 96시간 |
09-04 실행의 구조도 봐야 합니다. 그날은 wave1 세 편(money 12:07, politics-left 12:27, travel 12:36)이 커밋된 뒤 wave2 세 사이트의 초안이 12:4612:58 에 생성됐고 wave2 는 커밋되지 않은 채 남았습니다. wave1 이 main 에 얹어진 committer 시각이 13:18:22 이므로 실행은 적어도 그때까지는 살아 있었고 종료는 그 이후의 일이지만 정확한 종료 시각은 남아 있지 않습니다. 멈춘 기제는 기록에 없습니다. 러너 로그는 저장소 밖에 남는 자리라 왜 그 시점에 끝났는지 확인할 수 없고 이 글은 그 한계를 받아들이고 기록이 있는 것 — 커밋, frontmatter, 남은 코드 — 로만 움직입니다. 참고로 네 초안은 모두 GLM 폴백으로 생성됐습니다. 09-08 13:4041 에 네 사이트의 chore(<site>): GLM 폴백으로 생성됨 표시 커밋이 붙었고 note 헬스체크 글 frontmatter 에 generatedBy: glm 이 실제로 들어가 있습니다.
politics-right·note·dev 의 0은 09-04 부터 09-07 까지 넉 날 이어졌다. 사건 기간(09-03~08) 안에서 politics-left 의 0편일은 09-07 하루뿐이다.
일자별로 세어 보면 이렇게 됩니다(발행 = main 발행 커밋 기준, KST).
| 일자(요일) | money | travel | politics-left | politics-right | note | dev | 계 |
|---|---|---|---|---|---|---|---|
| 09-03(목) | 1 (01:04) | 0 | 2 (18:42) | 0 | 0 | 1 (01:04) | 4 |
| 09-04(금) | 1 (12:07) | 1 (12:36) | 1 (12:27) | 0 | 0 | 0 | 3 |
| 09-05(토) | 1 (06:41) | 1 (06:55) | 1 (07:48) | 0 | 0 | 0 | 3 |
| 09-06(일) | 1 (07:05) | 1 (07:19) | 1 (07:19) | 0 | 0 | 0 | 3 |
| 09-07(월) | 1 (07:26) | 1 (07:19) | 0 | 0 | 0 | 0 | 2 |
| 09-08(화) | 2 (07:12·12:59) | 2 (06:24·12:16) | 1 (11:09) | 1 (12:34) | 1 (13:07) | 1 (13:36) | 8 |
| 09-09(수) | 1 (07:19) | 0 | 0 | 1 (10:05) | 1 (09:35) | 1 (09:33) | 4 |
| 09-10(목) | 1 (07:47) | 1 (05:53) | 1 (05:54) | 0 | 0 | 1 (09:50) | 4 |
| 09-11(금) | 1 (07:43) | 1 (07:21) | 1 (07:06) | 1 (08:18) | 1 (08:12) | 0 | 5 |
| 09-12(토) | 1 (06:51) | 1 (07:00) | 1 (07:32) | 0 | 0 | 1 (08:22) | 4 |
09-08 의 8편은 아침 정기 실행의 2편(travel 06:24, money 07:12)과 낮 회수 세션의 6편(11:09~13:36)을 합친 것입니다. 회수 6편 중 travel 12:16 과 money 12:59 는 그날 새로 쓴 글이고 나머지 넷이 위 표의 이어받은 글입니다. money 큐에는 "2026-09-08 planner (2회차)"로 기록이 남습니다(같은 날의 다른 사이트 큐 기록은 형태가 다릅니다). 스킵 쪽도 세면 13건입니다 — 09-05 세 건, 09-06 세 건, 09-07 세 건, 09-08 아침 네 건(politics-left 가 합류한 날). 이 3·3·3·4 분해는 보드 원기록이 남아 있지 않아 트리 상태와 당시 설계, git 발행 기록으로부터 환산한 값이라 집계 원본이 아니라 유도 근거입니다.
09-03 행에도 각주를 하나 붙입니다. 이날의 네 편(money 1·politics-left 2·dev 1)은 전부 9/19/2 실행이 남긴 잔여물의 수동 회수이고 정기 실행의 산출이 아닙니다. 같은 시각 01:04 에 남은 큐 기록 커밋 세 개(9/2 실행분"이라고 적고, 회수된 커밋의 메시지도 겹쳐 말합니다 — money 글(c786835·2fd8462·646fdec)의 메시지가 "9/1b1f642e)은 9/1 에 본문·삽화까지 다 써놓고 삽화 한 장이 비어 발행이 막혔다고, dev 글(29f9fbe)은 9/2 실행에서 이 글을 쓰다 2시간 타임아웃(exit 124)으로 죽었다고, politics-left 의 wip 커밋(6a06562)은 금액 규칙에 막힌 완성 2편을 보관합니다.
잠긴 시간은 09-04 낮부터 09-08 낮까지 96시간이다. 멈춘 기제는 기록에 없다.
정직한 참고가 하나 필요합니다. politics-right·note 는 09-03 에도 0편이었고 money·dev 의 1편은 앞서 말한 9/19/2 실행분 수동 회수뿐이었습니다. 이 0들은 09-0304 의 침묵 실행과 09-02 의 잘린 실행이 만든 것입니다(앞선 헬스체크 글의 영역입니다) note 는 08-26~09-03 에 초안 자체가 없었습니다 — 큐 공백입니다. politics-right 는 08-26 이후, dev 는 09-01 이후에도 공백이 있었습니다. 그러니 이 사건의 실체는 "매일 발행되던 사이트가 끊겼다"가 아닙니다. 완성된 초안의 감금, 네 번의 반복 스킵, 그리고 그 소식을 전하지 못한 통지의 단절이 사건입니다.
거른 것의 정체와 예전 설계 — "건드리지 않는다"의 대가
예전 설계에서 wt_prepare 는 잔여물을 발견하면 종료 코드 2를 내고 그 사이트를 오늘의 대상에서 뺐습니다. 당시 문서와 코드는 이렇게 생겼 있습니다(커밋 245f472 의 삭제 측).
0 준비됨
1 준비 실패 (그 사이트는 오늘 거른다)
2 잔여물 있음 — 사람이 볼 상태다. 건드리지 않는다루프는 rc=2 를 받으면 "작업 트리에 잔여물이 있다. 건너뛴다"를 출력하고 다음 사이트로 넘어갔습니다. 보드로 나가는 통지 문구는 "지난 실행이 그 트리에서 멈춘 흔적이다. 사람이 확인해야 다시 돈다"로 끝났습니다. 게다가 에이전트를 부르는 프롬프트는 항상 /daily-post <site> 하나뿐이어서 설령 실행이 이어진다고 해도 에이전트는 트리에 남은 초안을 보라는 말을 듣지 못했습니다.
이 설계의 전제는 "잔여물은 사람이 봐야 할 것"이었습니다. 그 전제가 틀린 이유는 잔여물의 실체에 있습니다. 잔여물의 대표적인 형태는 다 써 놓고 발행만 안 된 글입니다. 이번의 네 편이 그랬습니다. 그런 것을 통째로 거르면 그 트리는 사람이 매번 실행 로그를 뒤져 발견해 주지 않는 한 영영 안 풀립니다. 넉 날 동안 네 번의 실행이 정확히 그 행동을 반복했습니다.
사실 같은 수작업의 전례가 바로 전날 있었습니다. 09-03 01:04 커밋 6a06562 는 politics-left 의 완성 2편을 draft 유지 wip 로 커밋했고 같은 날 18:42 커밋 9c02b6e 에서 규칙을 수정한 뒤 발행됐습니다. 잔여물을 사람이 손으로 회수해 본 적이 있었던 것입니다. 245f472 는 그 수작업을 코드로 옮기고 "건드리지 않는다"는 종료 코드 2를 지운 커밋입니다.
숫자 하나가 사라지고 숫자의 뜻이 건너뛰기에서 이어받기로 바뀌었다.
건너뛰기에서 이어받기로 — 종료 코드 3
지금의 wt_prepare 는 세 갈래입니다(pipeline/worktree.sh:52-58).
0 준비됨 (깨끗한 트리)
1 준비 실패 (그 사이트는 오늘 거른다)
3 준비됨 — 지난 실행의 잔여물을 **이어받았다**. 부르는 쪽이 그 사실을 넘긴다rc=3 이 나오면 daily.sh 는 wt_dirt 로 잔여물 목록을 꺼내 에이전트 프롬프트에 붙입니다(pipeline/daily.sh:531-545).
"이 작업 트리에는 지난 실행이 남긴 것이 있다:"
"**오늘 글을 새로 시작하기 전에 이것부터 본다.**"
"- 본문·삽화까지 끝나 있고 발행만 안 된 초안이면, 그 글을 남은 단계(윤문·검수·발행)로 마저 몰고 간다. 오늘의 새 글은 쓰지 않는다."
"- 쓰다 만 조각이라 살릴 게 없으면 지우고 새로 시작한다. **무엇을 왜 지웠는지 마지막 보고에 적는다.**"
"- 어느 쪽이든 트리를 깨끗하게 만들고 끝낸다. 그대로 두면 다음 실행이 같은 것을 또 이어받는다."이어받은 실행이 새 글을 쓰게 되면 그 글도 발행까지 못 가고 잔여물이 두 겹이 되므로, "오늘의 새 글은 쓰지 않는다"가 프롬프트의 중심입니다. 끝난 초안이면 남은 단계로 몰고 가고 살릴 게 없으면 지우되 그 이유를 보고하게 합니다. 어느 쪽이든 트리를 깨끗하게 만드는 것으로 끝냅니다.
한 가지 위험한 순간이 있습니다. 이어받은 브랜치의 base 를 오늘 것으로 옮기는 부분입니다. 옮기는 이유는 코드 주석에 있습니다 — "나흘 묵은 파이프라인 코드로 돌면 그 사이 고친 검사 규칙이 안 걸린다". 다만 실패하면 옛 base 그대로 둡니다(pipeline/worktree.sh:94-95 의 || true).
실패하면 옛 base 그대로 둔다. 추적 파일이 양쪽에서 갈리면 git 이 거부하는데, 그때 억지로 옮기는 것은 잔여물을 버리는 것과 같다. 미추적 파일(새 글 디렉터리)은 checkout 이 건드리지 않으므로 대개 그냥 넘어간다. 옛 base 로 돌아도 회수는 된다 — wt_integrate 는
base..br만 집는다.
(worktree.sh 주석, pipeline/worktree.sh:88-94)
회수 쪽이 그 약속을 받습니다. wt_integrate 는 git rev-list --count "$base..$br" 로 개수를 세고 git cherry-pick "$base..$br" 로 가져오는데, 범위가 base..br 이라 브랜치가 옛 base 에 앉아 있어도 회수됩니다(pipeline/worktree.sh:121-134). 충돌하면 cherry-pick 을 abort 하고 1을 돌려 사람이 보게 합니다.
루프는 두 결과를 갈라 보드에 남깁니다(pipeline/daily.sh:707-744). rc=3 이면 WT_CARRIED("지난 실행의 잔여물을 이어받은 사이트:…"), 준비 실패면 WT_SKIPPED("작업 트리 준비에 실패해 건너뛴 사이트:…"). 검사도 교체됐습니다 — worktree.test.sh 에 "잔여물 → rc=3 (이어받음)", "base 를 옮겨도 잔여물이 산다", "막힌 경우 잔여물이 그대로다"가 들어갔습니다. 이 설계가 처음 작동한 날이 09-08 낮이고 결과가 앞 절의 8편입니다.
숫자만 간 알림, 고친 뒤에도 두 번 더 조용했다
첫 번째 침묵은 통지의 경로가 하나뿐이었다는 것입니다. rc=2 시절 스킵 통지는 track_note → Paperclip 보드 한 곳에만 걸렸는데, 그 보드가 09-04 이후 기록을 통째로 남기지 못했습니다. 커밋 3f38077 이 확인한 것은 실행마다 API error 404: Issue not found 였고 키 만료도 아니었습니다 — 그때 만료일 2027-09-04 까지 361일이 남아 있었고 last_used_at 은 09-04 에 동결돼 있었습니다. 원인은 발행 루틴이 러너 자식 프로세스에 주입한 PAPERCLIP_API_KEY 로, 주입된 키로는 이슈가 보이지 않았고 서버는 404 로 답했습니다. 이 이야기의 전체 경위는 앞선 헬스체크 글의 영역이라 여기서는 여기까지만 옮깁니다.
보고 채널이 둘인 구조에서는 한쪽이 죽으면 다른 쪽에 실패 건수를 붙여 주는데, 그래서 디스코드에는 "보드 기록 실패 6건"이라는 숫자만 갔습니다. 이 숫자의 저장소 내 출처는 딱 두 곳입니다 — FLOW.md:217 과 pipeline/report.sh:53 주석, 둘 다 09-08 수정 세션의 산출입니다. 당시 디스코드 메시지 원문은 저장소에 없으므로 이 글도 "문서에 남은 기록으로는 6건" 이상으로 말하지 않습니다. 어느 쪽이든 구조는 같습니다. 숫자는 "보고 채널이 아프다"를 말하고 내용은 "무슨 일이 났다"를 말하는데, 전해진 것은 숫자뿐이었고 무엇이 스킵됐는지는 어디에도 없었습니다. report.sh:49 의 주석이 이 상태를 한 문장으로 적습니다. "보고 채널이 하나면 그 하나가 죽는 순간 조용한 정지가 된다." GA4 글이 다룬 것은 관측 기기(gtag)의 죽음이고 이번은 보고 채널의 죽음으로 축은 다르지만, "프로세스는 초록불인데 소식이 없다"는 모양은 같았습니다.
두 번째 침묵은 고친 뒤에 왔습니다. 09-08 13:05 커밋 becf005 가 "보드에 못 남긴 내용을 디스코드로 옮기기"를 넣었습니다. 상한이 있습니다 — BLOG_BOARD_RELAY_MAX 기본 3. 보드가 하루 종일 죽은 날 track_note 는 열 번 가까이 실패하는데 그걸 다 옮기면 디스코드가 같은 사고로 열 줄이 되고 그러면 사람이 알림을 끕니다. 그래서 앞의 3건만 옮기고 마지막 한 건에는 "(보드가 계속 죽어 있어 이후 기록은 여기로 옮기지 않습니다…)"를 붙입니다. RELAYING 플래그는 보드 실패 → 디스코드, 그 디스코드 실패 → 보드의 맞재귀를 끊습니다(pipeline/report.sh:58-87).
그런데 이 옮기기는 09-09~11 사흘간 한 건도 작동하지 않았습니다(커밋 1728c3c 가 밝힙니다). 카드 열기부터 실패하면 이슈 ID 가 비는데, 당시 track_note 의 첫 줄은 if [ -z "$ISSUE_ID" ]; then return 0; fi — 카드가 없으면 조용히 돌아가는 입구가 함수 맨 앞에 있었습니다. 그 사흘 보드는 404 에서 401 로만 바뀌어 있었습니다. 09-08 의 수정이 주입 키 한 겹만 벗긴 것입니다. 런타임이 PAPERCLIP_API_URL 도 같이 넣어 자격증명 조회가 깨졌고 last_used_at 은 09-08 에서 76시간 멈춰 있었습니다.
숫자는 "보고 채널이 아프다"를 말하고 내용은 "무슨 일이 났다"를 말한다. 둘은 다른 정보다.
그 사흘의 발행 자체는 매일 있었습니다 — 09-09 네 편, 09-10 네 편, 09-11 다섯 편. 다만 전 사이트는 아니었고 여섯 사이트 모두 최소 하루씩 한도 초과로 GLM 폴백으로 발행됐습니다(GLM 표시 커밋: money 09-09·10·11, note 09-09·11, politics-right 09-09·11, dev 09-10, politics-left 09-11, travel 09-11 — "매일 여섯 사이트 전부"라는 강한 독해는 근거가 없습니다). 주어를 정확히 해 둡니다. 이 기록이 안 남은 것은 보고 채널이지 git 이 아니었습니다. GLM 표시 커밋은 날짜별로 남아 있습니다. 남지 않은 것은 "카드 열기부터 실패한 날의 실행 내용"이었고 relay 가 그것을 받도록 만들어져 있었는데 입구에서 조용히 돌아간 것입니다.
구멍을 막은 것이 09-11 17:51 커밋 1728c3c 입니다. 한 커밋에 네 건이 들어갔습니다.
track.ts가PAPERCLIP_API_URL까지 unset- 보고 함수를
pipeline/report.sh로 분리하고BOARD_DOWN과report.test.sh추가 - 스레드 제안이 러너 잠금에 걸려 사흘 연속 생략된 부분의 무시
- 티스토리 지연 상한 480초
뒤의 둘은 각각 스레드·티스토리 이야기라 티스토리 글의 영역이고 여기서는 두 번째를 봅니다.
BOARD_DOWN 은 "보드에 적을 곳이 없는 날"을 이름으로 만든 것입니다. daily.sh 가 오늘 실행 카드를 시도했는데 못 잡으면 BOARD_DOWN=1 을 세우고(pipeline/daily.sh:376-389) track_note 는 이슈 ID 가 빈 날에도 이 깃발이 서 있으면 내용을 디스코드로 옮깁니다(pipeline/report.sh:89-101). "보드를 아예 안 쓴 실행"(0)과는 구분하는데 — 안 쓴 실행은 옮길 이유가 없으므로 — 그 구분이 테스트 4번으로 고정돼 있습니다.
마지막 조각은 검증 방법입니다. 이 함수가 예전엔 daily.sh 안에 있어서 커밋의 말대로 "나머지 경우를 돌려볼 방법이 없었습니다". report.test.sh 는 PATH 앞에 가짜 bun 스텁을 끼워 네트워크 없이 보드와 디스코드를 마음대로 죽이고 일곱 경우를 밟습니다.
- 보드 정상이면 옮기지 않는다
- 코멘트 실패면 옮긴다
- 카드 없는 날도 옮긴다
- 보드를 시도하지 않은 실행은 조용하다
- 5회 실패면 3건만 옮기고 3번째에 중단 고지를 붙이며, 실패는 5건 그대로 집계한다
- 양채널 동시 사망이면 재귀 없이 각 1회
- 디스코드 알림이 실패하면 반대로 보드에 옮긴다
커밋은 "bun test 452 통과 · report.test.sh 7경우 통과"를 남깁니다. 8월 21일 구조적 가드레일 글이 "게이트가 자기 경로만 지켰다"를 다뤘는데 이번도 같은 방향입니다. 09-08 의 리허설은 보드를 없는 이슈로 죽이고 track_note 를 다섯 번 돌리는 방식이어서, 카드는 잡았는데 코멘트가 실패하는 경우와 양채널을 다 죽인 경우까지는 밟았습니다. 밟지 않은 것은 카드 열기부터 실패하는 경우이고 그때 검증되지 않은 것이 바로 그 경우였습니다. FLOW.md:229 의 결론이 이 글의 결론이기도 합니다. 리허설이 밟지 않은 경우는 검증된 게 아니다.
근거와 참고
- 커밋
245f472(2026-09-08 10:10 KST) — rc=3 설계 본체, 잔여물 실측 목록(글자 수·SVG·draft 상태), worktree.test.sh 교체, "조용한 정지" 표현 - 커밋
3f38077(2026-09-08 10:32 KST) — 보드 404 원인(주입 키), 키 만료 361일 남음·last_used_at 동결 확인, 감시 전환 - 커밋
becf005(2026-09-08 13:05 KST) — 보드→디스코드 relay,BLOG_BOARD_RELAY_MAX=3,RELAYING - 커밋
1728c3c(2026-09-11 17:51 KST) — relay 0건 원인,PAPERCLIP_API_URLunset, report.sh 분리,BOARD_DOWN, report.test.sh 7경우, bun test 452 통과 - 커밋
80d284d·803d945·e8092af·727d655(2026-09-08 11:09~13:36 KST) — 이어받아 발행된 네 편 - 커밋
6a06562·9c02b6e(2026-09-03 01:04·18:42 KST) — 잔여물 수동 회수의 전례. 같은 시각의 큐 기록 커밋c786835·2fd8462·646fdec은 메시지에 "9/1~9/2 실행분"이라고 남기고, 회수된b1f642e·29f9fbe의 커밋 메시지도 9/1·9/2 실행의 잔여물임을 적는다 - 현재 코드 —
pipeline/worktree.sh:52-134(종료 코드·base 보존·wt_integrate),pipeline/daily.sh:531-545(carry 프롬프트)·:707-744(루프·WT_CARRIED/WT_SKIPPED)·:376-389(BOARD_DOWN 설정),pipeline/report.sh:28-101(BOARD_DOWN 정의·relay·track_note),pipeline/report.test.sh(가짜 bun 7경우) FLOW.md:205-229— 채널 이중화 설계 문단.:217·report.sh:53의 "보드 기록 실패 6건",:229의 "리허설이 밟지 않은 경우는 검증된 게 아니다"- 발행 시각의 원천 — git 커밋 메타데이터(+0900)와 글 frontmatter
date(UTC 저장, KST 로 환산). 이 글의 모든 시각은 author date(작업 트리에서 에이전트가 커밋한 시각) 기준이고 cherry-pick 으로 main 에 얹어진 committer 시각은 별도다 — 09-04 wave1 셋(b7796dd·5de1eb3·f4c1eac)은 셋 다 13:18:22, 09-08 이어받기 네 편(80d284d·803d945·e8092af·727d655)은 wt_integrate 일괄 13:41:43. push·배포 시각은 이 기준에 없다 - 앞선 글 — 셸 헬스체크 빈 응답 exit 124·티스토리 미러링 제거·GA4 조회수 0·구조적 가드레일