oh-my-customcode 1.1.76 → 1.1.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ Before declaring any task `[Done]`, verify completion against task-type-specific
10
10
 
11
11
  | Task Type | REQUIRED Verification Before [Done] |
12
12
  |-----------|-------------------------------------|
13
- | Release | All issues closed, version bumped, PR merged; **대기 조건은 AND** — `release.yml` completed **AND** GitHub Release `isDraft=false` (npm 도달은 충분조건이 아님, 아래 참조); **External automation verified**: `.github/workflows/` listed AND `gh run list --limit 10` checked for auto-publish workflows |
13
+ | Release | All issues closed, version bumped, PR merged; **대기 조건은 AND** — `release.yml` completed **AND** GitHub Release `isDraft=false` (npm 도달은 충분조건이 아님; 근거는 Read 도구로 원문 주석 참조); **External automation verified**: `.github/workflows/` listed AND `gh run list --limit 10` checked for auto-publish workflows |
14
14
  | Implementation | Code compiles/passes lint, tests pass (if exist), no TODO markers left |
15
15
  | Documentation | Links valid, counts accurate, cross-references updated |
16
16
  | Git Operations | Operation succeeded (check exit code), working tree clean |
@@ -18,12 +18,15 @@ Before declaring any task `[Done]`, verify completion against task-type-specific
18
18
  | Agent/Skill Creation | Frontmatter valid, referenced skills exist, routing updated |
19
19
  | UI/Frontend | Browser render verified (dev server running + page loaded), no console errors, visual output matches intent; **CSS/style changes**: capture before/after visual diff or screenshot; type-check passing alone is NOT sufficient |
20
20
 
21
+ <!-- DETAIL: async-wait Origin #1584
21
22
  > **비동기 연쇄의 대기 조건 = 가장 늦게 완료되는 산출물 (Origin: #1584 #2)**: 릴리즈 체인처럼 산출물이 순차 생성되는 비동기 연쇄에서, 중간 산출물 도달을 완료로 읽으면 뒤따르는 산출물이 미완인 채 남는다. npm publish는 `release.yml` **안에서** GitHub Release 생성보다 먼저 끝나므로, npm 도달 시점에 검증을 끝내면 Release가 `draft=true`로 남을 수 있다. `gh run view <id> --json status`(completed) **AND** `gh release view <tag> --json isDraft`(false)를 둘 다 확인한다.
22
23
  >
23
24
  > v1.1.44는 타이밍이 맞아 드러나지 않고 v1.1.45에서 노출된 **간헐적 결함**이다 — 한 번 통과한 검증 순서가 경합을 배제하지 않는다.
25
+ -->
24
26
 
25
- ## Optional: Quantitative Evidence (advisory, added v0.114.0, #1034)
27
+ ## Optional: Quantitative Evidence (advisory, added v0.114.0, #1034) — supplementary 4-metric evidence (correctness/step_ratio/tool_call_ratio/latency_ratio) for [Done], not a binary gate. See full spec via Read tool.
26
28
 
29
+ <!-- DETAIL: Optional Quantitative Evidence detail
27
30
  For complex agent invocations or multi-step workflows, attach 4-metric evidence to [Done] declarations as supplementary evidence (NOT a binary gate):
28
31
 
29
32
  | Metric | Source | Format |
@@ -47,6 +50,7 @@ For complex agent invocations or multi-step workflows, attach 4-metric evidence
47
50
  - Skill: `agent-eval-framework` (4-metric framework + ideal trajectory schema)
48
51
  - Guide: `guides/agent-eval/README.md` (measurement methodology)
49
52
  - Issue: #1034
53
+ -->
50
54
 
51
55
  ## Self-Check (Before Declaring Done)
52
56
 
@@ -83,7 +87,9 @@ Never accept "pre-existing" without direct base-branch evidence. A false "pre-ex
83
87
  |--------------|----------|
84
88
  | 보유 실측값과 어긋나는 서브에이전트 서술을 "리뷰 항목으로 넘깁니다"라며 이월 | 즉시 정정 위임 또는 판정을 가르는 **읽기 전용** 명령 1개를 직접 실행(`git show` / `gh … view` 등 — 파일 수정·상태 변경은 계속 위임, R010) |
85
89
 
90
+ <!-- DETAIL: Origin #1704
86
91
  Origin: #1704 #2 (v1.1.73 세션 — sauron FAIL + 적대적 리뷰 F3 동시 적발, 인용 오류 계열 4회째. 오케스트레이터는 위임서에 "제가 실측한 커밋 메시지(#1688)와 어긋날 수 있어 리뷰 항목으로 넘깁니다"라고 적어 판정 가능한 사실을 판정하지 않았습니다). Cross-ref: R020 Read-Before-Characterize, R010 「출처 인용과 인접 문구 점검도 같은 규율」.
92
+ -->
87
93
 
88
94
  ### 원인 분석도 완료 보고와 같은 등급의 검증 대상 (Origin: #1595 #3)
89
95
 
@@ -100,13 +106,19 @@ Origin: #1704 #2 (v1.1.73 세션 — sauron FAIL + 적대적 리뷰 F3 동시
100
106
  | 서브에이전트의 원인 분석을 결론으로 접수하고 후속 계획의 전제로 사용 | 가설로 접수 → 결정론적 명령으로 정정 후 전제화 |
101
107
  | 오케스트레이터와 서브에이전트의 진단이 양립 불가한데 어느 쪽이 맞는지 실측 없이 한쪽 채택 | 양립 불가를 **모순 신호**로 취급 — 두 진단을 가르는 명령을 즉시 실행 |
102
108
 
109
+ <!-- DETAIL: Origin #1595 #3
103
110
  Origin: #1595 #3 (v1.1.48 세션 — checkout 거부 메시지에 대해 mgr-gitnerd는 "develop에 tracked로 존재", 오케스트레이터는 "develop에 없음"으로 정반대 진단. `git cat-file -e` + `git show --name-status`로 정정 — 서브에이전트 분석이 틀렸고 오케스트레이터의 사실은 맞았으나 결론이 틀렸다). Cross-ref: R020 Read-Before-Characterize, R010 「참인 전제 ≠ 참인 함의」.
111
+ -->
104
112
 
105
113
  ### Verification-Delegation Non-Termination (검증 위임 판정 종료 보장)
106
114
 
115
+ <!-- DETAIL: Verification-Delegation clause explanation
107
116
  구조 검증(mgr-sauron R017)·판정·품질 게이트를 서브에이전트에 위임할 때, 위임 프롬프트에 **"최종 PASS/FAIL 판정 없이 turn을 종료하지 말라"**를 명시한다 — 단 이 clause는 **보조 수단**일 뿐 1차 방어선이 아니다. clause를 명시해도 mid-step 종료가 **누적 14회** 재발했다(v1.1.13/14/17/18/19 … v1.1.44, 아래 Origin 참조). **예방의 1차 방어선은 위임 경계 분할**(아래 「위임 경계를 Phase 개수로 설계」)이고, **사후 1차 방어선은 오케스트레이터의 직접 ground-truth 실측**이다.
117
+ -->
108
118
 
119
+ <!-- DETAIL: mid-step termination symptom examples
109
120
  mid-step 종료는 예상 가능한 정상 실패 모드로 취급한다 — 발생 시 즉시 ground-truth를 실측해 실제 진행 상태를 확인한다. **증상만으로 결과를 넘겨짚지 않는다**: 같은 "...중" 한 줄 종료라도 실측 결과는 **세 방향 모두** 관측됐다 — (a) 보고=완료("merging now" → 실측 시 PR 이미 MERGED, resume 불필요), (b) 보고=미완료("CI 실행 중" → 실측 시 PR OPEN 미머지, resume 필요), (c) **실제가 보고보다 앞섬**("커밋 1 완료, 커밋 2 스테이징으로 이어갑니다" → 실측 시 3개 커밋 전부 완료). 세 방향이 모두 나온 이상 증상 기반 진행도 추론은 **원리적으로 불가능**하며, 실측만이 유일한 판정 수단이다. 미완이면 SendMessage로 resume하되, 오케스트레이터가 실측한 값(예: "CI 전부 통과, mergeStateStatus=CLEAN")을 resume 메시지에 동봉해 에이전트가 재폴링 후 재종료하는 루프를 끊는다.
121
+ -->
110
122
 
111
123
  | Anti-pattern | Required |
112
124
  |--------------|----------|
@@ -116,28 +128,41 @@ mid-step 종료는 예상 가능한 정상 실패 모드로 취급한다 — 발
116
128
 
117
129
  #### 위임 경계를 Phase 개수로 설계 (예방 1차 방어선)
118
130
 
131
+ <!-- DETAIL: Phase 위임 설명 (표와 중복)
119
132
  다중 Phase 작업을 한 에이전트에 위임하면 **Phase 경계가 곧 종료 유혹 지점**이 된다 — 완료 조건 번호 명시와 종료 금지 clause를 넣어도 동일하다. 위임 단위는 **단일 목표 1개**로 자르고, Phase가 2개 이상이면 분할해 순차 발주한다.
133
+ -->
120
134
 
121
135
  | Anti-pattern | Required |
122
136
  |--------------|----------|
123
137
  | 다중 Phase 작업(3-Phase 검증, 3-커밋 시퀀스)을 한 에이전트에 위임하고 clause로 종료를 막으려 함 | 위임 단위를 단일 목표 1개로 분할해 순차 발주 — 경계 분할이 clause 강화보다 실효적 |
124
138
 
139
+ <!-- DETAIL: 대조 실증 #1574
125
140
  대조 실증(#1574, v1.1.44 세션): 단일 목표 위임(PR 생성 / 머지 / 브랜치 정리 / 버전 범프) **4건 전원 완주**, 다중 Phase 위임(mgr-sauron 3-Phase, mgr-gitnerd 3-커밋) **2건 모두 mid-step 종료**. 같은 세션에서 릴리즈 단계를 push+범프 / PR 생성 / 머지로 3분할한 것이 이 설계의 적용례다.
141
+ -->
126
142
 
143
+ <!-- DETAIL: 배선 R016 설명
127
144
  **배선 (R016 Rule Wiring Check)**: 이 조항의 발동 실행 경로는 `auto-dev.yaml`의 `deep-plan` / `deep-verify` 스텝이다. 파이프라인 정의가 `skill: deep-plan`처럼 **스킬 이름만** 적고 있으면, 그 정의를 따르는 것이 이 조항을 우회하는 경로가 된다 — `skill:` 값은 **분할의 근거가 되는 스킬 정의**를 가리키는 것이지 "1회 호출하라"는 지시가 아니다. 다중 Phase 스킬을 파이프라인 스텝으로 두는 정의에는 분할 지시를 **스텝 설명에 함께 기재**한다(auto-dev.yaml은 4개 사본이 CI로 동일성 강제됨).
145
+ -->
128
146
 
129
147
  | Anti-pattern | Required |
130
148
  |--------------|----------|
131
149
  | 파이프라인 정의가 `skill: <다중 Phase 스킬>`이므로 그대로 호출 | 스킬 정의의 Phase를 먼저 읽고 단일 목표 위임으로 분할해 순차 발주; 파이프라인 정의에도 분할 지시를 배선 |
132
150
 
151
+ <!-- DETAIL: Origin 보강 #1595 #4
133
152
  Origin 보강: #1595 #4 (v1.1.48 세션 — `deep-plan`(3-Phase)이 식별 헤더만 출력하고 tool_uses=0으로 6.9초에 종료, 산출물 0 실측. `mgr-sauron`(3-Phase)은 판정 없이 종료. 두 건 모두 이 조항을 **알고 있었음에도** `auto-dev.yaml`의 스킬 지정을 따라 그대로 호출한 결과 — 텍스트는 있고 배선이 없던 사례).
153
+ -->
134
154
 
155
+ <!-- DETAIL: Origin #1443 누적 이력
135
156
  Origin: #1443 (Session 126 회고 찐빠 #1) — v1.1.3 R017 검증에서 mgr-sauron이 source-hash 대조 중 판정 없이 종료 → resume 후 PASS. v1.1.4에서 "판정 반드시 출력" 명시로 1회 완료(대조 실증). **5회 재발 확인(#1492, Session 132)**: v1.1.13/14/17(clause 명시에도 재발) → v1.1.18(완료조건 6항목+종료금지 명시에도 "merging now" 한 줄 남기고 종료, 실측 결과 이미 완료) → v1.1.19(위임 프롬프트에 "4회 무시됨"까지 명시했으나 "CI 실행 중" 한 줄 남기고 종료, 실측 결과 미완료). Session 132에서 2회 모두 오케스트레이터 직접 실측으로 복구 — clause 강화가 아니라 실측 습관화가 유일하게 실증된 방어선. **누적 11회 확인(#1518 찐빠 #2, Session 136)**: v1.1.30 릴리즈 세션에서도 "완료 조건 5항목 실측 + 판정 없이 종료 금지" 명시에도 mgr-gitnerd가 "폴링 완료 통지를 기다리겠습니다" 한 줄만 남기고 종료 → 오케스트레이터 직접 실측으로 복구(lockfile push 완료 / CI pending / PR OPEN); 이번엔 "대기 중" 증상이 실제 미완료였고 Session 132의 "머지 중" 증상은 실제 완료였다는 대비로 증상→결과 추론 금지가 재확인됨. **누적 14회 + 3방향째 확인(#1574, v1.1.44 세션)**: mgr-sauron 3-Phase / mgr-gitnerd 3-커밋 위임 2건이 Phase 경계에서 종료했고(위 「위임 경계를 Phase 개수로 설계」의 대조 실증), 그중 mgr-gitnerd는 "커밋 2로 이어가겠다"고 보고했으나 실측 시 3개 커밋이 이미 전부 완료 — 실제가 보고보다 앞서는 세 번째 방향.
157
+ -->
136
158
 
159
+ <!-- DETAIL: cross-reference pointer
137
160
  Cross-reference: R018 (Member Completion Verification), `feedback_release_delegation_phasing`, `feedback_orchestrator_direct_verify` (release delegation phasing을 verification 위임에도 확장).
161
+ -->
138
162
 
139
163
  #### maxTurns 절단 실증 (Origin: v1.1.50 세션)
140
164
 
165
+ <!-- DETAIL: maxTurns 절단 실증 상세
141
166
  **실측 (v1.1.50 세션)**: 오케스트레이터가 4개 그룹을 병렬 위임했고 **그중 3개가 20턴 `maxTurns` 한도로 절단**됐다. 세 건 모두 통지에 `stopped at its 20-turn limit (partial result)`이 명시됐고 출력이 작업 중간에서 끊겼다 — 한 건은 문장 중간에서 절단(진행도 불명, 실측 필요), 한 건은 "Templates 미러를 동기화합니다"라고 예고한 직후 절단(오케스트레이터는 미실행으로 추정했으나 **실측 결과 미러 동기화까지 이미 완료**돼 있었다 — 위 「증상만으로 결과를 넘겨짚지 않는다」의 "(c) 실제가 보고보다 앞섬" 재현), 한 건은 "Now R020 — three items"라고 다음 작업을 예고한 직후 절단(실측 결과 **편집은 완료, 검증만 미수행** 상태였다). 세 건 모두 **절단 위치 문장과 실제 진행도가 어긋났다** — 이것이 이 실증의 핵심이다.
142
167
 
143
168
  1. **확정**: `maxTurns` 절단은 이 조항이 누적 14회로 기록한 "판정 없이 종료" 증상의 **실재하는 원인 중 하나**다. CC v2.1.246부터 partial로 표시되므로 이제 **관측 가능**하다(그 이전에는 완료로 보였다 — R018 v2.1.246 노트 교차참조).
@@ -149,15 +174,18 @@ Cross-reference: R018 (Member Completion Verification), `feedback_release_delega
149
174
  7. **리서치형 위임의 산출물 우선 기록 (Origin: #1621 #2b, v1.1.51 세션)**: 파일 편집형뿐 아니라 리서치형(수집 중심) 위임도 절단에 취약하다 — v1.1.51 세션에서 훅 이벤트 감사 위임이 22회 도구 호출(WebFetch/Read)을 전부 수집에 쓰고 **아티팩트를 1회도 Write하지 않은 채 절단**되어, 수집한 산출물 전량이 에이전트 컨텍스트에만 존재하고 파일에는 남지 않았다(재개 지시 "산출물 우선 기록"으로 복구). 리서치형 위임의 표준 문안에는 **"첫 2턴 안에 아티팩트 골격을 Write하고 수집 즉시 증분 Edit하라 — 수집 완료 후 일괄 기록 금지"**를 포함한다. 절단은 항상 마지막 작업을 자르므로, 기록을 마지막에 몰면 절단 시 산출물이 전량 유실된다 — 위 5항(파일 편집형의 "미러 즉시 동기화")의 리서치형 대응이다.
150
175
  8. **훅 피드백 잠식 (Origin: #1625 #5)**: settings 훅은 서브에이전트 세션에도 발화하므로, 세션 종료성 훅(Stop 계열)의 반복 피드백이 서브에이전트의 마지막 턴들을 소모·오염시켜 최종 보고가 "대기 중" 류로 끝날 수 있다 — mid-step 종료·"실제가 보고보다 앞섬"의 신규 원인 축. v1.1.53 세션에서 커밋 에이전트 2건의 "대기 중" 보고가 실측 결과 모두 완전 완료였다. 절단·대기 보고를 받으면 훅 피드백 잠식 가능성도 원인 후보에 포함하고 ground-truth로 판정한다.
151
176
  9. **문서 미러·parity 위임 상한 — 3파일 이하, 산술 통과가 절단 부재를 보장하지 않음 (Origin: #1709 찐빠 #1, v1.1.75 세션)**: 6항의 편집 항목 산술(항목 × 2턴 + 파일 고정비 3턴)을 **적용하지 않고** 문서 미러·parity 위임(카운트·용어·목록 동기화를 여러 문서에 반복 반영) 7파일을 단일 발주하면 절단됩니다 — 6항 공식대로면 7파일은 고정비만 `7×3=21`턴으로 이미 20턴을 초과하므로, 산술을 적용했다면 애초에 단일 발주하지 않았을 상황이었습니다. 실측 결과 6파일 편집은 완결(카운트·Agora 행·훅 수·CONTRIBUTING 절차 재작성)됐고 남은 1파일(AGENTS.md)은 변경 불필요였습니다. 같은 반복의 6개 편집 항목·1파일 위임(ARCHITECTURE_ko 미러)도 정확히 20턴에서 절단됐으나 보고는 전달됐습니다 — 이 건은 신설 공식(파일 수 × 3 + 편집 항목 수 × 2 ≤ 16, `1×3+6×2=15`)을 **통과**하고도 절단됐으므로, 이 산술은 절단 부재를 보장하는 게이트가 아니라 **상한 가이드**입니다. 문서 미러·parity는 편집 항목 수가 파일마다 반복돼 산술을 누락하면 초과 폭이 커지므로, 4항의 일반 파일 편집형 "파일 4~5개 상한"보다 좁은 **3파일 이하 상한**을 따로 두고, 위임서에 위 턴 산술(≤16 — 20턴 한도 아래 여유를 둔 제안값이며 근거 수치는 미확정)을 함께 기재합니다. 3파일 상한은 6항 산술을 대체하지 않는 **보조 상한**입니다. 배선: auto-dev.yaml implement 스텝 표준 제약 블록 (4사본).
177
+ -->
152
178
 
153
179
  | Anti-pattern | Required |
154
180
  |--------------|----------|
155
181
  | 파일 수만 세어 위임 크기 판정 → 조항 다수 파일에서 절단 | 편집 항목 수 × 2턴 + 파일 고정비(3턴)로 산술 |
156
182
  | 리서치 위임이 수집을 끝낸 뒤 일괄 기록 | 첫 2턴 내 골격 Write + 증분 Edit |
157
183
  | "대기 중" 보고를 미완료로 단정 | 훅 피드백 잠식 가능성 포함해 ground-truth로 완료 여부 판정 |
158
- | 문서 미러·parity 위임을 "파일 4~5개 상한" 근거로 7파일까지 단일 발주 | 문서 미러·parity 위임은 파일 3개 이하로 분할 + 턴 산술(파일 × 3 + 항목 × 2 ≤ 16)을 위임서에 기재 |
184
+ | 문서 미러·parity 위임을 "파일 4~5개 상한" 근거로 7파일까지 단일 발주 | 문서 미러·parity 위임은 파일 3개 이하로 분할 + 턴 산술(파일 × 3 + 항목 × 2 ≤ 16)을 위임서에 기재(상한 가이드 — 통과해도 절단 가능) |
159
185
 
186
+ <!-- DETAIL: v2.1.257 버전노트
160
187
  > **v2.1.257+**: 서브에이전트가 컴퓨터 절전·연결 끊김·서버 오류로 응답이 mid-stream 절단될 때 불완전 응답으로 그대로 종료하던 동작이 **자동 이어감**으로 수정되었습니다. 즉 "판정 없이 종료" 증상의 원인 축 중 **네트워크/서버 절단 축은 v2.1.257부터 소멸**하며, 남는 실재 원인은 `maxTurns` 한도(위 실증)·위임 경계 미분할·에이전트 자체 판단 종료·훅 피드백 잠식(8항)입니다. 따라서 v2.1.257+ 환경에서 mid-step 종료를 관측하면 네트워크 절단을 원인 후보에서 먼저 제외하고 `maxTurns` partial 표시 유무를 확인합니다 — 단 원인 축 하나가 사라졌다고 ground-truth 실측 원칙을 낮추지 않습니다. 같은 릴리즈에서 턴을 백그라운드로 보낼 때(`←`/Ctrl+B) 실행 중이던 도구가 거부된 것으로 처리되던 결함도 수정되어, 구버전 background 세션의 "도구 거부됨" 기록은 실제 거부의 증거가 아닐 수 있습니다.
188
+ -->
161
189
 
162
190
  Cross-reference: R018 (v2.1.246 maxTurns partial-marking 노트), R009 (Member Prompt Size Cap — 프롬프트 토큰 상한과 별개로 턴 수 상한도 위임 크기 설계 변수임을 추가).
163
191
 
@@ -194,9 +222,11 @@ Cross-reference: R018 (v2.1.246 maxTurns partial-marking 노트), R009 (Member P
194
222
  | "UI changes done" / "CSS updated" | type-check passes but browser render not verified; visual output unknown | Start dev server, open browser, confirm visual output; capture screenshot or describe what was seen |
195
223
  -->
196
224
 
197
- ### Tool-Call Payload Completeness
225
+ ### Tool-Call Payload Completeness — required 파라미터는 invoke 시점에 확인(완료 선언 시점이 아님); canonical owner는 R008 (#1324). See detail via Read tool.
198
226
 
227
+ <!-- DETAIL: Tool-Call Payload Completeness pointer detail
199
228
  도구 호출의 required 파라미터는 invoke 전에 확인한다(완료 선언 후가 아니라 호출 시점의 전제조건). announce(prefix)만 출력하고 payload 의 required 필드를 누락하는 패턴은 R008 "Required-Parameter Completeness Check"가 canonical owner다. Reference: #1324.
229
+ -->
200
230
 
201
231
  ## Completion Contract Format — [Contract] + [Done] with criterion/evidence pairs. See template via Read tool.
202
232
 
@@ -250,15 +280,21 @@ Original incident: v0.87.2~v0.88.0 session (issue #869). The originating memory
250
280
  | 인터럽트 후 기존 작업 진행 | 인터럽트 내용 통합 또는 명시적 deferral 후 진행 |
251
281
  | "사과만 짧게" | 부족 — plan 재정렬 후속 필수 |
252
282
 
283
+ <!-- DETAIL: Reference #1188
253
284
  Reference issues: #1188 item #8.
285
+ -->
254
286
 
255
287
  ### Interrupt ≠ Prior-Request Cancellation (#1341 ①)
256
288
 
289
+ <!-- DETAIL: Origin #1341
257
290
  > Origin: #1341 찐빠 #1 — 사용자가 멀티라인 요청("스킬 FSD를 만들자 … 내용은 아래와 같다")을 두 줄에 나눠 보내려다 중간에 인터럽트했는데, 모델이 이를 "직전 요청 취소" 신호로 단정하고 즉시 다른 작업(/goal 자율 루프)으로 전환했다. 사용자가 "취소가 아니야, 두 줄이 한 번에 안 가서 인터럽트했던 것"으로 정정.
291
+ -->
258
292
 
259
293
  **적용 범위 (비파괴 한정)**: 이 규칙은 **비파괴적** 직전/진행 중 요청에만 적용된다 (스킬/문서 생성, 분석, 비파괴 편집 등). 인터럽트된 작업이 **파괴적·비가역 작업**(R001 — `git reset --hard`, `git clean -fd`, `rm`, 터널/DNS/k8s/인프라 삭제 등)이면 이 규칙은 적용되지 않으며, 아래 Safety Carve-Out을 따른다.
260
294
 
295
+ <!-- DETAIL: 비파괴 작업 설명 (표와 중복)
261
296
  비파괴 작업에 한해: 사용자 인터럽트 직후 첫 메시지가 모호하면, 직전 요청을 "취소"로 단정하지 않는다. 인터럽트는 입력 교정·추가 입력·멀티라인 연속 입력 중단 등 다양한 의도일 수 있으며, 취소는 그중 하나일 뿐이다. 직전 요청 맥락이 살아있는 상태에서 인터럽트 의도를 단정해 다른 작업으로 전환하지 말고, 모호하면 한 번 확인한 뒤 (비파괴적 후속 처리를) 진행한다.
297
+ -->
262
298
 
263
299
  **Safety Carve-Out — 파괴적 작업 (fail-closed, stop-first ask-after)**: 진행 중이던 작업이 파괴적·비가역 작업이면, 인터럽트 수신 시 의도가 모호하더라도 그 작업을 **먼저 즉시 중단(halt/abort)**한 뒤 의도를 확인한다. 재개는 명시적 재승인을 요구한다. 인터럽트의 핵심 가치는 emergency-stop이므로 파괴적 작업에서는 의도 명료화보다 정지가 우선한다(R001 우선). 여기서 "진행"은 파괴적 작업의 계속을 의미하지 않는다.
264
300
 
@@ -272,7 +308,9 @@ Reference issues: #1188 item #8.
272
308
  | 멀티라인/연속 입력 중간의 인터럽트를 "전체 취소"로 해석 | 추가 입력·교정 가능성 고려; 사용자 다음 메시지를 기다리거나 의도 확인 |
273
309
  | 파괴적 작업 진행 중 인터럽트를 "맥락 유지 후 계속"으로 처리 | 즉시 halt(fail-closed) 후 의도 확인; 재개는 명시적 재승인 (stop-first ask-after, R001 우선) |
274
310
 
311
+ <!-- DETAIL: interrupt-intent extension 설명
275
312
  This is the interrupt-intent extension of Read-Before-Characterize ("actual intent ≠ assumed intent"), scoped to non-destructive context. **Applicability vs "Interrupt Priority Re-Ordering" (above)**: Priority Re-Ordering는 인터럽트가 **명확한 새 작업/룰 위반을 동반**할 때; 인터럽트 첫 메시지가 **모호**하면 본 섹션이 우선(확인 먼저). Cross-reference: R003 (Request Handling — Interrupt row; precedence Risky > Interrupt), R001 (파괴적 작업 halt 우선).
313
+ -->
276
314
 
277
315
  ## Diagnostic Hypothesis Verification
278
316
 
@@ -285,11 +323,15 @@ This is the interrupt-intent extension of Read-Before-Characterize ("actual inte
285
323
  | 권한/토큰 오류 | 플래그/옵션 변경으로 우회 시도 | 권한 범위·토큰 종류 직접 확인 |
286
324
  | 트랜스크립트·로그 통계로 원인 추정 | 통계적 상관(예: "첫 레코드 thinking 13/21")만으로 코드 경로의 인과를 "확정"해 이슈 코멘트·메모리에 기록 | 해당 코드 경로를 읽고 판정 로직을 1:1 재현(jq/스크립트)해 인과를 확인한 뒤 기록; 그 전에는 R011 `[hypothesis]` 태그로만 저장 |
287
325
 
326
+ <!-- DETAIL: Common Violation #1217
288
327
  ### Common Violation (#1217 item #4)
289
328
  npm publish E403을 `--provenance` attestation 충돌로 오진단 → release workflow에서 `--provenance` 제거 커밋 머지 → 2차 시도 동일 실패 → 실제 원인은 NPM_TOKEN 권한(Automation token 필요). 잘못된 추정으로 릴리즈 워크플로우를 영구 변경.
329
+ -->
290
330
 
331
+ <!-- DETAIL: Common Violation #1652
291
332
  ### Common Violation (#1652 #1) — 통계적 상관 ≠ 코드 인과
292
333
  v1.1.59 세션에서 #1643(advisor "R007 헤더=0" 오탐) 원인을 트랜스크립트 통계만으로 "advisor가 thinking 전용 첫 레코드를 병합하지 못함"이라 이슈 코멘트·feedback 메모리에 확정 기록 → triage가 현행 코드(이미 병합·thinking 제외)와의 불일치를 지적 → 진단 에이전트가 jq로 판정 로직을 1:1 재현해 반박 — 실제 원인은 레이블 문구 모호성(값은 위반 건수인데 "헤더=0"으로 읽힘). 같은 세션 2회째: `gh pr merge --delete-branch` 로컬 부수효과를 reflog 3건으로 "확정" 저장했으나 4번째 머지(PR #1651)에서 재현되지 않아 "원인 미확정"으로 정정. 두 건 모두 상관을 인과로 승격한 Read-Before-Characterize 자기 위반이며, R011 즉시 저장과 결합해 틀린 전제가 영속화될 뻔했다. Cross-ref: R011 「Mid-Session Immediate Save」 `[hypothesis]` 행, R010 「저장소 상태 기재도 같은 규율」, 아래 「Self-Violation Counting Is Also Diagnosis」.
334
+ -->
293
335
 
294
336
  ### Self-Check (영구 변경 전)
295
337
  1. 가설을 뒷받침하는 직접 증거(로그/에러 코드/문서)가 있는가?
@@ -298,21 +340,29 @@ v1.1.59 세션에서 #1643(advisor "R007 헤더=0" 오탐) 원인을 트랜스
298
340
  4. 결함이 발생한 실행 경로(워크플로우 YAML/스킬 정의/스크립트/CI 설정)를 직접 읽었는가? 수동 재현 성공으로 자동화 경로의 동작을 추정하지 않았는가?
299
341
  하나라도 NO면 검증을 먼저 수행한다. 근본 원인 진단은 `superpowers:systematic-debugging` 참조.
300
342
 
343
+ <!-- DETAIL: Origin #1533
301
344
  Origin: #1533 (lockfile 4릴리즈 누락을 "스테이징 누락"으로 오진 — 실제 원인은 version-bump 절차에 build 단계 부재; 수동 재현 결과로 자동화 경로를 추정).
345
+ -->
302
346
 
303
347
  ### Variant: Parallel Read + Permanent-Change Dispatch (#1250)
304
348
 
349
+ <!-- DETAIL: parallel read 설명 (표와 중복)
305
350
  진단 자료 수집(로그 조사, 파일 Read)과 그 진단에 의존하는 영구 변경(이슈 등록, 수정 에이전트 위임)을 **같은 메시지에서 병렬 실행**하면, Read 결과를 받기 전에 가설이 확정된다. 병렬 배치는 결과를 동시에 받으므로 "Read 후 판단"이 불가능하다.
351
+ -->
306
352
 
307
353
  | 금지 | 필수 |
308
354
  |------|------|
309
355
  | 파일 Read + 그 내용 기반 이슈/수정 지시를 한 병렬 배치에 묶기 | 진단 Read는 먼저, 결과 수령 후 *다음 턴*에 변경 지시 |
310
356
  | 로그 조사와 동시에 "원인은 X" 이슈 생성 | 로그 결과 확인 후 원인 확정 |
311
357
 
358
+ <!-- DETAIL: Common Violation #1250
312
359
  #### Common Violation (#1250)
313
360
  triage-dispatch.yml 실패 원인을 파일 Read 전에 "triaged 라벨 부재 + omcustom CLI 부재"로 추정 → 같은 메시지에서 이슈 등록 + mgr-gitnerd 수정 지시를 병렬 실행. 직후 도착한 Read 결과가 실제 원인(외부 Airflow issue_triage DAG의 HTTP 530)을 드러냄. 코드 수정 방향은 우연히 맞았으나 이슈/PR/커밋 서술이 틀려 정정 부채 발생. 머지 전 발각되어 이슈/PR 본문 정정으로 회복.
361
+ -->
314
362
 
363
+ <!-- DETAIL: diagnosis dependency 요약
315
364
  > 진단에 의존하는 쓰기/위임은 진단 결과를 본 다음 턴에 수행한다. R009 병렬 실행은 독립 작업에만 적용 — 진단→변경은 순차 의존이다.
365
+ -->
316
366
 
317
367
  ### Read-Before-Characterize
318
368
 
@@ -324,33 +374,47 @@ triage-dispatch.yml 실패 원인을 파일 Read 전에 "triaged 라벨 부재 +
324
374
  | 첫 namespace/scope만 보고 전체 단정 | 관련 scope 확인 후 결론 |
325
375
  | 정렬 기준 미검증 시계열 단정 (`ls\|tail`로 "최신") | 시계열 판단은 mtime/timestamp 정렬(`ls -t`/`find -newermt`) 명시 후 결론 — 파일명순 ≠ 시간순 (#1417) |
326
376
 
377
+ <!-- DETAIL: Origin #1266
327
378
  Origin: #1266 ④.
379
+ -->
328
380
 
329
381
  ### Self-Violation Counting Is Also Diagnosis (#1553 ②)
330
382
 
383
+ <!-- DETAIL: 자기위반 계수 intro (표와 중복)
331
384
  **자기 위반 횟수를 세는 것도 진단이다.** 회고·자가 보고에서 "몇 번 위반했는가"를 기억(recall)으로 세면 체계적으로 **과소 계상**된다 — 위반 순간은 정의상 자각 없이 지나간 순간이므로, 기억에는 나중에 스스로 알아챈 소수만 남는다. 위반 횟수는 추정하지 말고 **transcript를 실제로 파싱해** 센다(예: 응답 시작 라인에 R007 헤더 패턴이 없는 assistant turn 수를 grep/스크립트로 집계).
385
+ -->
332
386
 
333
387
  | Anti-pattern | Required |
334
388
  |--------------|----------|
335
389
  | 회고에서 "직전 두 응답에서 누락했습니다"처럼 기억 기반으로 위반 횟수 보고 | transcript를 파싱해 실측 집계 후 보고 (예: 헤더 패턴 미매칭 turn 수 grep) |
336
390
  | 실측 없이 "몇 회 정도" 추정치로 위반 심각도를 특성화 | 실측값으로 심각도 판정 — 과소 계상은 후속 조치 우선순위를 왜곡한다 |
337
391
 
392
+ <!-- DETAIL: 실증 2026-07-30
338
393
  실증: 2026-07-30 세션에서 자가 보고는 "직전 두 응답에서 누락"(2회)이었으나 transcript 실측은 **7회**였다 — 3.5배 과소 계상. Origin: #1553 찐빠 #2.
394
+ -->
339
395
 
396
+ <!-- DETAIL: 계수 미수행 명시 elaboration
340
397
  **계수를 수행하지 않았다면 그 사실을 명시할 것 (Origin: #1601, v1.1.49 세션)**: 시간·비용 제약으로 transcript 파싱 계수를 생략하는 경우, 회고 자체에 "전수 계수 미수행"임을 밝혀야 한다. 계수하지 않은 회고의 항목 목록은 위반 전수가 아니라 **"진행 중 자각했거나 서브에이전트가 지적한 항목"에 한정**되며, 이를 밝히지 않으면 독자가 목록을 전수로 오해해 후속 조치 우선순위가 왜곡된다. v1.1.49 세션 회고는 계수를 수행하지 않았고 그 사실을 스스로 명시했다(좋은 사례) — 대조적으로 그 이전 세션(위 실증)은 계수 미수행 여부를 밝히지 않은 기억 기반 자가 보고였고 실측 대비 3.5배 과소 계상이었다.
398
+ -->
341
399
 
400
+ <!-- DETAIL: 자기 적용 각도 설명
342
401
  이는 Read-Before-Characterize의 **자기 적용** 각도다 — 진단 대상이 외부 로그가 아니라 자기 자신의 transcript일 때에도 "읽기 전 특성화 금지"가 동일하게 적용된다.
402
+ -->
343
403
 
344
- #### 자율 루프 세션의 턴 경계 정의 (계수 전 확정 필수)
404
+ #### 자율 루프 세션의 턴 경계 정의 (계수 전 확정 필수) — role 필터 선행 후 tool_result 제외 경계로 정의; 확정 전 위반 횟수 단정 금지. See full spec via Read tool.
345
405
 
406
+ <!-- DETAIL: 자율루프 턴 경계 정의 상세
346
407
  위 파싱 레시피는 **"사용자 프롬프트 = 턴 경계"**를 암묵 전제한다. `/fsd` 같은 자율 루프는 사용자 프롬프트가 거의 없어(실측: 사용자 프롬프트 4개 대 assistant 응답 30여 회) 이 전제로는 경계 재구성이 실패하고, 계수 자체가 성립하지 않는다. 자율 루프 transcript를 셀 때는 **두 단계를 순서대로** 수행하고, 완료 전에는 **위반 횟수를 단정하지 않는다**.
347
408
 
348
409
  1. **전처리 — `.message.role`이 존재하는 라인만 필터링**한다. 트랜스크립트에는 role 없는 라인(메타·이벤트·요약)이 assistant/user 사이에 대량으로 끼어 있어, 필터 없이는 **인접성 판정 자체가 깨진다**. 2단계의 어떤 경계 정의도 이 필터 없이는 성립하지 않는다.
349
410
  2. **경계 정의(규범)** — 응답 시작 경계는 **`content`에 `tool_result` 블록을 포함하지 않는 user 메시지**로 정의한다. 도구 결과도 `role: user`로 기록되므로, "user→assistant 전이 = 응답 시작"이라는 단순 정의는 도구 결과 뒤에 이어지는 assistant 메시지를 전부 새 응답으로 오인해 **위반 건수를 대폭 과대 계상**한다. 실증: 이 정의를 쓰지 않고 파싱했을 때 R007 위반이 177건으로 나왔으나, 위 규범대로 경계를 고치자 1건이 됐다(177배 과대). R008도 44 → 33으로 정정됐다.
411
+ -->
350
412
 
351
413
  ### 자가 계수는 advisor 판정식을 재현한다
352
414
 
415
+ <!-- DETAIL: 자가계수 intro (표와 중복)
353
416
  자체 해석 패턴으로 위반을 세지 말고, `.claude/hooks/scripts/r007-r008-drift-advisor.sh`의 판정식을 **1:1 재현**한다. 실증: 자체 announce 패턴을 advisor보다 좁게 잡아(번호 매긴 병렬 스폰 라인 `[N] agent:model → desc` 형식을 announce로 미포함) R008 위반을 과대 계상했다 — advisor 스크립트 자체를 참조하지 않고 "그럴듯한 정의"로 재구현하면 같은 종류의 오차가 반복된다.
417
+ -->
354
418
 
355
419
  | Anti-pattern | Required |
356
420
  |--------------|----------|
@@ -360,60 +424,84 @@ Origin: #1266 ④.
360
424
  | "user→assistant 전이"를 응답 시작 경계로 단순 정의 → `tool_result`(role=user) 뒤 assistant 응답을 전부 새 응답으로 오산입 | 경계 = `tool_result` 블록을 포함하지 않는 user 메시지 (규범) |
361
425
  | 자체 해석 패턴(예: 좁게 잡은 announce 정규식)으로 위반을 재계산 | `r007-r008-drift-advisor.sh`의 판정식을 그대로 재현 |
362
426
 
427
+ <!-- DETAIL: Origin #1574 자율루프
363
428
  Origin: #1574 (v1.1.44 세션 — 자율 루프에서 R007 헤더 누락 계수를 시도했으나 사용자 프롬프트 4개로 턴 경계 재구성 불가); 1단계 필터는 #1584 #3 (v1.1.45 세션 — 위 조항을 신설했음에도 계수가 재실패. 실제 장애물은 경계 정의가 아니라 **`role=null` 라인 661개 / 전체 1215줄의 54%**였고, 필터 추가 즉시 성립(응답 시작 50, R007 위반 0) — 조항이 원인을 절반만 짚어 재발한 사례). 경계 규범 승격 및 advisor 판정식 재현은 #1593 #6 (경계 오정의로 R007 177배 과대 계상, `tool_result` 배제 정의로 정정; R008은 좁은 announce 패턴 자가 재구현으로 44→33 정정). Cross-ref: R005(계수/매칭 방법 확인 — 도구 기본 동작 미확인 시 결과 오해석).
429
+ -->
364
430
 
365
431
  ### Proxy Signal vs Canonical Ground-Truth (#1336 ①②)
366
432
 
433
+ <!-- DETAIL: Origin #1336
367
434
  > Origin: #1336 ①② — transcription was alarmed as "stopped" because `.txt` files looked stale, but the canonical DB had transcripts current to 06-09 21:30 (.txt is not the whisper collector's output — it emits only to the DB). Separately, SMS was over-diagnosed as "fully blocked" from one empty OneDrive XML path + a single 401, while the DB held 17 SMS rows ingested via the app path.
435
+ -->
368
436
 
437
+ <!-- DETAIL: Proxy Signal intro (표와 중복)
369
438
  When diagnosing pipeline/data state, verify the CANONICAL store (the authoritative datastore — DB, the system of record) BEFORE characterizing state from a secondary proxy (a `.txt`/file artifact) or a single ingestion path. Two failure modes share this meta-pattern:
439
+ -->
370
440
 
371
441
  | Anti-pattern | Required |
372
442
  |--------------|----------|
373
443
  | Characterize pipeline health from a filesystem proxy (`.txt` presence/mtime) | Query the canonical store (DB transcript count/recency) first |
374
444
  | Generalize one ingestion path's failure (one empty XML / one 401) to "whole pipeline blocked" | Check the final landing store's count across ALL paths before concluding blockage |
375
445
 
446
+ <!-- DETAIL: single path 재확인 restatement
376
447
  A single path's failure does NOT prove the whole multi-path pipeline is down. Confirm the system-of-record before alarming or dispatching reprocessing.
448
+ -->
377
449
 
378
450
  ### Directory-Context Before Multi-Copy Unification/Deletion
379
451
 
452
+ <!-- DETAIL: Directory-Context intro (표와 중복)
380
453
  다중 사본(동일 파일이 N곳에 존재)을 통일하거나 삭제하기 전, 각 사본이 위치한 **디렉토리 전체 맥락**을 확인한다(`ls`로 형제 파일 파악). 사본 파일 하나만 보고 "orphan"·"stub"으로 특성화하면, 같은 디렉토리의 형제 파일(다른 역할을 가진)이 함께 덮이거나 맥락이 누락된다. Read-Before-Characterize를 파일 단위에서 디렉토리 단위로 확장한 규칙이다.
454
+ -->
381
455
 
382
456
  | 금지 | 필수 |
383
457
  |------|------|
384
458
  | 사본 파일만 보고 "orphan/stub"으로 단정 후 통일/삭제 | 사본이 속한 디렉토리 전체(`ls`)를 확인 — 형제 파일 역할·연계 파악 후 처리 |
385
459
 
460
+ <!-- DETAIL: Common Violation #1290
386
461
  #### Common Violation (#1290 찐빠 #2, cross-session)
387
462
  Session 108에서 `auto-dev.yaml` 4곳을 canonical 통일할 때, repo-root `./workflows/`에 `eraser.yaml`이 공존하는 디렉토리 맥락을 미확인하고 덮었다. Session 109에서 디렉토리 단위 Read-Before-Characterize로 보정(`eraser.yaml` 발견 → #1289 등록, destructive 삭제 회피). 결과는 무해했으나 맥락이 불완전했다.
463
+ -->
388
464
 
465
+ <!-- DETAIL: Origin #1290
389
466
  Origin: #1290 (session 109 retrospective).
467
+ -->
390
468
 
391
469
  ### Config-Schema-Before-Edit
392
470
 
471
+ <!-- DETAIL: Origin #1327
393
472
  > Origin: #1327 찐빠 #2 — a provider switch (to DeepSeek) planned a 3-command edit (auth + provider + default) but omitted `base_url`, which stayed pointed at the previous provider (openrouter.ai) — traffic would have mis-routed. The config's base_url override-precedence was never read before planning the edits.
473
+ -->
394
474
 
395
475
  Before planning edits to a configuration (provider switch, endpoint/base_url override, credential injection, multi-key precedence), READ the full config schema and its override-precedence chain first. Do NOT plan partial edits before understanding which fields override which.
396
476
 
477
+ <!-- DETAIL: Config-Schema scope 예외 설명
397
478
  This applies when a change touches a field that participates in an override/precedence/inheritance chain (e.g. provider + base_url, multi-key fallback, layered defaults). A single independent field edit (flip a flag, bump a timeout) does NOT require a full-schema read.
479
+ -->
398
480
 
399
481
  | Anti-pattern | Required |
400
482
  |--------------|----------|
401
483
  | Plan a provider/endpoint switch as N commands without reading the config's override chain | Read the full config schema (which field wins, defaults, inheritance) → enumerate EVERY field the switch touches (incl. base_url) → then plan |
402
484
 
485
+ <!-- DETAIL: 훅 스크립트 각도 설명
403
486
  **훅 스크립트 각도 — stdin 필드 형상은 실측 후 편집 (Origin: #1658 #1, v1.1.62)**: 훅 스크립트가 읽는 stdin 필드(`tool_input`/`tool_response`/`agent_id` 등)를 편집·가드·억제하기 전에 **실제 페이로드 형상을 실측**한다 — 트랜스크립트의 `attachment.type=="hook_success"` 레코드에서 `attachment.stdout`이 pass-through 훅이 되돌린 stdin 원문이며, CC 바이너리 내장 훅 문서로 교차검증한다. 처방("가드 추가·`?` 억제")만 위임하면 선택자 결함 위에 가드를 얹어 마지막 실패 신호까지 지운다. 실증: v1.1.62에서 `secret-filter.sh`가 PostToolUse에 존재하지 않는 `tool_output`(0/1764)을 읽어 실제 페이로드를 한 번도 스캔하지 않던 선재 결함 위에 `?` 억제가 추가됐고(rc=5 신호 소멸), 적대적 리뷰가 실측 형상 재현으로 FAIL 판정해 `tool_response`(1764/1764)로 교체했다. 훅 편집 위임서 표준 문안: "스크립트가 읽는 stdin 필드는 `hook_success` 레코드로 형상 실측 후 편집".
487
+ -->
404
488
 
405
489
  | Anti-pattern | Required |
406
490
  |--------------|----------|
407
491
  | 훅 위임서에 "가드 추가·`?` 억제" 처방만 전달 | 읽는 필드의 실제 형상(`hook_success` stdin 원문 + 바이너리 훅 문서) 실측을 위임서 완료 조건에 포함 |
408
492
 
493
+ <!-- DETAIL: 값 표현 변경 각도 설명
409
494
  **값 표현 변경 각도 — 소비자 경로 전수 열거 (Origin: #1691 #2, v1.1.71)**: 저장되는 값의 **표현**(정규화 규칙·인코딩·키 형식)을 바꾸는 위임서는 그 값을 **읽는 모든 소비자 경로**를 `grep`으로 열거하고 **동일 인코딩으로 대조**하도록 완료 조건에 넣습니다. v1.1.68에서 stuck-detector `edit_hash`의 정규화만 바꾸고 소비자(JSON 직렬화 저장값 ↔ grep 원문 패턴)를 열거하지 않아 따옴표·백슬래시 회귀가 1차 구현에 남았고, 위임서의 "consumers logic unchanged" 지시 때문에 에이전트가 발견한 결함을 고치지 않고 넘겼습니다. 이 맥락의 "소비자 로직 변경 금지" 지시는 "결함 발견 시 보고 후 지시 대기"로 씁니다 — 프로덕션·권한 경계의 금지 목록(R010 「Pre-Delegation Privileged-Scope Boundary」)은 이 완화 대상이 아닙니다.
495
+ -->
410
496
 
411
497
  | Anti-pattern | Required |
412
498
  |--------------|----------|
413
499
  | 값의 정규화·인코딩만 바꾸고 소비자 경로를 열거하지 않은 위임 | 소비자 경로 전수 grep + 동일 인코딩 대조를 완료 조건에 포함 |
414
500
  | "소비자 로직 변경 금지"로 결함 수정까지 봉쇄 | "결함 발견 시 보고 후 지시 대기"로 완화 |
415
501
 
502
+ <!-- DETAIL: sibling discipline 설명
416
503
  Sibling discipline to Read-Before-Characterize (that rule governs diagnosis — don't label before reading; this one governs edit-planning completeness — enumerate every interdependent field before editing). Cross-ref: R023 (verification ladder — config completeness is a Tier-1 deterministic pre-check).
504
+ -->
417
505
 
418
506
  ### Degraded-Output Re-Verification Gate (529 / buffering)
419
507
 
@@ -424,10 +512,14 @@ When tool outputs show degradation signs — 529 errors, duplicated or truncated
424
512
  | Dispatch a recovery agent off a single 529-buffered read | Re-run a minimal deterministic check (`wc -c`, single-field `gh ... view`, `head`) and confirm before acting |
425
513
  | Declare a file "corrupted/오염" from one empty Read | Confirm byte count / content via an independent command first |
426
514
 
515
+ <!-- DETAIL: Common Violation #1269
427
516
  #### Common Violation (#1269 ①)
428
517
  Session 106: during 529 buffering, a CHANGELOG was misdiagnosed as "61x 중복 오염" from buffered output and a recovery agent was dispatched — a self-violation of the same-session Read-Before-Characterize rule (#1266 ④). Deterministic count re-verification showed the file was clean. The 529 gate makes the re-verification mandatory, not advisory.
518
+ -->
429
519
 
520
+ <!-- DETAIL: Origin #1269
430
521
  Origin: #1269 ① (R020 self-violation, session 106).
522
+ -->
431
523
 
432
524
  ### Failure/Interrupt Report ≠ Actual Failure (reverse direction)
433
525
 
@@ -439,27 +531,47 @@ Origin: #1269 ① (R020 self-violation, session 106).
439
531
  | **v2.1.246+**: 헤드리스/원격 세션에서 수신 메시지로 인터럽트된 MCP 도구 호출이 "출력 없이 완료됨"으로 보고됨(v2.1.246 이전) | 실제로는 **인터럽트**됐다 — 정상 완료가 아니었다 | v2.1.246+는 명시적 interrupted 에러로 보고하도록 수정됨; 구버전 세션의 "빈 출력 완료"는 무음 인터럽트였을 수 있음 |
440
532
  | **v2.1.246+**: 실행 중 인터럽트된 셸 명령이 "Ran 1 shell command"로만 표시(잘렸다는 표시 없음, v2.1.246 이전) | 명령이 **완주하지 못했다** | 출력 완결성을 별도로 확인(예상 출력 패턴 대조) 없이 "실행됨"만으로 성공 단정 금지 |
441
533
 
534
+ <!-- DETAIL: v2.1.252/257/258 버전노트
442
535
  > **v2.1.252/257/258+**: 실패/중단 관련 보고 무결성 결함 3건이 추가로 수정되었습니다. (252) 매우 큰 실패 출력(디스크 풀 상태의 git 오류 등)을 실은 background task 알림이 대화를 API 요청 크기 한도 밖으로 밀어내던 결함 — R021 v2.1.247 훅 출력 폭주 계열의 background task 각도이며, 구버전에서 "Prompt is too long"으로 세션이 멈춘 것은 작업 자체의 실패가 아니라 실패 **알림의 크기** 때문일 수 있었습니다. (257) `claude -p`가 모델이 armed한 Monitor가 아직 도는 중인데도 최종 결과 약 5초 뒤 종료하던 결함이 수정되어, 이제 감시가 발화하거나 타임아웃될 때까지 대기합니다 — 무인 `-p` 실행에서 Monitor 결과 부재는 이제 "감시 미발화"로 해석하며 "조기 종료"로 오판하지 않습니다. (258) 원격·예약 세션이 재전송된 permission approval을 적용하지 못한 뒤 "user messages must have non-empty content"로 실패하던 결함이 수정되었습니다 — R010 v2.1.234 "background subagent 승인·거부가 드롭될 수 있던 결함" 계열의 원격 세션 각도이며, 구버전 `/schedule`·remote 세션의 이 오류 문구는 프롬프트 자체의 결함이 아니라 승인 채널의 결함이었습니다.
536
+ -->
443
537
 
538
+ <!-- DETAIL: v2.1.234 버전노트
444
539
  > **v2.1.234+**: print/SDK 모드에서 SIGTERM 수신 시 더 이상 interrupted turn이나 synthetic tool denial을 기록하지 않는다(명령은 여전히 종료되고 프로세스는 exit code 143). 무인 실행(`-p` 모드) 강제 종료 후 트랜스크립트를 완료 판정 근거로 쓸 때, v2.1.234+에서는 SIGTERM에 의한 중단이 트랜스크립트 상에 "interrupted"로 남지 않는다는 점을 전제해야 한다 — 트랜스크립트가 깨끗해 보여도 실제로는 SIGTERM으로 잘렸을 수 있다.
540
+ -->
445
541
 
542
+ <!-- DETAIL: 교훈 restatement
446
543
  **교훈**: 위 Core Rule("actual outcome ≠ attempt")은 방향이 없다 — 도구가 성공을 보고하든 실패를 보고하든, 보고 자체는 ground-truth가 아니다. 실패 보고를 받았다고 곧바로 재시도·롤백에 들어가지 말고, 먼저 실제 산출물 상태를 확인한다.
544
+ -->
447
545
 
546
+ <!-- DETAIL: v2.1.259/261 버전노트
448
547
  > **v2.1.259/261+**: "정지 보고 ≠ 실제 정지" 결함 3건이 수정되었습니다. (259) Stop이 remote-control 세션의 background agent·workflow를 실제로 멈추지 못했던 결함 — 이제 kill된 task는 프로세스가 종료될 때까지 계속 표시되고 재정지 가능합니다. (261) SDK·cloud 세션이 첫 프롬프트 직후, turn이 시작하기 전에 도착한 Stop/interrupt를 무시하고 turn을 끝까지 실행하던 결함이 수정되었습니다. (261) 터미널 진행 표시(iTerm2, Ghostty, ConEmu)가 background workflow/agent가 아직 실행 중인데도 세션을 완료된 것으로 표시하던 결함이 수정되었습니다. 세 건 모두 이 섹션 원칙의 **역방향 쌍둥이**입니다 — "정지됨"/"완료됨" 신호도 ground-truth가 아니므로, 인터럽트가 실제로 적용됐다고 단정하기 전에 프로세스/run 상태(`gh run list`, task 패널, `pgrep`)로 확인합니다. 같은 릴리즈에서 (259) 이전 정지 실행이 종료 중인 상태에서 workflow run을 재개하면 그 에이전트들이 **중복 실행**될 수 있던 결함도 수정되었습니다(cross-ref R023 Workflow resume).
548
+ -->
449
549
 
550
+ <!-- DETAIL: v2.1.265/267 버전노트
450
551
  > **v2.1.265/267+**: (265) 이전 프로세스가 도구 실행 중 죽은 뒤 재개하면 마지막 프롬프트를 더 이상 재작성하지 않고, 중단된 도구 호출을 유지하며 **interrupted로 명시 표시**합니다 — 위 v2.1.246 행(인터럽트된 셸 명령이 단순 "실행됨"으로만 표시)의 연장선으로, 이 경로에서는 이제 트랜스크립트에 명시적 interrupted 마커가 남으므로 v2.1.265+에서는 그 부재가 유의미한 증거지만 구버전에서는 아닙니다. (267) `/compact` 또는 다른 슬래시 커맨드 직후 `-p --resume`으로 재개할 때 가짜 "Continue from where you left off." turn이 더 이상 삽입되지 않습니다 — `/fsd` 류 `-p` 루프에서 이런 turn을 사용자 입력으로 오인할 수 있었던 경로와 관련됩니다(R015: 이것은 지시가 아닙니다). 또한 큰 세션(트랜스크립트 5MB 초과)을 재개할 때 병렬 도구 호출과 그 훅 출력이 재로드된 대화에서 누락되던 결함도 수정되었습니다(cross-ref R021) — 회고적 트랜스크립트 계수(「Self-Violation Counting Is Also Diagnosis」)에서, 구버전으로 재개된 5MB 초과 세션은 도구 호출이 유실됐을 수 있으므로 그런 트랜스크립트의 계수는 **하한값**으로 취급합니다.
552
+ -->
451
553
 
554
+ <!-- DETAIL: v2.1.269 버전노트
452
555
  > **v2.1.269+**: 원격·헤드리스 세션이 background agent가 아직 실행 중인데도 "waiting for your input"을 보고하던 결함이 수정되었습니다(`CLAUDE_CODE_BG_TASKS_REPORT_RUNNING=0`으로 구동작 복원 가능) — 구버전 `-p`/원격 실행에서 idle 보고는 백그라운드 작업 완료의 증거가 아니었습니다. 같은 릴리즈에서 compaction 이후 Claude에 전달되는 git status가 세션 시작 시점이 아니라 **현재** 상태로 바뀌었습니다 — R017 「게이트는 분기 시점 1회가 아니라 상태변경 위임마다」와 직접 교차: v2.1.269 이전에는 compaction 후 오케스트레이터가 stale git 스냅샷으로 추론할 수 있었으므로, compaction 직후 HEAD/브랜치 재실측은 선택이 아니었습니다. 또한 (269) `/goal` 실행이 API 오류·네트워크 끊김·토큰 한도 후 무음으로 멈추던 결함이 수정되어, 이제 backoff로 재시도하거나 중단 사유를 명시합니다 — `/goal`을 감싸는 `/fsd`에도 해당합니다.
556
+ -->
453
557
 
558
+ <!-- DETAIL: v2.1.273 버전노트
454
559
  > **v2.1.273+**: 서브에이전트/백그라운드 에이전트가 스트리밍 최종 응답에 토큰 사용량이 빠졌거나 model id가 없을 때 **FAILED로 보고되고 결과가 전달되지 않던** 결함이 수정되었습니다 — 작업은 완료됐으나 전달만 실패한, 이 섹션이 다루는 "실패 보고 ≠ 실제 실패"의 정확한 사례입니다. 같은 릴리즈에서 SDK와 `--output-format stream-json` 출력이, 실행 도중(예: `CLAUDE_AUTO_BACKGROUND_TASKS`로) background로 이동한 서브에이전트의 남은 메시지와 최종 보고를 누락하던 결함도 수정되었고, context meter와 auto-compact가 advisor 도구 턴을 실제 크기의 약 2배로 계상해 auto-compact가 실제 창의 절반 지점에서 발동하던 결함도 수정되었습니다(cross-ref R013). 위 v2.1.246 `maxTurns` partial 표시와 함께, 이들은 「위임 경계를 Phase 개수로 설계」가 다루는 "판정 없이 종료" 증상의 추가 플랫폼 원인입니다 — 위 Core Rule의 ground-truth 원칙은 그대로 유지됩니다.
560
+ -->
455
561
 
562
+ <!-- DETAIL: v2.1.274 버전노트
456
563
  > **v2.1.274+**: background agent 알림이, 에이전트가 여전히 자신의 백그라운드 작업을 기다리며 재개 예정인데도 "실행 중인 백그라운드 작업 없음"으로 보고하던 결함이 수정되었습니다. 재개된 background agent가 인터럽트된 도구 배치 중 하나가 메시지와 함께 승인됐을 때 배치의 절반을 유실하던 결함도 수정되었습니다. "unexpected tool_use_id" 400 오류를 끝없이 재시도하며 멈추던 세션도 수정되어, 손상된 트랜스크립트는 가능하면 자가 복구하고 그렇지 않으면 `/rewind` 힌트가 붙은 명확한 오류로 루프를 끝냅니다. compaction을 거친 세션을 `--continue`/`--resume`으로 재개할 때 활성 `/goal`이 유실되던 결함과, 훅 기반 세션(활성 `/goal`)이 2차 overflow에서 compaction 대신 "Prompt is too long"으로 종료되던 결함도 모두 수정되었습니다 — `/goal`을 감싸는 `/fsd`에서, 구버전의 재개 후 goal 유실은 수렴 신호가 아니라 플랫폼 결함이었습니다. 같은 릴리즈에서 서브에이전트의 진행 요약이 폭주하는 다단락 응답으로 대체되던 결함도 수정되었습니다.
564
+ -->
457
565
 
566
+ <!-- DETAIL: v2.1.275 버전노트
458
567
  > **v2.1.275+**: (275) CHANGELOG 원문: "Fixed self-hosted runners with `--drain-wait-sec` losing the final result of a turn that finished during a SIGTERM drain; the runner now waits briefly for the turn to be reported." 위 v2.1.234 SIGTERM 노트의 runner 각도 확장이며, 275 이전 drain 중 종료된 턴의 결과 부재는 미완료의 증거가 아니었습니다. (275) CHANGELOG 원문: "Fixed `--resume` and `--continue` dropping a conversation's earlier thinking when a built-in tool it started with has since been switched off by a server-side flag." 재개된 대화에서 이전 reasoning 부재는 원본 부재의 증거가 아니며, R021 「발화 ≠ 재개 후 보존」 5번째 각도와 같은 계열입니다(cross-ref R021). (275) CHANGELOG 원문: "Changed hosted sessions to keep an unanswered permission prompt up after a container restart, instead of asking again." hosted 세션에서 컨테이너 재시작 후 "재요청 없음"은 승인이 적용됐다는 뜻이 아니라 프롬프트가 유지된 것이므로, 승인 여부는 ground-truth로 확인해야 합니다(R010 v2.1.234 승인 드롭 노트 계열).
568
+ -->
459
569
 
460
570
  ### CI Publish-Step Error vs Published-Artifact Ground Truth
461
571
 
572
+ <!-- DETAIL: Origin #1332
462
573
  > Origin: #1332 — `npm publish --provenance` emitted a Sigstore `TLOG_CREATE_ENTRY_ERROR` 409, but the publish step's `|| npm view <pkg>@<ver>` fallback recovered (the package WAS published) and release.yml succeeded on all jobs. A subagent read the tlog error in the logs and prematurely declared the run "failed", recommending a re-run; deterministic ground-truth (`npm view`, `gh release view`) showed the release had fully succeeded.
574
+ -->
463
575
 
464
576
  A CI publish/deploy step that LOGS an error has NOT necessarily failed — the step may recover via a fallback (`|| npm view ...`), or the error may be in a non-fatal sub-step (provenance attestation, eventual-consistency probe). Before declaring a publish/release run failed — and ESPECIALLY before re-running, rolling back, or permanently changing the workflow — verify the PUBLISHED ARTIFACT directly:
465
577
 
@@ -470,23 +582,33 @@ A CI publish/deploy step that LOGS an error has NOT necessarily failed — the s
470
582
  | Docker registry | image tag/manifest exists |
471
583
  | Run outcome | `gh run view <id> --json jobs` job conclusions — NOT a single step's log line |
472
584
 
585
+ <!-- DETAIL: publish-domain extension 설명
473
586
  This is the publish-domain extension of Read-Before-Characterize ("actual outcome ≠ attempt"). Re-running a publish that actually succeeded risks duplicate-publish errors; permanently changing a workflow on a misdiagnosis is worse (cf. #1217 — npm E403 misdiagnosed as a `--provenance` conflict → wrong workflow change → repeated failure; real cause was token scope).
587
+ -->
474
588
 
475
589
  ### CI Job Conclusion vs Actual Execution (docs-only path-filter)
476
590
 
591
+ <!-- DETAIL: Origin #1503
477
592
  > Origin: #1503 찐빠 #2 (FSD 3릴리즈 세션 회고) — v1.1.23 릴리즈에서 서브에이전트가 PR CI의 "Test/Rust Tests: SUCCESS"를 "두 잡 실행됨"으로 특성화했으나, 실측(job duration 5초 + "Docs-only skip notice" step 로그) 결과 v1.1.22 docs-only path-filter가 code=false로 판정해 두 잡이 skip-notice만 돌고 success를 보고한 것이었다.
593
+ -->
478
594
 
595
+ <!-- DETAIL: CI Job Conclusion intro (표와 중복)
479
596
  v1.1.22+ 이후 `.github/workflows/ci.yml`의 조건부 잡(Test / Rust Tests / Lint / Lockfile Sync)은 conclusion=success가 **full-run과 fast-skip(docs-only 변경 시 비싼 스텝 건너뜀) 양쪽**에서 나온다. CI 잡이 실제로 **실행**됐는지는 conclusion만으로 판정 불가하다 — job duration(수 분 vs ~5초) 또는 step 로그("Docs-only skip notice" 실행 여부)로 확인한다. R020 Core Rule("actual outcome ≠ attempt")을 CI 잡 결과 해석에 적용한 것이다.
597
+ -->
480
598
 
481
599
  | Anti-pattern | Required |
482
600
  |--------------|----------|
483
601
  | CI 잡 conclusion=success를 "잡이 실행됨"으로 특성화 | duration/step-log로 full-run vs fast-skip 구분 후 특성화 |
484
602
 
603
+ <!-- DETAIL: cross-reference 설명
485
604
  Cross-reference: 위 CI Publish-Step Error vs Published-Artifact Ground Truth, R023 (path-filter 있는 verification ladder).
605
+ -->
486
606
 
487
607
  ### State-Change Claim → Live System Verification (#1335 ①)
488
608
 
609
+ <!-- DETAIL: Origin #1335
489
610
  > Origin: #1335 ① — issue #101 (secretary teardown) was closed as "대체 완료·teardown 보류", but the secretary LaunchAgents (onedrive-bridge / calendar-worker / minikube-mount) were STILL running on the host. The user caught it ("secretary 리소스 다 내려가있는거 맞지?") — they were not.
611
+ -->
490
612
 
491
613
  Before closing or marking-done an issue/task that CLAIMS an infrastructure or resource STATE change (a service stopped, a resource torn down, a deployment removed, a process killed), verify the ACTUAL live system state — not just that the change command was issued. "Issued the teardown" ≠ "the resource is down".
492
614
 
@@ -497,11 +619,15 @@ Before closing or marking-done an issue/task that CLAIMS an infrastructure or re
497
619
  | Container removed | `docker ps -a` does not list it |
498
620
  | Process killed | process check (`pgrep`/`ps`) returns empty |
499
621
 
622
+ <!-- DETAIL: infra/state extension 설명
500
623
  This is the infra/state extension of "actual outcome ≠ attempt". Closing on the command-issued assumption leaves orphaned running resources.
624
+ -->
501
625
 
502
626
  ### Binary/Rendered-Artifact Completeness (text-grep ≠ complete)
503
627
 
628
+ <!-- DETAIL: Origin #1384
504
629
  > Origin: #1384 (second-brain 공개 저장소 redaction 세션 회고 찐빠 #1) — 텍스트 + git 히스토리 force-push 후 "원격 완전 정리됨"이라 선언했으나, 직후 렌더된 다이어그램 PNG 3종에 redaction 대상 식별자가 시각적으로 잔존 + 텍스트 잔여 호스트 토큰 1건 발견 → 추가 force-push 2회 필요. redaction 범위를 grep 가능한 텍스트로만 잡고, 렌더된 이미지/바이너리를 완결 선언 전에 점검하지 않음.
630
+ -->
505
631
 
506
632
  완료/완결성을 주장하는 작업(redaction, 식별자 제거, 콘텐츠 정리, 시크릿 스크럽, 데이터 마이그레이션)에서 텍스트 grep 통과는 완결을 보장하지 않는다. 렌더된 이미지/바이너리 산출물(PNG/PDF/렌더 다이어그램/임베디드 메타데이터/EXIF)에 동일 대상이 시각적·바이너리적으로 잔존할 수 있다. "완전 제거됨/완료" 선언 전, 텍스트뿐 아니라 바이너리/이미지/렌더 산출물 완결성까지 검증해야 한다.
507
633
 
@@ -510,7 +636,9 @@ This is the infra/state extension of "actual outcome ≠ attempt". Closing on th
510
636
  | 텍스트 grep 통과 후 "완전 제거됨/정리됨" 선언 | 렌더 이미지/바이너리/임베디드 메타데이터 시각·내용 스캔까지 통과한 뒤 선언 |
511
637
  | redaction 범위를 grep 가능 텍스트로만 한정 → 잔여를 순차 발견하며 force-push 반복 | 사전 전수 점검(대소문자 무시 텍스트 + 부분문자열 변형 + 바이너리/이미지 + 참조/고아 분석) 후 단일 패스 rewrite (R005 효율) |
512
638
 
639
+ <!-- DETAIL: redaction/binary extension 설명
513
640
  This is the redaction/binary extension of the UI/Frontend "browser render verified" row in the Task-Type Completion Matrix — text-layer verification alone is insufficient when rendered/binary artifacts carry the same content. Cross-reference: R001 (보안 완결성 — 시크릿/식별자 잔존 차단), R005 (단일 패스 효율 — 사전 전수 점검이 반복 force-push를 방지).
641
+ -->
514
642
 
515
643
  ## Integration
516
644