okstra 0.173.0 → 0.174.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/architecture/storage-model.md +13 -3
- package/docs/architecture.md +5 -21
- package/docs/cli.md +3 -2
- package/docs/container.md +1 -1
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/project-structure-overview.md +13 -13
- package/docs/task-process/README.md +1 -1
- package/docs/task-process/implementation-planning.md +1 -1
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +1 -1
- package/runtime/bin/lib/okstra/globals.sh +1 -1
- package/runtime/bin/okstra-provider-exec.py +29 -12
- package/runtime/bin/okstra-trace-cleanup.sh +58 -129
- package/runtime/prompts/lead/adapters/cmux.md +2 -0
- package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
- package/runtime/prompts/lead/plan-body-verification.md +3 -3
- package/runtime/prompts/lead/report-writer.md +6 -6
- package/runtime/prompts/profiles/_common-contract.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +2 -0
- package/runtime/prompts/profiles/_implementation-verifier.md +2 -2
- package/runtime/prompts/profiles/error-analysis.md +1 -1
- package/runtime/prompts/profiles/implementation-planning.md +12 -9
- package/runtime/prompts/profiles/implementation.md +2 -1
- package/runtime/prompts/profiles/release-handoff.md +1 -1
- package/runtime/python/okstra_ctl/adapters/dispatch/__init__.py +1 -6
- package/runtime/python/okstra_ctl/adapters/hosts/external/relay.md +4 -4
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +5 -0
- package/runtime/python/okstra_ctl/conformance.py +68 -0
- package/runtime/python/okstra_ctl/dispatch_core.py +89 -39
- package/runtime/python/okstra_ctl/dispatch_state.py +142 -14
- package/runtime/python/okstra_ctl/doctor.py +2 -2
- package/runtime/python/okstra_ctl/domain/worker_exec.py +5 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +5 -4
- package/runtime/python/okstra_ctl/pane_reclaim.py +13 -22
- package/runtime/python/okstra_ctl/render_final_report.py +15 -19
- package/runtime/python/okstra_ctl/report_contract.py +0 -1
- package/runtime/python/okstra_ctl/report_finalize.py +68 -9
- package/runtime/python/okstra_ctl/run.py +43 -2
- package/runtime/python/okstra_ctl/schema_excerpt.py +1 -1
- package/runtime/python/okstra_ctl/scope_provenance.py +1 -1
- package/runtime/python/okstra_ctl/session.py +69 -12
- package/runtime/python/okstra_ctl/team.py +51 -25
- package/runtime/python/okstra_ctl/tmux.py +19 -149
- package/runtime/python/okstra_ctl/worker_request.py +2 -0
- package/runtime/python/okstra_ctl/worktree.py +69 -3
- package/runtime/python/okstra_token_usage/cli.py +1 -1
- package/runtime/python/okstra_token_usage/collect.py +66 -6
- package/runtime/skills/okstra-setup/references/project-config.md +11 -0
- package/runtime/templates/reports/settings.template.json +0 -24
- package/runtime/validators/lib/fixtures.sh +49 -17
- package/runtime/validators/validate-implementation-plan-stages.py +63 -3
- package/runtime/validators/validate-run.py +14 -473
- package/runtime/validators/validate_session_conformance.py +1 -1
- package/src/cli-registry.mjs +8 -1
- package/src/commands/execute/team.mjs +3 -3
- package/src/commands/execute/worktree-status.mjs +109 -0
- package/src/commands/lifecycle/install.mjs +0 -2
- package/src/commands/report/finalize.mjs +13 -6
- package/runtime/bin/okstra-subagent-reclaim.sh +0 -26
- package/runtime/schemas/final-report-v1.0.schema.json +0 -6366
- package/runtime/templates/reports/final-report.template.md +0 -1258
|
@@ -1,1258 +0,0 @@
|
|
|
1
|
-
{# OKSTRA Final Report — Jinja2 template (schemas/final-report-v1.0).
|
|
2
|
-
Consumed by scripts/okstra-render-final-report.py against the JSON
|
|
3
|
-
SSOT at runs/<task-type>/reports/final-report-<task-type>-<seq>.data.json.
|
|
4
|
-
Custom filters: format_int, format_usd, format_duration_ms,
|
|
5
|
-
yaml_scalar, yaml_inline_list, model_detail, mdcell (defined in
|
|
6
|
-
render_final_report.py). Every data interpolation inside a table row
|
|
7
|
-
carries `| mdcell` so a literal `|` in worker prose (e.g. "PASS|FAIL")
|
|
8
|
-
cannot split the row — except t() labels and format_int/format_usd/
|
|
9
|
-
format_duration_ms outputs, which cannot contain `|` by construction.
|
|
10
|
-
Never apply mdcell outside table cells (code fences, headings, prose).
|
|
11
|
-
Token Usage cells render as `--` while tokenUsage.*.totalTokens is
|
|
12
|
-
null in Phase 6; Phase 7 mutates the data.json then re-renders. #}
|
|
13
|
-
---
|
|
14
|
-
title: {{ frontmatter.title | yaml_scalar }}
|
|
15
|
-
id: {{ frontmatter.id | yaml_scalar }}
|
|
16
|
-
tags: {{ frontmatter.tags | yaml_inline_list }}
|
|
17
|
-
status: {{ frontmatter.status }}
|
|
18
|
-
aliases: {{ frontmatter.aliases | yaml_inline_list }}
|
|
19
|
-
date: {{ frontmatter.date }}
|
|
20
|
-
task-id: {{ frontmatter.taskId | yaml_scalar }}
|
|
21
|
-
task-group: {{ frontmatter.taskGroup | yaml_scalar }}
|
|
22
|
-
project-id: {{ frontmatter.projectId | yaml_scalar }}
|
|
23
|
-
taskType: {{ frontmatter.taskType | yaml_scalar }}
|
|
24
|
-
workerId: {{ frontmatter.workerId | yaml_scalar }}
|
|
25
|
-
approved: {{ frontmatter.approved | yaml_scalar }}
|
|
26
|
-
implementation-option: {{ frontmatter.implementationOption | yaml_scalar }}
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# {{ header.taskKey }} - Multi-Agent Cross Verification Final Report
|
|
30
|
-
|
|
31
|
-
- Created at: {{ header.createdAt }}
|
|
32
|
-
- Task Key: {{ header.taskKey }}
|
|
33
|
-
- Task Type: {{ header.taskType }}
|
|
34
|
-
- Report Owner: `{{ header.reportOwner }}` (model: `{{ header.leadModel | model_detail }}`)
|
|
35
|
-
- Report Author: `{{ header.reportAuthor }}`
|
|
36
|
-
- Lead Model: `{{ header.leadModel | model_detail }}`
|
|
37
|
-
{% for row in followUpTasks if row.origin == 'phase-continuation' %}{% if loop.first %}- Next Step: run `/okstra-run`, select task `{{ header.taskKey }}`, choose task-type `{{ row.suggestedTaskType }}`
|
|
38
|
-
{% endif %}{% endfor %}- Okstra Version: `{{ header.okstraVersion }}`
|
|
39
|
-
|
|
40
|
-
{% if clarificationCarryIn and clarificationCarryIn.sourceFile %}
|
|
41
|
-
## 0. Clarification Response Carried In From Previous Run
|
|
42
|
-
|
|
43
|
-
{{ t("sectionIntro.clarificationCarryIn") }}
|
|
44
|
-
|
|
45
|
-
- Source file: `{{ clarificationCarryIn.sourceFile }}`
|
|
46
|
-
{% if implementationPlanning and implementationPlanning.incrementalDecision %}
|
|
47
|
-
{% set incrementalDecision = implementationPlanning.incrementalDecision %}
|
|
48
|
-
### 0.1 Incremental Re-Verification Scope
|
|
49
|
-
|
|
50
|
-
- Decision mode: `{{ incrementalDecision.mode }}`
|
|
51
|
-
- Reason: {{ incrementalDecision.reason }}
|
|
52
|
-
{% if incrementalDecision.mode == 'incremental' %}
|
|
53
|
-
- Re-verified stages: {% for s in incrementalDecision.reverifyStages %}`stage-{{ s }}`{% if not loop.last %}, {% endif %}{% else %}(none){% endfor +%}
|
|
54
|
-
- Carried-forward stages: {% for s in incrementalDecision.carryStages %}`stage-{{ s }}` carried-forward (unchanged){% if not loop.last %}, {% endif %}{% else %}(none){% endfor +%}
|
|
55
|
-
|
|
56
|
-
Carried-forward plan items retain their prior verdicts verbatim; each such item carries a `carriedForwardFromSeq` tag pointing at the run it was verified in.
|
|
57
|
-
{% endif %}
|
|
58
|
-
{% endif %}
|
|
59
|
-
|
|
60
|
-
{% endif %}
|
|
61
|
-
## Summary of the Problem or Verification Target
|
|
62
|
-
|
|
63
|
-
{{ t("sectionIntro.ticketCoverage") }}
|
|
64
|
-
|
|
65
|
-
| {{ t("columns.recordMeta") }} | {{ t("columns.summary") }} |
|
|
66
|
-
|--------|------------|
|
|
67
|
-
{% for row in summary -%}
|
|
68
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>{{ t("columns.source") }}: {{ row.source | mdcell }} | {{ row.summary | mdcell }} |
|
|
69
|
-
{% endfor %}
|
|
70
|
-
|
|
71
|
-
## Verdict Card
|
|
72
|
-
|
|
73
|
-
{{ t("sectionIntro.verdictCard") }}
|
|
74
|
-
|
|
75
|
-
| {{ t("verdictCard.tableHeaderLabel") }} | {{ t("verdictCard.tableHeaderValue") }} |
|
|
76
|
-
|------|----|
|
|
77
|
-
| Final Conclusion | {{ verdictCard.finalConclusion | mdcell }} |
|
|
78
|
-
| Verdict Token | `{{ verdictCard.verdictToken | mdcell }}` |
|
|
79
|
-
| Direction | `{{ verdictCard.direction | mdcell }}` |
|
|
80
|
-
| Approval Required? | `{% if verdictCard.approvalRequired %}yes — {{ t("verdictCard.approvalRequiredSuffix") }}{% else %}no{% endif %}` |
|
|
81
|
-
| Next Step | {{ verdictCard.nextStep | mdcell }} |
|
|
82
|
-
|
|
83
|
-
{% if readerSummary %}
|
|
84
|
-
## {{ t("readerSummary.heading") }}
|
|
85
|
-
|
|
86
|
-
{{ t("sectionIntro.readerSummary") }}
|
|
87
|
-
|
|
88
|
-
| {{ t("readerSummary.tableHeaderItem") }} | {{ t("readerSummary.tableHeaderValue") }} |
|
|
89
|
-
|------|----|
|
|
90
|
-
| {{ t("readerSummary.decisionLabel") }} | {{ readerSummary.decision | mdcell }} |
|
|
91
|
-
| {{ t("readerSummary.humanActionRequiredLabel") }} | {{ readerSummary.humanActionRequired | mdcell }} |
|
|
92
|
-
| {{ t("readerSummary.blockingItemsLabel") }} | {{ readerSummary.blockingItems | mdcell }} |
|
|
93
|
-
| {{ t("readerSummary.safeToSkipLabel") }} | {{ readerSummary.safeToSkip | mdcell }} |
|
|
94
|
-
| {{ t("readerSummary.recommendedCommandLabel") }} | `{{ readerSummary.recommendedCommand | mdcell }}` |
|
|
95
|
-
|
|
96
|
-
{% endif %}
|
|
97
|
-
## {{ t("rationale.heading") }}
|
|
98
|
-
|
|
99
|
-
{{ t("rationale.intro") }}
|
|
100
|
-
|
|
101
|
-
**{{ t("rationale.motivationLabel") }}** — {{ rationale.motivation }}
|
|
102
|
-
|
|
103
|
-
**{{ t("rationale.problemLabel") }}** — {{ rationale.problem }}
|
|
104
|
-
|
|
105
|
-
**{{ t("rationale.approachLabel") }}** — {{ rationale.approach }}
|
|
106
|
-
|
|
107
|
-
**{{ t("rationale.justificationLabel") }}** — {{ rationale.justification }}
|
|
108
|
-
|
|
109
|
-
## 1. Clarification Items
|
|
110
|
-
|
|
111
|
-
{{ t("sectionIntro.clarificationItems") }}
|
|
112
|
-
|
|
113
|
-
{% if clarificationItems | length == 0 -%}
|
|
114
|
-
{{ t("emptyState.noClarification") }}
|
|
115
|
-
{%- else %}
|
|
116
|
-
{{ t("clarification.fillAndRerun") }}
|
|
117
|
-
|
|
118
|
-
- Claude Code: `/okstra-run resume-clarification task-key={{ header.taskKey }}`
|
|
119
|
-
- {{ t("clarification.separateTerminalLabel") }}: `scripts/okstra.sh --resume-clarification --task-key {{ header.taskKey }}`
|
|
120
|
-
|
|
121
|
-
| {{ t("columns.recordMeta") }} | Statement | Expected form | User input |
|
|
122
|
-
|---|---|---|---|
|
|
123
|
-
{% for row in clarificationItems -%}
|
|
124
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>Kind: `{{ row.kind | mdcell }}`<br>Blocks: `{{ row.blocks | mdcell }}`<br>Status: {{ row.status | mdcell }} | {{ row.statement | mdcell }} | {{ row.expectedForm | mdcell }} | {{ (row.userInput or '') | mdcell }} |
|
|
125
|
-
{% endfor %}
|
|
126
|
-
{%- endif %}
|
|
127
|
-
|
|
128
|
-
## 2. Evidence and Detailed Analysis
|
|
129
|
-
|
|
130
|
-
### 2.1 Primary Evidence
|
|
131
|
-
|
|
132
|
-
{% if evidence.primary | length == 0 -%}
|
|
133
|
-
{{ t("emptyState.primaryEvidence") }}
|
|
134
|
-
{%- else %}
|
|
135
|
-
| {{ t("columns.recordMeta") }} | Evidence |
|
|
136
|
-
|--------|----------|
|
|
137
|
-
{% for row in evidence.primary -%}
|
|
138
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>Source items: {{ row.sourceItems | join(', ') | mdcell }}<br>Source: {{ row.source | mdcell }} | {{ row.evidence | mdcell }} |
|
|
139
|
-
{% endfor %}
|
|
140
|
-
{%- endif %}
|
|
141
|
-
|
|
142
|
-
{{ t("evidence.sourceItemsColumnNote") }}
|
|
143
|
-
|
|
144
|
-
### 2.2 Secondary Evidence or Alternate Interpretations
|
|
145
|
-
|
|
146
|
-
{% if not evidence.secondary or evidence.secondary | length == 0 -%}
|
|
147
|
-
{{ t("emptyState.secondaryEvidence") }}
|
|
148
|
-
{%- else %}
|
|
149
|
-
| {{ t("columns.recordMeta") }} | Hypothesis or supporting evidence | Source / confidence |
|
|
150
|
-
|--------|-----------------------------------|---------------------|
|
|
151
|
-
{% for row in evidence.secondary -%}
|
|
152
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}` | {{ row.hypothesis | mdcell }} | {{ row.confidence | mdcell }} |
|
|
153
|
-
{% endfor %}
|
|
154
|
-
{%- endif %}
|
|
155
|
-
|
|
156
|
-
{% if header.taskType in ('requirements-discovery', 'error-analysis', 'implementation-planning') %}
|
|
157
|
-
|
|
158
|
-
### 2.3 End State Coverage{% if t("sectionAside.endStateCoverage") != "End State Coverage" %} ({{ t("sectionAside.endStateCoverage") }}){%- endif %}
|
|
159
|
-
|
|
160
|
-
{% if endStateCoverage | length == 0 -%}
|
|
161
|
-
{{ t("emptyState.endStateCoverage") }}
|
|
162
|
-
{%- else %}
|
|
163
|
-
{{ t("sectionIntro.endStateCoverage") }}
|
|
164
|
-
|
|
165
|
-
| ID | {{ t("columns.disposition") }} | {{ t("columns.coveredBy") }} | {{ t("columns.evidence") }} | {{ t("columns.rationale") }} |
|
|
166
|
-
|----|---------------|-----------|----------|-----------|
|
|
167
|
-
{% for row in endStateCoverage -%}
|
|
168
|
-
| {{ row.id | mdcell }} | `{{ row.disposition | mdcell }}` | {{ row.coveredBy | mdcell }} | {{ (row.evidence | join(", ")) | mdcell }} | {{ row.rationale | mdcell }} |
|
|
169
|
-
{% endfor %}
|
|
170
|
-
{%- endif %}
|
|
171
|
-
|
|
172
|
-
{% endif %}
|
|
173
|
-
|
|
174
|
-
{% if header.taskType == 'error-analysis' %}
|
|
175
|
-
### 2.4 Error Analysis Result{% if t("errorAnalysis.heading") != "Error Analysis Result" %} ({{ t("errorAnalysis.heading") }}){% endif %}
|
|
176
|
-
|
|
177
|
-
- **{{ t("errorAnalysis.symptomVerbatim") }}:** {{ errorAnalysis.symptomVerbatim }}
|
|
178
|
-
- **{{ t("errorAnalysis.observableFailure") }}:** {{ errorAnalysis.observableFailure }}
|
|
179
|
-
- **{{ t("errorAnalysis.reproductionStatus") }}:** `{{ errorAnalysis.reproduction.status }}`
|
|
180
|
-
- **{{ t("errorAnalysis.reproductionEvidence") }}:** {{ errorAnalysis.reproduction.evidence | join(", ") }}
|
|
181
|
-
{% if errorAnalysis.reproduction.blockedReason %}- **{{ t("errorAnalysis.blockedReason") }}:** {{ errorAnalysis.reproduction.blockedReason }}
|
|
182
|
-
{% endif %}
|
|
183
|
-
|
|
184
|
-
{% if errorAnalysis.causeCandidates | length == 0 -%}
|
|
185
|
-
{{ t("emptyState.errorAnalysisCauseCandidates") }}
|
|
186
|
-
{%- else %}
|
|
187
|
-
| ID | {{ t("errorAnalysis.candidate") }} | {{ t("errorAnalysis.supportingEvidence") }} | {{ t("errorAnalysis.falsifyingEvidence") }} | {{ t("errorAnalysis.confidence") }} | {{ t("errorAnalysis.disproveWith") }} |
|
|
188
|
-
|---|---|---|---|---|---|
|
|
189
|
-
{% for row in errorAnalysis.causeCandidates -%}
|
|
190
|
-
| {{ row.id | mdcell }} | {{ row.statement | mdcell }} | {{ row.supportingEvidence | join(", ") | mdcell }} | {{ row.falsifyingEvidenceChecked | join(", ") | mdcell }} | `{{ row.confidence | mdcell }}` | {{ row.disproveWith | mdcell }} |
|
|
191
|
-
{% endfor %}
|
|
192
|
-
{%- endif %}
|
|
193
|
-
|
|
194
|
-
- **{{ t("errorAnalysis.nextDiagnostic") }}:** {{ errorAnalysis.nextDiagnostic.action }}
|
|
195
|
-
- **{{ t("errorAnalysis.confirmingSignal") }}:** {{ errorAnalysis.nextDiagnostic.confirmingSignal }}
|
|
196
|
-
- **{{ t("errorAnalysis.rejectingSignal") }}:** {{ errorAnalysis.nextDiagnostic.rejectingSignal }}
|
|
197
|
-
- **{{ t("errorAnalysis.route") }}:** `{{ errorAnalysis.routing.nextTaskType }}`{% if errorAnalysis.routing.leadingCauseId %} — `{{ errorAnalysis.routing.leadingCauseId }}`{% endif %} — {{ errorAnalysis.routing.rationale }}
|
|
198
|
-
{% endif %}
|
|
199
|
-
|
|
200
|
-
## 3. Recommended Next Steps
|
|
201
|
-
|
|
202
|
-
{% if recommendedNextSteps | length == 0 -%}
|
|
203
|
-
- No further action required. Final verdict in section 7 stands.
|
|
204
|
-
{%- else %}
|
|
205
|
-
{% for step in recommendedNextSteps -%}
|
|
206
|
-
{{ loop.index }}. {{ step.text }}
|
|
207
|
-
{% if step.commands -%}
|
|
208
|
-
{% for cmd in step.commands %}
|
|
209
|
-
- {{ cmd.label }}:
|
|
210
|
-
- Claude Code: `{{ cmd.claudeCode }}`
|
|
211
|
-
- {{ t("clarification.separateTerminalLabel") }}: `{{ cmd.terminal }}`
|
|
212
|
-
{% endfor -%}
|
|
213
|
-
{%- endif %}
|
|
214
|
-
{% endfor %}
|
|
215
|
-
{%- endif %}
|
|
216
|
-
|
|
217
|
-
## 4. Follow-up Tasks{% if t("followUpTasks.headingAside") != "Follow-up Tasks" %} ({{ t("followUpTasks.headingAside") }}){% endif %}
|
|
218
|
-
|
|
219
|
-
{% if followUpTasks | length == 0 -%}
|
|
220
|
-
{{ t("emptyState.noFollowUp") }}
|
|
221
|
-
{%- else %}
|
|
222
|
-
| {{ t("columns.recordMeta") }} | Title | Scope (files/areas) | Reason / Why deferred |
|
|
223
|
-
|--------|-------|---------------------|------------------------|
|
|
224
|
-
{% for row in followUpTasks -%}
|
|
225
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>Origin: `{{ row.origin | mdcell }}`<br>New Task ID: `{{ row.newTaskId | mdcell }}`<br>Type: `{{ row.suggestedTaskType | mdcell }}`<br>Priority: `{{ row.priority | mdcell }}`<br>Auto-spawn: `{{ row.autoSpawn | mdcell }}` | {{ row.title | mdcell }} | {{ row.scope | mdcell }} | {{ row.reason | mdcell }} |
|
|
226
|
-
{% endfor %}
|
|
227
|
-
{%- endif %}
|
|
228
|
-
|
|
229
|
-
## 5. Missing Information and Risks
|
|
230
|
-
|
|
231
|
-
{% if missingInformation | length == 0 -%}
|
|
232
|
-
{{ t("emptyState.risks") }}
|
|
233
|
-
{%- else %}
|
|
234
|
-
| {{ t("columns.recordMeta") }} | Item | Risk if ignored | Mitigation Owner |
|
|
235
|
-
|--------|------|-----------------|------------------|
|
|
236
|
-
{% for row in missingInformation -%}
|
|
237
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}` | {{ row.item | mdcell }} | {{ row.risk | mdcell }} | {{ row.owner | mdcell }} |
|
|
238
|
-
{% endfor %}
|
|
239
|
-
{%- endif %}
|
|
240
|
-
|
|
241
|
-
{% if header.taskType == 'implementation-planning' %}
|
|
242
|
-
## 5.4 Implementation Plan Deliverables
|
|
243
|
-
|
|
244
|
-
### Option Candidates{% if t("sectionAside.optionCandidates") != "Option Candidates" %} ({{ t("sectionAside.optionCandidates") }}){% endif %}
|
|
245
|
-
|
|
246
|
-
{% for opt in implementationPlanning.optionCandidates %}
|
|
247
|
-
**{{ opt.name }}**
|
|
248
|
-
|
|
249
|
-
- File Structure:
|
|
250
|
-
|
|
251
|
-
| {{ t("columns.recordMeta") }} | Path (and line-range) | Change summary |
|
|
252
|
-
|------|------------------------|----------------|
|
|
253
|
-
{% for fs in opt.fileStructure -%}
|
|
254
|
-
| **{{ fs.id | mdcell }}**<br>Ticket: `{{ fs.ticketId | mdcell }}`<br>Action: {{ fs.action | mdcell }} | `{{ fs.path | mdcell }}` | {{ fs.summary | mdcell }}{% if fs.details %}<br><small>{{ fs.details | mdcell }}</small>{% endif %} |
|
|
255
|
-
{% endfor %}
|
|
256
|
-
|
|
257
|
-
- {{ t("implementationPlanning.optionInterfacesLabel") }}: {{ opt.interfaces }}
|
|
258
|
-
- {{ t("implementationPlanning.optionBlastRadiusLabel") }}: {{ opt.blastRadius }}
|
|
259
|
-
|
|
260
|
-
{% endfor %}
|
|
261
|
-
|
|
262
|
-
### Trade-off Matrix{% if t("sectionAside.tradeOffMatrix") != "Trade-off Matrix" %} ({{ t("sectionAside.tradeOffMatrix") }}){% endif %}
|
|
263
|
-
|
|
264
|
-
| Option | Complexity | Risk | Reversibility | Test Coverage Cost | Rollout Cost |
|
|
265
|
-
|--------|-----------|------|---------------|--------------------|--------------|
|
|
266
|
-
{% for row in implementationPlanning.tradeoffMatrix -%}
|
|
267
|
-
| {{ row.option | mdcell }} | {{ row.complexity | mdcell }} | {{ row.risk | mdcell }} | {{ row.reversibility | mdcell }} | {{ row.testCoverageCost | mdcell }} | {{ row.rolloutCost | mdcell }} |
|
|
268
|
-
{% endfor %}
|
|
269
|
-
|
|
270
|
-
### Recommended Option{% if t("sectionAside.recommendedOption") != "Recommended Option" %} ({{ t("sectionAside.recommendedOption") }}){% endif %}
|
|
271
|
-
|
|
272
|
-
| {{ t("implementationPlanning.recommendedTableHeaderLabel") }} | {{ t("implementationPlanning.recommendedTableHeaderValue") }} |
|
|
273
|
-
|------|----|
|
|
274
|
-
| Recommended Option | {{ implementationPlanning.recommendedOption.name | mdcell }} |
|
|
275
|
-
| {{ t("implementationPlanning.coreReasonLabel") }} | {{ implementationPlanning.recommendedOption.coreReason | mdcell }} |
|
|
276
|
-
| {{ t("implementationPlanning.rationaleLabel") }} | {{ implementationPlanning.recommendedOption.rationale | mdcell }} |
|
|
277
|
-
| {{ t("implementationPlanning.rejectedSummaryLabel") }} | {{ implementationPlanning.recommendedOption.rejectedSummary | mdcell }} |
|
|
278
|
-
|
|
279
|
-
### Dependency / Migration Risk{% if t("sectionAside.dependencyRisk") != "Dependency / Migration Risk" %} ({{ t("sectionAside.dependencyRisk") }}){% endif %}
|
|
280
|
-
|
|
281
|
-
{% if implementationPlanning.dependencyMigrationRisk | length == 0 -%}
|
|
282
|
-
{{ t("emptyState.dependencyRisk") }}
|
|
283
|
-
{%- else %}
|
|
284
|
-
| ID | Kind | Item | {{ t("implementationPlanning.columnImpact") }} | {{ t("implementationPlanning.columnMitigation") }} |
|
|
285
|
-
|----|------|------|------|------------------|
|
|
286
|
-
{% for row in implementationPlanning.dependencyMigrationRisk -%}
|
|
287
|
-
| {{ row.id | mdcell }} | {{ row.kind | mdcell }} | {{ row.item | mdcell }} | {{ row.impact | mdcell }} | {{ row.mitigation | mdcell }} |
|
|
288
|
-
{% endfor %}
|
|
289
|
-
{%- endif %}
|
|
290
|
-
|
|
291
|
-
### Cross-Project Dependencies{% if t("sectionAside.crossProjectDependencies") != "Cross-Project Dependencies" %} ({{ t("sectionAside.crossProjectDependencies") }}){% endif %}
|
|
292
|
-
|
|
293
|
-
{% if implementationPlanning.crossProjectDependencies | length == 0 -%}
|
|
294
|
-
{{ t("emptyState.crossProjectDependencies") }}
|
|
295
|
-
{%- else %}
|
|
296
|
-
{% for xp in implementationPlanning.crossProjectDependencies %}
|
|
297
|
-
**{{ xp.id }} — [{{ xp.direction }}] {{ xp.project }}**
|
|
298
|
-
|
|
299
|
-
- {{ t("implementationPlanning.crossProjectFields.requiredWork") }}: {{ xp.requiredWork }}
|
|
300
|
-
- {{ t("implementationPlanning.crossProjectFields.verificationSignal") }}: {{ xp.verificationSignal }}
|
|
301
|
-
- {{ t("implementationPlanning.crossProjectFields.linkedWork") }}: {{ xp.linkedWork }}
|
|
302
|
-
- {{ t("implementationPlanning.crossProjectFields.howToStart") }}: {{ xp.howToStart }}
|
|
303
|
-
{% endfor %}
|
|
304
|
-
{{ t("implementationPlanning.crossProjectRecognitionNote") }}
|
|
305
|
-
{%- endif %}
|
|
306
|
-
|
|
307
|
-
### Validation Checklist{% if t("sectionAside.validationChecklist") != "Validation Checklist" %} ({{ t("sectionAside.validationChecklist") }}){% endif %}
|
|
308
|
-
|
|
309
|
-
| {{ t("columns.recordMeta") }} | Check | Command / Observation | Expected outcome |
|
|
310
|
-
|--------|-------|------------------------|-------------------|
|
|
311
|
-
{% for row in implementationPlanning.validationChecklist -%}
|
|
312
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>Phase: {{ row.phase | mdcell }} | {{ row.check | mdcell }} | `{{ row.commandOrObservation | mdcell }}` | {{ row.expectedOutcome | mdcell }} |
|
|
313
|
-
{% endfor %}
|
|
314
|
-
|
|
315
|
-
### Rollback Strategy{% if t("sectionAside.rollbackStrategy") != "Rollback Strategy" %} ({{ t("sectionAside.rollbackStrategy") }}){% endif %}
|
|
316
|
-
|
|
317
|
-
| ID | Step | Action | Trigger signal | {{ t("columns.checkMethod") }} |
|
|
318
|
-
|----|------|--------|----------------|-----------|
|
|
319
|
-
{% for row in implementationPlanning.rollbackStrategy -%}
|
|
320
|
-
| {{ row.id | mdcell }} | {{ row.step | mdcell }} | `{{ row.action | mdcell }}` | {{ row.triggerSignal | mdcell }} | `{{ row.verificationMethod | mdcell }}` |
|
|
321
|
-
{% endfor %}
|
|
322
|
-
|
|
323
|
-
### Requirement Coverage
|
|
324
|
-
|
|
325
|
-
| ID | Source | Requirement | Covered by option / stage / step | Status |
|
|
326
|
-
|----|--------|-------------|-----------------------------------|--------|
|
|
327
|
-
{% for row in implementationPlanning.requirementCoverage -%}
|
|
328
|
-
| {{ row.id | mdcell }} | `{{ row.source | mdcell }}` | {{ row.requirement | mdcell }} | {{ row.coveredBy | mdcell }} | `{% if row.status == "documented-deviation" %}documented-deviation — refs: {{ (row.decisionRefs | join(", ")) | mdcell }}; approval: {{ row.approvalDisposition | mdcell }}{% else %}{{ row.status | mdcell }}{% endif %}` |
|
|
329
|
-
{% endfor %}
|
|
330
|
-
|
|
331
|
-
### Decision Drafts{% if t("sectionAside.decisionDrafts") != "Decision Drafts" %} ({{ t("sectionAside.decisionDrafts") }}){% endif %}
|
|
332
|
-
|
|
333
|
-
{% if (implementationPlanning.decisionDrafts | length == 0) and (implementationPlanning.skippedAdrCandidates | length == 0) -%}
|
|
334
|
-
{{ t("emptyState.decisionDrafts") }}
|
|
335
|
-
{%- else %}
|
|
336
|
-
{% for d in implementationPlanning.decisionDrafts %}
|
|
337
|
-
#### {{ d.number }}-{{ d.slug }}
|
|
338
|
-
|
|
339
|
-
- **{{ t("implementationPlanning.decisionDraftFields.status") }}:** {{ d.status }}
|
|
340
|
-
- **{{ t("implementationPlanning.decisionDraftFields.context") }}:** {{ d.context }}
|
|
341
|
-
- **{{ t("implementationPlanning.decisionDraftFields.decision") }}:** {{ d.decision }}
|
|
342
|
-
- **{{ t("implementationPlanning.decisionDraftFields.consequences") }}:** {{ d.consequences }}
|
|
343
|
-
- **{{ t("implementationPlanning.decisionDraftFields.alternativesConsidered") }}:** {{ d.alternativesConsidered }}
|
|
344
|
-
{% endfor %}
|
|
345
|
-
{% for s in implementationPlanning.skippedAdrCandidates %}
|
|
346
|
-
- skipped adr-candidate: {{ s.topic }} — reason: {{ s.reason }}
|
|
347
|
-
{% endfor %}
|
|
348
|
-
{%- endif %}
|
|
349
|
-
|
|
350
|
-
## 5.5 Stage Map
|
|
351
|
-
|
|
352
|
-
| stage | title | depends-on | step-count | exit-contract-summary |
|
|
353
|
-
|-------|-------|------------|------------|-----------------------|
|
|
354
|
-
{% for row in implementationPlanning.stageMap -%}
|
|
355
|
-
| {{ row.stage | mdcell }} | {{ row.title | mdcell }} | {{ row.dependsOn | mdcell }} | {{ row.stepCount | mdcell }} | {{ row.exitContractSummary | mdcell }} |
|
|
356
|
-
{% endfor %}
|
|
357
|
-
|
|
358
|
-
{% for stage in implementationPlanning.stages %}
|
|
359
|
-
## 5.5.{{ stage.stage }} Stage {{ stage.stage }}: {{ stage.title }}
|
|
360
|
-
|
|
361
|
-
- **Slice value:** {{ stage.sliceValue }}
|
|
362
|
-
- **Acceptance:** {{ stage.acceptance }}
|
|
363
|
-
{% if not stage.tddExemption %}
|
|
364
|
-
- **Test case (success):** {{ stage.testCaseSuccess }}
|
|
365
|
-
- **Test case (boundary):** {{ stage.testCaseBoundary }}
|
|
366
|
-
- **Test case (failure):** {{ stage.testCaseFailure }}
|
|
367
|
-
{% endif %}
|
|
368
|
-
{% if stage.conformanceTests %}
|
|
369
|
-
- **Conformance tests:** stage-{{ stage.stage }} — {{ stage.conformanceTests }}
|
|
370
|
-
{% else %}
|
|
371
|
-
- **Conformance exemption:** {{ stage.conformanceExemption }}
|
|
372
|
-
{% endif %}
|
|
373
|
-
{% if stage.tddExemption %}
|
|
374
|
-
- **TDD exemption:** {{ stage.tddExemption }}
|
|
375
|
-
{% endif %}
|
|
376
|
-
|
|
377
|
-
### Carry-In
|
|
378
|
-
|
|
379
|
-
{{ stage.carryIn }}
|
|
380
|
-
|
|
381
|
-
### Stepwise Execution Order
|
|
382
|
-
|
|
383
|
-
| step | action | files | command | outcome | expected |
|
|
384
|
-
|------|--------|-------|---------|---------|----------|
|
|
385
|
-
{% for row in stage.stepwiseExecution -%}
|
|
386
|
-
| {{ row.step | mdcell }} | {{ row.action | mdcell }} | `{{ row.files | mdcell }}` | `{{ row.command | mdcell }}` | {{ row.outcome | mdcell }} | {{ row.expectedDetail | mdcell }} |
|
|
387
|
-
{% endfor %}
|
|
388
|
-
|
|
389
|
-
### Stage Exit Contract
|
|
390
|
-
|
|
391
|
-
{{ stage.exitContract }}
|
|
392
|
-
|
|
393
|
-
### Stage Validation
|
|
394
|
-
|
|
395
|
-
{{ stage.stageValidation }}
|
|
396
|
-
|
|
397
|
-
{% endfor %}
|
|
398
|
-
|
|
399
|
-
### 5.5.9 Plan Body Verification{% if t("sectionAside.planBodyVerification") != "Plan Body Verification" %} ({{ t("sectionAside.planBodyVerification") }}){% endif %}
|
|
400
|
-
|
|
401
|
-
{{ t("sectionIntro.planBodyVerification") }}
|
|
402
|
-
|
|
403
|
-
- **Round count**: `{{ implementationPlanning.planBodyVerification.roundCount }}`
|
|
404
|
-
- **Gate result**: `{{ implementationPlanning.planBodyVerification.gateResult }}`
|
|
405
|
-
{% if implementationPlanning.planBodyVerification.participatingAnalysers %}- **Participating analysers**: `{{ implementationPlanning.planBodyVerification.participatingAnalysers.voting }}` / `{{ implementationPlanning.planBodyVerification.participatingAnalysers.rostered }}`
|
|
406
|
-
{% endif %}
|
|
407
|
-
{% if implementationPlanning.planBodyVerification.gateBlockedBy %}- **Blocked by**: {% for cause in implementationPlanning.planBodyVerification.gateBlockedBy %}`{{ cause }}`{% if not loop.last %}, {% endif %}{% endfor %}
|
|
408
|
-
{% endif %}
|
|
409
|
-
{% if implementationPlanning.planBodyVerification.uniformVerifiers %}- **{{ t("implementationPlanning.planBodyUniformVerifierLabel") }}**: {% for u in implementationPlanning.planBodyVerification.uniformVerifiers %}`{{ u.worker }}` → `{{ u.verdict }}` ({{ u.itemCount }}){% if not loop.last %}, {% endif %}{% endfor %}
|
|
410
|
-
|
|
411
|
-
> {{ t("implementationPlanning.planBodyUniformVerifierLegend") }}
|
|
412
|
-
{% endif %}
|
|
413
|
-
> {{ t("implementationPlanning.planBodyGateLegend") }}
|
|
414
|
-
>
|
|
415
|
-
> {{ t("implementationPlanning.planBodyBlockedByLegend") }}
|
|
416
|
-
|
|
417
|
-
#### Verdict details
|
|
418
|
-
|
|
419
|
-
{{ t("implementationPlanning.planBodyVerdictLegend") }}
|
|
420
|
-
|
|
421
|
-
{{ t("implementationPlanning.planBodyBreakageLegend") }}
|
|
422
|
-
|
|
423
|
-
{% for item in implementationPlanning.planBodyVerification.planItems %}
|
|
424
|
-
**{{ item.id }} — {{ item.subject }}**{% if item.sourceSection %} ({{ t("implementationPlanning.planBodySourceLabel") }} {{ item.sourceSection }}){% endif %}{% if item.clarificationId %} — {{ t("implementationPlanning.planBodyBlockerLabel") }} {{ item.clarificationId }}{% endif %}{% if item.selfFixNote %} — {{ item.selfFixNote }}{% endif %}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
| Worker | Verdict | Breakage kind | Fixability | Note |
|
|
428
|
-
|--------|---------|---------------|------------|------|
|
|
429
|
-
{% for v in item.verdicts %}| {{ v.worker | mdcell }} | {{ v.verdict | mdcell }} | {{ (v.breakageKind or '--') | mdcell }} | {{ (v.fixability or '--') | mdcell }} | {{ (v.note or '') | mdcell }} |
|
|
430
|
-
{% endfor %}
|
|
431
|
-
|
|
432
|
-
{% endfor %}
|
|
433
|
-
#### Dissent log
|
|
434
|
-
|
|
435
|
-
{% if implementationPlanning.planBodyVerification.dissentLog | length == 0 -%}
|
|
436
|
-
{{ t("emptyState.dissent") }}
|
|
437
|
-
{%- else %}
|
|
438
|
-
{% for row in implementationPlanning.planBodyVerification.dissentLog -%}
|
|
439
|
-
- **{{ row.planItem }}**: `{{ row.workerRole }}` — {{ row.body }}
|
|
440
|
-
{% endfor %}
|
|
441
|
-
{%- endif %}
|
|
442
|
-
|
|
443
|
-
### 5.5.10 Implementation Design Preparation{% if t("implementationPlanning.designPreparation.heading") != "Implementation Design Preparation" %} ({{ t("implementationPlanning.designPreparation.heading") }}){% endif %}
|
|
444
|
-
|
|
445
|
-
- **{{ t("implementationPlanning.designPreparation.mode") }}:** `{{ implementationPlanning.designPreparation.mode }}`
|
|
446
|
-
- **{{ t("implementationPlanning.designPreparation.reason") }}:** {{ implementationPlanning.designPreparation.reason }}
|
|
447
|
-
|
|
448
|
-
{% if implementationPlanning.designPreparation["items"] | length == 0 -%}
|
|
449
|
-
{{ t("implementationPlanning.designPreparation.empty") }}
|
|
450
|
-
{%- else %}
|
|
451
|
-
{% for item in implementationPlanning.designPreparation["items"] %}
|
|
452
|
-
#### {{ item.id }} — {{ item.title }}
|
|
453
|
-
|
|
454
|
-
- **{{ t("implementationPlanning.designPreparation.kind") }}:** `{{ item.kind }}`
|
|
455
|
-
- **{{ t("implementationPlanning.designPreparation.status") }}:** `{{ item.status }}`
|
|
456
|
-
- **{{ t("implementationPlanning.designPreparation.stages") }}:** {{ item.stageRefs | join(", ") }}
|
|
457
|
-
- **{{ t("implementationPlanning.designPreparation.need") }}:** {{ item.need }}
|
|
458
|
-
{% if item.knownFacts %}
|
|
459
|
-
- **{{ t("implementationPlanning.designPreparation.knownFacts") }}:**
|
|
460
|
-
{% for fact in item.knownFacts %}
|
|
461
|
-
- {{ fact.statement }} — {{ fact.evidence }}
|
|
462
|
-
{% endfor %}
|
|
463
|
-
{% endif %}
|
|
464
|
-
{% if item.openQuestions %}
|
|
465
|
-
- **{{ t("implementationPlanning.designPreparation.openQuestions") }}:** {{ item.openQuestions | join("; ") }}
|
|
466
|
-
{% endif %}
|
|
467
|
-
- **{{ t("implementationPlanning.designPreparation.aiProposal") }}:** {{ item.aiProposal.summary }}
|
|
468
|
-
- **{{ t("implementationPlanning.designPreparation.proposalDetails") }}:** {{ item.aiProposal.details | join("; ") or t("implementationPlanning.designPreparation.none") }}
|
|
469
|
-
- **{{ t("implementationPlanning.designPreparation.proposalAssumptions") }}:** {{ item.aiProposal.assumptions | join("; ") or t("implementationPlanning.designPreparation.none") }}
|
|
470
|
-
- **{{ t("implementationPlanning.designPreparation.proposalEvidence") }}:** {{ item.aiProposal.evidence | join("; ") or t("implementationPlanning.designPreparation.none") }}
|
|
471
|
-
- **{{ t("implementationPlanning.designPreparation.proposalConfidence") }}:** `{{ item.aiProposal.confidence }}`
|
|
472
|
-
- **{{ t("implementationPlanning.designPreparation.humanConfirmation") }}:**
|
|
473
|
-
- **{{ t("implementationPlanning.designPreparation.confirmationRequired") }}:** `{% if item.humanConfirmation.required %}yes{% else %}no{% endif %}`
|
|
474
|
-
- **{{ t("implementationPlanning.designPreparation.confirmationReason") }}:** {{ item.humanConfirmation.reason }}
|
|
475
|
-
- **{{ t("implementationPlanning.designPreparation.suggestedAction") }}:** {{ item.humanConfirmation.suggestedAction }}
|
|
476
|
-
{% if item.replanTriggerFields %}
|
|
477
|
-
- **{{ t("implementationPlanning.designPreparation.replanTriggerFields") }}:** `{{ item.replanTriggerFields | join("`, `") }}`
|
|
478
|
-
{% endif %}
|
|
479
|
-
{% if item.workingAssumption %}
|
|
480
|
-
- **{{ t("implementationPlanning.designPreparation.workingAssumption") }}:** {{ item.workingAssumption }}
|
|
481
|
-
{% endif %}
|
|
482
|
-
{% if item.guardrails %}
|
|
483
|
-
- **{{ t("implementationPlanning.designPreparation.guardrails") }}:** {{ item.guardrails | join("; ") }}
|
|
484
|
-
{% endif %}
|
|
485
|
-
{% if item.reviewAt %}
|
|
486
|
-
{% if item.reviewAt.stage %}
|
|
487
|
-
- **{{ t("implementationPlanning.designPreparation.reviewAt") }}:** {{ item.reviewAt.phase }} — stage {{ item.reviewAt.stage }}
|
|
488
|
-
{% else %}
|
|
489
|
-
- **{{ t("implementationPlanning.designPreparation.reviewAt") }}:** {{ item.reviewAt.phase }}
|
|
490
|
-
{% endif %}
|
|
491
|
-
{% endif %}
|
|
492
|
-
{% if item.ifStillOpen %}
|
|
493
|
-
- **{{ t("implementationPlanning.designPreparation.ifStillOpen") }}:** `{{ item.ifStillOpen }}`
|
|
494
|
-
{% endif %}
|
|
495
|
-
{% if item.requestPath %}
|
|
496
|
-
- **{{ t("implementationPlanning.designPreparation.requestPath") }}:** `{{ item.requestPath }}`
|
|
497
|
-
{% endif %}
|
|
498
|
-
{% if item.blockReason %}
|
|
499
|
-
- **{{ t("implementationPlanning.designPreparation.blockReason") }}:** {{ item.blockReason }}
|
|
500
|
-
{% endif %}
|
|
501
|
-
{% if item.requiredDecision %}
|
|
502
|
-
- **{{ t("implementationPlanning.designPreparation.requiredDecision") }}:** {{ item.requiredDecision }}
|
|
503
|
-
{% endif %}
|
|
504
|
-
{% if item.notApplicableReason %}
|
|
505
|
-
- **{{ t("implementationPlanning.designPreparation.notApplicableReason") }}:** {{ item.notApplicableReason }}
|
|
506
|
-
{% endif %}
|
|
507
|
-
{% endfor %}
|
|
508
|
-
{%- endif %}
|
|
509
|
-
|
|
510
|
-
### 5.5.11 Variation-Point Analysis{% if t("implementationPlanning.variationPointAnalysis.heading") != "Variation-Point Analysis" %} ({{ t("implementationPlanning.variationPointAnalysis.heading") }}){% endif %}
|
|
511
|
-
|
|
512
|
-
- **{{ t("implementationPlanning.variationPointAnalysis.hasMultiple") }}:** `{% if implementationPlanning.variationPointAnalysis.hasMultipleImplementations %}yes{% else %}no{% endif %}`
|
|
513
|
-
|
|
514
|
-
{% if not implementationPlanning.variationPointAnalysis.hasMultipleImplementations -%}
|
|
515
|
-
- **{{ t("implementationPlanning.variationPointAnalysis.rationale") }}:** {{ implementationPlanning.variationPointAnalysis.noVariationRationale }}
|
|
516
|
-
{% else %}
|
|
517
|
-
{% for point in implementationPlanning.variationPointAnalysis["points"] %}
|
|
518
|
-
- **{{ t("implementationPlanning.variationPointAnalysis.behavior") }}:** {{ point.behavior }}
|
|
519
|
-
- **{{ t("implementationPlanning.variationPointAnalysis.implementations") }}:** {{ point.implementations | join(", ") }}
|
|
520
|
-
- **{{ t("implementationPlanning.variationPointAnalysis.evidence") }}:** {{ point.evidence }}
|
|
521
|
-
- **{{ t("implementationPlanning.variationPointAnalysis.extract") }}:** `{% if point.extractionDecision.extract %}yes{% else %}no{% endif %}` — {{ point.extractionDecision.interfaceKind }} ({{ point.extractionDecision.coveredBy }}) — {{ point.extractionDecision.rationale }}
|
|
522
|
-
{% endfor %}
|
|
523
|
-
{% endif %}
|
|
524
|
-
|
|
525
|
-
**{{ t("implementationPlanning.variationPointAnalysis.testSeams") }}:**
|
|
526
|
-
|
|
527
|
-
{% if implementationPlanning.recommendedOption["testSeams"] | length == 0 -%}
|
|
528
|
-
{{ t("implementationPlanning.variationPointAnalysis.seamEmpty") }}
|
|
529
|
-
{% else %}
|
|
530
|
-
{% for seam in implementationPlanning.recommendedOption["testSeams"] -%}
|
|
531
|
-
- {{ seam.boundary }} — {{ seam.injectedAs }} → {{ seam.replacedInTest }}
|
|
532
|
-
{% endfor %}
|
|
533
|
-
{% endif %}
|
|
534
|
-
|
|
535
|
-
{% endif %}
|
|
536
|
-
{% if header.taskType == 'release-handoff' %}
|
|
537
|
-
## 5.6 Release Handoff Deliverables
|
|
538
|
-
|
|
539
|
-
{{ t("releaseHandoff.auditNote") }}
|
|
540
|
-
|
|
541
|
-
{% if releaseHandoff.handoffScope %}
|
|
542
|
-
### 5.6.0 Handoff Scope
|
|
543
|
-
|
|
544
|
-
- Mode: `{{ releaseHandoff.handoffScope.mode | mdcell }}`
|
|
545
|
-
{% if releaseHandoff.handoffScope.stages %}- Stages: {{ releaseHandoff.handoffScope.stages | join(', ') | mdcell }}
|
|
546
|
-
{% endif %}{% if releaseHandoff.handoffScope.collectorBranch %}- Collector branch: `{{ releaseHandoff.handoffScope.collectorBranch | mdcell }}`
|
|
547
|
-
{% endif %}{% if releaseHandoff.handoffScope.mergeCommits %}- Assemble merge commits: {{ releaseHandoff.handoffScope.mergeCommits | join(', ') | mdcell }}
|
|
548
|
-
{% endif %}{% if releaseHandoff.handoffScope.dependencyClosureVerdict %}- Dependency closure: {{ releaseHandoff.handoffScope.dependencyClosureVerdict | mdcell }}
|
|
549
|
-
{% endif %}
|
|
550
|
-
{% endif %}
|
|
551
|
-
### 5.6.1 Source Verification Report
|
|
552
|
-
{% if releaseHandoff.sourceVerificationReports %}
|
|
553
|
-
| Stage | Report path (project-relative) | Quoted `Verdict Token` row |
|
|
554
|
-
|-------|--------------------------------|----------------------------|
|
|
555
|
-
{% for row in releaseHandoff.sourceVerificationReports -%}
|
|
556
|
-
| {{ row.stage | mdcell }} | `{{ row.path | mdcell }}` | {{ row.verdictTokenQuote | mdcell }} |
|
|
557
|
-
{% endfor %}
|
|
558
|
-
{%- else %}
|
|
559
|
-
- Path (project-relative): `{{ releaseHandoff.sourceVerificationReport.path }}`
|
|
560
|
-
- Quoted `Verdict Token` row from that report's `## 7.` table:
|
|
561
|
-
> {{ releaseHandoff.sourceVerificationReport.verdictTokenQuote | mdquote(2) }}
|
|
562
|
-
{% endif %}
|
|
563
|
-
|
|
564
|
-
### 5.6.2 Feature Branch & Working-Tree State{% if t("releaseHandoff.branchStateAside") != "captured at run start" %} ({{ t("releaseHandoff.branchStateAside") }}){% endif %}
|
|
565
|
-
|
|
566
|
-
- Feature branch: `{{ releaseHandoff.featureBranchState.branchName }}`
|
|
567
|
-
- {{ t("releaseHandoff.gitStatusShortLabel") }}:
|
|
568
|
-
```
|
|
569
|
-
{{ releaseHandoff.featureBranchState.gitStatusShort | indent(2) }}
|
|
570
|
-
```
|
|
571
|
-
- {{ t("releaseHandoff.existingPrLabel") }}: `{{ releaseHandoff.featureBranchState.existingPrUrl or '(none)' }}`
|
|
572
|
-
|
|
573
|
-
### 5.6.3 User Selections{% if t("releaseHandoff.userSelectionsAside") != "menu response log" %} ({{ t("releaseHandoff.userSelectionsAside") }}){% endif %}
|
|
574
|
-
|
|
575
|
-
| {{ t("releaseHandoff.questionsTableHeader.questionId") }} | {{ t("releaseHandoff.questionsTableHeader.questionBody") }} | {{ t("releaseHandoff.questionsTableHeader.userResponse") }} | {{ t("releaseHandoff.questionsTableHeader.allowedOptions") }} |
|
|
576
|
-
|---------|-----------|--------------------|--------------------|
|
|
577
|
-
| H1 | {{ t("releaseHandoff.h1Body") }} | `{{ releaseHandoff.userSelections.h1 | mdcell }}` | `local checkout` / `push + PR` / `skip` |
|
|
578
|
-
{% if releaseHandoff.userSelections.h1c %}
|
|
579
|
-
| H1c | Local checkout target | `{{ releaseHandoff.userSelections.h1c | mdcell }}` | `whole-task branch` / `stage <N> stack branch` |
|
|
580
|
-
{% endif %}
|
|
581
|
-
| H2 | {{ t("releaseHandoff.h2Body") }} | `{{ (releaseHandoff.userSelections.h2 or t("releaseHandoff.h2DefaultLabel")) | mdcell }}` | {{ t("releaseHandoff.h2OptionsLabel") }} |
|
|
582
|
-
| H2b | Merge conflict probe | `{{ (releaseHandoff.userSelections.h2b or releaseHandoff.mergeConflictProbe.kind) | mdcell }}` | `not-run` / `clean` / `proceed anyway` / `change base branch` / `cancel` |
|
|
583
|
-
| H3 | {{ t("releaseHandoff.h3Body") }} | `{{ releaseHandoff.userSelections.h3 | mdcell }}` | `not-run` / `use as-is` / `edit then proceed` / `cancel` |
|
|
584
|
-
|
|
585
|
-
### 5.6.4 Executed Commands
|
|
586
|
-
|
|
587
|
-
{% if releaseHandoff.executedCommands | length == 0 -%}
|
|
588
|
-
- {{ t("releaseHandoff.noMutationNote") }}
|
|
589
|
-
{%- else %}
|
|
590
|
-
| # | command (verbatim) | exit code | {{ t("releaseHandoff.commandsTableHeader.outputSummary") }} |
|
|
591
|
-
|---|---------------------|-----------|--------------------|
|
|
592
|
-
{% for row in releaseHandoff.executedCommands -%}
|
|
593
|
-
| {{ row.number | mdcell }} | `{{ row.command | mdcell }}` | `{{ row.exitCode | mdcell }}` | {{ row.outputSummary | mdcell }} |
|
|
594
|
-
{% endfor %}
|
|
595
|
-
{%- endif %}
|
|
596
|
-
|
|
597
|
-
### 5.6.5 Commit List
|
|
598
|
-
|
|
599
|
-
{% if releaseHandoff.commitList.empty -%}
|
|
600
|
-
- No implementation commits found; release-handoff is blocked.
|
|
601
|
-
{%- else %}
|
|
602
|
-
| Short SHA | Full SHA | Subject | Files |
|
|
603
|
-
|-----------|----------|---------|-------|
|
|
604
|
-
{% for row in releaseHandoff.commitList -%}
|
|
605
|
-
| `{{ row.shortSha | mdcell }}` | `{{ row.fullSha | mdcell }}` | {{ row.subject | mdcell }} | {{ row.files | mdcell }} |
|
|
606
|
-
{% endfor %}
|
|
607
|
-
{%- endif %}
|
|
608
|
-
|
|
609
|
-
### 5.6.6 Merge Conflict Probe
|
|
610
|
-
|
|
611
|
-
{% if releaseHandoff.mergeConflictProbe.kind == 'not-run' -%}
|
|
612
|
-
- Not run (user picked local checkout or skip).
|
|
613
|
-
{%- elif releaseHandoff.mergeConflictProbe.kind == 'clean' -%}
|
|
614
|
-
- Clean — no conflicts against {{ releaseHandoff.mergeConflictProbe.baseBranch }} at {{ releaseHandoff.mergeConflictProbe.baseSha }}.
|
|
615
|
-
{%- else -%}
|
|
616
|
-
- Conflicts detected against {{ releaseHandoff.mergeConflictProbe.baseBranch }} at {{ releaseHandoff.mergeConflictProbe.baseSha }}; user chose {{ releaseHandoff.mergeConflictProbe.userChoice }}. Conflicting paths: {{ releaseHandoff.mergeConflictProbe.conflictingPaths | join(', ') }}.
|
|
617
|
-
{%- endif %}
|
|
618
|
-
|
|
619
|
-
### 5.6.7 Pull Request Outcome
|
|
620
|
-
|
|
621
|
-
{% if releaseHandoff.pullRequestOutcome.kind == 'no-action' -%}
|
|
622
|
-
- No PR action requested.
|
|
623
|
-
{%- elif releaseHandoff.pullRequestOutcome.kind == 'created' -%}
|
|
624
|
-
- PR created: {{ releaseHandoff.pullRequestOutcome.url }} — title: {{ releaseHandoff.pullRequestOutcome.title }} (base: {{ releaseHandoff.pullRequestOutcome.baseBranch }})
|
|
625
|
-
{%- elif releaseHandoff.pullRequestOutcome.kind == 'reused' -%}
|
|
626
|
-
- PR reused: {{ releaseHandoff.pullRequestOutcome.url }}
|
|
627
|
-
{%- else -%}
|
|
628
|
-
- PR creation skipped: {{ releaseHandoff.pullRequestOutcome.reason }}
|
|
629
|
-
{%- endif %}
|
|
630
|
-
|
|
631
|
-
### 5.6.8 Routing Recommendation
|
|
632
|
-
|
|
633
|
-
{{ releaseHandoff.routingRecommendation }}
|
|
634
|
-
|
|
635
|
-
### 5.6.9 Local Checkout Outcome
|
|
636
|
-
|
|
637
|
-
- Status: `{{ releaseHandoff.localCheckoutOutcome.status | mdcell }}`
|
|
638
|
-
{% if releaseHandoff.localCheckoutOutcome.status == 'checked-out' %}- Checked out `{{ releaseHandoff.localCheckoutOutcome.branch | mdcell }}` into `{{ releaseHandoff.localCheckoutOutcome.mainWorktreePath | mdcell }}`
|
|
639
|
-
- okstra worktree: {% if releaseHandoff.localCheckoutOutcome.removedWorktree %}`{{ releaseHandoff.localCheckoutOutcome.removedWorktree | mdcell }}` removed{% else %}none removed — already torn down, so the branch survived{% endif %}
|
|
640
|
-
{% endif %}
|
|
641
|
-
{% endif %}
|
|
642
|
-
{% if header.taskType == 'implementation' %}
|
|
643
|
-
## 5.7 Implementation Deliverables
|
|
644
|
-
|
|
645
|
-
### 5.7.1 Approved Plan Reference
|
|
646
|
-
|
|
647
|
-
- Plan file (project-relative): `{{ implementation.approvedPlanReference.planFile }}`
|
|
648
|
-
- Approval evidence:
|
|
649
|
-
> {{ implementation.approvedPlanReference.approvalEvidence | mdquote(2) }}
|
|
650
|
-
- {{ t("executionMeta.runExecutorWorktreePath") }}: `{{ implementation.approvedPlanReference.executorWorktreePath }}`
|
|
651
|
-
- {{ t("executionMeta.runBaseRef") }}: `{{ implementation.approvedPlanReference.baseRefSha }}`
|
|
652
|
-
|
|
653
|
-
### 5.7.2 Commit List
|
|
654
|
-
|
|
655
|
-
{% if implementation.commitList | length == 0 -%}
|
|
656
|
-
- No implementation commits produced; routing recommendation must be back to implementation-planning.
|
|
657
|
-
{%- else %}
|
|
658
|
-
| # | Short SHA | Full SHA | Plan Step | Subject | Files |
|
|
659
|
-
|---|-----------|----------|-----------|---------|-------|
|
|
660
|
-
{% for row in implementation.commitList -%}
|
|
661
|
-
| {{ row.number | mdcell }} | `{{ row.shortSha | mdcell }}` | `{{ row.fullSha | mdcell }}` | {{ row.planStep | mdcell }} | {{ row.subject | mdcell }} | {{ row.files | mdcell }} |
|
|
662
|
-
{% endfor %}
|
|
663
|
-
{%- endif %}
|
|
664
|
-
|
|
665
|
-
### 5.7.3 Diff Summary
|
|
666
|
-
|
|
667
|
-
```
|
|
668
|
-
{{ implementation.diffSummary.rawStat }}
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
| File | Action | Lines (+/-) | Plan step / Out-of-plan |
|
|
672
|
-
|------|--------|-------------|--------------------------|
|
|
673
|
-
{% for row in implementation.diffSummary.files -%}
|
|
674
|
-
| `{{ row.file | mdcell }}` | {{ row.action | mdcell }} | `{{ row.lines | mdcell }}` | {{ row.planStep | mdcell }} |
|
|
675
|
-
{% endfor %}
|
|
676
|
-
|
|
677
|
-
### 5.7.4 Out-of-plan Edits
|
|
678
|
-
|
|
679
|
-
{% if implementation.outOfPlanEdits | length == 0 -%}
|
|
680
|
-
{{ t("emptyState.outOfPlanEdits") }}
|
|
681
|
-
{%- else %}
|
|
682
|
-
| ID | File | Rationale | Trigger |
|
|
683
|
-
|----|------|-----------|---------|
|
|
684
|
-
{% for row in implementation.outOfPlanEdits -%}
|
|
685
|
-
| {{ row.id | mdcell }} | `{{ row.file | mdcell }}` | {{ row.rationale | mdcell }} | {{ row.trigger | mdcell }} |
|
|
686
|
-
{% endfor %}
|
|
687
|
-
{%- endif %}
|
|
688
|
-
|
|
689
|
-
### 5.7.5 Stage Sidecar Evidence
|
|
690
|
-
|
|
691
|
-
- Stage: `{{ implementation.stageSidecarEvidence.stageNumber }}` — {{ implementation.stageSidecarEvidence.stageTitle }}
|
|
692
|
-
{% if implementation.stageSidecarEvidence.withheld -%}
|
|
693
|
-
- Carry sidecar **withheld** — not written to `carry/stage-{{ implementation.stageSidecarEvidence.stageNumber }}.json`: {{ implementation.stageSidecarEvidence.withheld }}
|
|
694
|
-
{% endif -%}
|
|
695
|
-
- Carry sidecar JSON:
|
|
696
|
-
```json
|
|
697
|
-
{{ implementation.stageSidecarEvidence.carryJson | indent(2) }}
|
|
698
|
-
```
|
|
699
|
-
- Appended `consumers.jsonl` rows:
|
|
700
|
-
{% for row in implementation.stageSidecarEvidence.consumerRows -%}
|
|
701
|
-
> {{ row | mdquote(2) }}
|
|
702
|
-
{% endfor %}
|
|
703
|
-
|
|
704
|
-
### 5.7.6 Validation Evidence
|
|
705
|
-
|
|
706
|
-
| Phase | Command | Exit code | Output tail | TDD evidence |
|
|
707
|
-
|-------|---------|-----------|-------------|--------------|
|
|
708
|
-
{% for row in implementation.validationEvidence -%}
|
|
709
|
-
| {{ row.phase | mdcell }} | `{{ row.command | mdcell }}` | `{{ row.exitCode | mdcell }}` | {{ row.outputTail | mdcell }} | {{ (row.tddEvidence or '--') | mdcell }} |
|
|
710
|
-
{% endfor %}
|
|
711
|
-
|
|
712
|
-
### 5.7.7 Verifier Results
|
|
713
|
-
|
|
714
|
-
{% for block in implementation.verifierResults %}
|
|
715
|
-
- **{{ block.verifier }}** — Verdict: `{{ block.verdict }}`
|
|
716
|
-
- Read-only command log: {{ block.readOnlyCommandLog }}
|
|
717
|
-
- Independent validation re-run: {{ block.independentValidationRerun }}
|
|
718
|
-
- Style / lint / type-check: {{ block.styleLintTypecheck or '--' }}
|
|
719
|
-
- Declined fix recommendations: {{ block.declinedFixRecommendations or t("emptyState.declinedFixRecommendations") }}
|
|
720
|
-
- Discrepancy: {{ block.discrepancy or t("emptyState.discrepancy") }}
|
|
721
|
-
{% endfor %}
|
|
722
|
-
|
|
723
|
-
### 5.7.8 Rollback Verification
|
|
724
|
-
|
|
725
|
-
| Category | Rollback command | Verification | Result |
|
|
726
|
-
|----------|-------------------|---------------|--------|
|
|
727
|
-
{% for row in implementation.rollbackVerification -%}
|
|
728
|
-
| {{ row.category | mdcell }} | `{{ row.rollbackCommand | mdcell }}` | {{ row.verification | mdcell }} | `{{ row.result | mdcell }}` |
|
|
729
|
-
{% endfor %}
|
|
730
|
-
|
|
731
|
-
### 5.7.9 Manual User Test (Draft)
|
|
732
|
-
|
|
733
|
-
{% if implementation.manualUserTest.applicable -%}
|
|
734
|
-
{% for item in implementation.manualUserTest.items %}
|
|
735
|
-
- **{{ item.target }}**
|
|
736
|
-
- {{ t("manualUserTest.environmentSetup") }}: {{ item.environmentSetup }}
|
|
737
|
-
- {{ t("manualUserTest.steps") }}:
|
|
738
|
-
{% for step in item.steps %} {{ loop.index }}. {{ step }}
|
|
739
|
-
{% endfor %} - {{ t("manualUserTest.expectedResult") }}: {{ item.expectedResult }}
|
|
740
|
-
{% endfor %}
|
|
741
|
-
{%- else -%}
|
|
742
|
-
- {{ t("manualUserTest.notApplicable") }}: {{ implementation.manualUserTest.exemptionReason }}
|
|
743
|
-
{%- endif %}
|
|
744
|
-
|
|
745
|
-
### 5.7.10 Routing Recommendation
|
|
746
|
-
|
|
747
|
-
{{ implementation.routingRecommendation }}
|
|
748
|
-
|
|
749
|
-
{% endif %}
|
|
750
|
-
{% if header.taskType == 'final-verification' %}
|
|
751
|
-
## 5.8 Final Verification Deliverables
|
|
752
|
-
|
|
753
|
-
### 5.8.1 Source Implementation Report
|
|
754
|
-
|
|
755
|
-
- Path (project-relative): `{{ finalVerification.sourceImplementationReport.path }}`
|
|
756
|
-
- {{ t("evidenceMeta.commitListSummary") }}:
|
|
757
|
-
> {{ finalVerification.sourceImplementationReport.commitListQuote | mdquote(2) }}
|
|
758
|
-
- {{ t("evidenceMeta.diffSummaryQuote") }}:
|
|
759
|
-
> {{ finalVerification.sourceImplementationReport.diffSummaryQuote | mdquote(2) }}
|
|
760
|
-
- {{ t("evidenceMeta.targetWorktreePath") }}: `{{ finalVerification.sourceImplementationReport.worktreePath }}`
|
|
761
|
-
- {{ t("evidenceMeta.implementationBaseRef") }}: `{{ finalVerification.sourceImplementationReport.implementationBaseRef }}`
|
|
762
|
-
- {{ t("evidenceMeta.capturedHeadSha") }}: `{{ finalVerification.sourceImplementationReport.capturedHeadSha }}`
|
|
763
|
-
- {{ t("evidenceMeta.gitStatusAtRunStart") }}:
|
|
764
|
-
```
|
|
765
|
-
{{ finalVerification.sourceImplementationReport.gitStatusShort | indent(2) }}
|
|
766
|
-
```
|
|
767
|
-
- {{ t("evidenceMeta.gitDiffStatAtRunStart") }}:
|
|
768
|
-
```
|
|
769
|
-
{{ finalVerification.sourceImplementationReport.gitDiffStat | indent(2) }}
|
|
770
|
-
```
|
|
771
|
-
{% if verificationScope in ['whole-task', 'single-stage'] %}- {{ t("finalVerification.verificationScope") }}: `{{ verificationScope }}`
|
|
772
|
-
{% endif %}{% if finalVerification.stageReports %}- {{ t("finalVerification.stageReportsLabel") }}:
|
|
773
|
-
{% for row in finalVerification.stageReports %} - stage {{ row.stage }}: `{{ row.reportPath }}`
|
|
774
|
-
{% endfor %}{% endif %}
|
|
775
|
-
|
|
776
|
-
### 5.8.2 Acceptance Blockers
|
|
777
|
-
|
|
778
|
-
{% if finalVerification.acceptanceBlockers | length == 0 -%}
|
|
779
|
-
- No acceptance blockers found.
|
|
780
|
-
{%- else %}
|
|
781
|
-
| ID | Severity | Statement | Evidence | Recommended follow-up phase |
|
|
782
|
-
|----|----------|-----------|----------|------------------------------|
|
|
783
|
-
{% for row in finalVerification.acceptanceBlockers -%}
|
|
784
|
-
| {{ row.id | mdcell }} | `{{ row.severity | mdcell }}` | {{ row.statement | mdcell }} | {{ row.evidence | mdcell }} | `{{ row.followUpPhase | mdcell }}` |
|
|
785
|
-
{% endfor %}
|
|
786
|
-
{%- endif %}
|
|
787
|
-
|
|
788
|
-
### 5.8.3 Residual Risk
|
|
789
|
-
|
|
790
|
-
{% if finalVerification.residualRisk | length == 0 -%}
|
|
791
|
-
{{ t("emptyState.lingeringRisks") }}
|
|
792
|
-
{%- else %}
|
|
793
|
-
| ID | Item | Mitigation owner | Escalation trigger |
|
|
794
|
-
|----|------|------------------|---------------------|
|
|
795
|
-
{% for row in finalVerification.residualRisk -%}
|
|
796
|
-
| {{ row.id | mdcell }} | {{ row.item | mdcell }} | {{ row.owner | mdcell }} | {{ row.escalationTrigger | mdcell }} |
|
|
797
|
-
{% endfor %}
|
|
798
|
-
{%- endif %}
|
|
799
|
-
|
|
800
|
-
### 5.8.4 Validation Evidence{% if t("finalVerification.validationEvidenceAside") != "requirements coverage" %} ({{ t("finalVerification.validationEvidenceAside") }}){% endif %}
|
|
801
|
-
|
|
802
|
-
| ID | {{ t("finalVerification.columnRequirement") }} | Artifact | Status |
|
|
803
|
-
|----|--------------------------------|----------|--------|
|
|
804
|
-
{% for row in finalVerification.validationEvidence -%}
|
|
805
|
-
| {{ row.id | mdcell }} | {{ row.requirement | mdcell }} | `{{ row.artifact | mdcell }}` | {{ row.status | mdcell }} |
|
|
806
|
-
{% endfor %}
|
|
807
|
-
|
|
808
|
-
### 5.8.5 Read-only Command Log
|
|
809
|
-
|
|
810
|
-
| # | Tier | Command (verbatim) | Status | Exit code | Output tail |
|
|
811
|
-
|---|------|---------------------|--------|-----------|-------------|
|
|
812
|
-
{% for row in finalVerification.readonlyCommandLog -%}
|
|
813
|
-
| {{ row.number | mdcell }} | {{ row.tier | mdcell }} | `{{ row.command | mdcell }}` | `{{ row.status | mdcell }}` | {{ (row.exitCode if row.exitCode is not none else '—') | mdcell }} | {{ (row.statusReason if row.status in ['rejected', 'env-unavailable', 'advisory'] else row.outputTail) | mdcell }} |
|
|
814
|
-
{% endfor %}
|
|
815
|
-
|
|
816
|
-
### 5.8.6 Conditional Acceptance Conditions
|
|
817
|
-
|
|
818
|
-
{% if not finalVerdict.conditionalAcceptanceConditions -%}
|
|
819
|
-
- Not applicable (verdict is not `conditional-accept`).
|
|
820
|
-
{%- else %}
|
|
821
|
-
| ID | Condition | Evidence required | Blocks release-handoff |
|
|
822
|
-
|----|-----------|-------------------|------------------------|
|
|
823
|
-
{% for row in finalVerdict.conditionalAcceptanceConditions -%}
|
|
824
|
-
| {{ row.id | mdcell }} | {{ row.condition | mdcell }} | {{ row.evidenceRequired | mdcell }} | {{ row.blocksReleaseHandoff | mdcell }} |
|
|
825
|
-
{% endfor %}
|
|
826
|
-
{%- endif %}
|
|
827
|
-
|
|
828
|
-
### 5.8.7 Manual User Test Results
|
|
829
|
-
|
|
830
|
-
{% if finalVerification.manualUserTest.applicable -%}
|
|
831
|
-
| {{ t("manualUserTest.performed") }} | {{ t("manualUserTest.result") }} | {{ t("manualUserTest.observed") }} |
|
|
832
|
-
|---|---|---|
|
|
833
|
-
{% for row in finalVerification.manualUserTest.results -%}
|
|
834
|
-
| {{ row.target | mdcell }} — {{ row.performed | mdcell }} | `{{ row.result | mdcell }}` | {{ row.observed | mdcell }} |
|
|
835
|
-
{% endfor %}
|
|
836
|
-
{%- else -%}
|
|
837
|
-
- {{ t("manualUserTest.notApplicable") }}: {{ finalVerification.manualUserTest.exemptionReaffirm }}
|
|
838
|
-
{%- endif %}
|
|
839
|
-
|
|
840
|
-
### 5.8.8 Routing Recommendation
|
|
841
|
-
|
|
842
|
-
{{ finalVerification.routingRecommendation }}
|
|
843
|
-
|
|
844
|
-
### 5.8.9 Could-Not-Verify Roll-up
|
|
845
|
-
|
|
846
|
-
Single scan of every agreed check that this run did NOT confirm — requirement gaps, commands not run (rejected / not-configured / env-unavailable), advisory commands, and blocked manual tests — aggregated from the sections above.
|
|
847
|
-
|
|
848
|
-
{% for row in finalVerification.validationEvidence if row.status == 'gap' -%}
|
|
849
|
-
- `{{ row.id | mdcell }}` requirement gap — {{ row.requirement | mdcell }}
|
|
850
|
-
{% endfor -%}
|
|
851
|
-
{% for row in finalVerification.readonlyCommandLog if row.status in ['rejected', 'not-configured', 'env-unavailable', 'advisory'] -%}
|
|
852
|
-
- `{{ row.command | mdcell }}` — {{ row.status | mdcell }}: {{ row.statusReason | mdcell }}
|
|
853
|
-
{% endfor -%}
|
|
854
|
-
{% if finalVerification.manualUserTest.applicable -%}
|
|
855
|
-
{% for row in finalVerification.manualUserTest.results if row.result == 'blocked' -%}
|
|
856
|
-
- manual: {{ row.target | mdcell }} — {{ row.performed | mdcell }} (blocked): {{ row.observed | mdcell }}
|
|
857
|
-
{% endfor -%}
|
|
858
|
-
{% endif -%}
|
|
859
|
-
{% if not (
|
|
860
|
-
finalVerification.validationEvidence | selectattr('status', 'equalto', 'gap') | list
|
|
861
|
-
or finalVerification.readonlyCommandLog | selectattr('status', 'in', ['rejected', 'not-configured', 'env-unavailable', 'advisory']) | list
|
|
862
|
-
or (
|
|
863
|
-
finalVerification.manualUserTest.applicable
|
|
864
|
-
and finalVerification.manualUserTest.results | selectattr('result', 'equalto', 'blocked') | list
|
|
865
|
-
)
|
|
866
|
-
) -%}
|
|
867
|
-
- All agreed checks were executed or covered — nothing left unverified.
|
|
868
|
-
{%- endif %}
|
|
869
|
-
|
|
870
|
-
{% endif %}
|
|
871
|
-
{% if analysisCommon %}
|
|
872
|
-
## 5.9 Analysis Basis
|
|
873
|
-
|
|
874
|
-
{{ t("analysis.basisIntro") }}
|
|
875
|
-
|
|
876
|
-
### 5.9.1 Snapshot and Scope
|
|
877
|
-
|
|
878
|
-
| Item | Value |
|
|
879
|
-
|------|-------|
|
|
880
|
-
| Run sequence | `{{ analysisCommon.runSeq | mdcell }}` |
|
|
881
|
-
| Source commit | `{{ analysisCommon.sourceCommit | mdcell }}` |
|
|
882
|
-
| Included paths | {{ analysisCommon.scope.includedPaths | join(', ') | mdcell }} |
|
|
883
|
-
| Excluded paths | {{ analysisCommon.scope.excludedPaths | join(', ') | mdcell }} |
|
|
884
|
-
| Unscanned paths | {{ (analysisCommon.scope.unscannedPaths | join(', ') or '--') | mdcell }} |
|
|
885
|
-
| Resolved target mode | `{{ (analysisCommon.scope.resolvedTarget.inputMode or '--') | mdcell }}` |
|
|
886
|
-
| Resolved target | {{ (analysisCommon.scope.resolvedTarget.requestedValue or '--') | mdcell }} |
|
|
887
|
-
|
|
888
|
-
### 5.9.2 Evidence Inputs
|
|
889
|
-
|
|
890
|
-
{% if analysisCommon.evidenceInputs | length == 0 -%}
|
|
891
|
-
{{ t("analysis.empty") }}
|
|
892
|
-
{%- else %}
|
|
893
|
-
| Task key | Task type | Report path | Run | Source commit | Relation | Freshness | Review status |
|
|
894
|
-
|----------|-----------|-------------|-----|---------------|----------|-----------|---------------|
|
|
895
|
-
{% for row in analysisCommon.evidenceInputs -%}
|
|
896
|
-
| {{ row.taskKey | mdcell }} | `{{ row.taskType | mdcell }}` | `{{ row.reportPath | mdcell }}` | `{{ row.runSeq | mdcell }}` | `{{ row.sourceCommit | mdcell }}` | `{{ row.relation | mdcell }}` | `{{ row.freshness | mdcell }}` | `{{ row.reviewStatus | mdcell }}` |
|
|
897
|
-
{% endfor %}
|
|
898
|
-
{%- endif %}
|
|
899
|
-
|
|
900
|
-
### 5.9.3 Confirmed Facts
|
|
901
|
-
|
|
902
|
-
{% if analysisCommon.confirmedFacts | length == 0 -%}
|
|
903
|
-
{{ t("analysis.empty") }}
|
|
904
|
-
{%- else %}
|
|
905
|
-
| ID | Claim | Current code evidence | Confidence | Review resolution |
|
|
906
|
-
|----|-------|-----------------------|------------|-------------------|
|
|
907
|
-
{% for row in analysisCommon.confirmedFacts -%}
|
|
908
|
-
{% set review = namespace(value=t("analysis.reviewNotRecorded")) -%}
|
|
909
|
-
{% for resolution in analysisCommon.analysisReviewResolution if resolution.affectedId == row.id -%}
|
|
910
|
-
{% set review.value = resolution.outcome ~ ': ' ~ resolution.resolution -%}
|
|
911
|
-
{% endfor -%}
|
|
912
|
-
| {{ row.id | mdcell }} | {{ row.statement | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} | confirmed | {{ review.value | mdcell }} |
|
|
913
|
-
{% endfor %}
|
|
914
|
-
{%- endif %}
|
|
915
|
-
|
|
916
|
-
### 5.9.4 Inferences and Unknowns
|
|
917
|
-
|
|
918
|
-
{% if analysisCommon.inferences | length == 0 -%}
|
|
919
|
-
{{ t("analysis.empty") }}
|
|
920
|
-
{%- else %}
|
|
921
|
-
| ID | Claim | Evidence IDs | Confidence |
|
|
922
|
-
|----|-------|--------------|------------|
|
|
923
|
-
{% for row in analysisCommon.inferences -%}
|
|
924
|
-
| {{ row.id | mdcell }} | {{ row.statement | mdcell }} | {{ row.evidenceIds | join(', ') | mdcell }} | `{{ row.confidence | mdcell }}` |
|
|
925
|
-
{% endfor %}
|
|
926
|
-
{%- endif %}
|
|
927
|
-
|
|
928
|
-
{% if analysisCommon.unknowns | length > 0 %}
|
|
929
|
-
| ID | Question | Reason | Affects verdict |
|
|
930
|
-
|----|----------|--------|-----------------|
|
|
931
|
-
{% for row in analysisCommon.unknowns -%}
|
|
932
|
-
| {{ row.id | mdcell }} | {{ row.question | mdcell }} | {{ row.reason | mdcell }} | `{{ row.affectsVerdict | mdcell }}` |
|
|
933
|
-
{% endfor %}
|
|
934
|
-
{% endif %}
|
|
935
|
-
|
|
936
|
-
### 5.9.5 Analysis Review Resolution
|
|
937
|
-
|
|
938
|
-
{% if analysisCommon.analysisReviewResolution | length == 0 -%}
|
|
939
|
-
{{ t("analysis.empty") }}
|
|
940
|
-
{%- else %}
|
|
941
|
-
| Affected ID | Outcome | Resolution | Evidence |
|
|
942
|
-
|-------------|---------|------------|----------|
|
|
943
|
-
{% for row in analysisCommon.analysisReviewResolution -%}
|
|
944
|
-
| {{ row.affectedId | mdcell }} | `{{ row.outcome | mdcell }}` | {{ row.resolution | mdcell }} | {{ row.evidence | join('<br>') | mdcell }} |
|
|
945
|
-
{% endfor %}
|
|
946
|
-
{%- endif %}
|
|
947
|
-
|
|
948
|
-
{% endif %}
|
|
949
|
-
{% if projectAnalysis %}
|
|
950
|
-
## 5.10 Project Analysis
|
|
951
|
-
|
|
952
|
-
{{ t("analysis.projectIntro") }}
|
|
953
|
-
|
|
954
|
-
{% if projectAnalysis.techStack %}
|
|
955
|
-
### 5.10.0 Tech Stack
|
|
956
|
-
|
|
957
|
-
| Language | Version | Version source | Files | Lines |
|
|
958
|
-
|----------|---------|----------------|-------|-------|
|
|
959
|
-
{% for row in projectAnalysis.techStack.languages -%}
|
|
960
|
-
| {{ row.name | mdcell }} | {{ row.version | mdcell }} | {{ row.versionSource | mdcell }} | {{ row.fileCount | default('--') | mdcell }} | {{ row.lineCount | default('--') | mdcell }} |
|
|
961
|
-
{% endfor %}
|
|
962
|
-
{% if projectAnalysis.techStack.frameworks %}
|
|
963
|
-
| Framework | Version | Version source | Role |
|
|
964
|
-
|-----------|---------|----------------|------|
|
|
965
|
-
{% for row in projectAnalysis.techStack.frameworks -%}
|
|
966
|
-
| {{ row.name | mdcell }} | {{ row.version | mdcell }} | {{ row.versionSource | mdcell }} | {{ row.role | mdcell }} |
|
|
967
|
-
{% endfor %}
|
|
968
|
-
{% endif %}
|
|
969
|
-
{% if projectAnalysis.techStack.toolchain %}
|
|
970
|
-
| Tool kind | Name | Version | Command |
|
|
971
|
-
|-----------|------|---------|---------|
|
|
972
|
-
{% for row in projectAnalysis.techStack.toolchain -%}
|
|
973
|
-
| {{ row.kind | mdcell }} | {{ row.name | mdcell }} | {{ row.version | default('--') | mdcell }} | {{ row.command | default('--') | mdcell }} |
|
|
974
|
-
{% endfor %}
|
|
975
|
-
{% endif %}
|
|
976
|
-
{% endif %}
|
|
977
|
-
|
|
978
|
-
### 5.10.1 Components
|
|
979
|
-
|
|
980
|
-
| ID | Name | Responsibility | Paths | Current code evidence |
|
|
981
|
-
|----|------|----------------|-------|-----------------------|
|
|
982
|
-
{% for row in projectAnalysis.components -%}
|
|
983
|
-
| {{ row.id | mdcell }} | {{ row.name | mdcell }} | {{ row.responsibility | mdcell }} | {{ row.paths | join(', ') | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
984
|
-
{% endfor %}
|
|
985
|
-
|
|
986
|
-
### 5.10.2 Dependencies and Boundaries
|
|
987
|
-
|
|
988
|
-
| From | To | Direction | Current code evidence |
|
|
989
|
-
|------|----|-----------|-----------------------|
|
|
990
|
-
{% for row in projectAnalysis.dependencies -%}
|
|
991
|
-
| {{ row.fromComponentId | mdcell }} | {{ row.toComponentId | mdcell }} | {{ row.direction | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
992
|
-
{% endfor %}
|
|
993
|
-
|
|
994
|
-
| Kind | Path | Symbol | Role | Current code evidence |
|
|
995
|
-
|------|------|--------|------|-----------------------|
|
|
996
|
-
{% for row in projectAnalysis.entryPoints -%}
|
|
997
|
-
| {{ row.kind | mdcell }} | `{{ row.path | mdcell }}` | `{{ row.symbol | mdcell }}` | {{ row.role | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
998
|
-
{% endfor %}
|
|
999
|
-
|
|
1000
|
-
### 5.10.3 Stores and External Systems
|
|
1001
|
-
|
|
1002
|
-
| Store | Owner | Read boundary | Write boundary | Current code evidence |
|
|
1003
|
-
|-------|-------|---------------|----------------|-----------------------|
|
|
1004
|
-
{% for row in projectAnalysis.dataStores -%}
|
|
1005
|
-
| {{ row.name | mdcell }} | {{ row.ownerComponentId | mdcell }} | {{ row.readBoundary | mdcell }} | {{ row.writeBoundary | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1006
|
-
{% endfor %}
|
|
1007
|
-
|
|
1008
|
-
| External system | Adapter | Direction | Current code evidence |
|
|
1009
|
-
|-----------------|---------|-----------|-----------------------|
|
|
1010
|
-
{% for row in projectAnalysis.externalSystems -%}
|
|
1011
|
-
| {{ row.name | mdcell }} | {{ row.adapter | mdcell }} | {{ row.direction | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1012
|
-
{% endfor %}
|
|
1013
|
-
|
|
1014
|
-
{% if projectAnalysis.internalInterfaces %}
|
|
1015
|
-
### 5.10.3b Internal Interfaces
|
|
1016
|
-
|
|
1017
|
-
| ID | Name | Kind | Owner | Signature | Consumers | Current code evidence |
|
|
1018
|
-
|----|------|------|-------|-----------|-----------|-----------------------|
|
|
1019
|
-
{% for row in projectAnalysis.internalInterfaces -%}
|
|
1020
|
-
| {{ row.id | mdcell }} | {{ row.name | mdcell }} | {{ row.kind | mdcell }} | {{ row.ownerComponentId | mdcell }} | `{{ row.signature | mdcell }}` | {{ row.consumers | default([]) | join(', ') | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}`{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1021
|
-
{% endfor %}
|
|
1022
|
-
{% endif %}
|
|
1023
|
-
{% if projectAnalysis.workflows %}
|
|
1024
|
-
### 5.10.3c Workflows
|
|
1025
|
-
|
|
1026
|
-
{% for flow in projectAnalysis.workflows -%}
|
|
1027
|
-
**{{ flow.id | mdcell }} — {{ flow.name | mdcell }}** (trigger: {{ flow.trigger | mdcell }}{% if flow.outcome %}; outcome: {{ flow.outcome | mdcell }}{% endif %})
|
|
1028
|
-
|
|
1029
|
-
| Step | Action | Component | External system |
|
|
1030
|
-
|------|--------|-----------|-----------------|
|
|
1031
|
-
{% for step in flow.steps -%}
|
|
1032
|
-
| {{ step.order | mdcell }} | {{ step.action | mdcell }} | {{ step.componentId | mdcell }} | {{ step.externalSystem | default('--') | mdcell }} |
|
|
1033
|
-
{% endfor %}
|
|
1034
|
-
{% endfor %}
|
|
1035
|
-
{% endif %}
|
|
1036
|
-
|
|
1037
|
-
### 5.10.4 Feature Index
|
|
1038
|
-
|
|
1039
|
-
| ID | Name | Description | Representative entry point | Related components | Current code evidence |
|
|
1040
|
-
|----|------|-------------|----------------------------|--------------------|-----------------------|
|
|
1041
|
-
{% for row in projectAnalysis.featureIndex -%}
|
|
1042
|
-
| {{ row.id | mdcell }} | {{ row.name | mdcell }} | {{ row.description | mdcell }} | `{{ row.representativeEntryPoint.path | mdcell }}:{{ row.representativeEntryPoint.symbol | mdcell }}` | {{ row.componentIds | join(', ') | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1043
|
-
{% endfor %}
|
|
1044
|
-
|
|
1045
|
-
- Scan coverage: `{{ projectAnalysis.scanCoverage.scannedPathCount }}` scanned / `{{ projectAnalysis.scanCoverage.unscannedPathCount }}` unscanned — {{ projectAnalysis.scanCoverage.reason }}
|
|
1046
|
-
|
|
1047
|
-
{% endif %}
|
|
1048
|
-
{% if featureAnalysis %}
|
|
1049
|
-
## 5.11 Feature Analysis
|
|
1050
|
-
|
|
1051
|
-
{{ t("analysis.featureIntro") }}
|
|
1052
|
-
|
|
1053
|
-
### 5.11.1 Confirmed Target
|
|
1054
|
-
|
|
1055
|
-
| Mode | Requested value | Feature ID | Entry points |
|
|
1056
|
-
|------|-----------------|------------|--------------|
|
|
1057
|
-
| `{{ featureAnalysis.target.inputMode | mdcell }}` | {{ featureAnalysis.target.requestedValue | mdcell }} | {{ (featureAnalysis.target.featureId or '--') | mdcell }} | {% for row in featureAnalysis.target.entryPoints %}`{{ row.path | mdcell }}:{{ row.symbol | mdcell }}`{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1058
|
-
|
|
1059
|
-
### 5.11.2 Flows, Rules, and State Changes
|
|
1060
|
-
|
|
1061
|
-
| ID | Kind | Claim | Current code evidence | Source reports |
|
|
1062
|
-
|----|------|-------|-----------------------|----------------|
|
|
1063
|
-
{% for row in featureAnalysis.flows -%}
|
|
1064
|
-
| {{ row.id | mdcell }} | `{{ row.kind | mdcell }}` | {% for step in row.steps %}{{ step.sequence | mdcell }}. {{ step.action | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} | {{ row.sourceReportRefs | join(', ') | mdcell }} |
|
|
1065
|
-
{% endfor %}
|
|
1066
|
-
{% for row in featureAnalysis.domainRules -%}
|
|
1067
|
-
| {{ row.id | mdcell }} | `rule` | {{ row.condition | mdcell }} → {{ row.outcome | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} | {{ row.sourceReportRefs | join(', ') | mdcell }} |
|
|
1068
|
-
{% endfor %}
|
|
1069
|
-
{% for row in featureAnalysis.stateChanges -%}
|
|
1070
|
-
| {{ row.id | mdcell }} | `state-change` | {{ row.dataStore | mdcell }}.{{ row.field | mdcell }} — {{ row.change | mdcell }}{% if row.sideEffects %}<br>Side effects: {{ row.sideEffects | join(', ') | mdcell }}{% endif %} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} | {{ row.sourceReportRefs | join(', ') | mdcell }} |
|
|
1071
|
-
{% endfor %}
|
|
1072
|
-
|
|
1073
|
-
### 5.11.3 External Interactions and Tests
|
|
1074
|
-
|
|
1075
|
-
| Target | Input | Output | Failure handling | Current code evidence |
|
|
1076
|
-
|--------|-------|--------|------------------|-----------------------|
|
|
1077
|
-
{% for row in featureAnalysis.externalInteractions -%}
|
|
1078
|
-
| {{ row.target | mdcell }} | {{ row.input | mdcell }} | {{ row.output | mdcell }} | {{ row.failureHandling | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1079
|
-
{% endfor %}
|
|
1080
|
-
|
|
1081
|
-
| ID | Target IDs | Test paths | Gaps |
|
|
1082
|
-
|----|------------|------------|------|
|
|
1083
|
-
{% for row in featureAnalysis.testCoverage -%}
|
|
1084
|
-
| {{ row.id | mdcell }} | {{ row.targetIds | join(', ') | mdcell }} | {{ row.testPaths | join(', ') | mdcell }} | {{ (row.gaps | join(', ') or '--') | mdcell }} |
|
|
1085
|
-
{% endfor %}
|
|
1086
|
-
|
|
1087
|
-
{% endif %}
|
|
1088
|
-
{% if changeImpactAnalysis %}
|
|
1089
|
-
## 5.12 Change Impact Analysis
|
|
1090
|
-
|
|
1091
|
-
{{ t("analysis.changeImpactIntro") }}
|
|
1092
|
-
|
|
1093
|
-
### 5.12.1 Change and Preserved Behavior
|
|
1094
|
-
|
|
1095
|
-
- Change request: {{ changeImpactAnalysis.changeRequest.summary }} — evidence: `{{ changeImpactAnalysis.changeRequest.briefEvidence }}`
|
|
1096
|
-
|
|
1097
|
-
| Preserved behavior | Current code evidence |
|
|
1098
|
-
|--------------------|-----------------------|
|
|
1099
|
-
{% for row in changeImpactAnalysis.preservedBehaviors -%}
|
|
1100
|
-
| {{ row.statement | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1101
|
-
{% endfor %}
|
|
1102
|
-
|
|
1103
|
-
### 5.12.2 Impact Items and Blast Radius
|
|
1104
|
-
|
|
1105
|
-
| ID | Target | Impact kind | Level | Confidence | Source reports | Current code evidence |
|
|
1106
|
-
|----|--------|-------------|-------|------------|----------------|-----------------------|
|
|
1107
|
-
{% for row in changeImpactAnalysis.impactItems -%}
|
|
1108
|
-
| {{ row.id | mdcell }} | {{ row.target | mdcell }} | {{ row.impactKind | mdcell }} | `{{ row.level | mdcell }}` | `{{ row.confidence | mdcell }}` | {{ row.sourceReportRefs | join(', ') | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1109
|
-
{% endfor %}
|
|
1110
|
-
|
|
1111
|
-
| Source impact ID | Affected target | Direction | Current code evidence |
|
|
1112
|
-
|------------------|-----------------|-----------|-----------------------|
|
|
1113
|
-
{% for row in changeImpactAnalysis.dependencyBlastRadius -%}
|
|
1114
|
-
| {{ row.sourceImpactId | mdcell }} | {{ row.affectedTarget | mdcell }} | {{ row.direction | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1115
|
-
{% endfor %}
|
|
1116
|
-
|
|
1117
|
-
### 5.12.3 Test, Operational, and Planning Inputs
|
|
1118
|
-
|
|
1119
|
-
| Test scope | Action | Test paths | Current code evidence |
|
|
1120
|
-
|------------|--------|------------|-----------------------|
|
|
1121
|
-
{% for row in changeImpactAnalysis.testImpact -%}
|
|
1122
|
-
| {{ row.scope | mdcell }} | `{{ row.action | mdcell }}` | {{ row.testPaths | join(', ') | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1123
|
-
{% endfor %}
|
|
1124
|
-
|
|
1125
|
-
| Operational area | Impact | Current code evidence |
|
|
1126
|
-
|------------------|--------|-----------------------|
|
|
1127
|
-
{% for row in changeImpactAnalysis.operationalImpact -%}
|
|
1128
|
-
| {{ row.area | mdcell }} | {{ row.impact | mdcell }} | {% for evidence in row.currentCodeEvidence %}`{{ evidence.path | mdcell }}:{{ evidence.line | mdcell }}` — {{ evidence.claim | mdcell }}{% if not loop.last %}<br>{% endif %}{% endfor %} |
|
|
1129
|
-
{% endfor %}
|
|
1130
|
-
|
|
1131
|
-
| Planning constraint | Unknown |
|
|
1132
|
-
|---------------------|---------|
|
|
1133
|
-
{% for row in changeImpactAnalysis.planningInputs -%}
|
|
1134
|
-
| {{ row.constraint | mdcell }} | `{{ row.unknown | mdcell }}` |
|
|
1135
|
-
{% endfor %}
|
|
1136
|
-
|
|
1137
|
-
{% endif %}
|
|
1138
|
-
{# `improvement-discovery` is not in the data.json TaskType enum — its
|
|
1139
|
-
`## 5.9 Improvement Candidates` report is authored directly by the report
|
|
1140
|
-
writer (report-writer-worker.md), never rendered through this template. #}
|
|
1141
|
-
{% if fixCycle and fixCycle.cycle %}
|
|
1142
|
-
## 5.10 Fix History
|
|
1143
|
-
|
|
1144
|
-
> This run belongs to a post-release bug-fix cycle registered in `history/fix-cycles.jsonl`.
|
|
1145
|
-
|
|
1146
|
-
- Cycle: `{{ fixCycle.cycle }}` — {{ fixCycle.symptom }}
|
|
1147
|
-
- Target report: `{{ fixCycle.targetReport }}`
|
|
1148
|
-
{% if fixCycle.runs %}
|
|
1149
|
-
- Runs in this cycle so far:
|
|
1150
|
-
{% for r in fixCycle.runs %}
|
|
1151
|
-
- {{ r.taskType }} seq {{ r.runSeq }}{% if r.runManifest %} (`{{ r.runManifest }}`){% endif %}
|
|
1152
|
-
{% endfor %}
|
|
1153
|
-
{% endif %}
|
|
1154
|
-
{% endif %}
|
|
1155
|
-
## 6. Cross Verification Results
|
|
1156
|
-
|
|
1157
|
-
{% if crossVerification.roundHistory and not crossVerification.roundHistory.disabled -%}
|
|
1158
|
-
### 6.0 Round History
|
|
1159
|
-
|
|
1160
|
-
{% if crossVerification.roundHistory.rounds | length > 1 -%}
|
|
1161
|
-
| Round | inputQueueSize | resolvedCount | carriedForwardCount | dispatches (worker:status:durationMs) | skippedWorkers (worker:reason) |
|
|
1162
|
-
|-------|----------------|---------------|----------------------|----------------------------------------|---------------------------------|
|
|
1163
|
-
{% for row in crossVerification.roundHistory.rounds -%}
|
|
1164
|
-
| {{ row.round | mdcell }} | {{ row.inputQueueSize | mdcell }} | {{ row.resolvedCount | mdcell }} | {{ row.carriedForwardCount | mdcell }} | {{ row.dispatches | mdcell }} | {{ row.skippedWorkers | mdcell }} |
|
|
1165
|
-
{% endfor %}
|
|
1166
|
-
|
|
1167
|
-
- `round2SkippedReason`: `{{ crossVerification.roundHistory.round2SkippedReason }}` ← {{ t("roundHistory.round2SkippedReasonNote") }}
|
|
1168
|
-
{% elif crossVerification.roundHistory.rounds | length == 1 -%}
|
|
1169
|
-
{% set r = crossVerification.roundHistory.rounds[0] -%}
|
|
1170
|
-
- {{ t("roundHistory.singleRoundPrefix") }} resolved={{ r.resolvedCount }}, carriedForward={{ r.carriedForwardCount }}, round2SkippedReason=`{{ crossVerification.roundHistory.round2SkippedReason }}`
|
|
1171
|
-
{% else -%}
|
|
1172
|
-
- {{ t("roundHistory.noRoundsNote") }} round2SkippedReason=`{{ crossVerification.roundHistory.round2SkippedReason }}`
|
|
1173
|
-
{% endif %}
|
|
1174
|
-
|
|
1175
|
-
{% endif %}
|
|
1176
|
-
### 6.1 Consensus
|
|
1177
|
-
|
|
1178
|
-
{% if crossVerification.consensus | length == 0 -%}
|
|
1179
|
-
{{ t("emptyState.consensusItems") }}
|
|
1180
|
-
{%- else %}
|
|
1181
|
-
| {{ t("columns.recordMeta") }} | Statement | Evidence (path:line / log / worker report) |
|
|
1182
|
-
|--------|-----------|---------------------------------------------|
|
|
1183
|
-
{% for row in crossVerification.consensus -%}
|
|
1184
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>Source items: {{ row.sourceItems | join(', ') | mdcell }} | {{ row.statement | mdcell }} | {{ row.evidence | mdcell }} |
|
|
1185
|
-
{% endfor %}
|
|
1186
|
-
{%- endif %}
|
|
1187
|
-
|
|
1188
|
-
{{ t("sectionIntro.sourceItemsRule") }}
|
|
1189
|
-
|
|
1190
|
-
### 6.2 Differences
|
|
1191
|
-
|
|
1192
|
-
{% if crossVerification.differences | length == 0 -%}
|
|
1193
|
-
{{ t("emptyState.differences") }}
|
|
1194
|
-
{%- else %}
|
|
1195
|
-
| {{ t("columns.recordMeta") }} | Disagreement | Evidence |
|
|
1196
|
-
|--------|--------------|----------|
|
|
1197
|
-
{% for row in crossVerification.differences -%}
|
|
1198
|
-
| **{{ row.id | mdcell }}**<br>Ticket: `{{ row.ticketId | mdcell }}`<br>Workers: {% for w in row.workersPosition %}{{ w.worker | mdcell }}:{{ w.itemId | mdcell }} ({{ w.position | mdcell }}){% if not loop.last %} / {% endif %}{% endfor %} | {{ row.disagreement | mdcell }} | {{ row.evidence | mdcell }} |
|
|
1199
|
-
{% endfor %}
|
|
1200
|
-
{%- endif %}
|
|
1201
|
-
|
|
1202
|
-
## 7. Final Verdict
|
|
1203
|
-
|
|
1204
|
-
{{ t("finalVerdict.intro") }}
|
|
1205
|
-
|
|
1206
|
-
| {{ t("verdictCard.tableHeaderLabel") }} | {{ t("verdictCard.tableHeaderValue") }} |
|
|
1207
|
-
|------|----|
|
|
1208
|
-
| Final Conclusion | {{ finalVerdict.finalConclusion | mdcell }} |
|
|
1209
|
-
| Verdict Token | `{{ finalVerdict.verdictToken | mdcell }}` |
|
|
1210
|
-
| Direction | `{{ finalVerdict.direction | mdcell }}` |
|
|
1211
|
-
| {{ t("verdictCard.rationaleLabel") }} | {{ finalVerdict.rationaleRowIds | join(', ') | mdcell }} |
|
|
1212
|
-
| {{ t("verdictCard.nextStepLabel") }} | {{ finalVerdict.nextStep | mdcell }} |
|
|
1213
|
-
|
|
1214
|
-
{% if ticketCoverage.omit %}
|
|
1215
|
-
{# Ticket Coverage omitted entirely — release-handoff / final-verification #}
|
|
1216
|
-
{%- else %}
|
|
1217
|
-
## Ticket Coverage
|
|
1218
|
-
|
|
1219
|
-
{{ t("ticketCoverage.intro") }}
|
|
1220
|
-
|
|
1221
|
-
{% if ticketCoverage.singleTicket -%}
|
|
1222
|
-
- Single ticket run: {{ ticketCoverage.singleTicket }}
|
|
1223
|
-
{%- else %}
|
|
1224
|
-
| Ticket ID | {{ t("ticketCoverage.columnSections") }} | {{ t("ticketCoverage.columnRelatedIds") }} |
|
|
1225
|
-
|-----------|-----------|---------------|
|
|
1226
|
-
{% for row in ticketCoverage.rows -%}
|
|
1227
|
-
| `{{ row.ticketId | mdcell }}` | `{{ row.sections | mdcell }}` | `{{ row.relatedIds | mdcell }}` |
|
|
1228
|
-
{% endfor %}
|
|
1229
|
-
{%- endif %}
|
|
1230
|
-
|
|
1231
|
-
{% endif %}
|
|
1232
|
-
## Execution Status by Agent
|
|
1233
|
-
|
|
1234
|
-
{{ t("sectionIntro.executionStatus") }}
|
|
1235
|
-
|
|
1236
|
-
| {{ t("columns.recordMeta") }} | Summary of Key Findings |
|
|
1237
|
-
|--------|-------------------------|
|
|
1238
|
-
{% for row in executionStatus -%}
|
|
1239
|
-
| **{{ row.agent | mdcell }}**<br>Role: {{ row.role | mdcell }}<br>Model: {{ row.model | mdcell }}<br>Status: {{ row.status | mdcell }}<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 | mdcell }} |
|
|
1240
|
-
{% endfor %}
|
|
1241
|
-
|
|
1242
|
-
## {{ t("tokenSummary.heading") }}
|
|
1243
|
-
|
|
1244
|
-
| {{ t("tokenSummary.tableHeaderItem") }} | {{ t("columns.rawTokens") }} | {{ t("columns.billableTokensInputEquiv") }} | {{ t("columns.cost") }} |
|
|
1245
|
-
|------|-----------|------------------------|------------|
|
|
1246
|
-
| {{ t("tokenSummary.rowLead") }} | `{{ tokenUsage.lead.totalTokens | format_int }}` | `{{ tokenUsage.lead.billableTokens | format_int }}` | `{{ tokenUsage.lead.costUsd | format_usd }}` |
|
|
1247
|
-
| {{ t("tokenSummary.rowWorkerTotal") }} | `{{ tokenUsage.worker.totalTokens | format_int }}` | `{{ tokenUsage.worker.billableTokens | format_int }}` | `{{ tokenUsage.worker.costUsd | format_usd }}` |
|
|
1248
|
-
{% for row in tokenUsage.workerDetails or [] -%}
|
|
1249
|
-
| - {{ row.label | mdcell }} | `{{ row.totalTokens | format_int }}`{% if row.cliTotalTokens is not none and row.cliTotalTokens > 0 %}<br>CLI: `{{ row.cliTotalTokens | format_int }}`{% endif %} | `{{ row.billableTokens | format_int }}` | `{{ row.costUsd | format_usd }}`{% if row.cliCostUsd is not none and row.cliCostUsd > 0 %}<br>+ CLI `{{ row.cliCostUsd | format_usd }}`{% endif %} |
|
|
1250
|
-
{% endfor -%}
|
|
1251
|
-
| {{ t("tokenSummary.rowGrandTotal") }} | **`{{ tokenUsage.grand.totalTokens | format_int }}`** | **`{{ tokenUsage.grand.billableTokens | format_int }}`** | **`{{ tokenUsage.grand.costUsd | format_usd }}`** |
|
|
1252
|
-
{% if tokenUsage.cli and tokenUsage.cli.costUsd is not none and tokenUsage.cli.costUsd > 0 -%}
|
|
1253
|
-
| {{ t("tokenSummary.rowCliExtra") }} | | | `{{ tokenUsage.cli.costUsd | format_usd }}` |
|
|
1254
|
-
{% endif %}
|
|
1255
|
-
|
|
1256
|
-
{# At Phase 6 numeric cells are null and render as `--`.
|
|
1257
|
-
Phase 7's okstra-token-usage.py populates tokenUsage in data.json then
|
|
1258
|
-
re-invokes this renderer to produce the final markdown. #}
|