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.
- package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +294 -0
- package/docs/superpowers/plans/2026-06-04-coverage-critic.md +516 -0
- package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +251 -0
- package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +323 -0
- package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +90 -0
- package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +99 -0
- package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +90 -0
- package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +87 -0
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/SKILL.md +3 -1
- package/runtime/bin/lib/okstra/tmux-pane.sh +40 -0
- package/runtime/bin/okstra-codex-exec.sh +17 -21
- package/runtime/bin/okstra-gemini-exec.sh +12 -15
- package/runtime/bin/okstra-trace-cleanup.sh +13 -1
- package/runtime/prompts/profiles/_common-contract.md +5 -5
- package/runtime/prompts/profiles/error-analysis.md +1 -0
- package/runtime/prompts/profiles/final-verification.md +2 -0
- package/runtime/prompts/profiles/implementation-planning.md +5 -1
- package/runtime/prompts/profiles/requirements-discovery.md +1 -0
- package/runtime/prompts/wizard/prompts.ko.json +13 -0
- package/runtime/python/okstra_ctl/render.py +24 -3
- package/runtime/python/okstra_ctl/report_views.py +16 -29
- package/runtime/python/okstra_ctl/run.py +12 -0
- package/runtime/python/okstra_ctl/wizard.py +72 -1
- package/runtime/skills/okstra-convergence/SKILL.md +80 -5
- package/runtime/skills/okstra-run/SKILL.md +1 -0
- package/runtime/templates/project-docs/task-index.template.md +1 -8
- package/runtime/templates/reports/final-report.template.md +24 -28
- package/runtime/templates/reports/i18n/en.json +14 -15
- package/runtime/templates/reports/i18n/ko.json +14 -15
- 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
|
-
- 이 문서는
|
|
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
|
-
|
|
|
57
|
-
|
|
56
|
+
| {{ t("columns.recordMeta") }} | {{ t("columns.summary") }} |
|
|
57
|
+
|--------|------------|
|
|
58
58
|
{% for row in summary -%}
|
|
59
|
-
| {{ row.id }}
|
|
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
|
-
|
|
|
87
|
-
|
|
84
|
+
| {{ t("columns.recordMeta") }} | Summary of Key Findings |
|
|
85
|
+
|--------|-------------------------|
|
|
88
86
|
{% for row in executionStatus -%}
|
|
89
|
-
| {{ row.agent }}
|
|
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
|
-
|
|
|
134
|
-
|
|
131
|
+
| {{ t("columns.recordMeta") }} | Statement | Evidence (path:line / log / worker report) |
|
|
132
|
+
|--------|-----------|---------------------------------------------|
|
|
135
133
|
{% for row in crossVerification.consensus -%}
|
|
136
|
-
| {{ row.id }}
|
|
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
|
-
|
|
|
148
|
-
|
|
145
|
+
| {{ t("columns.recordMeta") }} | Disagreement | Evidence |
|
|
146
|
+
|--------|--------------|----------|
|
|
149
147
|
{% for row in crossVerification.differences -%}
|
|
150
|
-
| {{ row.id }}
|
|
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
|
-
|
|
|
174
|
-
|
|
171
|
+
| {{ t("columns.recordMeta") }} | Evidence |
|
|
172
|
+
|--------|----------|
|
|
175
173
|
{% for row in evidence.primary -%}
|
|
176
|
-
| {{ row.id }}
|
|
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
|
-
|
|
|
188
|
-
|
|
185
|
+
| {{ t("columns.recordMeta") }} | Hypothesis or supporting evidence | Source / confidence |
|
|
186
|
+
|--------|-----------------------------------|---------------------|
|
|
189
187
|
{% for row in evidence.secondary -%}
|
|
190
|
-
| {{ row.id }}
|
|
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
|
-
|
|
|
200
|
-
|
|
197
|
+
| {{ t("columns.recordMeta") }} | Item | Risk if ignored | Mitigation Owner |
|
|
198
|
+
|--------|------|-----------------|------------------|
|
|
201
199
|
{% for row in missingInformation -%}
|
|
202
|
-
| {{ row.id }}
|
|
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
|
-
|
|
|
602
|
-
|
|
597
|
+
| {{ t("columns.recordMeta") }} | Title | Scope (files/areas) | Reason / Why deferred |
|
|
598
|
+
|--------|-------|---------------------|------------------------|
|
|
603
599
|
{% for row in followUpTasks -%}
|
|
604
|
-
| {{ row.id }}
|
|
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
|
|
42
|
-
"clarificationCarryIn": "
|
|
43
|
-
"ticketCoverage": "
|
|
44
|
-
"executionStatus": "
|
|
45
|
-
"sourceItemsRule": "`Source items`
|
|
46
|
-
"
|
|
47
|
-
"
|
|
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": "
|
|
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": "
|
|
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
|
|
74
|
+
"sourceItemsColumnNote": "The `Source items` column is described in §1.1."
|
|
76
75
|
},
|
|
77
76
|
"roundHistory": {
|
|
78
|
-
"round2SkippedReasonNote": "
|
|
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
|
|
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": "한눈에 보는 결과
|
|
42
|
-
"clarificationCarryIn": "이전 보고서의
|
|
43
|
-
"ticketCoverage": "
|
|
44
|
-
"executionStatus": "각 worker 의
|
|
45
|
-
"sourceItemsRule": "`Source items`
|
|
46
|
-
"
|
|
47
|
-
"
|
|
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": "
|
|
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": "최종 결론과 권장
|
|
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`
|
|
74
|
+
"sourceItemsColumnNote": "`Source items` 열 설명은 §1.1 과 동일합니다."
|
|
76
75
|
},
|
|
77
76
|
"roundHistory": {
|
|
78
|
-
"round2SkippedReasonNote": "
|
|
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": "컬럼
|
|
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
|
-
> 가로축은 **상대
|
|
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
|
|