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