okstra 0.200.0 → 0.201.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.md +4 -2
- package/dist/cli-registry.mjs +6 -0
- package/dist/cli-registry.mjs.map +1 -1
- package/docs/cli.md +14 -3
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +7 -3
- package/runtime/bin/okstra-spawn-followups.py +2 -2
- package/runtime/prompts/duties/technical-verification-worker.md +44 -0
- package/runtime/prompts/launch.template.md +7 -1
- package/runtime/prompts/lead/okstra-lead-contract.md +7 -2
- package/runtime/prompts/lead/plan-body-verification.md +3 -1
- package/runtime/prompts/lead/report-writer.md +11 -5
- package/runtime/prompts/lead/team-contract.md +6 -0
- package/runtime/prompts/profiles/_implementation-verifier.md +7 -1
- package/runtime/prompts/profiles/final-verification.md +5 -0
- package/runtime/prompts/profiles/forbidden-actions.json +6 -0
- package/runtime/prompts/profiles/implementation-option-selection.md +7 -1
- package/runtime/prompts/profiles/implementation-planning.md +1 -0
- package/runtime/prompts/profiles/technical-verification.md +53 -0
- package/runtime/prompts/wizard/prompts.ko.json +2 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -4
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/providers/zai/adapter.py +36 -5
- package/runtime/python/okstra_ctl/agent/invocation.py +14 -6
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +4 -3
- package/runtime/python/okstra_ctl/agent/prompt_cli/corrections.py +83 -22
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +44 -2
- package/runtime/python/okstra_ctl/conformance.py +2 -20
- package/runtime/python/okstra_ctl/dispatch_core.py +25 -5
- package/runtime/python/okstra_ctl/dispatch_state.py +2 -0
- package/runtime/python/okstra_ctl/domain/provider.py +0 -1
- package/runtime/python/okstra_ctl/domain/role.py +1 -0
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +6 -1
- package/runtime/python/okstra_ctl/implementation_direction.py +64 -7
- package/runtime/python/okstra_ctl/implementation_options.py +58 -45
- package/runtime/python/okstra_ctl/model_pool.py +2 -5
- package/runtime/python/okstra_ctl/next_phase.py +3 -0
- package/runtime/python/okstra_ctl/plan_items.py +15 -0
- package/runtime/python/okstra_ctl/plan_items_cli.py +9 -3
- package/runtime/python/okstra_ctl/qa_commands.py +30 -0
- package/runtime/python/okstra_ctl/registry/provider_registry.py +11 -8
- package/runtime/python/okstra_ctl/render.py +3 -0
- package/runtime/python/okstra_ctl/render_final_report.py +1 -0
- package/runtime/python/okstra_ctl/report_assembly.py +8 -2
- package/runtime/python/okstra_ctl/report_contract.py +3 -0
- package/runtime/python/okstra_ctl/report_corrections.py +209 -93
- package/runtime/python/okstra_ctl/report_finalize.py +25 -8
- package/runtime/python/okstra_ctl/report_html/router.py +2 -0
- package/runtime/python/okstra_ctl/report_html/view_models/technical_verification.py +21 -0
- package/runtime/python/okstra_ctl/report_projections.py +4 -3
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +181 -47
- package/runtime/python/okstra_ctl/run.py +82 -0
- package/runtime/python/okstra_ctl/team.py +4 -1
- package/runtime/python/okstra_ctl/technical_verification.py +195 -0
- package/runtime/python/okstra_ctl/usage_identity.py +54 -0
- package/runtime/python/okstra_ctl/usage_report.py +22 -8
- package/runtime/python/okstra_ctl/verification_target.py +74 -0
- package/runtime/python/okstra_ctl/wizard/__init__.py +1 -1
- package/runtime/python/okstra_ctl/wizard/cli.py +2 -1
- package/runtime/python/okstra_ctl/wizard/confirmation.py +38 -2
- package/runtime/python/okstra_ctl/wizard/engine.py +3 -0
- package/runtime/python/okstra_ctl/wizard/ids.py +1 -0
- package/runtime/python/okstra_ctl/wizard/outcome.py +63 -0
- package/runtime/python/okstra_ctl/wizard/picker_navigation.py +2 -2
- package/runtime/python/okstra_ctl/wizard/registry.py +1 -1
- package/runtime/python/okstra_ctl/wizard/render.py +8 -55
- package/runtime/python/okstra_ctl/wizard/roles.py +11 -7
- package/runtime/python/okstra_ctl/wizard/sources.py +28 -2
- package/runtime/python/okstra_ctl/wizard/state.py +13 -6
- package/runtime/python/okstra_ctl/wizard/steps_plan.py +8 -0
- package/runtime/python/okstra_ctl/worker_liveness.py +52 -39
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +2 -0
- package/runtime/python/okstra_ctl/workflow.py +8 -0
- package/runtime/python/okstra_ctl/write_policy.py +23 -0
- package/runtime/python/okstra_token_usage/blocks.py +50 -1
- package/runtime/python/okstra_token_usage/claude.py +42 -21
- package/runtime/python/okstra_token_usage/codex.py +17 -0
- package/runtime/python/okstra_token_usage/collect.py +299 -162
- package/runtime/python/okstra_token_usage/cursor.py +2 -3
- package/runtime/python/okstra_token_usage/report.py +35 -30
- package/runtime/python/okstra_token_usage/task_totals.py +3 -12
- package/runtime/schemas/final-report-v2.0.schema.json +298 -7
- package/runtime/schemas/final-report-v3.0.schema.json +298 -7
- package/runtime/schemas/report-narrative-v3.0.schema.json +1 -0
- package/runtime/schemas/report-synthesis-packet-v1.0.schema.json +1 -1
- package/runtime/schemas/report-writer-corrections-v1.0.schema.json +30 -3
- package/runtime/skills/okstra-run/SKILL.md +10 -2
- package/runtime/skills/okstra-setup/SKILL.md +42 -7
- package/runtime/templates/report-writer-prompt-preamble.md +7 -3
- package/runtime/templates/reports/html/i18n/en.json +11 -0
- package/runtime/templates/reports/html/i18n/ko.json +11 -0
- package/runtime/templates/reports/html/tasks/implementation-option-selection.template.html +7 -3
- package/runtime/templates/reports/html/tasks/technical-verification.template.html +35 -0
- package/runtime/templates/reports/md/tasks/technical-verification.template.md +5 -0
- package/runtime/validators/validate-run.py +9 -4
|
@@ -21,6 +21,7 @@ from okstra_ctl.design_prep import ( # noqa: E402
|
|
|
21
21
|
from okstra_ctl.usage_cells import duration_ms_from_bounds # noqa: E402
|
|
22
22
|
|
|
23
23
|
from .task_totals import task_cumulative_usage # noqa: E402
|
|
24
|
+
from .blocks import accounting_workers # noqa: E402
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class SubstituteRefusedError(RuntimeError):
|
|
@@ -155,7 +156,7 @@ def _cache_reads(summary: dict, team_state: dict) -> dict[str, int]:
|
|
|
155
156
|
lead = _cache_read_tokens(team_state.get("leadUsage"))
|
|
156
157
|
worker = sum(
|
|
157
158
|
_cache_read_tokens(entry.get("usage"))
|
|
158
|
-
for entry in team_state
|
|
159
|
+
for entry in accounting_workers(team_state)
|
|
159
160
|
if isinstance(entry, dict)
|
|
160
161
|
)
|
|
161
162
|
worker += _cache_read_tokens(summary.get("unattributedWorkerUsage"))
|
|
@@ -171,7 +172,7 @@ def _cache_read_tokens(usage: object) -> int:
|
|
|
171
172
|
|
|
172
173
|
def _worker_detail_rows(team_state: dict) -> list[dict]:
|
|
173
174
|
rows = []
|
|
174
|
-
for worker in team_state
|
|
175
|
+
for worker in accounting_workers(team_state):
|
|
175
176
|
if isinstance(worker, dict):
|
|
176
177
|
rows.append(
|
|
177
178
|
_worker_detail_row(_worker_detail_label(worker), worker.get("usage") or {})
|
|
@@ -212,6 +213,37 @@ def populate_data_token_cells(data_path: Path, team_state: dict) -> int:
|
|
|
212
213
|
data = json.loads(data_path.read_text(encoding="utf-8"))
|
|
213
214
|
changes = 0
|
|
214
215
|
|
|
216
|
+
changes += _populate_summary_token_cells(data, summary, team_state, data_path)
|
|
217
|
+
|
|
218
|
+
# Execution Status by Agent — per-row token / cost / duration.
|
|
219
|
+
# `collect.py` writes lead usage to `team_state["leadUsage"]` (flat
|
|
220
|
+
# usage_block), while worker usage lives at `worker["usage"]`. Wrap
|
|
221
|
+
# the lead block so `_populate_execution_row` can read both shapes
|
|
222
|
+
# via the same `source["usage"]` path.
|
|
223
|
+
lead_source = {"usage": team_state.get("leadUsage") or {}}
|
|
224
|
+
workers = accounting_workers(team_state)
|
|
225
|
+
rows = data.get("executionStatus") or []
|
|
226
|
+
used_workers: set[int] = set()
|
|
227
|
+
for row in rows:
|
|
228
|
+
role = row.get("role", "")
|
|
229
|
+
if "lead" in role.lower():
|
|
230
|
+
_populate_execution_row(row, lead_source)
|
|
231
|
+
changes += 1
|
|
232
|
+
continue
|
|
233
|
+
idx = _match_worker_index(row, workers, used_workers)
|
|
234
|
+
if idx is not None:
|
|
235
|
+
used_workers.add(idx)
|
|
236
|
+
_populate_execution_row(row, workers[idx])
|
|
237
|
+
changes += 1
|
|
238
|
+
|
|
239
|
+
data_path.write_text(
|
|
240
|
+
json.dumps(data, indent=2, ensure_ascii=False) + "\n",
|
|
241
|
+
encoding="utf-8",
|
|
242
|
+
)
|
|
243
|
+
return changes
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def _populate_summary_token_cells(data: dict, summary: dict, team_state: dict, data_path: Path) -> int:
|
|
215
247
|
# Token Usage Summary table — four rows.
|
|
216
248
|
cost = summary.get("estimatedCostUsd") or {}
|
|
217
249
|
lead_cost = cost.get("lead") or 0
|
|
@@ -245,34 +277,7 @@ def populate_data_token_cells(data_path: Path, team_state: dict) -> int:
|
|
|
245
277
|
cumulative = task_cumulative_usage(data_path)
|
|
246
278
|
if cumulative is not None:
|
|
247
279
|
token_usage["taskCumulative"] = cumulative
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
# Execution Status by Agent — per-row token / cost / duration.
|
|
251
|
-
# `collect.py` writes lead usage to `team_state["leadUsage"]` (flat
|
|
252
|
-
# usage_block), while worker usage lives at `worker["usage"]`. Wrap
|
|
253
|
-
# the lead block so `_populate_execution_row` can read both shapes
|
|
254
|
-
# via the same `source["usage"]` path.
|
|
255
|
-
lead_source = {"usage": team_state.get("leadUsage") or {}}
|
|
256
|
-
workers = team_state.get("workers") or []
|
|
257
|
-
rows = data.get("executionStatus") or []
|
|
258
|
-
used_workers: set[int] = set()
|
|
259
|
-
for row in rows:
|
|
260
|
-
role = row.get("role", "")
|
|
261
|
-
if "lead" in role.lower():
|
|
262
|
-
_populate_execution_row(row, lead_source)
|
|
263
|
-
changes += 1
|
|
264
|
-
continue
|
|
265
|
-
idx = _match_worker_index(row, workers, used_workers)
|
|
266
|
-
if idx is not None:
|
|
267
|
-
used_workers.add(idx)
|
|
268
|
-
_populate_execution_row(row, workers[idx])
|
|
269
|
-
changes += 1
|
|
270
|
-
|
|
271
|
-
data_path.write_text(
|
|
272
|
-
json.dumps(data, indent=2, ensure_ascii=False) + "\n",
|
|
273
|
-
encoding="utf-8",
|
|
274
|
-
)
|
|
275
|
-
return changes
|
|
280
|
+
return 4
|
|
276
281
|
|
|
277
282
|
|
|
278
283
|
def populate_token_cells(
|
|
@@ -16,6 +16,8 @@ from __future__ import annotations
|
|
|
16
16
|
import json
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
|
|
19
|
+
from .blocks import normalize_usage_block, usage_blocks
|
|
20
|
+
|
|
19
21
|
_TEAM_STATE_GLOB = "runs/*/state/team-state-*.json"
|
|
20
22
|
_SUMMED_KEYS = (
|
|
21
23
|
("totalTokens", "totalTokens"),
|
|
@@ -40,17 +42,6 @@ def _task_root(data_path: Path) -> Path | None:
|
|
|
40
42
|
return parents[3]
|
|
41
43
|
|
|
42
44
|
|
|
43
|
-
def _usage_blocks(team_state: dict) -> list[dict]:
|
|
44
|
-
blocks = [team_state.get("leadUsage") or {}]
|
|
45
|
-
for worker in team_state.get("workers") or []:
|
|
46
|
-
if isinstance(worker, dict):
|
|
47
|
-
blocks.append(worker.get("usage") or {})
|
|
48
|
-
unattributed = (team_state.get("usageSummary") or {}).get("unattributedWorkerUsage")
|
|
49
|
-
if isinstance(unattributed, dict):
|
|
50
|
-
blocks.append(unattributed)
|
|
51
|
-
return [block for block in blocks if isinstance(block, dict)]
|
|
52
|
-
|
|
53
|
-
|
|
54
45
|
def _number(value: object) -> int | float:
|
|
55
46
|
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
|
56
47
|
return 0
|
|
@@ -76,7 +67,7 @@ def task_cumulative_usage(data_path: Path) -> dict | None:
|
|
|
76
67
|
continue
|
|
77
68
|
if not isinstance(team_state, dict):
|
|
78
69
|
continue
|
|
79
|
-
blocks =
|
|
70
|
+
blocks = [normalize_usage_block(block) for block in usage_blocks(team_state)]
|
|
80
71
|
measured = sum(_number(block.get("totalTokens")) for block in blocks)
|
|
81
72
|
if measured <= 0:
|
|
82
73
|
continue
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"additionalProperties": false,
|
|
27
27
|
"properties": {
|
|
28
|
+
"technicalVerification": {"$ref": "#/$defs/TechnicalVerification"},
|
|
28
29
|
"schemaVersion": {
|
|
29
30
|
"const": "2.0",
|
|
30
31
|
"description": "Schema version. Renderer refuses to process unknown versions."
|
|
@@ -1664,6 +1665,86 @@
|
|
|
1664
1665
|
}
|
|
1665
1666
|
},
|
|
1666
1667
|
"allOf": [
|
|
1668
|
+
{
|
|
1669
|
+
"if": {
|
|
1670
|
+
"properties": {
|
|
1671
|
+
"header": {
|
|
1672
|
+
"properties": {
|
|
1673
|
+
"taskType": {
|
|
1674
|
+
"const": "technical-verification"
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
},
|
|
1679
|
+
"required": [
|
|
1680
|
+
"header"
|
|
1681
|
+
]
|
|
1682
|
+
},
|
|
1683
|
+
"then": {
|
|
1684
|
+
"required": [
|
|
1685
|
+
"technicalVerification"
|
|
1686
|
+
],
|
|
1687
|
+
"properties": {
|
|
1688
|
+
"frontmatter": {
|
|
1689
|
+
"properties": {
|
|
1690
|
+
"approved": {
|
|
1691
|
+
"const": false
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
},
|
|
1695
|
+
"implementationOptionSelection": false,
|
|
1696
|
+
"implementationPlanning": false,
|
|
1697
|
+
"implementation": false,
|
|
1698
|
+
"finalVerification": false,
|
|
1699
|
+
"releaseHandoff": false,
|
|
1700
|
+
"errorAnalysis": false,
|
|
1701
|
+
"requirementsDiscovery": false,
|
|
1702
|
+
"improvementDiscovery": false,
|
|
1703
|
+
"analysisCommon": false,
|
|
1704
|
+
"projectAnalysis": false,
|
|
1705
|
+
"featureAnalysis": false,
|
|
1706
|
+
"changeImpactAnalysis": false,
|
|
1707
|
+
"followUpTasks": {
|
|
1708
|
+
"contains": {
|
|
1709
|
+
"properties": {
|
|
1710
|
+
"origin": {
|
|
1711
|
+
"const": "phase-continuation"
|
|
1712
|
+
}
|
|
1713
|
+
},
|
|
1714
|
+
"required": [
|
|
1715
|
+
"origin"
|
|
1716
|
+
]
|
|
1717
|
+
},
|
|
1718
|
+
"minContains": 1,
|
|
1719
|
+
"maxContains": 1,
|
|
1720
|
+
"items": {
|
|
1721
|
+
"if": {
|
|
1722
|
+
"properties": {
|
|
1723
|
+
"origin": {
|
|
1724
|
+
"const": "phase-continuation"
|
|
1725
|
+
}
|
|
1726
|
+
},
|
|
1727
|
+
"required": [
|
|
1728
|
+
"origin"
|
|
1729
|
+
]
|
|
1730
|
+
},
|
|
1731
|
+
"then": {
|
|
1732
|
+
"properties": {
|
|
1733
|
+
"suggestedTaskType": {
|
|
1734
|
+
"const": "implementation-option-selection"
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
},
|
|
1742
|
+
"else": {
|
|
1743
|
+
"properties": {
|
|
1744
|
+
"technicalVerification": false
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
},
|
|
1667
1748
|
{
|
|
1668
1749
|
"description": "Frontmatter approval input matches the implementation-planning contract.",
|
|
1669
1750
|
"if": {
|
|
@@ -2013,6 +2094,7 @@
|
|
|
2013
2094
|
"properties": {
|
|
2014
2095
|
"taskType": {
|
|
2015
2096
|
"enum": [
|
|
2097
|
+
"technical-verification",
|
|
2016
2098
|
"requirements-discovery",
|
|
2017
2099
|
"project-analysis",
|
|
2018
2100
|
"feature-analysis",
|
|
@@ -2192,6 +2274,7 @@
|
|
|
2192
2274
|
}
|
|
2193
2275
|
],
|
|
2194
2276
|
"oneOf": [
|
|
2277
|
+
{"required": ["technicalVerification"]},
|
|
2195
2278
|
{
|
|
2196
2279
|
"required": [
|
|
2197
2280
|
"requirementsDiscovery"
|
|
@@ -3073,7 +3156,8 @@
|
|
|
3073
3156
|
"enum": [
|
|
3074
3157
|
"pending-direction-selection",
|
|
3075
3158
|
"implementation-planning",
|
|
3076
|
-
"blocked"
|
|
3159
|
+
"blocked",
|
|
3160
|
+
"technical-verification"
|
|
3077
3161
|
]
|
|
3078
3162
|
},
|
|
3079
3163
|
"userNarrative": {
|
|
@@ -3635,6 +3719,17 @@
|
|
|
3635
3719
|
],
|
|
3636
3720
|
"additionalProperties": false,
|
|
3637
3721
|
"properties": {
|
|
3722
|
+
"resolutionKind": {
|
|
3723
|
+
"type": "string",
|
|
3724
|
+
"enum": ["user-decision", "technical-verification"],
|
|
3725
|
+
"description": "Optional for historical reads; blocked report publication requires explicit classification."
|
|
3726
|
+
},
|
|
3727
|
+
"clarificationRefs": {
|
|
3728
|
+
"type": "array",
|
|
3729
|
+
"uniqueItems": true,
|
|
3730
|
+
"items": {"type": "string", "pattern": "^C-[0-9]{3}$"},
|
|
3731
|
+
"description": "User decisions require nonempty references to actual clarification records, including answered records."
|
|
3732
|
+
},
|
|
3638
3733
|
"fact": {
|
|
3639
3734
|
"type": "string",
|
|
3640
3735
|
"minLength": 1
|
|
@@ -3950,7 +4045,7 @@
|
|
|
3950
4045
|
},
|
|
3951
4046
|
"stageRefs": {
|
|
3952
4047
|
"type": "array",
|
|
3953
|
-
"minItems":
|
|
4048
|
+
"minItems": 0,
|
|
3954
4049
|
"uniqueItems": true,
|
|
3955
4050
|
"items": {
|
|
3956
4051
|
"type": "integer",
|
|
@@ -3959,7 +4054,7 @@
|
|
|
3959
4054
|
},
|
|
3960
4055
|
"stepRefs": {
|
|
3961
4056
|
"type": "array",
|
|
3962
|
-
"minItems":
|
|
4057
|
+
"minItems": 0,
|
|
3963
4058
|
"uniqueItems": true,
|
|
3964
4059
|
"items": {
|
|
3965
4060
|
"type": "string",
|
|
@@ -3968,7 +4063,7 @@
|
|
|
3968
4063
|
},
|
|
3969
4064
|
"validationRefs": {
|
|
3970
4065
|
"type": "array",
|
|
3971
|
-
"minItems":
|
|
4066
|
+
"minItems": 0,
|
|
3972
4067
|
"uniqueItems": true,
|
|
3973
4068
|
"items": {
|
|
3974
4069
|
"type": "string",
|
|
@@ -3977,7 +4072,7 @@
|
|
|
3977
4072
|
},
|
|
3978
4073
|
"fileRefs": {
|
|
3979
4074
|
"type": "array",
|
|
3980
|
-
"minItems":
|
|
4075
|
+
"minItems": 0,
|
|
3981
4076
|
"uniqueItems": true,
|
|
3982
4077
|
"items": {
|
|
3983
4078
|
"type": "string",
|
|
@@ -3987,10 +4082,59 @@
|
|
|
3987
4082
|
"status": {
|
|
3988
4083
|
"enum": [
|
|
3989
4084
|
"covered",
|
|
3990
|
-
"not-covered"
|
|
4085
|
+
"not-covered",
|
|
4086
|
+
"externally-tracked"
|
|
3991
4087
|
]
|
|
4088
|
+
},
|
|
4089
|
+
"crossProjectDependencyRefs": {
|
|
4090
|
+
"type": "array",
|
|
4091
|
+
"uniqueItems": true,
|
|
4092
|
+
"items": {
|
|
4093
|
+
"type": "string",
|
|
4094
|
+
"pattern": "^XP-[0-9]{3,}$"
|
|
4095
|
+
}
|
|
3992
4096
|
}
|
|
3993
|
-
}
|
|
4097
|
+
},
|
|
4098
|
+
"oneOf": [
|
|
4099
|
+
{
|
|
4100
|
+
"properties": {
|
|
4101
|
+
"status": {
|
|
4102
|
+
"enum": [
|
|
4103
|
+
"covered",
|
|
4104
|
+
"not-covered"
|
|
4105
|
+
]
|
|
4106
|
+
},
|
|
4107
|
+
"stageRefs": {
|
|
4108
|
+
"minItems": 1
|
|
4109
|
+
},
|
|
4110
|
+
"stepRefs": {
|
|
4111
|
+
"minItems": 1
|
|
4112
|
+
},
|
|
4113
|
+
"validationRefs": {
|
|
4114
|
+
"minItems": 1
|
|
4115
|
+
},
|
|
4116
|
+
"fileRefs": {
|
|
4117
|
+
"minItems": 1
|
|
4118
|
+
},
|
|
4119
|
+
"crossProjectDependencyRefs": {
|
|
4120
|
+
"maxItems": 0
|
|
4121
|
+
}
|
|
4122
|
+
}
|
|
4123
|
+
},
|
|
4124
|
+
{
|
|
4125
|
+
"required": [
|
|
4126
|
+
"crossProjectDependencyRefs"
|
|
4127
|
+
],
|
|
4128
|
+
"properties": {
|
|
4129
|
+
"status": {
|
|
4130
|
+
"const": "externally-tracked"
|
|
4131
|
+
},
|
|
4132
|
+
"crossProjectDependencyRefs": {
|
|
4133
|
+
"minItems": 1
|
|
4134
|
+
}
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
]
|
|
3994
4138
|
},
|
|
3995
4139
|
"SelectedDirectionCoverageSummary": {
|
|
3996
4140
|
"type": "object",
|
|
@@ -4056,8 +4200,155 @@
|
|
|
4056
4200
|
}
|
|
4057
4201
|
}
|
|
4058
4202
|
},
|
|
4203
|
+
"TechnicalVerification": {
|
|
4204
|
+
"type": "object",
|
|
4205
|
+
"additionalProperties": false,
|
|
4206
|
+
"required": [
|
|
4207
|
+
"sourceReport",
|
|
4208
|
+
"sourceDataSha256",
|
|
4209
|
+
"scope",
|
|
4210
|
+
"checks",
|
|
4211
|
+
"routing"
|
|
4212
|
+
],
|
|
4213
|
+
"properties": {
|
|
4214
|
+
"sourceReport": {
|
|
4215
|
+
"type": "string",
|
|
4216
|
+
"minLength": 1
|
|
4217
|
+
},
|
|
4218
|
+
"sourceDataSha256": {
|
|
4219
|
+
"type": "string",
|
|
4220
|
+
"pattern": "^[0-9a-f]{64}$"
|
|
4221
|
+
},
|
|
4222
|
+
"scope": {
|
|
4223
|
+
"const": "technical-evidence-only"
|
|
4224
|
+
},
|
|
4225
|
+
"checks": {
|
|
4226
|
+
"type": "array",
|
|
4227
|
+
"minItems": 1,
|
|
4228
|
+
"items": {
|
|
4229
|
+
"type": "object",
|
|
4230
|
+
"additionalProperties": false,
|
|
4231
|
+
"required": [
|
|
4232
|
+
"id",
|
|
4233
|
+
"candidateId",
|
|
4234
|
+
"factIndex",
|
|
4235
|
+
"fact",
|
|
4236
|
+
"hypothesis",
|
|
4237
|
+
"procedure",
|
|
4238
|
+
"confirmingSignal",
|
|
4239
|
+
"rejectingSignal",
|
|
4240
|
+
"status",
|
|
4241
|
+
"commands",
|
|
4242
|
+
"observation",
|
|
4243
|
+
"limitations"
|
|
4244
|
+
],
|
|
4245
|
+
"properties": {
|
|
4246
|
+
"id": {
|
|
4247
|
+
"type": "string",
|
|
4248
|
+
"pattern": "^TV-[0-9]{3}$"
|
|
4249
|
+
},
|
|
4250
|
+
"candidateId": {
|
|
4251
|
+
"type": "string",
|
|
4252
|
+
"pattern": "^IO-[0-9]{3}$"
|
|
4253
|
+
},
|
|
4254
|
+
"factIndex": {
|
|
4255
|
+
"type": "integer",
|
|
4256
|
+
"minimum": 0
|
|
4257
|
+
},
|
|
4258
|
+
"fact": {
|
|
4259
|
+
"type": "string",
|
|
4260
|
+
"minLength": 1
|
|
4261
|
+
},
|
|
4262
|
+
"hypothesis": {
|
|
4263
|
+
"type": "string",
|
|
4264
|
+
"minLength": 1
|
|
4265
|
+
},
|
|
4266
|
+
"procedure": {
|
|
4267
|
+
"type": "string",
|
|
4268
|
+
"minLength": 1
|
|
4269
|
+
},
|
|
4270
|
+
"confirmingSignal": {
|
|
4271
|
+
"type": "string",
|
|
4272
|
+
"minLength": 1
|
|
4273
|
+
},
|
|
4274
|
+
"rejectingSignal": {
|
|
4275
|
+
"type": "string",
|
|
4276
|
+
"minLength": 1
|
|
4277
|
+
},
|
|
4278
|
+
"status": {
|
|
4279
|
+
"enum": [
|
|
4280
|
+
"supported",
|
|
4281
|
+
"refuted",
|
|
4282
|
+
"inconclusive",
|
|
4283
|
+
"not-run"
|
|
4284
|
+
]
|
|
4285
|
+
},
|
|
4286
|
+
"commands": {
|
|
4287
|
+
"type": "array",
|
|
4288
|
+
"items": {
|
|
4289
|
+
"type": "object",
|
|
4290
|
+
"additionalProperties": false,
|
|
4291
|
+
"required": [
|
|
4292
|
+
"command",
|
|
4293
|
+
"cwd",
|
|
4294
|
+
"exitCode",
|
|
4295
|
+
"logPath"
|
|
4296
|
+
],
|
|
4297
|
+
"properties": {
|
|
4298
|
+
"command": {
|
|
4299
|
+
"type": "string",
|
|
4300
|
+
"minLength": 1
|
|
4301
|
+
},
|
|
4302
|
+
"cwd": {
|
|
4303
|
+
"type": "string",
|
|
4304
|
+
"minLength": 1
|
|
4305
|
+
},
|
|
4306
|
+
"exitCode": {
|
|
4307
|
+
"type": "integer"
|
|
4308
|
+
},
|
|
4309
|
+
"logPath": {
|
|
4310
|
+
"type": "string",
|
|
4311
|
+
"minLength": 1
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
}
|
|
4315
|
+
},
|
|
4316
|
+
"observation": {
|
|
4317
|
+
"type": "string",
|
|
4318
|
+
"minLength": 1
|
|
4319
|
+
},
|
|
4320
|
+
"limitations": {
|
|
4321
|
+
"type": "array",
|
|
4322
|
+
"items": {
|
|
4323
|
+
"type": "string",
|
|
4324
|
+
"minLength": 1
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4329
|
+
},
|
|
4330
|
+
"routing": {
|
|
4331
|
+
"type": "object",
|
|
4332
|
+
"additionalProperties": false,
|
|
4333
|
+
"required": [
|
|
4334
|
+
"nextTaskType",
|
|
4335
|
+
"rationale"
|
|
4336
|
+
],
|
|
4337
|
+
"properties": {
|
|
4338
|
+
"nextTaskType": {
|
|
4339
|
+
"const": "implementation-option-selection"
|
|
4340
|
+
},
|
|
4341
|
+
"rationale": {
|
|
4342
|
+
"type": "string",
|
|
4343
|
+
"minLength": 1
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
},
|
|
4059
4349
|
"TaskType": {
|
|
4060
4350
|
"enum": [
|
|
4351
|
+
"technical-verification",
|
|
4061
4352
|
"requirements-discovery",
|
|
4062
4353
|
"improvement-discovery",
|
|
4063
4354
|
"error-analysis",
|