okstra 0.48.0 → 0.50.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/kr/architecture.md +8 -8
- package/docs/kr/cli.md +2 -2
- package/docs/project-structure-overview.md +3 -3
- package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +323 -0
- package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +559 -0
- package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +87 -0
- package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +121 -0
- package/docs/task-process/error-analysis.md +1 -1
- package/docs/task-process/final-verification.md +1 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/docs/task-process/requirements-discovery.md +1 -1
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/SKILL.md +3 -3
- package/runtime/agents/workers/claude-worker.md +1 -1
- package/runtime/agents/workers/codex-worker.md +1 -1
- package/runtime/agents/workers/gemini-worker.md +1 -1
- package/runtime/agents/workers/report-writer-worker.md +3 -3
- 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-render-report-views.py +1 -1
- package/runtime/bin/okstra-trace-cleanup.sh +13 -1
- package/runtime/prompts/launch.template.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +15 -15
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +1 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +1 -1
- package/runtime/prompts/profiles/error-analysis.md +1 -1
- package/runtime/prompts/profiles/final-verification.md +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +9 -9
- package/runtime/prompts/profiles/improvement-discovery.md +5 -5
- package/runtime/prompts/profiles/release-handoff.md +2 -2
- package/runtime/prompts/profiles/requirements-discovery.md +2 -2
- package/runtime/python/okstra_ctl/clarification_items.py +11 -11
- package/runtime/python/okstra_ctl/render.py +1 -1
- package/runtime/python/okstra_ctl/render_final_report.py +1 -1
- package/runtime/python/okstra_ctl/report_views.py +26 -39
- package/runtime/python/okstra_ctl/run.py +3 -3
- package/runtime/python/okstra_ctl/wizard.py +90 -3
- package/runtime/python/okstra_ctl/workflow.py +1 -1
- package/runtime/skills/okstra-brief/SKILL.md +1 -1
- package/runtime/skills/okstra-convergence/SKILL.md +8 -8
- package/runtime/skills/okstra-report-writer/SKILL.md +22 -22
- package/runtime/skills/okstra-run/SKILL.md +2 -0
- package/runtime/skills/okstra-team-contract/SKILL.md +1 -1
- package/runtime/templates/project-docs/task-index.template.md +1 -8
- package/runtime/templates/reports/final-report.template.md +194 -198
- package/runtime/templates/reports/i18n/en.json +16 -17
- package/runtime/templates/reports/i18n/ko.json +16 -17
- package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +1 -1
- package/runtime/templates/reports/schedule.template.md +3 -7
- package/runtime/templates/reports/user-response.template.md +1 -1
- package/runtime/templates/worker-prompt-preamble.md +1 -1
- package/runtime/validators/lib/fixtures.sh +2 -2
- package/runtime/validators/validate-implementation-plan-stages.py +9 -9
- package/runtime/validators/validate-report-views.py +10 -10
- package/runtime/validators/validate-run.py +36 -36
- package/runtime/validators/validate_improvement_report.py +8 -8
|
@@ -42,171 +42,104 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
42
42
|
| Approval Required? | `{% if verdictCard.approvalRequired %}yes — {{ t("verdictCard.approvalRequiredSuffix") }}{% else %}no{% endif %}` |
|
|
43
43
|
| Next Step | {{ verdictCard.nextStep }} |
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
## 0. Clarification Response Carried In From Previous Run
|
|
47
|
-
|
|
48
|
-
- Source file: `{{ clarificationCarryIn.sourceFile }}`
|
|
49
|
-
- {{ t("sectionIntro.clarificationCarryIn") }}
|
|
50
|
-
|
|
51
|
-
{% endif %}
|
|
52
|
-
## Summary of the Problem or Verification Target
|
|
45
|
+
## 1. Clarification Items
|
|
53
46
|
|
|
54
|
-
{{ t("sectionIntro.
|
|
55
|
-
|
|
56
|
-
| ID | Ticket ID | {{ t("columns.summary") }} | {{ t("columns.source") }} |
|
|
57
|
-
|----|-----------|------------|----------------------------|
|
|
58
|
-
{% for row in summary -%}
|
|
59
|
-
| {{ row.id }} | `{{ row.ticketId }}` | {{ row.summary }} | {{ row.source }} |
|
|
60
|
-
{% endfor %}
|
|
61
|
-
|
|
62
|
-
{% if ticketCoverage.omit %}
|
|
63
|
-
{# Ticket Coverage omitted entirely — release-handoff / final-verification #}
|
|
64
|
-
{%- else %}
|
|
65
|
-
## Ticket Coverage
|
|
66
|
-
|
|
67
|
-
{{ t("ticketCoverage.intro") }}
|
|
47
|
+
{{ t("sectionIntro.clarificationItems") }}
|
|
68
48
|
|
|
69
|
-
{% if
|
|
70
|
-
|
|
49
|
+
{% if clarificationItems | length == 0 -%}
|
|
50
|
+
{{ t("emptyState.noClarification") }}
|
|
71
51
|
{%- else %}
|
|
72
|
-
|
|
73
|
-
|-----------|-----------|---------------|
|
|
74
|
-
{% for row in ticketCoverage.rows -%}
|
|
75
|
-
| `{{ row.ticketId }}` | `{{ row.sections }}` | `{{ row.relatedIds }}` |
|
|
76
|
-
{% endfor %}
|
|
77
|
-
{%- endif %}
|
|
78
|
-
|
|
79
|
-
{{ t("ticketCoverage.ruleNote") }}
|
|
80
|
-
|
|
81
|
-
{% endif %}
|
|
82
|
-
## Execution Status by Agent
|
|
52
|
+
{{ t("clarification.fillAndRerun") }}
|
|
83
53
|
|
|
84
|
-
{{
|
|
54
|
+
- Claude Code: `/okstra-run resume-clarification task-key={{ header.taskKey }}`
|
|
55
|
+
- {{ t("clarification.separateTerminalLabel") }}: `scripts/okstra.sh --resume-clarification --task-key {{ header.taskKey }}`
|
|
85
56
|
|
|
86
|
-
|
|
|
87
|
-
|
|
88
|
-
{% for row in
|
|
89
|
-
| {{ row.
|
|
57
|
+
| ID | Ticket ID | Kind | Statement | Expected form | Blocks | Status | User input |
|
|
58
|
+
|----|-----------|------|-----------|---------------|--------|--------|-----------|
|
|
59
|
+
{% for row in clarificationItems -%}
|
|
60
|
+
| {{ row.id }} | `{{ row.ticketId }}` | `{{ row.kind }}` | {{ row.statement }} | {{ row.expectedForm }} | `{{ row.blocks }}` | {{ row.status }} | {{ row.userInput or '' }} |
|
|
90
61
|
{% endfor %}
|
|
91
62
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
| {{ t("tokenSummary.tableHeaderItem") }} | {{ t("columns.rawTokens") }} | {{ t("columns.billableTokensInputEquiv") }} | {{ t("columns.cost") }} |
|
|
95
|
-
|------|-----------|------------------------|------------|
|
|
96
|
-
| {{ t("tokenSummary.rowLead") }} | `{{ tokenUsage.lead.totalTokens | format_int }}` | `{{ tokenUsage.lead.billableTokens | format_int }}` | `{{ tokenUsage.lead.costUsd | format_usd }}` |
|
|
97
|
-
| {{ t("tokenSummary.rowWorkerTotal") }} | `{{ tokenUsage.worker.totalTokens | format_int }}` | `{{ tokenUsage.worker.billableTokens | format_int }}` | `{{ tokenUsage.worker.costUsd | format_usd }}` |
|
|
98
|
-
| {{ t("tokenSummary.rowGrandTotal") }} | **`{{ tokenUsage.grand.totalTokens | format_int }}`** | **`{{ tokenUsage.grand.billableTokens | format_int }}`** | **`{{ tokenUsage.grand.costUsd | format_usd }}`** |
|
|
99
|
-
{% if tokenUsage.cli and tokenUsage.cli.costUsd is not none and tokenUsage.cli.costUsd > 0 -%}
|
|
100
|
-
| {{ t("tokenSummary.rowCliExtra") }} | | | `{{ tokenUsage.cli.costUsd | format_usd }}` |
|
|
101
|
-
{% endif %}
|
|
102
|
-
|
|
103
|
-
{# At Phase 6 numeric cells are null and render as `--`.
|
|
104
|
-
Phase 7's okstra-token-usage.py populates tokenUsage in data.json then
|
|
105
|
-
re-invokes this renderer to produce the final markdown. #}
|
|
106
|
-
|
|
107
|
-
## 1. Cross Verification Results
|
|
108
|
-
|
|
109
|
-
{% if crossVerification.roundHistory and not crossVerification.roundHistory.disabled -%}
|
|
110
|
-
### 1.0 Round History
|
|
63
|
+
{{ t("clarification.columnGuide") }}
|
|
111
64
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
{
|
|
116
|
-
| {{ row.round }} | {{ row.inputQueueSize }} | {{ row.resolvedCount }} | {{ row.carriedForwardCount }} | {{ row.dispatches }} | {{ row.skippedWorkers }} |
|
|
117
|
-
{% endfor %}
|
|
65
|
+
- **`Kind`** ∈ `{material, decision, data-point}`.
|
|
66
|
+
- **`Blocks`** ∈ `{approval, next-phase, none}`.
|
|
67
|
+
- **`Status`** ∈ `{open, answered, resolved, obsolete}`.
|
|
68
|
+
{%- endif %}
|
|
118
69
|
|
|
119
|
-
|
|
120
|
-
{% elif crossVerification.roundHistory.rounds | length == 1 -%}
|
|
121
|
-
{% set r = crossVerification.roundHistory.rounds[0] -%}
|
|
122
|
-
- {{ t("roundHistory.singleRoundPrefix") }} resolved={{ r.resolvedCount }}, carriedForward={{ r.carriedForwardCount }}, round2SkippedReason=`{{ crossVerification.roundHistory.round2SkippedReason }}`
|
|
123
|
-
{% else -%}
|
|
124
|
-
- {{ t("roundHistory.noRoundsNote") }} round2SkippedReason=`{{ crossVerification.roundHistory.round2SkippedReason }}`
|
|
125
|
-
{% endif %}
|
|
70
|
+
## 2. Evidence and Detailed Analysis
|
|
126
71
|
|
|
127
|
-
|
|
128
|
-
### 1.1 Consensus
|
|
72
|
+
### 2.1 Primary Evidence
|
|
129
73
|
|
|
130
|
-
{% if
|
|
131
|
-
{{ t("emptyState.
|
|
74
|
+
{% if evidence.primary | length == 0 -%}
|
|
75
|
+
{{ t("emptyState.primaryEvidence") }}
|
|
132
76
|
{%- else %}
|
|
133
|
-
|
|
|
134
|
-
|
|
135
|
-
{% for row in
|
|
136
|
-
| {{ row.id }}
|
|
77
|
+
| {{ t("columns.recordMeta") }} | Evidence |
|
|
78
|
+
|--------|----------|
|
|
79
|
+
{% for row in evidence.primary -%}
|
|
80
|
+
| **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>Source items: {{ row.sourceItems | join(', ') }}<br>Source: {{ row.source }} | {{ row.evidence }} |
|
|
137
81
|
{% endfor %}
|
|
138
82
|
{%- endif %}
|
|
139
83
|
|
|
140
|
-
{{ t("
|
|
84
|
+
{{ t("evidence.sourceItemsColumnNote") }}
|
|
141
85
|
|
|
142
|
-
###
|
|
86
|
+
### 2.2 Secondary Evidence or Alternate Interpretations
|
|
143
87
|
|
|
144
|
-
{% if
|
|
145
|
-
{{ t("emptyState.
|
|
88
|
+
{% if not evidence.secondary or evidence.secondary | length == 0 -%}
|
|
89
|
+
{{ t("emptyState.secondaryEvidence") }}
|
|
146
90
|
{%- else %}
|
|
147
|
-
|
|
|
148
|
-
|
|
149
|
-
{% for row in
|
|
150
|
-
| {{ row.id }}
|
|
91
|
+
| {{ t("columns.recordMeta") }} | Hypothesis or supporting evidence | Source / confidence |
|
|
92
|
+
|--------|-----------------------------------|---------------------|
|
|
93
|
+
{% for row in evidence.secondary -%}
|
|
94
|
+
| **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}` | {{ row.hypothesis }} | {{ row.confidence }} |
|
|
151
95
|
{% endfor %}
|
|
152
96
|
{%- endif %}
|
|
153
97
|
|
|
154
|
-
##
|
|
155
|
-
|
|
156
|
-
{{ t("finalVerdict.intro") }}
|
|
98
|
+
## 3. Recommended Next Steps
|
|
157
99
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
| Final Conclusion | {{ finalVerdict.finalConclusion }} |
|
|
161
|
-
| Verdict Token | `{{ finalVerdict.verdictToken }}` |
|
|
162
|
-
| Direction | `{{ finalVerdict.direction }}` |
|
|
163
|
-
| {{ t("verdictCard.rationaleLabel") }} | {{ finalVerdict.rationaleRowIds | join(', ') }} |
|
|
164
|
-
| {{ t("verdictCard.nextStepLabel") }} | {{ finalVerdict.nextStep }} |
|
|
165
|
-
|
|
166
|
-
## 3. Evidence and Detailed Analysis
|
|
167
|
-
|
|
168
|
-
### 3.1 Primary Evidence
|
|
169
|
-
|
|
170
|
-
{% if evidence.primary | length == 0 -%}
|
|
171
|
-
{{ t("emptyState.primaryEvidence") }}
|
|
100
|
+
{% if recommendedNextSteps | length == 0 -%}
|
|
101
|
+
- No further action required. Final verdict in section 7 stands.
|
|
172
102
|
{%- else %}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
{%
|
|
176
|
-
|
|
103
|
+
{% for step in recommendedNextSteps -%}
|
|
104
|
+
{{ loop.index }}. {{ step.text }}
|
|
105
|
+
{% if step.commands -%}
|
|
106
|
+
{% for cmd in step.commands %}
|
|
107
|
+
- {{ cmd.label }}:
|
|
108
|
+
- Claude Code: `{{ cmd.claudeCode }}`
|
|
109
|
+
- {{ t("clarification.separateTerminalLabel") }}: `{{ cmd.terminal }}`
|
|
110
|
+
{% endfor -%}
|
|
111
|
+
{%- endif %}
|
|
177
112
|
{% endfor %}
|
|
178
113
|
{%- endif %}
|
|
179
114
|
|
|
180
|
-
{{ t("
|
|
181
|
-
|
|
182
|
-
### 3.2 Secondary Evidence or Alternate Interpretations
|
|
115
|
+
## 4. Follow-up Tasks{% if t("followUpTasks.headingAside") != "Follow-up Tasks" %} ({{ t("followUpTasks.headingAside") }}){% endif %}
|
|
183
116
|
|
|
184
|
-
{% if
|
|
185
|
-
{{ t("emptyState.
|
|
117
|
+
{% if followUpTasks | length == 0 -%}
|
|
118
|
+
{{ t("emptyState.noFollowUp") }}
|
|
186
119
|
{%- else %}
|
|
187
|
-
|
|
|
188
|
-
|
|
189
|
-
{% for row in
|
|
190
|
-
| {{ row.id }}
|
|
120
|
+
| {{ t("columns.recordMeta") }} | Title | Scope (files/areas) | Reason / Why deferred |
|
|
121
|
+
|--------|-------|---------------------|------------------------|
|
|
122
|
+
{% for row in followUpTasks -%}
|
|
123
|
+
| **{{ 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 }} |
|
|
191
124
|
{% endfor %}
|
|
192
125
|
{%- endif %}
|
|
193
126
|
|
|
194
|
-
##
|
|
127
|
+
## 5. Missing Information and Risks
|
|
195
128
|
|
|
196
129
|
{% if missingInformation | length == 0 -%}
|
|
197
130
|
{{ t("emptyState.risks") }}
|
|
198
131
|
{%- else %}
|
|
199
|
-
|
|
|
200
|
-
|
|
132
|
+
| {{ t("columns.recordMeta") }} | Item | Risk if ignored | Mitigation Owner |
|
|
133
|
+
|--------|------|-----------------|------------------|
|
|
201
134
|
{% for row in missingInformation -%}
|
|
202
|
-
| {{ row.id }}
|
|
135
|
+
| **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}` | {{ row.item }} | {{ row.risk }} | {{ row.owner }} |
|
|
203
136
|
{% endfor %}
|
|
204
137
|
{%- endif %}
|
|
205
138
|
|
|
206
139
|
{% if header.taskType == 'implementation-planning' %}
|
|
207
|
-
##
|
|
140
|
+
## 5.5 Implementation Plan Deliverables
|
|
208
141
|
|
|
209
|
-
###
|
|
142
|
+
### 5.5.1 Option Candidates{% if t("sectionAside.optionCandidates") != "Option Candidates" %} ({{ t("sectionAside.optionCandidates") }}){% endif %}
|
|
210
143
|
|
|
211
144
|
{% for opt in implementationPlanning.optionCandidates %}
|
|
212
145
|
**{{ opt.name }}**
|
|
@@ -224,7 +157,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
224
157
|
|
|
225
158
|
{% endfor %}
|
|
226
159
|
|
|
227
|
-
###
|
|
160
|
+
### 5.5.2 Trade-off Matrix{% if t("sectionAside.tradeOffMatrix") != "Trade-off Matrix" %} ({{ t("sectionAside.tradeOffMatrix") }}){% endif %}
|
|
228
161
|
|
|
229
162
|
| Option | Complexity | Risk | Reversibility | Test Coverage Cost | Rollout Cost |
|
|
230
163
|
|--------|-----------|------|---------------|--------------------|--------------|
|
|
@@ -232,7 +165,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
232
165
|
| {{ row.option }} | {{ row.complexity }} | {{ row.risk }} | {{ row.reversibility }} | {{ row.testCoverageCost }} | {{ row.rolloutCost }} |
|
|
233
166
|
{% endfor %}
|
|
234
167
|
|
|
235
|
-
###
|
|
168
|
+
### 5.5.3 Recommended Option{% if t("sectionAside.recommendedOption") != "Recommended Option" %} ({{ t("sectionAside.recommendedOption") }}){% endif %}
|
|
236
169
|
|
|
237
170
|
| {{ t("implementationPlanning.recommendedTableHeaderLabel") }} | {{ t("implementationPlanning.recommendedTableHeaderValue") }} |
|
|
238
171
|
|------|----|
|
|
@@ -241,7 +174,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
241
174
|
| {{ t("implementationPlanning.rationaleLabel") }} | {{ implementationPlanning.recommendedOption.rationale }} |
|
|
242
175
|
| {{ t("implementationPlanning.rejectedSummaryLabel") }} | {{ implementationPlanning.recommendedOption.rejectedSummary }} |
|
|
243
176
|
|
|
244
|
-
###
|
|
177
|
+
### 5.5.4 Stepwise Execution Order{% if t("sectionAside.stepwiseExecutionOrder") != "Stepwise Execution Order" %} ({{ t("sectionAside.stepwiseExecutionOrder") }}){% endif %}
|
|
245
178
|
|
|
246
179
|
| Step | Ticket ID | Action (≤ 5min) | Files | Command / Test | Expected outcome |
|
|
247
180
|
|------|-----------|------------------|-------|----------------|-------------------|
|
|
@@ -249,9 +182,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
249
182
|
| {{ row.step }} | `{{ row.ticketId }}` | {{ row.action }} | `{{ row.files }}` | `{{ row.commandOrTest }}` | {{ row.expectedOutcome }} |
|
|
250
183
|
{% endfor %}
|
|
251
184
|
|
|
252
|
-
{{ t("
|
|
253
|
-
|
|
254
|
-
### 4.5.5 Dependency / Migration Risk{% if t("sectionAside.dependencyRisk") != "Dependency / Migration Risk" %} ({{ t("sectionAside.dependencyRisk") }}){% endif %}
|
|
185
|
+
### 5.5.5 Dependency / Migration Risk{% if t("sectionAside.dependencyRisk") != "Dependency / Migration Risk" %} ({{ t("sectionAside.dependencyRisk") }}){% endif %}
|
|
255
186
|
|
|
256
187
|
{% if implementationPlanning.dependencyMigrationRisk | length == 0 -%}
|
|
257
188
|
{{ t("emptyState.dependencyRisk") }}
|
|
@@ -263,7 +194,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
263
194
|
{% endfor %}
|
|
264
195
|
{%- endif %}
|
|
265
196
|
|
|
266
|
-
###
|
|
197
|
+
### 5.5.6 Validation Checklist{% if t("sectionAside.validationChecklist") != "Validation Checklist" %} ({{ t("sectionAside.validationChecklist") }}){% endif %}
|
|
267
198
|
|
|
268
199
|
| Phase | Ticket ID | Check | Command / Observation | Expected outcome |
|
|
269
200
|
|-------|-----------|-------|------------------------|-------------------|
|
|
@@ -271,7 +202,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
271
202
|
| {{ row.phase }} | `{{ row.ticketId }}` | {{ row.check }} | `{{ row.commandOrObservation }}` | {{ row.expectedOutcome }} |
|
|
272
203
|
{% endfor %}
|
|
273
204
|
|
|
274
|
-
###
|
|
205
|
+
### 5.5.7 Rollback Strategy{% if t("sectionAside.rollbackStrategy") != "Rollback Strategy" %} ({{ t("sectionAside.rollbackStrategy") }}){% endif %}
|
|
275
206
|
|
|
276
207
|
| ID | Step | Action | Trigger signal | {{ t("columns.checkMethod") }} |
|
|
277
208
|
|----|------|--------|----------------|-----------|
|
|
@@ -279,7 +210,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
279
210
|
| {{ row.id }} | {{ row.step }} | `{{ row.action }}` | {{ row.triggerSignal }} | `{{ row.verificationMethod }}` |
|
|
280
211
|
{% endfor %}
|
|
281
212
|
|
|
282
|
-
###
|
|
213
|
+
### 5.5.9 Plan Body Verification{% if t("sectionAside.planBodyVerification") != "Plan Body Verification" %} ({{ t("sectionAside.planBodyVerification") }}){% endif %}
|
|
283
214
|
|
|
284
215
|
{{ t("sectionIntro.planBodyVerification") }}
|
|
285
216
|
|
|
@@ -306,17 +237,17 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
306
237
|
|
|
307
238
|
{% endif %}
|
|
308
239
|
{% if header.taskType == 'release-handoff' %}
|
|
309
|
-
##
|
|
240
|
+
## 5.6 Release Handoff Deliverables
|
|
310
241
|
|
|
311
242
|
{{ t("releaseHandoff.auditNote") }}
|
|
312
243
|
|
|
313
|
-
###
|
|
244
|
+
### 5.6.1 Source Verification Report
|
|
314
245
|
|
|
315
246
|
- Path (project-relative): `{{ releaseHandoff.sourceVerificationReport.path }}`
|
|
316
|
-
- Quoted `Verdict Token` row from that report's `##
|
|
247
|
+
- Quoted `Verdict Token` row from that report's `## 7.` table:
|
|
317
248
|
> {{ releaseHandoff.sourceVerificationReport.verdictTokenQuote }}
|
|
318
249
|
|
|
319
|
-
###
|
|
250
|
+
### 5.6.2 Feature Branch & Working-Tree State{% if t("releaseHandoff.branchStateAside") != "captured at run start" %} ({{ t("releaseHandoff.branchStateAside") }}){% endif %}
|
|
320
251
|
|
|
321
252
|
- Feature branch: `{{ releaseHandoff.featureBranchState.branchName }}`
|
|
322
253
|
- {{ t("releaseHandoff.gitStatusShortLabel") }}:
|
|
@@ -325,7 +256,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
325
256
|
```
|
|
326
257
|
- {{ t("releaseHandoff.existingPrLabel") }}: `{{ releaseHandoff.featureBranchState.existingPrUrl or '(none)' }}`
|
|
327
258
|
|
|
328
|
-
###
|
|
259
|
+
### 5.6.3 User Selections{% if t("releaseHandoff.userSelectionsAside") != "menu response log" %} ({{ t("releaseHandoff.userSelectionsAside") }}){% endif %}
|
|
329
260
|
|
|
330
261
|
| {{ t("releaseHandoff.questionsTableHeader.questionId") }} | {{ t("releaseHandoff.questionsTableHeader.questionBody") }} | {{ t("releaseHandoff.questionsTableHeader.userResponse") }} | {{ t("releaseHandoff.questionsTableHeader.allowedOptions") }} |
|
|
331
262
|
|---------|-----------|--------------------|--------------------|
|
|
@@ -333,7 +264,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
333
264
|
| H2 | {{ t("releaseHandoff.h2Body") }} | `{{ releaseHandoff.userSelections.h2 or t("releaseHandoff.h2DefaultLabel") }}` | {{ t("releaseHandoff.h2OptionsLabel") }} |
|
|
334
265
|
| H3 | {{ t("releaseHandoff.h3Body") }} | `{{ releaseHandoff.userSelections.h3 }}` | `use as-is` / `edit then proceed` / `cancel` |
|
|
335
266
|
|
|
336
|
-
###
|
|
267
|
+
### 5.6.4 Executed Commands
|
|
337
268
|
|
|
338
269
|
{% if releaseHandoff.executedCommands | length == 0 -%}
|
|
339
270
|
- {{ t("releaseHandoff.noMutationNote") }}
|
|
@@ -345,7 +276,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
345
276
|
{% endfor %}
|
|
346
277
|
{%- endif %}
|
|
347
278
|
|
|
348
|
-
###
|
|
279
|
+
### 5.6.5 Commit List
|
|
349
280
|
|
|
350
281
|
{% if releaseHandoff.commitList.empty -%}
|
|
351
282
|
- No implementation commits found; release-handoff is blocked.
|
|
@@ -357,7 +288,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
357
288
|
{% endfor %}
|
|
358
289
|
{%- endif %}
|
|
359
290
|
|
|
360
|
-
###
|
|
291
|
+
### 5.6.6 Merge Conflict Probe
|
|
361
292
|
|
|
362
293
|
{% if releaseHandoff.mergeConflictProbe.kind == 'not-run' -%}
|
|
363
294
|
- Not run (user picked local only or skip).
|
|
@@ -367,7 +298,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
367
298
|
- Conflicts detected against {{ releaseHandoff.mergeConflictProbe.baseBranch }} at {{ releaseHandoff.mergeConflictProbe.baseSha }}; user chose {{ releaseHandoff.mergeConflictProbe.userChoice }}. Conflicting paths: {{ releaseHandoff.mergeConflictProbe.conflictingPaths | join(', ') }}.
|
|
368
299
|
{%- endif %}
|
|
369
300
|
|
|
370
|
-
###
|
|
301
|
+
### 5.6.7 Pull Request Outcome
|
|
371
302
|
|
|
372
303
|
{% if releaseHandoff.pullRequestOutcome.kind == 'no-action' -%}
|
|
373
304
|
- No PR action requested.
|
|
@@ -379,15 +310,15 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
379
310
|
- PR creation skipped: {{ releaseHandoff.pullRequestOutcome.reason }}
|
|
380
311
|
{%- endif %}
|
|
381
312
|
|
|
382
|
-
###
|
|
313
|
+
### 5.6.8 Routing Recommendation
|
|
383
314
|
|
|
384
315
|
{{ releaseHandoff.routingRecommendation }}
|
|
385
316
|
|
|
386
317
|
{% endif %}
|
|
387
318
|
{% if header.taskType == 'implementation' %}
|
|
388
|
-
##
|
|
319
|
+
## 5.7 Implementation Deliverables
|
|
389
320
|
|
|
390
|
-
###
|
|
321
|
+
### 5.7.1 Approved Plan Reference
|
|
391
322
|
|
|
392
323
|
- Plan file (project-relative): `{{ implementation.approvedPlanReference.planFile }}`
|
|
393
324
|
- Approval evidence:
|
|
@@ -395,7 +326,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
395
326
|
- {{ t("executionMeta.runExecutorWorktreePath") }}: `{{ implementation.approvedPlanReference.executorWorktreePath }}`
|
|
396
327
|
- {{ t("executionMeta.runBaseRef") }}: `{{ implementation.approvedPlanReference.baseRefSha }}`
|
|
397
328
|
|
|
398
|
-
###
|
|
329
|
+
### 5.7.2 Commit List
|
|
399
330
|
|
|
400
331
|
{% if implementation.commitList | length == 0 -%}
|
|
401
332
|
- No implementation commits produced; routing recommendation must be back to implementation-planning.
|
|
@@ -407,7 +338,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
407
338
|
{% endfor %}
|
|
408
339
|
{%- endif %}
|
|
409
340
|
|
|
410
|
-
###
|
|
341
|
+
### 5.7.3 Diff Summary
|
|
411
342
|
|
|
412
343
|
```
|
|
413
344
|
{{ implementation.diffSummary.rawStat }}
|
|
@@ -419,7 +350,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
419
350
|
| `{{ row.file }}` | {{ row.action }} | `{{ row.lines }}` | {{ row.planStep }} |
|
|
420
351
|
{% endfor %}
|
|
421
352
|
|
|
422
|
-
###
|
|
353
|
+
### 5.7.4 Out-of-plan Edits
|
|
423
354
|
|
|
424
355
|
{% if implementation.outOfPlanEdits | length == 0 -%}
|
|
425
356
|
{{ t("emptyState.outOfPlanEdits") }}
|
|
@@ -431,7 +362,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
431
362
|
{% endfor %}
|
|
432
363
|
{%- endif %}
|
|
433
364
|
|
|
434
|
-
###
|
|
365
|
+
### 5.7.5 Validation Evidence
|
|
435
366
|
|
|
436
367
|
| Phase | Command | Exit code | Output tail | TDD evidence |
|
|
437
368
|
|-------|---------|-----------|-------------|--------------|
|
|
@@ -439,7 +370,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
439
370
|
| {{ row.phase }} | `{{ row.command }}` | `{{ row.exitCode }}` | {{ row.outputTail }} | {{ row.tddEvidence or '--' }} |
|
|
440
371
|
{% endfor %}
|
|
441
372
|
|
|
442
|
-
###
|
|
373
|
+
### 5.7.6 Verifier Results
|
|
443
374
|
|
|
444
375
|
{% for block in implementation.verifierResults %}
|
|
445
376
|
- **{{ block.verifier }}** — Verdict: `{{ block.verdict }}`
|
|
@@ -450,7 +381,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
450
381
|
- Discrepancy: {{ block.discrepancy or t("emptyState.discrepancy") }}
|
|
451
382
|
{% endfor %}
|
|
452
383
|
|
|
453
|
-
###
|
|
384
|
+
### 5.7.7 Rollback Verification
|
|
454
385
|
|
|
455
386
|
| Category | Rollback command | Verification | Result |
|
|
456
387
|
|----------|-------------------|---------------|--------|
|
|
@@ -458,15 +389,15 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
458
389
|
| {{ row.category }} | `{{ row.rollbackCommand }}` | {{ row.verification }} | `{{ row.result }}` |
|
|
459
390
|
{% endfor %}
|
|
460
391
|
|
|
461
|
-
###
|
|
392
|
+
### 5.7.8 Routing Recommendation
|
|
462
393
|
|
|
463
394
|
{{ implementation.routingRecommendation }}
|
|
464
395
|
|
|
465
396
|
{% endif %}
|
|
466
397
|
{% if header.taskType == 'final-verification' %}
|
|
467
|
-
##
|
|
398
|
+
## 5.8 Final Verification Deliverables
|
|
468
399
|
|
|
469
|
-
###
|
|
400
|
+
### 5.8.1 Source Implementation Report
|
|
470
401
|
|
|
471
402
|
- Path (project-relative): `{{ finalVerification.sourceImplementationReport.path }}`
|
|
472
403
|
- {{ t("evidenceMeta.commitListSummary") }}:
|
|
@@ -485,7 +416,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
485
416
|
{{ finalVerification.sourceImplementationReport.gitDiffStat }}
|
|
486
417
|
```
|
|
487
418
|
|
|
488
|
-
###
|
|
419
|
+
### 5.8.2 Acceptance Blockers
|
|
489
420
|
|
|
490
421
|
{% if finalVerification.acceptanceBlockers | length == 0 -%}
|
|
491
422
|
- No acceptance blockers found.
|
|
@@ -497,7 +428,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
497
428
|
{% endfor %}
|
|
498
429
|
{%- endif %}
|
|
499
430
|
|
|
500
|
-
###
|
|
431
|
+
### 5.8.3 Residual Risk
|
|
501
432
|
|
|
502
433
|
{% if finalVerification.residualRisk | length == 0 -%}
|
|
503
434
|
{{ t("emptyState.lingeringRisks") }}
|
|
@@ -509,7 +440,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
509
440
|
{% endfor %}
|
|
510
441
|
{%- endif %}
|
|
511
442
|
|
|
512
|
-
###
|
|
443
|
+
### 5.8.4 Validation Evidence{% if t("finalVerification.validationEvidenceAside") != "requirements coverage" %} ({{ t("finalVerification.validationEvidenceAside") }}){% endif %}
|
|
513
444
|
|
|
514
445
|
| ID | {{ t("finalVerification.columnRequirement") }} | Artifact | Status |
|
|
515
446
|
|----|--------------------------------|----------|--------|
|
|
@@ -517,7 +448,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
517
448
|
| {{ row.id }} | {{ row.requirement }} | `{{ row.artifact }}` | {{ row.status }} |
|
|
518
449
|
{% endfor %}
|
|
519
450
|
|
|
520
|
-
###
|
|
451
|
+
### 5.8.5 Read-only Command Log
|
|
521
452
|
|
|
522
453
|
| # | Tier | Command (verbatim) | Status | Exit code | Output tail |
|
|
523
454
|
|---|------|---------------------|--------|-----------|-------------|
|
|
@@ -525,7 +456,7 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
525
456
|
| {{ row.number }} | {{ row.tier }} | `{{ row.command }}` | `{{ row.status }}` | {{ row.exitCode if row.exitCode is not none else '—' }} | {{ row.rejectionReason if row.status == 'rejected' else row.outputTail }} |
|
|
526
457
|
{% endfor %}
|
|
527
458
|
|
|
528
|
-
###
|
|
459
|
+
### 5.8.6 Conditional Acceptance Conditions
|
|
529
460
|
|
|
530
461
|
{% if not finalVerdict.conditionalAcceptanceConditions -%}
|
|
531
462
|
- Not applicable (verdict is not `conditional-accept`).
|
|
@@ -537,13 +468,13 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
537
468
|
{% endfor %}
|
|
538
469
|
{%- endif %}
|
|
539
470
|
|
|
540
|
-
###
|
|
471
|
+
### 5.8.7 Routing Recommendation
|
|
541
472
|
|
|
542
473
|
{{ finalVerification.routingRecommendation }}
|
|
543
474
|
|
|
544
475
|
{% endif %}
|
|
545
476
|
{% if header.taskType == 'improvement-discovery' %}
|
|
546
|
-
##
|
|
477
|
+
## 5.9 Improvement Candidates
|
|
547
478
|
|
|
548
479
|
> Lens whitelist and column schema enforced by `validators/validate-improvement-report.py`. Row count is bounded by the brief's `candidate-cap` (default 8, absolute max 12).
|
|
549
480
|
|
|
@@ -551,56 +482,121 @@ approved: {{ frontmatter.approved | yaml_scalar }}
|
|
|
551
482
|
|---------|------|-------|-------|----------|--------|-----------|----------------|------------------------|----------|
|
|
552
483
|
|
|
553
484
|
{% endif %}
|
|
554
|
-
##
|
|
555
|
-
|
|
556
|
-
{{ t("sectionIntro.clarificationItems") }}
|
|
485
|
+
## 6. Cross Verification Results
|
|
557
486
|
|
|
558
|
-
{% if
|
|
559
|
-
|
|
560
|
-
{%- else %}
|
|
561
|
-
{{ t("clarification.fillAndRerun") }}
|
|
562
|
-
|
|
563
|
-
- Claude Code: `/okstra-run resume-clarification task-key={{ header.taskKey }}`
|
|
564
|
-
- {{ t("clarification.separateTerminalLabel") }}: `scripts/okstra.sh --resume-clarification --task-key {{ header.taskKey }}`
|
|
487
|
+
{% if crossVerification.roundHistory and not crossVerification.roundHistory.disabled -%}
|
|
488
|
+
### 6.0 Round History
|
|
565
489
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
490
|
+
{% if crossVerification.roundHistory.rounds | length > 1 -%}
|
|
491
|
+
| Round | inputQueueSize | resolvedCount | carriedForwardCount | dispatches (worker:status:durationMs) | skippedWorkers (worker:reason) |
|
|
492
|
+
|-------|----------------|---------------|----------------------|----------------------------------------|---------------------------------|
|
|
493
|
+
{% for row in crossVerification.roundHistory.rounds -%}
|
|
494
|
+
| {{ row.round }} | {{ row.inputQueueSize }} | {{ row.resolvedCount }} | {{ row.carriedForwardCount }} | {{ row.dispatches }} | {{ row.skippedWorkers }} |
|
|
570
495
|
{% endfor %}
|
|
571
496
|
|
|
572
|
-
{{ t("
|
|
497
|
+
- `round2SkippedReason`: `{{ crossVerification.roundHistory.round2SkippedReason }}` ← {{ t("roundHistory.round2SkippedReasonNote") }}
|
|
498
|
+
{% elif crossVerification.roundHistory.rounds | length == 1 -%}
|
|
499
|
+
{% set r = crossVerification.roundHistory.rounds[0] -%}
|
|
500
|
+
- {{ t("roundHistory.singleRoundPrefix") }} resolved={{ r.resolvedCount }}, carriedForward={{ r.carriedForwardCount }}, round2SkippedReason=`{{ crossVerification.roundHistory.round2SkippedReason }}`
|
|
501
|
+
{% else -%}
|
|
502
|
+
- {{ t("roundHistory.noRoundsNote") }} round2SkippedReason=`{{ crossVerification.roundHistory.round2SkippedReason }}`
|
|
503
|
+
{% endif %}
|
|
573
504
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
505
|
+
{% endif %}
|
|
506
|
+
### 6.1 Consensus
|
|
507
|
+
|
|
508
|
+
{% if crossVerification.consensus | length == 0 -%}
|
|
509
|
+
{{ t("emptyState.consensusItems") }}
|
|
510
|
+
{%- else %}
|
|
511
|
+
| {{ t("columns.recordMeta") }} | Statement | Evidence (path:line / log / worker report) |
|
|
512
|
+
|--------|-----------|---------------------------------------------|
|
|
513
|
+
{% for row in crossVerification.consensus -%}
|
|
514
|
+
| **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>Source items: {{ row.sourceItems | join(', ') }} | {{ row.statement }} | {{ row.evidence }} |
|
|
515
|
+
{% endfor %}
|
|
577
516
|
{%- endif %}
|
|
578
517
|
|
|
579
|
-
|
|
518
|
+
{{ t("sectionIntro.sourceItemsRule") }}
|
|
580
519
|
|
|
581
|
-
|
|
582
|
-
|
|
520
|
+
### 6.2 Differences
|
|
521
|
+
|
|
522
|
+
{% if crossVerification.differences | length == 0 -%}
|
|
523
|
+
{{ t("emptyState.differences") }}
|
|
583
524
|
{%- else %}
|
|
584
|
-
{
|
|
585
|
-
|
|
586
|
-
{%
|
|
587
|
-
{% for
|
|
588
|
-
- {{ cmd.label }}:
|
|
589
|
-
- Claude Code: `{{ cmd.claudeCode }}`
|
|
590
|
-
- {{ t("clarification.separateTerminalLabel") }}: `{{ cmd.terminal }}`
|
|
591
|
-
{% endfor -%}
|
|
592
|
-
{%- endif %}
|
|
525
|
+
| {{ t("columns.recordMeta") }} | Disagreement | Evidence |
|
|
526
|
+
|--------|--------------|----------|
|
|
527
|
+
{% for row in crossVerification.differences -%}
|
|
528
|
+
| **{{ 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 }} |
|
|
593
529
|
{% endfor %}
|
|
594
530
|
{%- endif %}
|
|
595
531
|
|
|
596
|
-
## 7.
|
|
532
|
+
## 7. Final Verdict
|
|
597
533
|
|
|
598
|
-
{
|
|
599
|
-
|
|
534
|
+
{{ t("finalVerdict.intro") }}
|
|
535
|
+
|
|
536
|
+
| {{ t("verdictCard.tableHeaderLabel") }} | {{ t("verdictCard.tableHeaderValue") }} |
|
|
537
|
+
|------|----|
|
|
538
|
+
| Final Conclusion | {{ finalVerdict.finalConclusion }} |
|
|
539
|
+
| Verdict Token | `{{ finalVerdict.verdictToken }}` |
|
|
540
|
+
| Direction | `{{ finalVerdict.direction }}` |
|
|
541
|
+
| {{ t("verdictCard.rationaleLabel") }} | {{ finalVerdict.rationaleRowIds | join(', ') }} |
|
|
542
|
+
| {{ t("verdictCard.nextStepLabel") }} | {{ finalVerdict.nextStep }} |
|
|
543
|
+
|
|
544
|
+
{% if clarificationCarryIn and clarificationCarryIn.sourceFile %}
|
|
545
|
+
## 0. Clarification Response Carried In From Previous Run
|
|
546
|
+
|
|
547
|
+
- Source file: `{{ clarificationCarryIn.sourceFile }}`
|
|
548
|
+
- {{ t("sectionIntro.clarificationCarryIn") }}
|
|
549
|
+
|
|
550
|
+
{% endif %}
|
|
551
|
+
## Summary of the Problem or Verification Target
|
|
552
|
+
|
|
553
|
+
{{ t("sectionIntro.ticketCoverage") }}
|
|
554
|
+
|
|
555
|
+
| {{ t("columns.recordMeta") }} | {{ t("columns.summary") }} |
|
|
556
|
+
|--------|------------|
|
|
557
|
+
{% for row in summary -%}
|
|
558
|
+
| **{{ row.id }}**<br>Ticket: `{{ row.ticketId }}`<br>{{ t("columns.source") }}: {{ row.source }} | {{ row.summary }} |
|
|
559
|
+
{% endfor %}
|
|
560
|
+
|
|
561
|
+
{% if ticketCoverage.omit %}
|
|
562
|
+
{# Ticket Coverage omitted entirely — release-handoff / final-verification #}
|
|
600
563
|
{%- else %}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
{
|
|
604
|
-
|
|
564
|
+
## Ticket Coverage
|
|
565
|
+
|
|
566
|
+
{{ t("ticketCoverage.intro") }}
|
|
567
|
+
|
|
568
|
+
{% if ticketCoverage.singleTicket -%}
|
|
569
|
+
- Single ticket run: {{ ticketCoverage.singleTicket }}
|
|
570
|
+
{%- else %}
|
|
571
|
+
| Ticket ID | {{ t("ticketCoverage.columnSections") }} | {{ t("ticketCoverage.columnRelatedIds") }} |
|
|
572
|
+
|-----------|-----------|---------------|
|
|
573
|
+
{% for row in ticketCoverage.rows -%}
|
|
574
|
+
| `{{ row.ticketId }}` | `{{ row.sections }}` | `{{ row.relatedIds }}` |
|
|
605
575
|
{% endfor %}
|
|
606
576
|
{%- endif %}
|
|
577
|
+
|
|
578
|
+
{% endif %}
|
|
579
|
+
## Execution Status by Agent
|
|
580
|
+
|
|
581
|
+
{{ t("sectionIntro.executionStatus") }}
|
|
582
|
+
|
|
583
|
+
| {{ t("columns.recordMeta") }} | Summary of Key Findings |
|
|
584
|
+
|--------|-------------------------|
|
|
585
|
+
{% for row in executionStatus -%}
|
|
586
|
+
| **{{ 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 }} |
|
|
587
|
+
{% endfor %}
|
|
588
|
+
|
|
589
|
+
## {{ t("tokenSummary.heading") }}
|
|
590
|
+
|
|
591
|
+
| {{ t("tokenSummary.tableHeaderItem") }} | {{ t("columns.rawTokens") }} | {{ t("columns.billableTokensInputEquiv") }} | {{ t("columns.cost") }} |
|
|
592
|
+
|------|-----------|------------------------|------------|
|
|
593
|
+
| {{ t("tokenSummary.rowLead") }} | `{{ tokenUsage.lead.totalTokens | format_int }}` | `{{ tokenUsage.lead.billableTokens | format_int }}` | `{{ tokenUsage.lead.costUsd | format_usd }}` |
|
|
594
|
+
| {{ t("tokenSummary.rowWorkerTotal") }} | `{{ tokenUsage.worker.totalTokens | format_int }}` | `{{ tokenUsage.worker.billableTokens | format_int }}` | `{{ tokenUsage.worker.costUsd | format_usd }}` |
|
|
595
|
+
| {{ t("tokenSummary.rowGrandTotal") }} | **`{{ tokenUsage.grand.totalTokens | format_int }}`** | **`{{ tokenUsage.grand.billableTokens | format_int }}`** | **`{{ tokenUsage.grand.costUsd | format_usd }}`** |
|
|
596
|
+
{% if tokenUsage.cli and tokenUsage.cli.costUsd is not none and tokenUsage.cli.costUsd > 0 -%}
|
|
597
|
+
| {{ t("tokenSummary.rowCliExtra") }} | | | `{{ tokenUsage.cli.costUsd | format_usd }}` |
|
|
598
|
+
{% endif %}
|
|
599
|
+
|
|
600
|
+
{# At Phase 6 numeric cells are null and render as `--`.
|
|
601
|
+
Phase 7's okstra-token-usage.py populates tokenUsage in data.json then
|
|
602
|
+
re-invokes this renderer to produce the final markdown. #}
|