okstra 0.26.0 → 0.28.0

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.
Files changed (52) hide show
  1. package/README.kr.md +15 -0
  2. package/README.md +15 -0
  3. package/docs/kr/architecture.md +2 -6
  4. package/docs/kr/cli.md +40 -6
  5. package/docs/kr/performance-improvement-plan-v2.md +23 -0
  6. package/docs/kr/performance-improvement-plan.md +22 -0
  7. package/package.json +1 -1
  8. package/runtime/BUILD.json +2 -2
  9. package/runtime/agents/workers/claude-worker.md +4 -3
  10. package/runtime/agents/workers/codex-worker.md +4 -3
  11. package/runtime/agents/workers/gemini-worker.md +4 -3
  12. package/runtime/agents/workers/report-writer-worker.md +7 -2
  13. package/runtime/bin/okstra.sh +0 -1
  14. package/runtime/prompts/launch.template.md +1 -1
  15. package/runtime/prompts/profiles/_common-contract.md +36 -4
  16. package/runtime/prompts/profiles/error-analysis.md +12 -0
  17. package/runtime/prompts/profiles/implementation-planning.md +20 -0
  18. package/runtime/prompts/profiles/requirements-discovery.md +20 -0
  19. package/runtime/python/lib/okstra/cli.sh +1 -7
  20. package/runtime/python/lib/okstra/globals.sh +0 -1
  21. package/runtime/python/lib/okstra/usage.sh +1 -4
  22. package/runtime/python/okstra_ctl/render.py +3 -0
  23. package/runtime/python/okstra_ctl/run.py +0 -6
  24. package/runtime/python/okstra_ctl/run_context.py +1 -1
  25. package/runtime/python/okstra_ctl/wizard.py +25 -2
  26. package/runtime/python/okstra_token_usage/blocks.py +5 -1
  27. package/runtime/python/okstra_token_usage/claude.py +16 -1
  28. package/runtime/python/okstra_token_usage/cli.py +9 -2
  29. package/runtime/python/okstra_token_usage/collect.py +17 -3
  30. package/runtime/python/okstra_token_usage/pricing.py +159 -24
  31. package/runtime/python/okstra_token_usage/report.py +32 -3
  32. package/runtime/skills/okstra-brief/SKILL.md +532 -65
  33. package/runtime/skills/okstra-context-loader/SKILL.md +25 -11
  34. package/runtime/skills/okstra-convergence/SKILL.md +38 -14
  35. package/runtime/skills/okstra-history/SKILL.md +68 -37
  36. package/runtime/skills/okstra-logs/SKILL.md +26 -4
  37. package/runtime/skills/okstra-report-finder/SKILL.md +49 -22
  38. package/runtime/skills/okstra-report-writer/SKILL.md +62 -65
  39. package/runtime/skills/okstra-run/SKILL.md +35 -34
  40. package/runtime/skills/okstra-schedule/SKILL.md +51 -20
  41. package/runtime/skills/okstra-setup/SKILL.md +31 -12
  42. package/runtime/skills/okstra-status/SKILL.md +20 -8
  43. package/runtime/skills/okstra-team-contract/SKILL.md +41 -25
  44. package/runtime/skills/okstra-time-summary/SKILL.md +53 -16
  45. package/runtime/templates/reports/final-report.template.md +227 -207
  46. package/runtime/templates/reports/settings.template.json +7 -4
  47. package/runtime/validators/lib/fixtures.sh +47 -2
  48. package/runtime/validators/lib/validate-assets.sh +50 -24
  49. package/runtime/validators/validate-brief.py +385 -0
  50. package/runtime/validators/validate-brief.sh +35 -0
  51. package/runtime/validators/validate-run.py +313 -1
  52. package/runtime/validators/validate-workflow.sh +7 -33
@@ -11,40 +11,74 @@ project-id: "{{PROJECT_ID}}"
11
11
  taskType: "{{FM_TASK_TYPE}}"
12
12
  ---
13
13
 
14
+ <!--
15
+ Template authoring notes (NOT rendered to readers — HTML comments).
16
+
17
+ - All `<!-- ... -->` blocks in this file are author-side guidance. Do NOT
18
+ convert them into Markdown quote blocks (`> …`) in the produced report.
19
+ - "Conditional block" guards: where a section heading is wrapped in a
20
+ `<!-- RENDER_IF: <condition> -->` … `<!-- /RENDER_IF -->` pair, the
21
+ report-writer MUST delete the entire heading + body when the condition is
22
+ false. Leaving a section heading with placeholder body ("No prior X" /
23
+ "Not applicable") is a contract violation that the validator will catch.
24
+ - Section ordering rule: Verdict Card → Approval Block (planning only) →
25
+ Carry-in (only if non-empty) → Summary/Ticket/Status → Token table →
26
+ §1–§7. The reader's first 30 lines must answer "what was decided" and
27
+ "what do I do next"; deep evidence lives further down.
28
+ -->
29
+
14
30
  # {{TASK_KEY}} - Multi-Agent Cross Verification Final Report
31
+
15
32
  - Created at: {{RUN_TIMESTAMP_ISO}}
16
33
  - Task Key: {{TASK_KEY}}
17
34
  - Task Type: {{TASK_TYPE}}
18
35
  - Report Owner: `Claude lead`
19
36
  - Lead Model: `{{LEAD_MODEL}}`
20
37
  - Okstra Version: `{{OKSTRA_VERSION}}`
21
- - Clarification Response Carried In: `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}`
38
+
39
+ ## Verdict Card
40
+
41
+ 한눈에 보는 결과 카드. 본 표의 모든 값은 `## 2. Final Verdict` 및 `## 6. Recommended Next Steps` 의 권위 있는 값과 정확히 일치해야 합니다. 두 곳의 값이 다르면 본 카드를 깨진 인덱스로 간주합니다.
42
+
43
+ | 항목 | 값 |
44
+ |------|----|
45
+ | Final Conclusion | <한 줄 결론 — `## 2.` 의 Final Conclusion 셀과 동일> |
46
+ | Verdict Token | `<accepted / conditional-accept / blocked / not-applicable>` |
47
+ | Direction | `<continue-investigation / begin-implementation / approve / reject / hold>` |
48
+ | Approval Required? | `<yes — User Approval Request 블록 참조 / no>` |
49
+ | Next Step | <한 줄 — `## 6.` 첫 항목과 동일> |
50
+
51
+ <!-- RENDER_IF: task-type == implementation-planning -->
22
52
 
23
53
  ## User Approval Request (사용자 승인 게이트)
24
54
 
25
- > **이 블록은 `task-type` = `implementation-planning` 결과에서만 의미를 가집니다.** 다른 task-type의 보고서에서는 섹션 전체를 삭제하세요.
26
- >
27
- > 다음 `implementation` run은 아래 체크박스가 `[x]`로 표시되어 있을 때에만 진입할 수 있습니다 (`okstra_ctl.run._validate_approved_plan` 가 이 마커를 line-anchored 정규식으로 검사하여 통과/거부합니다). 본문(`Sections 1`–`4.5`)을 끝까지 읽고, `## 5. Clarification Items` 표에서 `Blocks=approval` 인 모든 행이 `Status` 가 `resolved` 또는 `obsolete` 인지 확인한 뒤 승인해 주세요. 한 행이라도 `open`/`answered` 로 남아 있으면 `Approved` 마커를 새기지 마십시오 — 향후 `validate-run.py` 가 이 정합성을 자동 검사할 예정입니다.
55
+ 다음 `implementation` run 은 아래 체크박스가 `[x]` 때에만 진입할 수 있습니다 (`okstra_ctl.run._validate_approved_plan` 가 line-anchored 정규식으로 검사). `## 5. Clarification Items` 표에서 `Blocks=approval` 모든 행이 `resolved` / `obsolete` 된 뒤 승인해 주세요.
28
56
 
29
- - 승인 여부 (사용자가 직접 편집): `- [ ] Approved` ← 승인하려면 `[ ]` 를 `[x]` 로 변경하여 저장하세요.
30
- - 승인 후 다음 단계 명령어 (방법 A — 수동 편집):
31
- - Claude Code 세션 안: `/okstra-run task-key={{TASK_KEY}} task-type=implementation approved-plan=<이 보고서 경로>`
57
+ - 승인 체크박스 (사용자가 직접 편집): `- [ ] Approved`
58
+ - 승인 후 다음 단계 명령 (수동 편집 방식):
59
+ - Claude Code: `/okstra-run task-key={{TASK_KEY}} task-type=implementation approved-plan=<이 보고서 경로>`
32
60
  - 별도 터미널: `scripts/okstra.sh --task-key {{TASK_KEY}} --task-type implementation --approved-plan <이 보고서 경로>`
33
- - 승인 + 실행 한 번에 (방법 B — 진입 명령 자체를 승인 의사로):
34
- - Claude Code 세션 안: `/okstra-run task-key={{TASK_KEY}} task-type=implementation approved-plan=<이 보고서 경로> approve`
61
+ - 승인 + 실행 한 번에 (진입 명령 자체를 승인 의사로):
62
+ - Claude Code: `/okstra-run task-key={{TASK_KEY}} task-type=implementation approved-plan=<이 보고서 경로> approve`
35
63
  - 별도 터미널: `scripts/okstra.sh --task-key {{TASK_KEY}} --task-type implementation --approved-plan <이 보고서 경로> --approve`
36
- - 방법 B `--approve` 입력 행위 자체를 승인 의사로 모델링합니다. 런타임이 블록의 체크박스를 자동으로 `[x]` 바꾸고, 섹션 하단에 `승인 일시 (CLI ack): <ISO8601>` audit 라인을 한 줄 덧붙입니다.
37
- - 승인을 보류하거나 거부하려면 체크박스는 `[ ]` 로 두고 `--approve` 도 사용하지 마세요. 필요한 변경 사항은 `## 5. Clarification Items` 표에 한 행으로 기록한 뒤 (`Blocks=approval` 로 표시) 같은 phase 를 재실행해 주세요.
64
+ - 보류·거부: 체크박스를 `[ ]` 두고 `--approve` 사용하지 마세요. 필요 변경은 `## 5.` 표에 `Blocks=approval` 행으로 등록한 같은 phase 재실행합니다.
65
+
66
+ <!-- /RENDER_IF -->
67
+
68
+ <!-- RENDER_IF: CLARIFICATION_RESPONSE_RELATIVE_PATH is non-empty
69
+ When empty, DELETE this entire `## 0.` heading and body. The validator
70
+ fails an empty Section 0 stub ("No prior clarification was provided"). -->
38
71
 
39
72
  ## 0. Clarification Response Carried In From Previous Run
73
+
40
74
  - Source file: `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}`
41
- - If the source path is empty, write `- No prior clarification response was provided for this run.` and skip the rest of this section.
42
- - If the source path is set, walk every row of the prior report's `## 5. Clarification Items` table (`C-001`, `C-002`, ...). For each row, summarize how its `User input` (or its absence) was used by this run's evidence, cite the new evidence (file path, line number, log excerpt, worker finding) that resolves or refutes the prior answer, and update the row's `Status` to `resolved` or `obsolete` when carrying it into this run's section 5.
43
- - Transitional rule (legacy carry-in only): if the prior report uses the deprecated `4.5.9 Open Questions` / `5.1 Additional Materials` / `5.2 Questions for the User` layout with `OQ-*` / `A*` / `Q*` IDs, walk every row of all three blocks. Map each legacy row into a single `C-*` row in this run's new `## 5. Clarification Items` table — assign `Kind = material` for prior `A*`, `Kind = decision` for prior `Q*` and prior `OQ*`, and `Blocks = approval` only for items the prior report flagged as gating the implementation-planning approval (default: `next-phase`). Keep the legacy ID in the new row's Statement column for traceability (e.g. `"[legacy OQ-003] ..."`).
75
+ - 이전 보고서의 `## 5. Clarification Items` 행(`C-001`, `C-002`, …) 증거에 비추어 검토하고, 각 행의 `Status` 를 `resolved` 또는 `obsolete` 로 갱신한 뒤 본 run 의 `## 5.` 표에 carry-in 합니다. 해소 근거(파일:라인 / 로그 / 워커 결과) 를 함께 인용합니다.
76
+
77
+ <!-- /RENDER_IF -->
44
78
 
45
79
  ## Summary of the Problem or Verification Target
46
80
 
47
- 3~5개의 row로 핵심 문제·요구사항·검증 대상을 표로 정리합니다. brief, 소스 자료, worker 결과를 근거로 작성합니다.
81
+ 3~5 row 로 핵심 문제·요구사항·검증 대상을 표로 정리합니다. brief, 소스 자료, worker 결과를 근거로 작성합니다.
48
82
 
49
83
  | ID | Ticket ID | 한 줄 요약 | 출처 (brief/source/worker) |
50
84
  |----|-----------|------------|----------------------------|
@@ -52,24 +86,20 @@ taskType: "{{FM_TASK_TYPE}}"
52
86
 
53
87
  ## Ticket Coverage
54
88
 
55
- run이 다룬 ticket 자리에서 확인하는 인덱스 표입니다. 본 보고서의 본문 항목들은 모두 `Ticket ID` 컬럼 또는 `[TICKETID: <id>]` 태그로 ticket과 묶여 있으며, 이 표는 그 역방향 인덱스입니다.
89
+ run 이 다룬 ticket 역방향 인덱스. 본문 항목들은 모두 `Ticket ID` 컬럼 또는 `[TICKETID: <id>]` 태그로 ticket 과 묶여 있습니다.
56
90
 
57
- - 한 run이 단일 ticket 다루는 경우: 표 대신 다음 한 줄로 대체할 수 있습니다 — `- Single ticket run: <TICKET-or-task-fallback>`
58
- - 다중 ticket이거나, `Issue / Ticket`이 비어 `Task ID` 폴백을 쓴 항목이 섞여 있는 경우: 표를 채웁니다.
91
+ - 단일 ticket run 경우: 표 대신 다음 한 — `- Single ticket run: <TICKET-or-task-fallback>`
92
+ - 다중 ticket 이거나 `Issue / Ticket` 비어 `Task ID` 폴백이 섞여 있는 경우: 표를 채웁니다.
59
93
 
60
94
  | Ticket ID | 등장 섹션 | 관련 항목 IDs |
61
95
  |-----------|-----------|---------------|
62
96
  | `<TICKET-123>` | `1.1, 3.1, 4.5.4` | `F-001, F-003, A1` |
63
97
 
64
- 규칙:
65
-
66
- - `Ticket ID` 컬럼은 본문에서 등장한 ticket 키와 정확히 동일한 문자열을 사용합니다. `Issue / Ticket`이 비어 폴백된 경우 `Task ID` 값을 prefix 없이 그대로 적습니다 (예: `8852`). 어느 쪽으로도 식별 불가한 경우 `unknown`을 사용합니다.
67
- - `등장 섹션`은 본 보고서의 섹션 번호를 콤마로 구분합니다. 동일 ticket이 여러 섹션에 등장하면 모두 나열합니다.
68
- - `관련 항목 IDs`는 `F-001`, `M-002`, `A1`, `Q1` 같은 row ID를 콤마로 나열합니다. 섹션 헤더 단위로만 ticket이 표시된 경우(개별 row ID가 없는 경우)에는 헤더 번호 자체를 적습니다 (예: `4.5.3`).
98
+ 규칙: `Ticket ID` 는 본문에서 등장한 ticket 키와 정확히 동일 문자열. `Issue / Ticket` 이 비어 폴백된 경우 `Task ID` 값을 prefix 없이 그대로 (예: `8852`). 식별 불가는 `unknown`. `관련 항목 IDs` 는 `F-001`, `M-002`, `A1`, `Q1` 같은 row ID 를 콤마로 나열하고, row ID 가 없는 경우 섹션 번호 (예: `4.5.3`) 를 적습니다.
69
99
 
70
100
  ## Execution Status by Agent
71
101
 
72
- 각 worker의 status, 배정 모델, key finding을 곳에 모읍니다. worker 산출물을 근거 없는 주장으로 대체하지 않습니다.
102
+ 각 worker 의 status, 배정 모델, key finding 을 한 표에 모읍니다. worker 산출물을 근거 없는 주장으로 대체하지 않습니다.
73
103
 
74
104
  {{EXECUTION_STATUS_TABLE_ROWS}}
75
105
 
@@ -82,13 +112,22 @@ taskType: "{{FM_TASK_TYPE}}"
82
112
  | **전체 합계** | **`{{GRAND_TOTAL_TOKENS}}`** | **`{{GRAND_BILLABLE_TOKENS}}`** | **`{{GRAND_COST_USD}}`** |
83
113
  | Codex/Gemini CLI 추가 비용 | | | `{{CLI_COST_USD}}` |
84
114
 
85
- > 처리 토큰 = input + output + cache_creation + cache_read (raw). 환산 토큰 = cache_read×0.1 + cache_creation×1.25 + output×5 + input (input-등가). 비용은 공시 가격 기준 추정치.
115
+ <!--
116
+ 환산식 설명·"읽는 법"·캐시 가중치 등은 `docs/kr/architecture.md#token-accounting`
117
+ 및 audit 사이드카에서 참조하세요. 본문 가독성 회복을 위해 인용구는 제거했습니다.
118
+
119
+ placeholders 정책:
120
+ - Phase 6 시점에는 10 개 `{{...}}` 토큰을 verbatim 으로 둡니다.
121
+ - Phase 7 의 `okstra-token-usage.py --substitute-final-report` 가 치환합니다.
122
+ - 임의 값 (`0` / `N/A` / `--` / `not-collected` / `pending`) 으로 대체 금지.
123
+ Validator 가 치환 실패와 임의 값 모두 fail 합니다.
124
+ -->
86
125
 
87
126
  ## 1. Cross Verification Results
88
127
 
89
128
  ### 1.0 Round History (convergence-enabled runs only)
90
129
 
91
- `state/convergence-<task-type>-<seq>.json` 의 값을 그대로 옮긴다. convergence가 비활성화된 run에서는 이 섹션 전체를 삭제한다.
130
+ `state/convergence-<task-type>-<seq>.json` 의 값을 그대로 옮깁니다. convergence 가 비활성화된 run 에서는 이 sub-section 전체를 삭제합니다.
92
131
 
93
132
  | Round | inputQueueSize | resolvedCount | carriedForwardCount | dispatches (worker:status:durationMs) | skippedWorkers (worker:reason) |
94
133
  |-------|----------------|---------------|----------------------|----------------------------------------|---------------------------------|
@@ -96,42 +135,49 @@ taskType: "{{FM_TASK_TYPE}}"
96
135
  | 2 | 1 | 1 | 0 | claude-worker:completed:92110 | -- |
97
136
 
98
137
  - `round2SkippedReason`: `not-skipped` ← 값은 `queue-empty | max-rounds-1 | all-reverify-non-result | not-skipped` 중 하나.
99
- - 실행된 round 수가 0 (Round 0에서 모든 finding이 곧장 full-consensus 가 된 경우) 이면 표 대신 한 줄로 적는다 — `- Round 0 grouping에서 모든 finding이 합의되어 재검증 라운드가 실행되지 않았습니다.`
138
+ - 실행된 round 수가 0 (Round 0 에서 모든 finding 이 곧장 full-consensus) 이면 표 대신 한 — `- Round 0 grouping 에서 모든 finding 이 합의되어 재검증 라운드가 실행되지 않았습니다.`
100
139
 
101
140
  ### 1.1 Consensus
102
141
 
103
- | ID | Ticket ID | Statement | Supporting workers | Evidence (path:line / log / worker report) |
104
- |----|-----------|-----------|--------------------|---------------------------------------------|
105
- | C-001 | `<TICKET-or-fallback>` | <합의된 결론> | claude, codex, gemini | <증거 위치> |
142
+ | ID | Ticket ID | Statement | Source items (worker:item) | Evidence (path:line / log / worker report) |
143
+ |----|-----------|-----------|----------------------------|---------------------------------------------|
144
+ | C-001 | `<TICKET-or-fallback>` | <합의된 결론> | claude:F-001, codex:1.1, gemini:F-3 | <증거 위치> |
106
145
 
107
- - 합의된 결론을 row마다 기록합니다. `Ticket ID`는 보고서 상단 `Ticket Coverage` 규칙을 따릅니다.
146
+ 우선 (bullet 으로 degrade 금지). 합의된 결론을 row 마다 기록합니다.
147
+
148
+ `Source items` 규칙: 본 합의 row 가 어느 워커의 어느 항목들에서 합성됐는지를 `<worker>:<item-id>` 페어 콤마-리스트로 적습니다. 워커 항목 ID 는 워커 자체가 부여한 leading-column ID 입니다 (claude 는 `F-NNN`, codex 는 `1.1` 같은 hierarchical, gemini 는 자유). 바로 이 컬럼이 합성된 `C-NNN` 을 원본 worker-results 파일로 역추적하는 단 하나의 다리입니다 — 단순 워커 이름만 (`claude, codex, gemini`) 적으면 추적성이 끊깁니다. 자세한 정책은 `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
108
149
 
109
150
  ### 1.2 Differences
110
151
 
111
- | ID | Ticket ID | Disagreement | Workers (position) | Evidence |
112
- |----|-----------|--------------|--------------------|----------|
113
- | D-001 | `<TICKET-or-fallback>` | <차이 요약> | claude (A) / codex (B) / gemini (-) | <증거 위치> |
152
+ | ID | Ticket ID | Disagreement | Workers (position + item) | Evidence |
153
+ |----|-----------|--------------|---------------------------|----------|
154
+ | D-001 | `<TICKET-or-fallback>` | <차이 요약> | claude:F-005 (A) / codex:1.3 (B) / gemini:-- | <증거 위치> |
155
+
156
+ 유의미한 차이 없음: 표 대신 — `- 유의미한 차이 없음. 1.1 Consensus 가 그대로 유효합니다.`
114
157
 
115
- - 유의미한 차이가 없을 경우 대신 다음 줄을 적습니다 `- 유의미한 차이 없음. 1.1 Consensus가 그대로 유효합니다.`
158
+ `Workers (position + item)` 규칙: 1.1 의 `Source items` 와 동일한 `<worker>:<item-id>` 형식이되 워커마다 `(<position>)` 라벨 (`A` / `B` / `-` 등) 함께 적어 어느 워커가 어느 입장을 취했는지 표시합니다. 해당 plan item 에 의견을 내지 않은 워커는 `<worker>:--` 로 기록합니다.
116
159
 
117
160
  ## 2. Final Verdict
118
161
 
119
- 최종 결론과 권장 방향을 한 표로 명시합니다. `Direction`은 다음 중 하나입니다 — `continue-investigation`, `begin-implementation`, `approve`, `reject`, `hold`. `task-type`이 `final-verification`이면 `Verdict Token` 값은 반드시 `accepted` / `conditional-accept` / `blocked` 중 정확히 하나여야 하며, `release-handoff`는 이 값을 진입 게이트로 사용합니다. 다른 task-type에서는 `Verdict Token`에 `not-applicable`을 적습니다.
162
+ 최종 결론과 권장 방향을 한 표로 명시합니다. `Direction` `continue-investigation / begin-implementation / approve / reject / hold`. `task-type` `final-verification` 이면 `Verdict Token` `accepted / conditional-accept / blocked` 중 하나여야 하며, `release-handoff` 이 값을 진입 게이트로 사용합니다. 다른 task-type 에서는 `not-applicable`.
120
163
 
121
164
  | 항목 | 값 |
122
165
  |------|----|
123
166
  | Final Conclusion | <한 줄 결론> |
124
167
  | Verdict Token | `<accepted / conditional-accept / blocked / not-applicable>` |
125
168
  | Direction | `<continue-investigation / begin-implementation / approve / reject / hold>` |
126
- | 근거 요약 | <`1.1`, `3.1` 등 본 보고서 행 ID를 콤마로> |
169
+ | 근거 요약 | <`1.1`, `3.1` 등 본 보고서 행 ID 를 콤마로> |
127
170
  | 다음 단계 | <Section 6 또는 7 중 어디로 이어지는지> |
128
171
 
129
172
  ## 3. Evidence and Detailed Analysis
173
+
130
174
  ### 3.1 Primary Evidence
131
175
 
132
- | ID | Ticket ID | Evidence | Source (path:line / log / worker report) |
133
- |----|-----------|----------|------------------------------------------|
134
- | E-001 | `<TICKET-or-fallback>` | <증거 한 줄 요약> | <출처> |
176
+ | ID | Ticket ID | Evidence | Source items (worker:item) | Source (path:line / log) |
177
+ |----|-----------|----------|----------------------------|---------------------------|
178
+ | E-001 | `<TICKET-or-fallback>` | <증거 한 줄 요약> | claude:F-002, codex:1.4 | `<path>:<line>` 또는 로그 인용 |
179
+
180
+ `Source items` 컬럼 규칙은 §1.1 과 동일 — `<worker>:<item-id>` 페어 콤마-리스트로 어느 워커 항목들에서 본 증거가 도출됐는지 기록합니다. 워커 결과 인용 없이 lead 가 독립적으로 (예: MCP 직접 조회로) 얻은 증거는 `lead:mcp-<순번>` 형식으로 적습니다 (예: `lead:mcp-1`). `Source (path:line / log)` 컬럼은 코드/로그 위치 자체를 기록합니다.
135
181
 
136
182
  ### 3.2 Secondary Evidence or Alternate Interpretations
137
183
 
@@ -139,46 +185,56 @@ taskType: "{{FM_TASK_TYPE}}"
139
185
  |----|-----------|-----------------------------------|---------------------|
140
186
  | S-001 | `<TICKET-or-fallback>` | <보조 증거 또는 대안 해석> | <출처 + low/mid> |
141
187
 
142
- - 해당 없음 시: `- 보조 증거 또는 대안 해석 없음.`
188
+ 해당 없음 시: `- 보조 증거 또는 대안 해석 없음.`
143
189
 
144
190
  ## 4. Missing Information and Risks
145
191
 
146
- | ID | Ticket ID | Item | Risk if ignored |
147
- |----|-----------|------|-----------------|
148
- | R-001 | `<TICKET-or-fallback>` | <누락 정보 또는 불확실 항목> | <무시할 때의 위험> |
192
+ | ID | Ticket ID | Item | Risk if ignored | Mitigation Owner |
193
+ |----|-----------|------|-----------------|------------------|
194
+ | R-001 | `<TICKET-or-fallback>` | <누락 정보 또는 불확실 항목> | <무시할 때의 위험> | <역할 / 팀> |
195
+
196
+ `I don't know` / `uncertain` 항목은 모두 표 안에 두고 본문 산문으로 흩지 않습니다.
149
197
 
150
- - `I don't know` / `uncertain`으로 표기해야 하는 항목은 모두 표 안에 두고 본문 산문 형식으로 흩지 않습니다.
198
+ <!-- RENDER_IF: task-type == implementation-planning
199
+ Delete the entire `## 4.5` block + sub-sections otherwise.
151
200
 
152
- ## 4.5 Implementation Plan Deliverables (implementation-planning runs only)
201
+ Validator (validators/validate-run.py PLANNING_REQUIRED_SECTIONS) does
202
+ substring matching for these 9 English keywords in order:
203
+ Option Candidates, Trade-off, Recommended Option,
204
+ Stepwise Execution Order, Dependency, Validation Checklist, Rollback,
205
+ User Approval Request, Plan Body Verification
206
+ The first 7 + 9th live below; "User Approval Request" is satisfied by
207
+ the top-of-report Approval block heading. Do NOT recreate a §4.5.8 stub
208
+ in body — validator now fails reports that contain one. -->
153
209
 
154
- > **이 섹션은 `task-type` = `implementation-planning` 실행 결과에만 포함하세요. 다른 task-type에서는 섹션 전체를 삭제하고 5 섹션으로 바로 넘어갑니다.**
155
- >
156
- > 아래 8개 하위 섹션의 **영문 제목 키워드는 그대로 유지해야 합니다**. `validate-run.py`가 다음 8개 문자열을 본문에서 찾습니다 — `Option Candidates` / `Trade-off` / `Recommended Option` / `Stepwise Execution Order` / `Dependency` / `Validation Checklist` / `Rollback` / `User Approval Request`. 한국어 번역은 괄호 안에 병기해도 좋지만 영문 키워드는 반드시 보존하세요. 본문은 한국어로 작성합니다.
210
+ ## 4.5 Implementation Plan Deliverables
157
211
 
158
212
  ### 4.5.1 Option Candidates (옵션 후보)
159
- - 최소 두 개의 구현 옵션을 제시합니다. 각 옵션마다 다음을 포함합니다.
160
- - **File Structure**: 다음 표 형식으로 파일 단위 책임을 한 줄씩 명시합니다. 행마다 `Ticket ID` 컬럼을 채웁니다.
161
213
 
162
- | ID | Ticket ID | Action | Path (and line-range) | Change summary |
163
- |----|-----------|--------|------------------------|----------------|
164
- | OF-001 | `<TICKET-or-fallback>` | Create / Modify / Delete | `<path>[:<line-range>]` | <한 줄 요약> |
165
- - 영향을 받는 인터페이스 / 공개 계약 / 다운스트림 소비자.
166
- - 폭발 반경 추정(units, configs, deployment manifests, data migrations).
214
+ 최소 개의 구현 옵션. 옵션마다:
215
+
216
+ - **File Structure** 파일 단위 책임을 줄씩 (`Ticket ID` 채움):
217
+
218
+ | ID | Ticket ID | Action | Path (and line-range) | Change summary |
219
+ |----|-----------|--------|------------------------|----------------|
220
+ | OF-001 | `<TICKET-or-fallback>` | Create / Modify / Delete | `<path>[:<line-range>]` | <한 줄 요약> |
221
+
222
+ - 영향을 받는 인터페이스 / 공개 계약 / 다운스트림 소비자.
223
+ - 폭발 반경 추정 (units, configs, deployment manifests, data migrations).
167
224
 
168
225
  ### 4.5.2 Trade-off Matrix (트레이드오프 매트릭스)
226
+
169
227
  | Option | Complexity | Risk | Reversibility | Test Coverage Cost | Rollout Cost |
170
228
  |--------|-----------|------|---------------|--------------------|--------------|
171
229
  | <Option A> | <…> | <…> | <…> | <…> | <…> |
172
230
 
173
231
  ### 4.5.3 Recommended Option (권장 옵션)
174
232
 
175
- 권장 옵션과 그 이유를 표로 정리합니다. `근거`는 `4.5.2`의 비교 결과 + 디자인 원칙(isolation, files-that-change-together, follow-established-patterns, YAGNI) 중 적용된 항목을 적습니다.
176
-
177
233
  | 항목 | 값 |
178
234
  |------|----|
179
235
  | Recommended Option | <옵션 이름> |
180
236
  | 핵심 이유 | <한 줄> |
181
- | 근거 (Trade-off 행 / 원칙) | <4.5.2 행 + 적용 디자인 원칙> |
237
+ | 근거 (Trade-off 행 / 원칙) | <4.5.2 행 + 적용 디자인 원칙: isolation / files-that-change-together / follow-established-patterns / YAGNI> |
182
238
  | 채택되지 않은 옵션 요약 | <짧게: 어떤 비용 때문에 탈락> |
183
239
 
184
240
  ### 4.5.4 Stepwise Execution Order (단계별 실행 순서)
@@ -187,16 +243,11 @@ taskType: "{{FM_TASK_TYPE}}"
187
243
  |------|-----------|------------------|-------|----------------|-------------------|
188
244
  | 1 | `<TICKET-or-fallback>` | <예: 실패하는 테스트 작성> | `tests/foo_test.py` | `pytest tests/foo_test.py::test_x -v` | FAIL with <reason> |
189
245
 
190
- 규칙:
191
-
192
- - 한 step은 약 2~5분 안에 완료할 수 있는 작은 작업이어야 합니다(예: "X에 실패하는 테스트 작성", "테스트 실행해 실패 확인", "최소 구현", "테스트 통과 확인", "commit").
193
- - 모든 step은 정확한 파일 경로와 정확한 명령어를 포함합니다. 코드 단계라면 실제 코드 또는 diff 스케치를 함께 적습니다 (`Action` 셀에 줄바꿈 가능).
194
- - TDD 순서(failing test → implementation → green → commit)가 가능한 영역이라면 이 순서를 따릅니다.
195
- - 한 step이 여러 ticket을 동시에 진행한다면 `Ticket ID`에 콤마로 함께 적습니다.
246
+ 규칙: 한 step 은 약 2~5 분. 모든 step 은 정확한 파일 경로와 명령어 포함. TDD 가능 영역은 failing test → implementation → green → commit 순서.
196
247
 
197
248
  ### 4.5.5 Dependency / Migration Risk (의존성·마이그레이션 위험)
198
249
 
199
- 순서 제약, 데이터 백필, feature-flag 선행 조건, repo-internal sequencing 등을 표로 정리합니다. 외부 승인·권한 확인·vendor 또는 외부 팀 조율은 공통 권한 규칙상 위험/일정 항목으로 추가하지 않습니다. 해당 없음 시: `- 의존성·마이그레이션 위험 없음.` 한 줄.
250
+ 순서 제약, 데이터 백필, feature-flag 선행 조건, repo-internal sequencing. 외부 승인·권한·vendor 조율은 위험/일정 항목으로 등록하지 않습니다. 해당 없음: `- 의존성·마이그레이션 위험 없음.`
200
251
 
201
252
  | ID | Kind (order / backfill / flag-precondition / repo-sequencing / other) | Item | 영향 | 완화 / 선행 작업 |
202
253
  |----|------------------------------------------------------------------------|------|------|------------------|
@@ -210,68 +261,73 @@ taskType: "{{FM_TASK_TYPE}}"
210
261
  | mid | `<TICKET-or-fallback>` | <체크 이름> | `<...>` | <...> |
211
262
  | post | `<TICKET-or-fallback>` | <체크 이름> | `<...>` | <...> |
212
263
 
213
- 추상적 서술 금지. 모든 row는 명령어 또는 관찰 가능한 결과를 포함해야 합니다.
264
+ 추상적 서술 금지. 모든 row 는 명령어 또는 관찰 가능한 결과를 포함.
214
265
 
215
266
  ### 4.5.7 Rollback Strategy (롤백 전략)
216
267
 
217
- revert 경로와 롤백 트리거 신호를 표로 정리합니다. 추상적 서술 금지 — 명령어 또는 관찰 가능한 신호여야 합니다.
218
-
219
268
  | ID | Step | Action (revert command / flag toggle / migration down) | Trigger signal (error rate / latency / user report 등) | 확인 방법 |
220
269
  |----|------|---------------------------------------------------------|--------------------------------------------------------|-----------|
221
270
  | RB-001 | 1 | `<예: git revert <SHA>>` | <예: 에러율 > 1% 5분 지속> | `<관찰 명령 / 대시보드>` |
222
271
 
223
- ### 4.5.8 User Approval Request (사용자 승인 요청 — 본 보고서 상단 참조)
224
- - 실제 승인 게이트는 본 보고서 **상단 `User Approval Request (사용자 승인 게이트)` 블록**에 있습니다. 이 하위 섹션은 validator가 요구하는 영문 키워드(`User Approval Request`)와 본문 구조 일관성을 위해 남겨 둡니다.
225
- - 본 섹션에는 승인 결정에 영향을 주는 *플랜 측 보충 메모*만 적습니다(예: 위험을 줄이기 위한 사전 작업, 승인 전 사용자가 확인해 두어야 할 사항). 승인 마커는 본 섹션이 아니라 상단 블록의 체크박스로만 부여합니다.
226
- - 사용자가 답하거나 자료를 첨부해야만 승인이 가능한 항목은 **이 섹션에 적지 않습니다** — `## 5. Clarification Items` 표에 한 행으로 등록하고 `Blocks=approval` 로 표시하세요. 같은 항목을 두 위치에 적으면 sync 가 깨집니다.
227
-
228
- ### 4.5.9 Plan Body Verification (워커 사후 검증)
272
+ ### 4.5.9 Plan Body Verification (계획 본문 검증)
229
273
 
230
- > **이 sub-section 은 `task-type` = `implementation-planning` 실행 결과에만 포함하세요.** Phase 6 에서 report-writer 가 합성한 4.5 본문(Option Candidates / Stepwise Execution Order / Dependency / Validation Checklist / Rollback)을 lead 가 plan-item 단위로 쪼개 워커들에게 다시 던지고 `AGREE / DISAGREE / SUPPLEMENT` 평결을 수집한 결과입니다. 자세한 라운드 프로토콜은 `skills/okstra-convergence/SKILL.md` "Plan-body verification mode" 섹션을 참고하세요.
274
+ Phase 6 에서 report-writer 가 합성한 4.5 본문을 lead 가 plan-item 단위로 워커들에게 다시 던지고 `AGREE / DISAGREE / SUPPLEMENT` 평결을 수집한 결과. 라운드 프로토콜은 `skills/okstra-convergence/SKILL.md` "Plan-body verification mode" 참조.
231
275
 
232
276
  - **Round count**: `<N>` (default: 1)
233
277
  - **Gate result**: `<passed | passed-with-dissent | blocked-by-disagreement | aborted-non-result>`
234
- - `passed` → 본 보고서 상단 `User Approval Request` 체크박스가 렌더됩니다.
235
- - `passed-with-dissent` → 상단 체크박스가 렌더되되, 반대 의견은 아래 `Dissent log` 에 기록.
236
- - `blocked-by-disagreement` → 상단 체크박스 라인 자체를 **렌더하지 않습니다**. majority DISAGREE 인 plan item 마다 `## 5. Clarification Items` 에 `Blocks=approval` row 가 추가되며, 사용자가 응답해야 다음 phase 로 넘어갈 수 있습니다.
237
- - `aborted-non-result` → 워커 dispatch 가 모두 non-result (timeout / error). 상단 체크박스 라인 렌더하지 않음 + `## 5. Clarification Items` 에 "plan-body verification could not run" row 가 추가됩니다.
278
+ - `passed` → 상단 `User Approval Request` 체크박스 라인 렌더.
279
+ - `passed-with-dissent` → 체크박스 렌더 + 반대 의견은 아래 `Dissent log` 에 기록.
280
+ - `blocked-by-disagreement` → 체크박스 라인 **렌더하지 않음**. majority DISAGREE 인 plan item 마다 `## 5.` 에 `Blocks=approval` row 추가.
281
+ - `aborted-non-result` → 워커 dispatch 가 모두 non-result. 체크박스 라인 렌더하지 않음 + `## 5.` 에 "plan-body verification could not run" row.
282
+
283
+ #### Verdict summary
284
+
285
+ 각 plan item 1 행. `Plan item` 열은 `P-Opt-<N>` / `P-Step-<N>` / `P-Dep-<N>` / `P-Val-<N>` / `P-Rb-<N>` prefix. `Section` 열은 4.5 내부 sub-section 번호. 워커별 평결은 아래 `Verdict details` 표로 분리합니다 (워커 수에 비례해 가로 폭이 폭발하던 단일 wide 표를 두 개로 쪼개 시인성을 회복).
238
286
 
239
- #### Verdict table
287
+ | Plan item | Ticket ID | Section | Classification |
288
+ |-----------|-----------|---------|----------------|
289
+ | P-Opt-1 | `<id>` | 4.5.1 | full-consensus |
290
+ | P-Step-3 | `<id>` | 4.5.4 | majority-disagree → C-7 |
240
291
 
241
- plan item 1 행. `Plan item` 열은 `P-Opt-<N>` / `P-Step-<N>` / `P-Dep-<N>` / `P-Val-<N>` / `P-Rb-<N>` prefix 사용. `Section` 열은 4.5 내부 sub-section 번호 (예: `4.5.4`).
292
+ - `Classification` `{full-consensus, partial-consensus, worker-unique, majority-disagree C-<N>}`.
293
+ - `majority-disagree → C-<N>` 의 `C-<N>` 은 `## 5. Clarification Items` 의 row ID 와 1:1 일치해야 합니다.
242
294
 
243
- | Plan item | Ticket ID | Section | <worker1> | <worker2> | ... | Classification |
244
- |-----------|-----------|---------|-----------|-----------|-----|----------------|
245
- | P-Opt-1 | `<id>` | 4.5.1 | AGREE | AGREE | ... | full-consensus |
246
- | P-Step-3 | `<id>` | 4.5.4 | DISAGREE(a) | DISAGREE(a) | ... | majority-disagree → C-7 |
295
+ #### Verdict details
247
296
 
248
- - DISAGREE 셀에는 spec 의 `(a|b|c|d|e)` breakage kind 를 함께 표기 (예: `DISAGREE(a)` = 참조 file path / symbol 불일치).
249
- - 마지막 열 `Classification` ∈ `{full-consensus, partial-consensus, worker-unique, majority-disagree → C-<N>}`. `majority-disagree → C-<N>` 의 `C-<N>` 은 본 보고서 `## 5. Clarification Items` 표에서 해당 변환 row 의 ID 와 일치해야 합니다.
297
+ 워커별 평결을 plan item × worker 쌍으로 1 행씩 기록합니다. 워커 수가 늘어나도 가로 폭이 늘지 않고 행 수만 늘어납니다. `Verdict` ∈ `{AGREE, DISAGREE, SUPPLEMENT, verification-error}`. `Breakage kind` 는 `DISAGREE` 때만 채우며 spec 의 `(a|b|c|d|e)` 하나 (a=참조 file path / symbol 불일치, b=… 자세한 정의는 `skills/okstra-convergence/SKILL.md`).
298
+
299
+ | Plan item | Worker | Verdict | Breakage kind | Note (선택) |
300
+ |-----------|--------|---------|---------------|-------------|
301
+ | P-Opt-1 | claude-worker | AGREE | -- | |
302
+ | P-Opt-1 | codex-worker | AGREE | -- | |
303
+ | P-Step-3 | claude-worker | DISAGREE | a | 참조한 `crates/.../mod.rs:120` 가 없음 |
304
+ | P-Step-3 | codex-worker | DISAGREE | a | 동일 — 파일 path 미존재 |
305
+ | P-Step-3 | gemini-worker | SUPPLEMENT | -- | 대체 step 제안 (Dissent log 참조) |
250
306
 
251
307
  #### Dissent log
252
308
 
253
- `partial-consensus` 와 `worker-unique` 로 분류된 plan item 의 반대 의견을 plan item 별로 묶어 적습니다. `majority-disagree` 항목의 반대 의견은 본 섹션 대신 `## 5. Clarification Items` 의 해당 row `Statement` 컬럼에 옮겨 적습니다.
309
+ `partial-consensus` 와 `worker-unique` 의 반대 의견을 plan item 별로 묶어 적습니다. `majority-disagree` 항목의 반대 의견은 본 섹션 대신 `## 5.` 의 해당 row `Statement` 컬럼에 옮겨 적습니다.
254
310
 
255
311
  - **P-XXX-N**: `<worker-role>` — `<반대 의견 본문 2-3 sentences>`
256
312
 
257
- #### Notes
313
+ <!-- /RENDER_IF (task-type == implementation-planning) -->
258
314
 
259
- - sub-section 이 누락된 채로 task-type = implementation-planning final report 가 생성되면 validator 가 `contract-violated` 로 종료합니다.
260
- - `Gate result` `blocked-by-disagreement` / `aborted-non-result` 인데 상단 `User Approval Request` 체크박스 라인이 존재하면 동일하게 contract violation 입니다.
315
+ <!-- RENDER_IF: task-type == release-handoff
316
+ Delete the entire `## 4.6` block + sub-sections otherwise. -->
261
317
 
262
- ## 4.6 Release Handoff Deliverables (release-handoff runs only)
318
+ ## 4.6 Release Handoff Deliverables
263
319
 
264
- > **이 섹션은 `task-type` = `release-handoff` 실행 결과에만 포함하세요. 다른 task-type에서는 섹션 전체를 삭제하고 5번 섹션으로 넘어갑니다.**
265
- >
266
- > 이 섹션은 git/gh mutating 명령이 실행된 phase의 감사 기록입니다. 모든 mutating command 는 반드시 위 `User Selections` 표의 사용자 응답과 1:1로 대응되어야 하며, 대응되지 않는 mutating command 가 있으면 self-review 가 `contract-violated` 로 종료해야 합니다.
320
+ git/gh mutating 명령이 실행된 phase 의 감사 기록. 모든 mutating command 는 반드시 아래 `User Selections` 표의 사용자 응답과 1:1 대응되어야 하며, 대응되지 않는 mutating command 가 있으면 self-review `contract-violated` 종료해야 합니다.
267
321
 
268
322
  ### 4.6.1 Source Verification Report (선행 final-verification 인용)
323
+
269
324
  - Path (project-relative): `<runs/final-verification/.../reports/final-report-final-verification-<seq>.md>`
270
- - Quoted `Verdict Token` row from that report's `## 2. Final Verdict` table (값이 정확히 `accepted`여야 함):
325
+ - Quoted `Verdict Token` row from that report's `## 2.` table (값이 정확히 `accepted` 여야 함):
271
326
  > <원문 인용>
272
- - 만약 원본 `Verdict Token` 값이 `accepted` 가 아니라면 본 run 은 **실행되지 않아야 했습니다**. self-review 단계에서 contract-violated 처리하고 routing 을 `final-verification` 으로 되돌립니다.
327
+ - 원본 `Verdict Token` 값이 `accepted` 가 아니면 본 run 은 실행되지 않아야 했습니다. self-review 에서 contract-violated 처리하고 routing 을 `final-verification` 으로 되돌립니다.
273
328
 
274
329
  ### 4.6.2 Feature Branch & Working-Tree State (run 시작 시점)
330
+
275
331
  - Feature branch (`git rev-parse --abbrev-ref HEAD`): `<branch-name>`
276
332
  - `git status --short` 출력:
277
333
  ```
@@ -280,160 +336,124 @@ revert 경로와 롤백 트리거 신호를 표로 정리합니다. 추상적
280
336
  - 기존 PR 존재 여부 (`gh pr list --head <branch> --state open --json url --jq '.[0].url'`): `<URL or empty>`
281
337
 
282
338
  ### 4.6.3 User Selections (메뉴 응답 기록)
339
+
283
340
  | 질문 ID | 질문 본문 | 사용자 응답 (원문) | 응답이 가능한 보기 |
284
341
  |---------|-----------|--------------------|--------------------|
285
342
  | H1 | 어떤 작업을 실행할까요? | <`local only` / `push + PR` / `skip`> | `local only` / `push + PR` / `skip` |
286
- | H2 | PR base 브랜치를 골라주세요. (H1=`push + PR` 인 경우에만 묻습니다) | <`staging` / `preprod` / `prod` / `main` / `dev` / 사용자가 입력한 브랜치명> | `staging` / `preprod` / `prod` / `main` / `dev` / 직접 입력 |
287
- | H3 | lead가 작성한 PR title / PR body 초안을 어떻게 처리할까요? | <`use as-is` / `edit then proceed` / `cancel`> | `use as-is` / `edit then proceed` / `cancel` |
343
+ | H2 | PR base 브랜치를 골라주세요. (H1=`push + PR` 인 경우에만 묻습니다) | <`staging` / `preprod` / `prod` / `main` / `dev` / 사용자가 입력한 브랜치명> | + 직접 입력 |
344
+ | H3 | lead 가 작성한 PR title / PR body 초안을 어떻게 처리할까요? | <`use as-is` / `edit then proceed` / `cancel`> | `use as-is` / `edit then proceed` / `cancel` |
288
345
 
289
- H1 `skip` 이거나 H3 `cancel` 인 경우, 본 섹션 다음의 4.6.4 ~ 4.6.6 은 빈 결과로 채우고 (mutating 명령 미실행) 4.6.7 routing 만 채웁니다.
346
+ H1 = `skip` 이거나 H3 = `cancel` 인 경우 4.6.4 ~ 4.6.6 은 빈 결과로 채우고 (mutating 명령 미실행) 4.6.7 routing 만 채웁니다.
290
347
 
291
348
  ### 4.6.4 Executed Commands (실행한 git / gh 명령 로그)
292
- - **Mutating commands**: 정확한 명령행 / exit code / 한 줄 stdout 요약을 한 행씩 모두 기록합니다. 누락은 contract-violated 입니다.
293
- - **Read-only inspection commands**: 요약 또는 명령행 목록만 적어도 됩니다.
349
+
350
+ - Mutating commands: 정확한 명령행 / exit code / 한 줄 stdout 요약을 한 행씩 모두 기록 (누락은 contract-violated).
351
+ - Read-only inspection commands: 요약 또는 명령행 목록만으로 충분.
294
352
 
295
353
  | # | command (verbatim) | exit code | stdout/stderr 요약 |
296
354
  |---|---------------------|-----------|--------------------|
297
355
  | 1 | `<예: git add path/to/file.py>` | `0` | `<요약>` |
298
356
 
299
357
  ### 4.6.5 Commit List (생성된 commit)
300
- - `implementation` phase에서 이미 생성된 commit 범위(`git log <base>..HEAD`)를 기록합니다. release-handoff는 새 commit을 만들지 않습니다.
301
- - 각 commit 의 short SHA / full SHA / subject / 영향 파일 목록을 한 항목씩 기록합니다.
302
- - commit 범위가 비어 있으면 release-handoff가 실행되면 안 됩니다. 다음 한 줄을 적고 routing을 `implementation`으로 되돌립니다.
303
- > `- No implementation commits found; release-handoff is blocked.`
358
+
359
+ `implementation` phase 에서 이미 생성된 commit 범위 (`git log <base>..HEAD`) 를 기록. release-handoff 는 새 commit 을 만들지 않습니다. 각 commit 의 short SHA / full SHA / subject / 영향 파일 목록.
360
+
361
+ commit 범위가 비어 있으면 release-handoff 는 실행되면 안 됩니다 → `- No implementation commits found; release-handoff is blocked.` + routing 을 `implementation` 으로 되돌림.
304
362
 
305
363
  ### 4.6.6 Pull Request Outcome (PR 결과)
306
- - 다음 네 가지 중 정확히 하나의 형식으로 한 줄을 적습니다.
307
- - `- No PR action requested.` (H1=`local only` 또는 `skip` 인 경우)
308
- - `- PR created: <url>` + 타이틀 + base 브랜치
309
- - `- PR reused: <url>` (run 시작 시점에 같은 head 의 open PR 이 이미 존재해 `gh pr create` 를 생략한 경우)
310
- - `- PR creation skipped: <reason>` (H3=`cancel`, 또는 push/PR 생성 도중 사용자가 중단 지시한 경우. reason 은 풀어 쓴 한 문장)
364
+
365
+ 다음 가지 정확히 하나의 형식으로 줄:
366
+
367
+ - `- No PR action requested.` (H1 = `local only` 또는 `skip`)
368
+ - `- PR created: <url>` + 타이틀 + base 브랜치
369
+ - `- PR reused: <url>` (run 시작 시 같은 head 의 open PR 이 이미 존재해 `gh pr create` 생략)
370
+ - `- PR creation skipped: <reason>` (H3 = `cancel`, 또는 push/PR 도중 사용자 중단)
311
371
 
312
372
  ### 4.6.7 Routing Recommendation (마지막 phase 라우팅)
313
- - `release-handoff` 는 lifecycle 의 종착 phase 이므로 일반적으로 `done` 으로 라우팅합니다.
314
- - 단, H1=`skip` 또는 H3=`cancel` 로 종료된 경우 사용자가 추후 재진입해 다시 release-handoff 를 실행할 수 있는지 한 줄로 명시합니다.
315
- - 형식 예시: `- Routing: done. PR <url> opened against <base>; no follow-up required.`
316
373
 
317
- ## 5. Clarification Items
374
+ `release-handoff` lifecycle 종착 phase 이므로 일반적으로 `done` 으로 라우팅합니다. H1 = `skip` 또는 H3 = `cancel` 로 종료된 경우 재진입 가능 여부를 한 줄로 명시합니다.
318
375
 
319
- 섹션은 다음 run 으로 넘어가기 전에 사용자가 답하거나 자료를 첨부해야 하는 항목을 **한 표 안에서** 추적합니다. `task-type`이 `error-analysis` 또는 `requirements-discovery` 이고 지금까지의 증거만으로 확신 있는 최종 판단이 어려울 때는 반드시 채웁니다. 그 외의 `task-type`에서는 lead 가 필요하다고 판단할 때만 채우고, 그렇지 않다면 `- 추가 정보 요청 없음. Section 2의 최종 판단이 그대로 유효합니다.` 한 줄만 남깁니다.
376
+ 형식 예시: `- Routing: done. PR <url> opened against <base>; no follow-up required.`
320
377
 
321
- 표가 도입되기 전에는 `4.5.9 Open Questions` / `5.1 추가 자료 요청` / `5.2 사용자 확인 질문` 세 자리에 같은 항목이 중복으로 적히는 문제가 있었습니다. 그 세 위치는 더 이상 사용하지 않으며, 모든 항목은 본 표의 한 행으로 표현합니다. 표 외부에 같은 항목을 다시 적지 마세요 (sync 깨집니다).
378
+ <!-- /RENDER_IF (task-type == release-handoff) -->
379
+
380
+ ## 5. Clarification Items
381
+
382
+ 다음 run 으로 넘어가기 전에 사용자가 답하거나 자료를 첨부해야 하는 항목을 **한 표 안에서** 추적합니다. `task-type` 이 `error-analysis` / `requirements-discovery` 이고 지금까지의 증거만으로 확신 있는 최종 판단이 어려울 때는 반드시 채웁니다. 그 외 task-type 에서는 lead 가 필요하다고 판단할 때만 채우고, 그렇지 않다면 `- 추가 정보 요청 없음. Section 2 의 최종 판단이 그대로 유효합니다.` 한 줄만 남깁니다.
322
383
 
323
384
  작성 원칙:
324
385
 
325
- - 개발자가 아닌 사람도 한 번 읽고 무엇을 어디서 가져와야 하는지 이해할 수 있게, 줄임말과 내부 용어 대신 풀어 쓴 문장으로 작성합니다. (예: "QPS" 대신 "초당 평균 요청 수", "AC 미정" 대신 "합격 기준이 아직 정의되지 않았습니다")
326
- - 한 행은 "왜 필요한지", "무엇을 묻거나 받아야 하는지", "어떤 형태의 답을 기대하는지"가 모두 분명히 드러나야 합니다. 한 줄짜리 단답형 질문은 피하고, 필요한 배경을 1~2 문장으로 함께 적습니다.
327
- - run 사이에 일관된 추적이 가능하도록 항목별 ID (`C-001`, `C-002`, ...) 는 한 번 부여한 뒤 다음 run 에서도 유지합니다. 이미 답변된 항목은 다음 run 에서도 삭제하지 말고 `Status`만 `resolved` 또는 `obsolete` 로 갱신합니다.
386
+ - 개발자가 아닌 사람도 한 번 읽고 무엇을 어디서 가져와야 하는지 이해할 수 있게, 줄임말과 내부 용어 대신 풀어 쓴 문장.
387
+ - 한 행은 "왜 필요한지", "무엇을 묻거나 받아야 하는지", "어떤 형태의 답을 기대하는지" 가 모두 드러나야 함.
388
+ - 항목별 ID (`C-001`, `C-002`, ) 는 run 유지. 답변된 항목은 다음 run 에서도 삭제하지 말고 `Status` `resolved` / `obsolete` 로 갱신.
389
+
390
+ 답을 채우신 뒤 같은 phase 를 다시 실행:
328
391
 
329
- 보고서에 답을 채우신 뒤에는 한 줄로 같은 phase 를 다시 실행하실 수 있습니다 (자동으로 `$EDITOR` 가 이 파일을 열고, 저장하면 같은 phase 가 `--clarification-response` 로 carry-in 되어 재실행됩니다).
330
- - Claude Code 세션 안: `/okstra-run resume-clarification task-key={{TASK_KEY}}`
392
+ - Claude Code: `/okstra-run resume-clarification task-key={{TASK_KEY}}`
331
393
  - 별도 터미널: `scripts/okstra.sh --resume-clarification --task-key {{TASK_KEY}}`
332
394
 
333
- 스크립트로 자동화하실 때는 형식 `scripts/okstra.sh --task-key {{TASK_KEY}} --task-type {{TASK_TYPE}} --clarification-response <이 파일 경로>` 그대로 사용하실 있습니다. Node `okstra` admin CLI `--task-key`/`--task-type`/`--resume-clarification` 을 받지 않으므로 위 두 진입점 중 하나를 사용하세요.
334
-
335
- ### 5.1 Clarification Items table
336
-
337
- | ID | Ticket ID | Kind | Statement (무엇이 필요한지 + 왜) | Expected form (답·자료의 모양) | Blocks | Status | User input (사용자가 다음 run 전에 채움) |
338
- |----|-----------|------|----------------------------------|-------------------------------|--------|--------|------------------------------------------|
339
- | C-001 | `<TICKET-or-fallback>` | `decision` | <예: "지난 주 새벽에 보고된 결제 실패가 일회성 사고였는지, 아니면 같은 증상이 다시 발생한 적이 있는지 알려주십시오. 이 결정에 따라 다음 run 의 task-type `error-analysis` 로 갈지 `requirements-discovery` 갈지가 갈립니다."> | <예: "(a) 일회성·재발 없음, (b) 재발 있음 — 가장 최근 시각 YYYY-MM-DD HH:MM, 영향 사용자 수 약 N명"> | `next-phase` | open | <빈칸으로 두고 다음 run 전에 사용자가 채움> |
340
- | C-002 | `<TICKET-or-fallback>` | `material` | <예: "오류가 처음 보고된 시각 전후 30분 동안의 worker 로그가 필요합니다. 어떤 task 가 실패했고 그때 큐에 무엇이 쌓여 있었는지를 함께 확인해야 root cause 가설을 좁힐 수 있기 때문입니다. Datadog `service:worker env:prod` 필터, 시각 범위 2026-04-30 09:30~10:30 KST. `.project-docs/tasks/8852/logs/worker-2026-04-30.log` 로 저장해 주십시오."> | <예: "위 경로의 .log 파일 (gzip 압축 가능)"> | `next-phase` | open | |
341
- | C-003 | `<TICKET-or-fallback>` | `data-point` | <예: "본 배치 시작 직전 `common.FontManualClassifiers` 의 `prediction=0` / `prediction=1` 행 수가 필요합니다. acceptance #5 의 동일성 검증 ground truth 입니다."> | <예: "두 정수 (prediction=0 count, prediction=1 count) 를 한 줄로"> | `approval` | open | |
342
-
343
- ### 5.2 컬럼 가이드
344
-
345
- - **`Kind`** `{material, decision, data-point}`:
346
- - `material` — 파일 / 스냅샷 / 로그 / 스크린샷 등 사용자가 따로 **첨부 또는 경로 공유** 해야 하는 자료.
347
- - `decision` 사용자가 선택지 하나를 고르거나 (a/b/c 보기, yes/no) 짧게 자유서술로 결정해 주셔야 진행 가능한 의사결정.
348
- - `data-point` 숫자 / ID / 날짜 / 짧은 문자열처럼 사용자가 명령 번으로 뽑아 **inline 으로** 답해 주실 있는 사실 확인.
349
- - **`Statement`**: 무엇을 묻거나 받아야 하는지 + 필요한지 + (material 경우) 어디서 가져오는지·어디에 두면 되는지를 1~3 문장으로. 자료 출처가 길면 본 셀에 풀어 적고 `Expected form` 셀은 짧게 유지합니다.
350
- - **`Expected form`**: 답 / 자료의 모양 — 예/아니오, 보기 a/b/c, 정수, 날짜, 파일 경로, URL 등. 가능하면 정확한 보기 또는 예시 한 줄.
351
- - **`Blocks`** ∈ `{approval, next-phase, none}`:
352
- - `approval` — `implementation-planning` 의 User Approval Request 통과를 막는 항목. 모두 `resolved`/`obsolete` 가 되어야 상단 체크박스를 `[x]` 로 바꿀 수 있습니다.
353
- - `next-phase` — 승인 게이트가 아니더라도 다음 run 진입에 답이 필요한 항목.
354
- - `none` — informational. 답이 없어도 다음 phase 는 진행 가능하지만 audit 기록을 위해 남깁니다.
355
- - **`Status`** ∈ `{open, answered, resolved, obsolete}`:
356
- - `open` — 요청했지만 아직 받지 못함.
357
- - `answered` — 사용자가 `User input` 칸을 채워 두었음 (다음 run 의 lead 가 검증해야 함).
358
- - `resolved` — 다음 run 에서 lead 가 답변·자료를 받아 검증을 마침.
359
- - `obsolete` — 이후 분석 결과로 더 이상 필요 없어진 항목.
360
- - **`User input`**: 사용자가 직접 채우는 칸. `material` 이면 첨부 파일 경로 / URL / 메모, `decision` 이면 선택 또는 짧은 서술, `data-point` 이면 inline 값.
361
-
362
- 작성 안티패턴 (자동 거절):
363
-
364
- - 같은 항목을 `## 4.5.8 User Approval Request` 보충 메모와 본 표에 동시 등록 — `Blocks=approval` 행 하나로 충분합니다.
365
- - 한 행을 두 개로 나눠 "자료 요청 행" 과 "관련 질문 행" 으로 쪼개기 — 자료 + yes/no 가 묶인 항목은 `Kind=material`, `Expected form` 에 "파일 경로 + yes/no" 라고 적은 한 행으로 처리합니다.
366
- - 사용자가 답하지 않아도 진행 가능한 항목을 `Blocks=approval` 로 표시 — `Blocks=none` 또는 `next-phase` 로 정확히 표시하세요. 잘못 표시하면 사용자가 불필요하게 게이트에 걸립니다.
395
+ | ID | Ticket ID | Kind | Statement (무엇이 필요한지 + 왜) | Expected form (답·자료의 모양) | Blocks | Status | User input |
396
+ |----|-----------|------|----------------------------------|-------------------------------|--------|--------|-----------|
397
+ | C-001 | `<TICKET-or-fallback>` | `decision` | <예: "지난 주 새벽 결제 실패가 일회성이었는지 재발했는지 알려주세요. 다음 run 의 task-type 이 `error-analysis` 로 갈지 `requirements-discovery` 로 갈지가 갈립니다."> | <예: "(a) 일회성, (b) 재발 — 최근 시각 YYYY-MM-DD HH:MM, 영향 사용자 수 약 N명"> | `next-phase` | open | <빈칸으로 두고 다음 run 전에 사용자가 채움> |
398
+ | C-002 | `<TICKET-or-fallback>` | `material` | <예: "오류 시각 전후 30분 worker 로그가 필요합니다. Datadog `service:worker env:prod` 필터, 시각 2026-04-30 09:30~10:30 KST. `.project-docs/okstra/tasks/8852/logs/worker-2026-04-30.log` 로 저장해 주세요."> | <예: "위 경로의 .log 파일 (gzip 가능)"> | `next-phase` | open | |
399
+ | C-003 | `<TICKET-or-fallback>` | `data-point` | <예: "본 배치 시작 직전 `common.FontManualClassifiers` `prediction=0` / `prediction=1` 수가 필요합니다. acceptance #5 의 동일성 검증 ground truth."> | <예: "두 정수 (prediction=0 count, prediction=1 count) 한 줄로"> | `approval` | open | |
400
+
401
+ 컬럼 가이드 (전체 정의는 `prompts/profiles/_common-contract.md §Clarification request policy` SSOT 참조):
402
+
403
+ - **`Kind`** `{material, decision, data-point}`.
404
+ - **`Blocks`** ∈ `{approval, next-phase, none}` — `approval` 은 implementation-planning 의 승인 게이트 차단.
405
+ - **`Status`** `{open, answered, resolved, obsolete}`.
406
+
407
+ 안티패턴 (validator fail 처리):
408
+
409
+ - 같은 항목을 별도 sub-section (`5.1 추가 자료 요청` / `5.2 사용자 확인 질문` / `4.5.9 Open Questions`) 으로 분리하기 8-열 한 곳으로만 표현합니다.
410
+ - 행을 개로 쪼개기 자료 + yes/no 묶인 항목은 `Kind=material`, `Expected form` "파일 경로 + yes/no" 라고 적은 행.
411
+ - 사용자가 답하지 않아도 진행 가능한 항목을 `Blocks=approval` 표시 `Blocks=none` / `next-phase` 정확히 표시.
367
412
 
368
413
  ## 6. Recommended Next Steps
369
414
 
370
- This section is **always present** in every final report — never omit the heading. If there are no concrete actions to take, write the single line `- No further action required. Final verdict in section 2 stands.` under the heading and stop.
415
+ This section is **always present** — never omit the heading. If there are no concrete actions, write the single line `- No further action required. Final verdict in section 2 stands.` and stop.
371
416
 
372
- When concrete actions exist, list them as a numbered list using the rules below. Each item must include the exact command(s) the user can copy-paste. Show **both** the Claude Code in-session form (`/okstra-run …`) and the external-terminal shell form (`scripts/okstra.sh …`) — the Node `okstra` admin CLI does NOT accept `--task-key` / `--task-type` / `--resume-clarification`. Prefer the `task-key` shorthand for follow-up runs and `resume-clarification` for clarification answer turn-arounds; show the equivalent full-args form only when useful.
417
+ When concrete actions exist, list them as a numbered list. Each item includes the exact copy-pasteable command(s). Show **both** the in-session form (`/okstra-run …`) and the external-terminal form (`scripts/okstra.sh …`) — the Node `okstra` admin CLI does NOT accept `--task-key` / `--task-type` / `--resume-clarification`.
373
418
 
374
- 1. **Highest-priority next action.** State what to do and why in one sentence, then the command. Example shortcut forms:
419
+ 1. **Highest-priority next action.** State what + why in one sentence, then the command.
375
420
  - Same phase rerun:
376
- - Claude Code 세션 안: `/okstra-run task-key={{TASK_KEY}} task-type={{TASK_TYPE}}`
421
+ - Claude Code: `/okstra-run task-key={{TASK_KEY}} task-type={{TASK_TYPE}}`
377
422
  - 별도 터미널: `scripts/okstra.sh --task-key {{TASK_KEY}} --task-type {{TASK_TYPE}}`
378
- - Next phase (omit `task-type` to use the manifest's `workflow.nextRecommendedPhase` automatically when it is a concrete phase, not `pending-routing-decision` / `done-or-follow-up`):
379
- - Claude Code 세션 안: `/okstra-run task-key={{TASK_KEY}} task-type=<next-phase>`
423
+ - Next phase (omit `task-type` to use the manifest's `workflow.nextRecommendedPhase` when concrete):
424
+ - Claude Code: `/okstra-run task-key={{TASK_KEY}} task-type=<next-phase>`
380
425
  - 별도 터미널: `scripts/okstra.sh --task-key {{TASK_KEY}} --task-type <next-phase>`
381
- 2. **Additional verification needed before implementation or release.** List read-only checks (test commands, log queries, dashboard URLs) that the user should run before moving to the next phase. No state-mutating commands here.
382
- 3. **Follow-up tasks or related tasks if needed.** Reference them by `task-key` when they already exist; otherwise describe the new brief to draft.
383
- 4. **If section 5 has any rows with `Status` in `{open, answered}`**, the highest-priority next step MUST be the clarification turn-around. Show both forms:
384
- - Preferred (interactive) opens this file in `$EDITOR`, then auto-reruns the same phase with `--clarification-response` carry-in:
385
- - Claude Code 세션 안: `/okstra-run resume-clarification task-key={{TASK_KEY}}`
386
- - 별도 터미널: `scripts/okstra.sh --resume-clarification --task-key {{TASK_KEY}}`
387
- - Scripted: `scripts/okstra.sh --task-key {{TASK_KEY}} --task-type {{TASK_TYPE}} --clarification-response <path-to-this-file-after-editing>`.
388
-
389
- Empty-state placeholder, copy verbatim when nothing else applies:
426
+ 2. **Additional read-only verification** before moving to the next phase (test commands, log queries, dashboard URLs). No state-mutating commands here.
427
+ 3. **Follow-up tasks** if needed. Reference by `task-key` when they exist; otherwise describe the new brief to draft.
428
+ 4. **If `## 5.` has any row with `Status` in `{open, answered}`**, the highest-priority next step MUST be the clarification turn-around:
429
+ - Preferred: `/okstra-run resume-clarification task-key={{TASK_KEY}}` / `scripts/okstra.sh --resume-clarification --task-key {{TASK_KEY}}`.
390
430
 
391
- ```
392
- - No further action required. Final verdict in section 2 stands.
393
- ```
431
+ Empty-state placeholder (copy verbatim when nothing else applies): `- No further action required. Final verdict in section 2 stands.`
394
432
 
395
433
  ## 7. Follow-up Tasks (후속 작업)
396
434
 
397
- 이 섹션은 본 run의 구현·검증 범위를 **넘어서는** 작업을 후속 task로 이어갈 있도록 표로 정리합니다.
398
-
399
- - `task-type` = `implementation` / `final-verification` / `release-handoff` runs: **필수**. 채울 항목이 없으면 표 대신 `- 후속 작업 없음.` 한 줄.
400
- - 그 외 task-type runs: 선택. lead가 필요하다고 판단할 때만 채웁니다.
435
+ 본 run 의 구현·검증 범위를 **넘어서는** 작업을 후속 task 이어가기 위한 표.
401
436
 
402
- 후속 항목의 출처는 다음 하나여야 합니다:
437
+ - `task-type` = `implementation` / `final-verification` / `release-handoff`: **필수**. 채울 항목이 없으면 표 대신 `- 후속 작업 없음.`
438
+ - 그 외 task-type: 선택. lead 가 필요하다고 판단할 때만.
403
439
 
404
- - `out-of-plan` 구현 발견됐으나 본 plan의 file list / step 범위를 벗어나 처리하지 못한 항목 (Out-of-plan edits 블록에 기록되지 않고 미처리로 남은 것).
405
- - `verifier-concern` — verifier가 PASS는 줬으나 후속 개선 권고로 남긴 항목.
406
- - `scope-boundary` — `implementation-planning`의 `4.5.5 Dependency / Migration Risk` 또는 task-brief `Out of Scope` 에서 의도적으로 제외했으나, 본 run 결과에 비추어 별도 ticket이 필요한 항목.
407
- - `open-question` — `## 5. Clarification Items` 에서 분리한 후속 작업 (사용자 답을 그대로 닫지 않고 별도 task 로 진행해야 하는 경우).
408
- - `manual` — lead가 추가로 식별한 follow-up.
440
+ 후속 항목 출처: `out-of-plan` / `verifier-concern` / `scope-boundary` / `open-question` / `manual` 하나.
409
441
 
410
- 규칙:
411
-
412
- - 각 row의 `Auto-spawn?` 값이 `yes` 이면 Phase 7 의 `scripts/okstra-spawn-followups.py` 가 자동으로 후속 task 디렉터리(`tasks/<TASK_GROUP>/<New Task ID>/`)와 `task-manifest.json` (status: `todo`), stub task-brief 를 생성합니다. `no` 이면 사람이 따로 결정합니다.
413
- - `Ticket ID` 는 본 보고서 상단 `Ticket Coverage` 규칙과 동일합니다. 후속 작업이 특정 외부 ticket(Jira/Linear/이슈 트래커 등)이나 본 보고서의 ticket 인덱스에 묶이면 그 키를 적고, 매핑이 없으면 `Task ID` 폴백 값을 prefix 없이 적습니다(예: `8852`). 어느 쪽으로도 식별 불가하면 `unknown`.
414
- - `New Task ID` 는 알파숫자·하이픈만 사용하는 짧은 slug 입니다 (예: `8852-followup-logs`). 같은 task-group 안에서 유일해야 합니다.
415
- - `Suggested task-type` 은 `requirements-discovery` / `error-analysis` / `implementation-planning` / `implementation` / `final-verification` / `release-handoff` 중 하나.
416
- - `Scope` 는 영향 파일·영역을 콤마 또는 한 줄로 적습니다.
417
- - `Reason / Why deferred` 는 본 run 에서 처리하지 못한 이유를 한 두 문장으로 적습니다. "시간이 없어서" 같은 모호한 사유는 거절됩니다.
418
- - 동일 follow-up 이 여러 run 에 걸쳐 등장하면 `New Task ID` 를 동일하게 유지하여 중복 spawn 을 방지합니다 (script 가 기존 디렉터리 존재 여부로 idempotent 처리).
442
+ 규칙: `Auto-spawn? = yes` 인 row 는 Phase 7 의 `scripts/okstra-spawn-followups.py` 가 자동으로 `tasks/<TASK_GROUP>/<New Task ID>/` 디렉터리 + `task-manifest.json` (status: `todo`) + stub task-brief 를 생성. `no` 는 사람이 처리. `New Task ID` 는 task-group 내 유일한 알파숫자·하이픈 slug. 동일 follow-up 이 여러 run 에 등장하면 `New Task ID` 를 동일하게 유지하여 중복 spawn 방지.
419
443
 
420
444
  | ID | Ticket ID | Origin | New Task ID | Title | Suggested task-type | Scope (files/areas) | Reason / Why deferred | Priority (P0/P1/P2) | Auto-spawn? |
421
445
  |----|-----------|--------|-------------|-------|---------------------|---------------------|------------------------|---------------------|-------------|
422
446
  | FU-001 | `<TICKET-or-fallback>` | `<out-of-plan / verifier-concern / scope-boundary / open-question / manual>` | `<new-task-id-slug>` | <한 줄 제목> | `<task-type>` | `<files / areas>` | <한 두 문장 사유> | `P1` | `yes` |
423
447
 
424
- 상태 예시 (해당 없음):
425
-
426
- ```
427
- - 후속 작업 없음.
428
- ```
448
+ 상태: `- 후속 작업 없음.`
429
449
 
430
- 본 섹션이 채워진 경우, Section 6 의 "Follow-up tasks or related tasks" 항목에 자동 생성된 task-key 와 진입 명령을 함께 적어 사용자가 즉시 이어갈 수 있게 합니다.
450
+ 본 섹션이 채워진 경우 Section 6 의 "Follow-up tasks" 항목에 자동 생성된 task-key 와 진입 명령을 함께 적어 사용자가 즉시 이어갈 수 있게 합니다.
431
451
 
432
452
  ## Writing Rules
433
- - Write the final report in Markdown.
434
- - Write the final report body in Korean.
435
- - Keep technical identifiers such as file paths, code symbols, model names, and status values in their original form when needed.
436
- - Keep the section structure unless the brief explicitly requires a different structure.
437
- - Prioritize evidence-based statements over speculation.
438
- - Do not replace the report body with meta commentary about storage, session limits, or prior messages.
439
- - This document is the final synthesis by `Claude lead`, not a raw dump of worker outputs.
453
+
454
+ - Markdown. 본문은 한국어. 기술 식별자 (파일 경로, 코드 심볼, 모델명, status 값) 는 원형 유지.
455
+ - 섹션 구조는 brief 명시적으로 다른 구조를 요구하지 않는 보존.
456
+ - 증거 기반 (speculation 금지). 메타 코멘트 (저장소·세션·이전 메시지 언급) 본문 대체 금지.
457
+ - 문서는 `Claude lead` 의 최종 합성이지 raw worker dump 가 아닙니다.
458
+ - 우선. 같은 모양의 항목을 여러 나열할 bullet 으로 degrade 금지.
459
+ - Reading Confirmation / 워커 raw output / 환산식 설명 audit 자료는 본문이 아닌 사이드카에 둡니다 (`runs/<task-type>/worker-results/<worker>-audit-<task-type>-<seq>.md`).