okstra 0.47.0 → 0.49.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 (32) hide show
  1. package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +294 -0
  2. package/docs/superpowers/plans/2026-06-04-coverage-critic.md +516 -0
  3. package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +251 -0
  4. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +323 -0
  5. package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +90 -0
  6. package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +99 -0
  7. package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +90 -0
  8. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +87 -0
  9. package/package.json +1 -1
  10. package/runtime/BUILD.json +2 -2
  11. package/runtime/agents/SKILL.md +3 -1
  12. package/runtime/bin/lib/okstra/tmux-pane.sh +40 -0
  13. package/runtime/bin/okstra-codex-exec.sh +17 -21
  14. package/runtime/bin/okstra-gemini-exec.sh +12 -15
  15. package/runtime/bin/okstra-trace-cleanup.sh +13 -1
  16. package/runtime/prompts/profiles/_common-contract.md +5 -5
  17. package/runtime/prompts/profiles/error-analysis.md +1 -0
  18. package/runtime/prompts/profiles/final-verification.md +2 -0
  19. package/runtime/prompts/profiles/implementation-planning.md +5 -1
  20. package/runtime/prompts/profiles/requirements-discovery.md +1 -0
  21. package/runtime/prompts/wizard/prompts.ko.json +13 -0
  22. package/runtime/python/okstra_ctl/render.py +24 -3
  23. package/runtime/python/okstra_ctl/report_views.py +16 -29
  24. package/runtime/python/okstra_ctl/run.py +12 -0
  25. package/runtime/python/okstra_ctl/wizard.py +72 -1
  26. package/runtime/skills/okstra-convergence/SKILL.md +80 -5
  27. package/runtime/skills/okstra-run/SKILL.md +1 -0
  28. package/runtime/templates/project-docs/task-index.template.md +1 -8
  29. package/runtime/templates/reports/final-report.template.md +24 -28
  30. package/runtime/templates/reports/i18n/en.json +14 -15
  31. package/runtime/templates/reports/i18n/ko.json +14 -15
  32. package/runtime/templates/reports/schedule.template.md +3 -7
@@ -68,11 +68,4 @@ taskType: "{{FM_TASK_TYPE}}"
68
68
 
69
69
  ## Notes
70
70
 
71
- - 이 문서는 사람용 quick summary입니다.
72
- - canonical metadata는 항상 `task-manifest.json`을 기준으로 확인합니다.
73
- - 동일한 버그나 작업을 다시 이어갈 때는 같은 `Task Group`과 `Task ID`를 재사용합니다.
74
- - `requirements-discovery`는 work category와 다음 phase routing 결정을 남기기 위한 초기 triage 단계입니다.
75
- - run directory는 `runs/<task-type>/` 규칙을 사용하여 서로 다른 task-type 실행을 경로 수준에서 분리합니다.
76
- - run directory 내부는 `manifests/`, `state/`, `prompts/`, `reports/`, `status/`, `sessions/`, `worker-results/`처럼 유형별 하위 폴더로 나뉩니다.
77
- - current run의 `prompts/` 디렉터리는 lead prompt snapshot과 worker prompt history file의 canonical 저장 위치입니다.
78
- - run-level artifact와 result 파일명은 같은 task-type 재실행을 구분하기 위해 `-YYYY-MM-DD_HH-MM-SS` suffix를 사용합니다.
71
+ - 이 문서는 사람이 빠르게 훑어보기 위한 요약입니다. 정본·상세 metadata 는 `task-manifest.json` 을 참조하세요.
@@ -53,10 +53,10 @@ approved: {{ frontmatter.approved | yaml_scalar }}
53
53
 
54
54
  {{ t("sectionIntro.ticketCoverage") }}
55
55
 
56
- | ID | Ticket ID | {{ t("columns.summary") }} | {{ t("columns.source") }} |
57
- |----|-----------|------------|----------------------------|
56
+ | {{ t("columns.recordMeta") }} | {{ t("columns.summary") }} |
57
+ |--------|------------|
58
58
  {% for row in summary -%}
59
- | {{ row.id }} | `{{ row.ticketId }}` | {{ row.summary }} | {{ row.source }} |
59
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>{{ t("columns.source") }}: {{ row.source }} | {{ row.summary }} |
60
60
  {% endfor %}
61
61
 
62
62
  {% if ticketCoverage.omit %}
@@ -76,17 +76,15 @@ approved: {{ frontmatter.approved | yaml_scalar }}
76
76
  {% endfor %}
77
77
  {%- endif %}
78
78
 
79
- {{ t("ticketCoverage.ruleNote") }}
80
-
81
79
  {% endif %}
82
80
  ## Execution Status by Agent
83
81
 
84
82
  {{ t("sectionIntro.executionStatus") }}
85
83
 
86
- | Agent | Role | Model | Status | {{ t("columns.rawTokens") }} | {{ t("columns.billableTokens") }} | {{ t("columns.cost") }} | Duration | Summary of Key Findings |
87
- |-------|------|-------|--------|-----------|-----------|------------|----------|-------------------------|
84
+ | {{ t("columns.recordMeta") }} | Summary of Key Findings |
85
+ |--------|-------------------------|
88
86
  {% for row in executionStatus -%}
89
- | {{ row.agent }} | {{ row.role }} | {{ row.model }} | {{ row.status }} | {{ row.totalTokens | format_int }}{% if row.cliTotalTokens %} (CLI: {{ row.cliTotalTokens | format_int }}){% endif %} | {{ row.billableTokens | format_int }} | {{ row.costUsd | format_usd }}{% if row.cliCostUsd %} (+ CLI {{ row.cliCostUsd | format_usd }}){% endif %} | {{ row.durationMs | format_duration_ms }} | {{ row.summary }} |
87
+ | **{{ row.agent }}**<br>Role: {{ row.role }}<br>Model: {{ row.model }}<br>Status: {{ row.status }}<br>{{ t("columns.rawTokens") }}: {{ row.totalTokens | format_int }}{% if row.cliTotalTokens %} (CLI: {{ row.cliTotalTokens | format_int }}){% endif %}<br>{{ t("columns.billableTokens") }}: {{ row.billableTokens | format_int }}<br>{{ t("columns.cost") }}: {{ row.costUsd | format_usd }}{% if row.cliCostUsd %} (+ CLI {{ row.cliCostUsd | format_usd }}){% endif %}<br>Duration: {{ row.durationMs | format_duration_ms }} | {{ row.summary }} |
90
88
  {% endfor %}
91
89
 
92
90
  ## {{ t("tokenSummary.heading") }}
@@ -130,10 +128,10 @@ approved: {{ frontmatter.approved | yaml_scalar }}
130
128
  {% if crossVerification.consensus | length == 0 -%}
131
129
  {{ t("emptyState.consensusItems") }}
132
130
  {%- else %}
133
- | ID | Ticket ID | Statement | Source items (worker:item) | Evidence (path:line / log / worker report) |
134
- |----|-----------|-----------|----------------------------|---------------------------------------------|
131
+ | {{ t("columns.recordMeta") }} | Statement | Evidence (path:line / log / worker report) |
132
+ |--------|-----------|---------------------------------------------|
135
133
  {% for row in crossVerification.consensus -%}
136
- | {{ row.id }} | `{{ row.ticketId }}` | {{ row.statement }} | {{ row.sourceItems | join(', ') }} | {{ row.evidence }} |
134
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>Source items: {{ row.sourceItems | join(', ') }} | {{ row.statement }} | {{ row.evidence }} |
137
135
  {% endfor %}
138
136
  {%- endif %}
139
137
 
@@ -144,10 +142,10 @@ approved: {{ frontmatter.approved | yaml_scalar }}
144
142
  {% if crossVerification.differences | length == 0 -%}
145
143
  {{ t("emptyState.differences") }}
146
144
  {%- else %}
147
- | ID | Ticket ID | Disagreement | Workers (position + item) | Evidence |
148
- |----|-----------|--------------|---------------------------|----------|
145
+ | {{ t("columns.recordMeta") }} | Disagreement | Evidence |
146
+ |--------|--------------|----------|
149
147
  {% for row in crossVerification.differences -%}
150
- | {{ row.id }} | `{{ row.ticketId }}` | {{ row.disagreement }} | {% for w in row.workersPosition %}{{ w.worker }}:{{ w.itemId }} ({{ w.position }}){% if not loop.last %} / {% endif %}{% endfor %} | {{ row.evidence }} |
148
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>Workers: {% for w in row.workersPosition %}{{ w.worker }}:{{ w.itemId }} ({{ w.position }}){% if not loop.last %} / {% endif %}{% endfor %} | {{ row.disagreement }} | {{ row.evidence }} |
151
149
  {% endfor %}
152
150
  {%- endif %}
153
151
 
@@ -170,10 +168,10 @@ approved: {{ frontmatter.approved | yaml_scalar }}
170
168
  {% if evidence.primary | length == 0 -%}
171
169
  {{ t("emptyState.primaryEvidence") }}
172
170
  {%- else %}
173
- | ID | Ticket ID | Evidence | Source items (worker:item) | Source (path:line / log) |
174
- |----|-----------|----------|----------------------------|---------------------------|
171
+ | {{ t("columns.recordMeta") }} | Evidence |
172
+ |--------|----------|
175
173
  {% for row in evidence.primary -%}
176
- | {{ row.id }} | `{{ row.ticketId }}` | {{ row.evidence }} | {{ row.sourceItems | join(', ') }} | {{ row.source }} |
174
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>Source items: {{ row.sourceItems | join(', ') }}<br>Source: {{ row.source }} | {{ row.evidence }} |
177
175
  {% endfor %}
178
176
  {%- endif %}
179
177
 
@@ -184,10 +182,10 @@ approved: {{ frontmatter.approved | yaml_scalar }}
184
182
  {% if not evidence.secondary or evidence.secondary | length == 0 -%}
185
183
  {{ t("emptyState.secondaryEvidence") }}
186
184
  {%- else %}
187
- | ID | Ticket ID | Hypothesis or supporting evidence | Source / confidence |
188
- |----|-----------|-----------------------------------|---------------------|
185
+ | {{ t("columns.recordMeta") }} | Hypothesis or supporting evidence | Source / confidence |
186
+ |--------|-----------------------------------|---------------------|
189
187
  {% for row in evidence.secondary -%}
190
- | {{ row.id }} | `{{ row.ticketId }}` | {{ row.hypothesis }} | {{ row.confidence }} |
188
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}` | {{ row.hypothesis }} | {{ row.confidence }} |
191
189
  {% endfor %}
192
190
  {%- endif %}
193
191
 
@@ -196,10 +194,10 @@ approved: {{ frontmatter.approved | yaml_scalar }}
196
194
  {% if missingInformation | length == 0 -%}
197
195
  {{ t("emptyState.risks") }}
198
196
  {%- else %}
199
- | ID | Ticket ID | Item | Risk if ignored | Mitigation Owner |
200
- |----|-----------|------|-----------------|------------------|
197
+ | {{ t("columns.recordMeta") }} | Item | Risk if ignored | Mitigation Owner |
198
+ |--------|------|-----------------|------------------|
201
199
  {% for row in missingInformation -%}
202
- | {{ row.id }} | `{{ row.ticketId }}` | {{ row.item }} | {{ row.risk }} | {{ row.owner }} |
200
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}` | {{ row.item }} | {{ row.risk }} | {{ row.owner }} |
203
201
  {% endfor %}
204
202
  {%- endif %}
205
203
 
@@ -249,8 +247,6 @@ approved: {{ frontmatter.approved | yaml_scalar }}
249
247
  | {{ row.step }} | `{{ row.ticketId }}` | {{ row.action }} | `{{ row.files }}` | `{{ row.commandOrTest }}` | {{ row.expectedOutcome }} |
250
248
  {% endfor %}
251
249
 
252
- {{ t("sectionIntro.stepRule") }}
253
-
254
250
  ### 4.5.5 Dependency / Migration Risk{% if t("sectionAside.dependencyRisk") != "Dependency / Migration Risk" %} ({{ t("sectionAside.dependencyRisk") }}){% endif %}
255
251
 
256
252
  {% if implementationPlanning.dependencyMigrationRisk | length == 0 -%}
@@ -598,9 +594,9 @@ approved: {{ frontmatter.approved | yaml_scalar }}
598
594
  {% if followUpTasks | length == 0 -%}
599
595
  {{ t("emptyState.noFollowUp") }}
600
596
  {%- else %}
601
- | ID | Ticket ID | Origin | New Task ID | Title | Suggested task-type | Scope (files/areas) | Reason / Why deferred | Priority (P0/P1/P2) | Auto-spawn? |
602
- |----|-----------|--------|-------------|-------|---------------------|---------------------|------------------------|---------------------|-------------|
597
+ | {{ t("columns.recordMeta") }} | Title | Scope (files/areas) | Reason / Why deferred |
598
+ |--------|-------|---------------------|------------------------|
603
599
  {% for row in followUpTasks -%}
604
- | {{ row.id }} | `{{ row.ticketId }}` | `{{ row.origin }}` | `{{ row.newTaskId }}` | {{ row.title }} | `{{ row.suggestedTaskType }}` | `{{ row.scope }}` | {{ row.reason }} | `{{ row.priority }}` | `{{ row.autoSpawn }}` |
600
+ | **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>Origin: `{{ row.origin }}`<br>New Task ID: `{{ row.newTaskId }}`<br>Type: `{{ row.suggestedTaskType }}`<br>Priority: `{{ row.priority }}`<br>Auto-spawn: `{{ row.autoSpawn }}` | {{ row.title }} | {{ row.scope }} | {{ row.reason }} |
605
601
  {% endfor %}
606
602
  {%- endif %}
@@ -19,6 +19,7 @@
19
19
  "noFollowUp": "- No follow-up tasks. The next phase for this run is in §6 (Recommended Next Steps)."
20
20
  },
21
21
  "columns": {
22
+ "recordMeta": "Record",
22
23
  "summary": "Summary",
23
24
  "source": "Source (brief/source/worker)",
24
25
  "rawTokens": "Raw tokens",
@@ -38,14 +39,13 @@
38
39
  "stepwiseExecutionOrder": "Stepwise Execution Order"
39
40
  },
40
41
  "sectionIntro": {
41
- "verdictCard": "At-a-glance verdict card. Every value in this table MUST exactly match the authoritative values in `## 2. Final Verdict` and `## 6. Recommended Next Steps`.",
42
- "clarificationCarryIn": "Walk every C-* row of the prior report's `## 5. Clarification Items` table against new evidence. Update each row's `Status` to `resolved` or `obsolete` and carry it into this run's `## 5.` table. Cite the resolution evidence (file:line / log / worker result) inline.",
43
- "ticketCoverage": "Summarize 3-5 core problems / requirements / verification targets as a table. Base this on the brief, source material, and worker results.",
44
- "executionStatus": "Aggregate each worker's status, assigned model, and key findings into one table. Do NOT replace worker artifacts with ungrounded claims.",
45
- "sourceItemsRule": "`Source items` rule: list which worker items this consensus row was synthesised from, as a comma-list of `<worker>:<item-id>` pairs. Full policy: `prompts/profiles/_common-contract.md` \"Cross-worker traceability\" SSOT.",
46
- "stepRule": "Rule: each step is roughly 2-5 minutes. Every step MUST include exact file paths and commands.",
47
- "planBodyVerification": "Result of Phase 6 report-writer's synthesised 4.5 body re-cast to workers by the lead on a plan-item basis, with verdicts collected.",
48
- "clarificationItems": "Track items that must be answered by the user or backed by attached material before the next run advances, **all inside one table**."
42
+ "verdictCard": "At-a-glance verdict card a summary that mirrors the values in `## 2. Final Verdict` and `## 6. Recommended Next Steps`.",
43
+ "clarificationCarryIn": "Unresolved `Clarification Items` from the prior report, re-examined against new evidence and carried in with updated status.",
44
+ "ticketCoverage": "Summary of the core problems, requirements, and verification targets this run covered.",
45
+ "executionStatus": "At-a-glance table of each worker's status, assigned model, and key findings.",
46
+ "sourceItemsRule": "The `Source items` column shows which worker items each consensus row was synthesised from, as `<worker>:<item-id>` pairs.",
47
+ "planBodyVerification": "Cross-verification results for each item in the plan body.",
48
+ "clarificationItems": "Items that need your answer or supporting material before the next step."
49
49
  },
50
50
  "tokenSummary": {
51
51
  "heading": "Token Usage Summary",
@@ -63,19 +63,18 @@
63
63
  "nextStepLabel": "Next step"
64
64
  },
65
65
  "ticketCoverage": {
66
- "intro": "Reverse index of tickets covered in this run. All body items are linked to a ticket via the `Ticket ID` column or `[TICKETID: <id>]` tag.",
66
+ "intro": "The tickets this run covered, with the sections and related items where each ticket appears.",
67
67
  "columnSections": "Sections",
68
- "columnRelatedIds": "Related item IDs",
69
- "ruleNote": "Rule: `Ticket ID` must match the ticket key exactly as it appears in the body. When `Issue / Ticket` is empty and falls back, use the `Task ID` value as-is without prefix (e.g. `8852`). Use `unknown` when not identifiable."
68
+ "columnRelatedIds": "Related item IDs"
70
69
  },
71
70
  "finalVerdict": {
72
- "intro": "State the final conclusion and recommended direction in one table. `Direction` `continue-investigation / begin-implementation / approve / reject / hold`. When `task-type` is `final-verification`, `Verdict Token` must be one of `accepted / conditional-accept / blocked`; `release-handoff` uses this value as an entry gate. For all other task-types use `not-applicable`."
71
+ "intro": "Final conclusion and recommended direction. `Direction` values: `continue-investigation / begin-implementation / approve / reject / hold`. When `task-type` is `final-verification`, `Verdict Token` is one of `accepted / conditional-accept / blocked` and serves as the `release-handoff` entry gate. For all other task-types: `not-applicable`."
73
72
  },
74
73
  "evidence": {
75
- "sourceItemsColumnNote": "`Source items` column rule is the same as §1.1."
74
+ "sourceItemsColumnNote": "The `Source items` column is described in §1.1."
76
75
  },
77
76
  "roundHistory": {
78
- "round2SkippedReasonNote": "value is one of `queue-empty | max-rounds-1 | all-reverify-non-result | not-skipped | convergence-disabled | single-analyser-only`",
77
+ "round2SkippedReasonNote": "(one of: `queue-empty`, `max-rounds-1`, `all-reverify-non-result`, `not-skipped`, `convergence-disabled`, `single-analyser-only`)",
79
78
  "singleRoundPrefix": "Single round —",
80
79
  "noRoundsNote": "No reverify rounds executed (all findings reached consensus at grouping)."
81
80
  },
@@ -128,7 +127,7 @@
128
127
  "clarification": {
129
128
  "fillAndRerun": "Fill in your answers then re-run the same phase:",
130
129
  "separateTerminalLabel": "Separate terminal",
131
- "columnGuide": "Column guide (full definitions: `prompts/profiles/_common-contract.md §Clarification request policy` SSOT):"
130
+ "columnGuide": "Column descriptions:"
132
131
  },
133
132
  "followUpTasks": {
134
133
  "headingAside": "Follow-up Tasks"
@@ -19,6 +19,7 @@
19
19
  "noFollowUp": "- 후속 작업 없음. 본 run 의 다음 phase 는 §6 (Recommended Next Steps) 참고."
20
20
  },
21
21
  "columns": {
22
+ "recordMeta": "항목",
22
23
  "summary": "한 줄 요약",
23
24
  "source": "출처 (brief/source/worker)",
24
25
  "rawTokens": "처리 토큰",
@@ -38,14 +39,13 @@
38
39
  "stepwiseExecutionOrder": "단계별 실행 순서"
39
40
  },
40
41
  "sectionIntro": {
41
- "verdictCard": "한눈에 보는 결과 카드. 표의 모든 값은 `## 2. Final Verdict` `## 6. Recommended Next Steps` 의 권위 있는 값과 정확히 일치해야 합니다.",
42
- "clarificationCarryIn": "이전 보고서의 `## 5. Clarification Items` 매 행(`C-001`, `C-002`, …) 을 증거에 비추어 검토하고, 각 행의 `Status` 를 `resolved` 또는 `obsolete` 로 갱신한 run 의 `## 5.` 표에 carry-in 합니다. 해소 근거(파일:라인 / 로그 / 워커 결과) 를 함께 인용합니다.",
43
- "ticketCoverage": "3~5 row 핵심 문제·요구사항·검증 대상을 표로 정리합니다. brief, 소스 자료, worker 결과를 근거로 작성합니다.",
44
- "executionStatus": "각 worker 의 status, 배정 모델, key finding 을 표에 모읍니다. worker 산출물을 근거 없는 주장으로 대체하지 않습니다.",
45
- "sourceItemsRule": "`Source items` 규칙: 합의 row 어느 워커의 어느 항목들에서 합성됐는지를 `<worker>:<item-id>` 페어 콤마-리스트로 적습니다. 자세한 정책은 `prompts/profiles/_common-contract.md` \"Cross-worker traceability\" SSOT.",
46
- "stepRule": "규칙: step 2~5 분. 모든 step 은 정확한 파일 경로와 명령어 포함.",
47
- "planBodyVerification": "Phase 6 에서 report-writer 합성한 4.5 본문을 lead 가 plan-item 단위로 워커들에게 다시 던지고 평결을 수집한 결과.",
48
- "clarificationItems": "다음 run 으로 넘어가기 전에 사용자가 답하거나 자료를 첨부해야 하는 항목을 **한 표 안에서** 추적합니다."
42
+ "verdictCard": "한눈에 보는 결과 카드 `## 2. Final Verdict` `## 6. Recommended Next Steps` 의 값을 그대로 옮긴 요약입니다.",
43
+ "clarificationCarryIn": "이전 보고서의 미해결 `Clarification Items` 증거로 재검토해 해소·갱신한이어받은 항목입니다.",
44
+ "ticketCoverage": " run 다룬 핵심 문제·요구사항·검증 대상 요약입니다.",
45
+ "executionStatus": "각 worker 의 상태·배정 모델·핵심 finding 을 한눈에 보는 표입니다.",
46
+ "sourceItemsRule": "`Source items` 열은 합의 항목이 어느 워커의 어느 항목에서 합성됐는지를 `<worker>:<item-id>` 형식으로 표기합니다.",
47
+ "planBodyVerification": "계획 본문의 항목을 plan-item 단위로 교차 검증한 결과입니다.",
48
+ "clarificationItems": "다음 진행 전에 사용자의 답변이나 자료 첨부가 필요한 항목입니다."
49
49
  },
50
50
  "tokenSummary": {
51
51
  "heading": "토큰 사용량 요약",
@@ -63,19 +63,18 @@
63
63
  "nextStepLabel": "다음 단계"
64
64
  },
65
65
  "ticketCoverage": {
66
- "intro": " run 이 다룬 ticket 역방향 인덱스. 본문 항목들은 모두 `Ticket ID` 컬럼 또는 `[TICKETID: <id>]` 태그로 ticket 과 묶여 있습니다.",
66
+ "intro": " run 이 다룬 ticket 과, ticket 등장한 섹션·관련 항목 목록입니다.",
67
67
  "columnSections": "등장 섹션",
68
- "columnRelatedIds": "관련 항목 IDs",
69
- "ruleNote": "규칙: `Ticket ID` 는 본문에서 등장한 ticket 키와 정확히 동일 문자열. `Issue / Ticket` 이 비어 폴백된 경우 `Task ID` 값을 prefix 없이 그대로 (예: `8852`). 식별 불가는 `unknown`."
68
+ "columnRelatedIds": "관련 항목 IDs"
70
69
  },
71
70
  "finalVerdict": {
72
- "intro": "최종 결론과 권장 방향을 한 표로 명시합니다. `Direction` `continue-investigation / begin-implementation / approve / reject / hold`. `task-type` 이 `final-verification` 이면 `Verdict Token` 은 `accepted / conditional-accept / blocked` 중 하나여야 하며, `release-handoff` 는 이 값을 진입 게이트로 사용합니다. 다른 task-type 에서는 `not-applicable`."
71
+ "intro": "최종 결론과 권장 방향입니다. `Direction` 값: `continue-investigation / begin-implementation / approve / reject / hold`. `task-type` 이 `final-verification` `Verdict Token` 은 `accepted / conditional-accept / blocked` 중 하나이며 `release-handoff` 진입 게이트로 쓰입니다. task-type 에서는 `not-applicable`."
73
72
  },
74
73
  "evidence": {
75
- "sourceItemsColumnNote": "`Source items` 컬럼 규칙은 §1.1 과 동일."
74
+ "sourceItemsColumnNote": "`Source items` 설명은 §1.1 과 동일합니다."
76
75
  },
77
76
  "roundHistory": {
78
- "round2SkippedReasonNote": "값은 `queue-empty | max-rounds-1 | all-reverify-non-result | not-skipped | convergence-disabled | single-analyser-only` 중 하나.",
77
+ "round2SkippedReasonNote": "(허용 값: `queue-empty`, `max-rounds-1`, `all-reverify-non-result`, `not-skipped`, `convergence-disabled`, `single-analyser-only`)",
79
78
  "singleRoundPrefix": "단일 라운드 —",
80
79
  "noRoundsNote": "재검증 라운드 미실행 (그룹핑 단계에서 전부 합의)."
81
80
  },
@@ -128,7 +127,7 @@
128
127
  "clarification": {
129
128
  "fillAndRerun": "답을 채우신 뒤 같은 phase 를 다시 실행:",
130
129
  "separateTerminalLabel": "별도 터미널",
131
- "columnGuide": "컬럼 가이드 (전체 정의는 `prompts/profiles/_common-contract.md §Clarification request policy` SSOT 참조):"
130
+ "columnGuide": "컬럼 설명:"
132
131
  },
133
132
  "followUpTasks": {
134
133
  "headingAside": "후속 작업"
@@ -82,7 +82,8 @@ _의존 정보 없음_
82
82
  If included, MUST use this exact heading literal `## Gantt Chart`.
83
83
  Render as ASCII inside a fenced ``` block with NO language tag.
84
84
  Mermaid / PlantUML / Graphviz are forbidden — see SKILL §"ASCII Gantt format".
85
- The axis is RELATIVE DAY-COUNTS (Day 1 / J1, …) — never calendar dates. -->
85
+ The axis is RELATIVE DAY-COUNTS (Day 1 / J1, …) — never calendar dates.
86
+ If day estimates are missing, omit this whole section and replace it with one blockquote: `> _Gantt Chart 생략: <reason>_` (SKILL §"MUST — emit a skip-reason note"). -->
86
87
 
87
88
  ```
88
89
  Day: 1 5 10 15 20 25 30
@@ -96,12 +97,7 @@ Phase 3
96
97
  <TASK-ID> (<size>) ████ (after <TASK-ID>)
97
98
  ```
98
99
 
99
- > 가로축은 **상대 일수** (Day 1 시작 = Phase 1 시작). 오늘 날짜·요일·달력일자 사용 금지.
100
- > 임계 경로(critical path) 항목은 `! crit` 주석, 추정 배분은 `est` 주석으로 표기.
101
- > 막대는 `█`(확정) + `░`(상한/불확실) 조합. 단일 mid-point bar 도 허용.
102
- > 데이터가 없어 이 섹션을 생략할 때는, `## Gantt Chart` 헤딩과 ASCII 블록 전체를
103
- > 다음 한 줄 blockquote로 대체한다 (SKILL §"MUST — emit a skip-reason note" 참조):
104
- > `> _Gantt Chart 생략: <구체 사유 — 예: "단일 task (DEV-9187) + XL effort 5–15d 범위로 정밀 day 추정 부재."_`
100
+ > 가로축은 **상대 일수**입니다 (Day 1 = Phase 1 시작). 범례: `! crit` = 임계 경로(critical path), `est` = 추정 배분, `█` = 확정 구간, `░` = 상한/불확실 구간.
105
101
 
106
102
  ---
107
103