okstra 0.179.2 → 0.183.2

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.
Files changed (258) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-registry.mjs +30 -2
  3. package/dist/cli-registry.mjs.map +1 -1
  4. package/dist/commands/execute/incremental-carry.mjs +9 -8
  5. package/dist/commands/execute/incremental-carry.mjs.map +1 -1
  6. package/dist/commands/execute/plan-verify.mjs +3 -1
  7. package/dist/commands/execute/plan-verify.mjs.map +1 -1
  8. package/dist/commands/execute/render-bundle.d.mts +4 -2
  9. package/dist/commands/execute/render-bundle.mjs +46 -5
  10. package/dist/commands/execute/render-bundle.mjs.map +1 -1
  11. package/dist/commands/execute/run.mjs +11 -3
  12. package/dist/commands/execute/run.mjs.map +1 -1
  13. package/dist/commands/inspect/model-io.d.mts +1 -0
  14. package/dist/commands/inspect/model-io.mjs +25 -0
  15. package/dist/commands/inspect/model-io.mjs.map +1 -0
  16. package/dist/commands/inspect/stage-map.mjs +29 -8
  17. package/dist/commands/inspect/stage-map.mjs.map +1 -1
  18. package/dist/commands/inspect/task-list.mjs +52 -6
  19. package/dist/commands/inspect/task-list.mjs.map +1 -1
  20. package/dist/commands/inspect/user-response.mjs +14 -4
  21. package/dist/commands/inspect/user-response.mjs.map +1 -1
  22. package/dist/commands/lifecycle/check-project.d.mts +1 -0
  23. package/dist/commands/lifecycle/check-project.mjs +69 -50
  24. package/dist/commands/lifecycle/check-project.mjs.map +1 -1
  25. package/dist/commands/lifecycle/contract-check.d.mts +1 -0
  26. package/dist/commands/lifecycle/contract-check.mjs +18 -0
  27. package/dist/commands/lifecycle/contract-check.mjs.map +1 -0
  28. package/dist/commands/lifecycle/preflight.mjs +154 -51
  29. package/dist/commands/lifecycle/preflight.mjs.map +1 -1
  30. package/dist/commands/pr/pr.d.mts +1 -0
  31. package/dist/commands/pr/pr.mjs +19 -1
  32. package/dist/commands/pr/pr.mjs.map +1 -1
  33. package/dist/commands/report/agent-activity.mjs +2 -2
  34. package/dist/commands/report/approval-decision.d.mts +1 -0
  35. package/dist/commands/report/approval-decision.mjs +21 -0
  36. package/dist/commands/report/approval-decision.mjs.map +1 -0
  37. package/dist/commands/report/design-snapshot.d.mts +1 -0
  38. package/dist/commands/report/design-snapshot.mjs +19 -0
  39. package/dist/commands/report/design-snapshot.mjs.map +1 -0
  40. package/dist/commands/report/translate.mjs +3 -0
  41. package/dist/commands/report/translate.mjs.map +1 -1
  42. package/dist/lib/host-registry-client.mjs +13 -9
  43. package/dist/lib/host-registry-client.mjs.map +1 -1
  44. package/docs/architecture/storage-model.md +1 -1
  45. package/docs/architecture.md +21 -10
  46. package/docs/cli.md +36 -20
  47. package/docs/container.md +6 -4
  48. package/docs/contributor-change-matrix.md +1 -1
  49. package/docs/for-ai/README.md +2 -2
  50. package/docs/for-ai/skills/okstra-brief-gen.md +5 -3
  51. package/docs/for-ai/skills/okstra-code-review.md +4 -4
  52. package/docs/for-ai/skills/okstra-container-build.md +20 -17
  53. package/docs/for-ai/skills/okstra-inspect.md +20 -23
  54. package/docs/for-ai/skills/okstra-manager.md +19 -18
  55. package/docs/for-ai/skills/okstra-memory.md +2 -2
  56. package/docs/for-ai/skills/okstra-pr-gen.md +3 -3
  57. package/docs/for-ai/skills/okstra-rollup.md +14 -13
  58. package/docs/for-ai/skills/okstra-run.md +7 -3
  59. package/docs/for-ai/skills/okstra-schedule-gen.md +15 -18
  60. package/docs/for-ai/skills/okstra-setup.md +7 -7
  61. package/docs/for-ai/skills/okstra-usage.md +5 -4
  62. package/docs/for-ai/skills/okstra-user-response.md +50 -32
  63. package/docs/project-structure-overview.md +43 -31
  64. package/docs/task-process/implementation-planning.md +2 -2
  65. package/docs/task-process/implementation.md +7 -4
  66. package/package.json +1 -1
  67. package/runtime/BUILD.json +2 -2
  68. package/runtime/agents/workers/claude-worker.md +4 -4
  69. package/runtime/agents/workers/report-writer-worker.md +15 -164
  70. package/runtime/agents/workers/translator-worker.md +5 -13
  71. package/runtime/bin/okstra-error-log.py +51 -11
  72. package/runtime/bin/okstra-report-translate.py +210 -23
  73. package/runtime/prompts/host-orchestration/implementation.md +1 -1
  74. package/runtime/prompts/launch.template.md +9 -12
  75. package/runtime/prompts/lead/adapters/cmux.md +1 -1
  76. package/runtime/prompts/lead/context-loader.md +41 -141
  77. package/runtime/prompts/lead/convergence.md +10 -8
  78. package/runtime/prompts/lead/okstra-lead-contract.md +40 -49
  79. package/runtime/prompts/lead/plan-body-verification.md +217 -23
  80. package/runtime/prompts/lead/report-writer.md +81 -421
  81. package/runtime/prompts/lead/team-contract.md +9 -54
  82. package/runtime/prompts/profiles/_clarification-recommendation.md +5 -4
  83. package/runtime/prompts/profiles/_coding-conventions-preflight.md +3 -2
  84. package/runtime/prompts/profiles/_common-contract.md +4 -4
  85. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  86. package/runtime/prompts/profiles/_implementation-diff-review.md +1 -1
  87. package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
  88. package/runtime/prompts/profiles/change-impact-analysis.md +1 -1
  89. package/runtime/prompts/profiles/error-analysis.md +1 -1
  90. package/runtime/prompts/profiles/feature-analysis.md +1 -1
  91. package/runtime/prompts/profiles/final-verification.md +1 -1
  92. package/runtime/prompts/profiles/implementation-planning.md +20 -12
  93. package/runtime/prompts/profiles/improvement-discovery.md +1 -1
  94. package/runtime/prompts/profiles/project-analysis.md +1 -1
  95. package/runtime/prompts/profiles/release-handoff.md +0 -1
  96. package/runtime/prompts/profiles/requirements-discovery.md +1 -1
  97. package/runtime/prompts/wizard/prompts.ko.json +0 -1
  98. package/runtime/python/okstra_ctl/adapters/hosts/capability_adapter.py +69 -17
  99. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +13 -4
  100. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +8 -2
  101. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +2 -2
  102. package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +50 -5
  103. package/runtime/python/okstra_ctl/adapters/hosts/external/relay.md +1 -1
  104. package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +2 -2
  105. package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +66 -5
  106. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +70 -2
  107. package/runtime/python/okstra_ctl/agent_activity.py +141 -38
  108. package/runtime/python/okstra_ctl/agent_invocation.py +19 -6
  109. package/runtime/python/okstra_ctl/agent_prompt_cli.py +70 -23
  110. package/runtime/python/okstra_ctl/analysis_inputs.py +5 -4
  111. package/runtime/python/okstra_ctl/analysis_packet.py +124 -3
  112. package/runtime/python/okstra_ctl/approval_decisions.py +328 -0
  113. package/runtime/python/okstra_ctl/attempt_evidence.py +2 -2
  114. package/runtime/python/okstra_ctl/backfill.py +13 -10
  115. package/runtime/python/okstra_ctl/batch.py +2 -4
  116. package/runtime/python/okstra_ctl/build_tools.py +6 -3
  117. package/runtime/python/okstra_ctl/claim_reproduction.py +101 -0
  118. package/runtime/python/okstra_ctl/clarification_items.py +27 -13
  119. package/runtime/python/okstra_ctl/cmux.py +130 -52
  120. package/runtime/python/okstra_ctl/code_review_target.py +34 -8
  121. package/runtime/python/okstra_ctl/consumers.py +5 -4
  122. package/runtime/python/okstra_ctl/container.py +103 -8
  123. package/runtime/python/okstra_ctl/context_cost.py +2 -1
  124. package/runtime/python/okstra_ctl/contract_graph.py +497 -0
  125. package/runtime/python/okstra_ctl/contract_graph_cli.py +62 -0
  126. package/runtime/python/okstra_ctl/convergence.py +338 -17
  127. package/runtime/python/okstra_ctl/convergence_engine.py +10 -18
  128. package/runtime/python/okstra_ctl/convergence_provenance.py +58 -8
  129. package/runtime/python/okstra_ctl/convergence_store.py +55 -34
  130. package/runtime/python/okstra_ctl/design_prep.py +7 -4
  131. package/runtime/python/okstra_ctl/design_snapshot.py +134 -0
  132. package/runtime/python/okstra_ctl/dispatch_core.py +97 -69
  133. package/runtime/python/okstra_ctl/dispatch_state.py +163 -63
  134. package/runtime/python/okstra_ctl/doctor.py +6 -3
  135. package/runtime/python/okstra_ctl/domain/worker_presentation.py +70 -9
  136. package/runtime/python/okstra_ctl/entrypoints/hosts.py +16 -30
  137. package/runtime/python/okstra_ctl/error_log_write.py +35 -30
  138. package/runtime/python/okstra_ctl/error_report.py +26 -1
  139. package/runtime/python/okstra_ctl/error_zip.py +27 -5
  140. package/runtime/python/okstra_ctl/execution_identity.py +3 -2
  141. package/runtime/python/okstra_ctl/execution_manifest.py +7 -4
  142. package/runtime/python/okstra_ctl/execution_mutation_audit.py +6 -2
  143. package/runtime/python/okstra_ctl/final_report_schema.py +26 -17
  144. package/runtime/python/okstra_ctl/fix_cycles.py +2 -2
  145. package/runtime/python/okstra_ctl/fixed_text.py +39 -0
  146. package/runtime/python/okstra_ctl/git_reconcile.py +41 -9
  147. package/runtime/python/okstra_ctl/handoff.py +5 -4
  148. package/runtime/python/okstra_ctl/i18n.py +4 -2
  149. package/runtime/python/okstra_ctl/implementation_direction.py +22 -14
  150. package/runtime/python/okstra_ctl/implementation_outcome.py +4 -7
  151. package/runtime/python/okstra_ctl/incremental_carry.py +130 -17
  152. package/runtime/python/okstra_ctl/incremental_scope.py +12 -4
  153. package/runtime/python/okstra_ctl/index.py +8 -11
  154. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +79 -7
  155. package/runtime/python/okstra_ctl/invocation.py +3 -6
  156. package/runtime/python/okstra_ctl/json_boundary.py +366 -0
  157. package/runtime/python/okstra_ctl/json_registry.py +10 -12
  158. package/runtime/python/okstra_ctl/jsonl.py +19 -2
  159. package/runtime/python/okstra_ctl/lead_events.py +33 -1
  160. package/runtime/python/okstra_ctl/listing.py +3 -3
  161. package/runtime/python/okstra_ctl/log_report.py +24 -2
  162. package/runtime/python/okstra_ctl/manager_cli.py +92 -7
  163. package/runtime/python/okstra_ctl/manager_store.py +12 -10
  164. package/runtime/python/okstra_ctl/material.py +5 -1
  165. package/runtime/python/okstra_ctl/migrate.py +29 -25
  166. package/runtime/python/okstra_ctl/model_cli.py +3 -15
  167. package/runtime/python/okstra_ctl/model_io_cli.py +1051 -0
  168. package/runtime/python/okstra_ctl/mutation_probe.py +13 -4
  169. package/runtime/python/okstra_ctl/pane_reclaim.py +3 -2
  170. package/runtime/python/okstra_ctl/path_hints.py +12 -0
  171. package/runtime/python/okstra_ctl/paths.py +21 -0
  172. package/runtime/python/okstra_ctl/plan_items.py +115 -4
  173. package/runtime/python/okstra_ctl/plan_items_cli.py +626 -34
  174. package/runtime/python/okstra_ctl/ports/worker_dispatch.py +2 -1
  175. package/runtime/python/okstra_ctl/pr_template.py +3 -2
  176. package/runtime/python/okstra_ctl/project_meta.py +5 -7
  177. package/runtime/python/okstra_ctl/recap.py +5 -4
  178. package/runtime/python/okstra_ctl/reconcile.py +21 -27
  179. package/runtime/python/okstra_ctl/registry/host_discovery.py +3 -2
  180. package/runtime/python/okstra_ctl/registry/provider_registry.py +3 -2
  181. package/runtime/python/okstra_ctl/render.py +74 -16
  182. package/runtime/python/okstra_ctl/render_final_report.py +10 -8
  183. package/runtime/python/okstra_ctl/report_assembly.py +509 -0
  184. package/runtime/python/okstra_ctl/report_contract.py +2 -1
  185. package/runtime/python/okstra_ctl/report_finalize.py +67 -32
  186. package/runtime/python/okstra_ctl/report_html/render.py +3 -2
  187. package/runtime/python/okstra_ctl/report_inputs.py +72 -0
  188. package/runtime/python/okstra_ctl/report_language.py +3 -2
  189. package/runtime/python/okstra_ctl/report_markdown.py +81 -8
  190. package/runtime/python/okstra_ctl/report_narrative.py +351 -0
  191. package/runtime/python/okstra_ctl/report_projections.py +265 -0
  192. package/runtime/python/okstra_ctl/report_synthesis_packet.py +518 -0
  193. package/runtime/python/okstra_ctl/report_views.py +3 -2
  194. package/runtime/python/okstra_ctl/rollup.py +65 -4
  195. package/runtime/python/okstra_ctl/run.py +184 -65
  196. package/runtime/python/okstra_ctl/run_audit.py +3 -2
  197. package/runtime/python/okstra_ctl/run_context.py +6 -9
  198. package/runtime/python/okstra_ctl/run_index_row.py +2 -8
  199. package/runtime/python/okstra_ctl/schedule_semantics.py +5 -2
  200. package/runtime/python/okstra_ctl/schema_excerpt.py +15 -8
  201. package/runtime/python/okstra_ctl/session_transcript.py +27 -1
  202. package/runtime/python/okstra_ctl/set_work_status.py +64 -38
  203. package/runtime/python/okstra_ctl/stage_fix_carry.py +8 -6
  204. package/runtime/python/okstra_ctl/stage_ledger.py +132 -18
  205. package/runtime/python/okstra_ctl/stage_map.py +96 -28
  206. package/runtime/python/okstra_ctl/stage_targets.py +3 -4
  207. package/runtime/python/okstra_ctl/team.py +3 -2
  208. package/runtime/python/okstra_ctl/team_reconcile.py +11 -2
  209. package/runtime/python/okstra_ctl/time_report.py +51 -4
  210. package/runtime/python/okstra_ctl/usage_identity.py +2 -1
  211. package/runtime/python/okstra_ctl/usage_report.py +58 -4
  212. package/runtime/python/okstra_ctl/user_response.py +1431 -66
  213. package/runtime/python/okstra_ctl/wizard.py +11 -44
  214. package/runtime/python/okstra_ctl/work_categories.py +3 -2
  215. package/runtime/python/okstra_ctl/worker_dispatch.py +5 -2
  216. package/runtime/python/okstra_ctl/worker_prompt_body.py +49 -3
  217. package/runtime/python/okstra_ctl/worker_prompt_contract.py +3 -2
  218. package/runtime/python/okstra_ctl/worker_prompt_policy.py +31 -3
  219. package/runtime/python/okstra_ctl/worker_runner.py +14 -12
  220. package/runtime/python/okstra_ctl/workflow.py +2 -1
  221. package/runtime/python/okstra_ctl/worktree.py +3 -2
  222. package/runtime/python/okstra_ctl/wrapper_status.py +4 -2
  223. package/runtime/python/okstra_ctl/write_policy.py +4 -2
  224. package/runtime/python/okstra_token_usage/antigravity.py +39 -12
  225. package/runtime/python/okstra_token_usage/collect.py +90 -38
  226. package/runtime/python/okstra_token_usage/grok.py +127 -0
  227. package/runtime/schemas/final-report-v2.0.schema.json +9 -0
  228. package/runtime/schemas/final-report-v3.0.schema.json +10219 -0
  229. package/runtime/schemas/report-narrative-v3.0.schema.json +30 -0
  230. package/runtime/schemas/report-synthesis-packet-v1.0.schema.json +140 -0
  231. package/runtime/skills/okstra-brief-gen/SKILL.md +9 -7
  232. package/runtime/skills/okstra-code-review/SKILL.md +21 -11
  233. package/runtime/skills/okstra-container-build/SKILL.md +18 -18
  234. package/runtime/skills/okstra-inspect/SKILL.md +12 -11
  235. package/runtime/skills/okstra-inspect/facets/error-zip.md +8 -8
  236. package/runtime/skills/okstra-inspect/facets/errors.md +2 -2
  237. package/runtime/skills/okstra-inspect/facets/history.md +9 -14
  238. package/runtime/skills/okstra-inspect/facets/logs.md +2 -2
  239. package/runtime/skills/okstra-inspect/facets/recap.md +5 -5
  240. package/runtime/skills/okstra-inspect/facets/report.md +6 -10
  241. package/runtime/skills/okstra-inspect/facets/status.md +9 -8
  242. package/runtime/skills/okstra-inspect/facets/time.md +3 -3
  243. package/runtime/skills/okstra-manager/SKILL.md +16 -14
  244. package/runtime/skills/okstra-memory/SKILL.md +3 -3
  245. package/runtime/skills/okstra-pr-gen/SKILL.md +5 -4
  246. package/runtime/skills/okstra-rollup/SKILL.md +6 -16
  247. package/runtime/skills/okstra-run/SKILL.md +7 -7
  248. package/runtime/skills/okstra-schedule-gen/SKILL.md +21 -17
  249. package/runtime/skills/okstra-setup/SKILL.md +21 -13
  250. package/runtime/skills/okstra-setup/references/project-config.md +2 -2
  251. package/runtime/skills/okstra-usage/SKILL.md +10 -10
  252. package/runtime/skills/okstra-user-response/SKILL.md +78 -107
  253. package/runtime/templates/report-writer-prompt-preamble.md +29 -19
  254. package/runtime/templates/reports/html/macros/forms.html +6 -4
  255. package/runtime/templates/reports/schedule.template.md +4 -4
  256. package/runtime/templates/worker-error-contract.md +17 -29
  257. package/runtime/validators/validate-run.py +636 -72
  258. package/runtime/validators/validate_session_conformance.py +43 -7
@@ -1,193 +1,164 @@
1
1
  ---
2
2
  name: okstra-user-response
3
3
  description: >-
4
- Use this to answer an okstra task's open clarification questions in-session, without hand-editing any file. The tell is a request to respond to an okstra run's clarification items or its approval gate — "answer okstra", "I'll answer the questions", "clarification response", "user response", "approve and move on". This skill lists tasks whose latest report still has open clarification blockers, then walks the open C-ids one at a time — each rewritten as a self-contained question with background, its options with their impact plus "Enter directly" — echoes the collected answers back for an explicit "confirmed" acknowledgement, optionally records approval, and writes the `user-responses/` sidecar via `okstra user-response write`. NOT for starting a run (okstra-run), inspecting a finished task (okstra-inspect), or generating a brief (okstra-brief-gen). The skill never picks an answer — it builds the option board and transcribes what the user decides.
4
+ Use this to answer an okstra task's open clarification questions in-session without hand-editing a report or sidecar. It projects the available tasks and one report as fixed text, asks one question at a time, confirms the user's exact answers, and publishes only the user-owned user-responses sidecar through a typed transaction. NOT for starting a run, inspecting a finished task, or generating a brief.
5
5
  ---
6
6
 
7
7
  # OKSTRA User Response
8
8
 
9
- Single entry point for answering the clarification questions an okstra run left behind (the open `C-*` rows under the final report's `## 1. Clarification Items`) **in-session**, and recording those answers as a `runs/<type>/user-responses/` sidecar. The next `/okstra-run` auto-attaches this sidecar via `--clarification-response`.
9
+ Use this skill for open `C-*` clarification items and explicit plan decisions. The user alone selects or writes every answer. Never infer an answer or approval.
10
10
 
11
- **Core principle — the skill never picks an answer for the user.** It builds the option board — background, a self-contained question, the report's options with their impact, `Enter directly` — and the user alone picks from it; every `value` is what the user chose or typed. It never calls `write` until the user has explicitly confirmed.
11
+ The model-facing commands are fixed text reads and typed transaction writes:
12
12
 
13
- **Second principle one question at a time.** Never batch two clarification items into one question, and never dump the whole open list at the user. Ask item 1, transcribe the answer, then ask item 2.
14
-
15
- | Sub-command | What it does |
13
+ | Command | Purpose |
16
14
  |---|---|
17
- | `list` | List tasks that still have approval-open clarification, newest report first. |
18
- | `show` | Expand one report's open `C-*` rows (statement + options + contextRefs). |
19
- | `write` | Record the collected answers (+ optional approval) as a `user-responses/` sidecar. |
15
+ | `user-response list-view` | Show tasks that still await user input. |
16
+ | `user-response show-view` | Show questions, choices, resolved context, and current response state. |
17
+ | `user-response begin` | Open a sidecar transaction for one report identity. |
18
+ | `user-response answer` | Add or replace one validated clarification answer. |
19
+ | `user-response plan-decision` | Record an explicit plan decision in the transaction. |
20
+ | `user-response legacy-report-authoring` | Record legacy report-authoring permission for report contract 2.0 only. |
21
+ | `user-response finalize` | Atomically merge and publish the user-owned sidecar. |
20
22
 
21
- ## Step 0: Preflight (shared)
23
+ Do not use the automation-oriented `list` or `show` commands. Do not open a report record to select fields. The fixed views provide every value this skill may use.
22
24
 
23
- Before anything:
25
+ ## Step 0: Preflight
24
26
 
25
27
  <!-- BEGIN FRAGMENT: bash-invocation-rule -->
26
28
  Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
27
29
  <!-- END FRAGMENT: bash-invocation-rule -->
28
30
 
29
31
  ```bash
30
- okstra preflight --runtime claude-code --json
32
+ okstra preflight --runtime claude-code
31
33
  ```
32
34
 
33
- Branch on the stdout JSON:
34
- - `ok: true` → carry `projectRoot` and `projectId` as literal strings; they are the base for every step below.
35
- - `ok: false` → this project has no okstra setup. Tell the user: "this project has no okstra setup. Run `/okstra-setup` first." Then stop. If the user pointed at a specific project directory, re-run targeting it: `okstra preflight --runtime claude-code --cwd <that-dir> --json` (`--cwd` is the sanctioned way to target a project — a leading `cd` would break the permission match); only if that **also** returns `ok:false` do you stop.
35
+ On `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. On `Okstra preflight: ready`, carry the fixed `Project root` and `Project ID` lines as literal values.
36
36
 
37
37
  <!-- BEGIN FRAGMENT: preflight-outdated-cli -->
38
38
  If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
39
39
  <!-- END FRAGMENT: preflight-outdated-cli -->
40
40
 
41
- Then resolve the okstra home once (the `list` sub-command needs it):
41
+ Resolve the installed home:
42
42
 
43
43
  ```bash
44
44
  okstra paths --field home
45
45
  ```
46
46
 
47
- Paste the printed path literally into `--home` below.
48
-
49
47
  <!-- BEGIN FRAGMENT: python-bootstrap-note -->
50
48
  Every subsequent `okstra <subcmd>` call self-bootstraps its Python path, so this skill never needs `okstra paths --shell` / `export PYTHONPATH=...`.
51
49
  <!-- END FRAGMENT: python-bootstrap-note -->
52
50
 
53
- ## Step 1: List awaiting tasks picker
51
+ ## Step 1: Select a task from the fixed list view
54
52
 
55
53
  ```bash
56
- okstra user-response list --home <resolved-home> --project <projectId> --limit 3
54
+ okstra user-response list-view --home <resolved-home> --project <projectId> --limit 3
57
55
  ```
58
56
 
59
- Returns a JSON array (latest report mtime first); each entry:
60
- `{taskKey, taskType, seq, reportPath, reportMtime, openBlockerCount, openApprovalCount, unreadable}`. `openBlockerCount` counts every open row that still owes the user an answer (`Blocks` = `approval` or `next-phase`); `openApprovalCount` is the `approval`-only subset that gates the frontmatter `approved` flip.
57
+ The view gives `Task key`, `Task type`, `Report`, open-item counts, and readability status. If the count is zero, answer `No task has open clarification items.` and stop. Do not continue with an unreadable entry.
61
58
 
62
- - Empty array answer `No task has open clarification items.` and stop.
63
- - Otherwise present a **3-option picker**: the top recommendations from the list (each shown as `taskKey (taskType, <openBlockerCount> open items)`), and the **final option is always "Enter directly"** — where the user pastes a `reportPath` or a `task-key` directly (for a task not in the top-3 window).
64
- - An entry with `unreadable: true` means its `## 1. Clarification Items` heading exists but drifted from the expected format. Flag it as `⚠ §1 format drift — the CLI could not parse its items` and do not proceed on it until the report is regenerated; do not fabricate rows for it.
59
+ Present up to three task choices. The final picker option is `Enter directly`, where the user may provide a report path or task key.
65
60
 
66
- Carry the chosen entry's `reportPath` and `taskKey` forward.
67
-
68
- ## Step 2: Fetch the open rows (data only — ask nothing yet)
61
+ ## Step 2: Read the fixed report view
69
62
 
70
63
  ```bash
71
- okstra user-response show --report <reportPath>
64
+ okstra user-response show-view --report <reportPath> --project-root <projectRoot>
72
65
  ```
73
66
 
74
- Returns `{reportPath, rows: [{id, kind, blocks, status, statement, expectedForm, options, contextRefs, resolvedRefs}]}`.
75
-
76
- Each entry of `options[]` is `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`. `role` is `recommended` for exactly one entry and `alternative` for the rest; `scopeImpact` is a token list drawn from `in-repo` / `cross-repo` / `new-schema` / `deferrable`; `addedWork` and `directionChange` are one sentence each. Activity-contract v1 approval options also carry the gate action in `disposition`. A legacy schema-v1 report has nowhere to record impact or a gate action, so those fields arrive empty — the CLI reconstructs only the answers from the report's `Expected form` cell.
77
-
78
- `resolvedRefs` is `[{ref, definition}]` — the CLI has already looked up what each record coordinate (`RB-002`, `FU-001`) means in the report record; `definition` is `null` when the record has no such row, when the citation is a section number (`§4.7`, leftover from an older report), or when the citation is a `path:line` pointer.
79
-
80
- This call is a **data fetch, not a presentation step**. Do not print `rows` at the user, and do not paste a raw `statement` as a question — a `statement` like `Rewrite RB-002 rollback (see §4.7)` is meaningless on its own, which is the whole reason this skill exists. Announce only the count and the plan:
81
-
82
- > `<N>` open items — I'll go through them one at a time.
67
+ The view contains the report identity, contract version, every open clarification question, its expected form, its current response and disposition, its options, approval context, plan option candidates, current plan decision, and resolved context. It is the only report-information source for this skill.
83
68
 
84
- Step 3 then turns exactly one row at a time into a question.
69
+ Each entry in `options[]` corresponds to `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`. Put the `recommended` option first and suffix its label with `(Recommended)`. Then put the alternatives in view order and finish with `Enter directly`.
85
70
 
86
- ## Step 3: Ask one item at a time (loop)
71
+ Contract 3.0 options also expose `reach` and `scopeEffects`. Contract 3.0 approval-blocking rows expose `approvalContext`. Present those values exactly as the view prints them.
87
72
 
88
- Walk the open rows in report order. **One item per `AskUserQuestion` call** — never batch two items into one call, and never pre-announce the items still to come. Ask, transcribe, move on. Head each item with its position and what it is holding up:
73
+ Each option description uses all three impact axes in this order:
89
74
 
90
- > **[2/5] C-014** blocks: approval gate
75
+ > `<rationale>`Scope: `<scopeImpact>` · Added work: `<addedWork>` · Direction: `<directionChange>`
91
76
 
92
- ### 3a. Background first (plain text, above the picker)
77
+ When an axis says `not stated in the report`, repeat that text. Do not infer missing impact. The skill must **never invent it**.
93
78
 
94
- `AskUserQuestion` carries one sentence of question, so the background goes in the message text right before the call. Write these three blocks, **3–6 lines total** enough that someone who never read the report can answer:
79
+ ## Step 3: Ask one clarification at a time
95
80
 
96
- 1. **Situation** what the run was doing when it stopped at this item, in the user's own domain terms.
97
- 2. **What is undecided** — the actual fork, with every internal token expanded inline from `resolvedRefs[].definition`; the user must never need to know what `RB-002` is to answer. Say what is stuck right now in plain words: `blocks: approval` → the approval gate stays shut and `implementation` cannot start; `blocks: next-phase` → the next phase cannot begin.
98
- 3. **What changes with your answer** — what each direction actually causes downstream.
81
+ For each item that still needs an answer, show its position, ID, blocking effect, question, expected form, and resolved context. Use one single-select question per clarification.
99
82
 
100
- Where the background comes from in this order:
83
+ Use the displayed values to confirm the user's choice. Do not copy a predefined option's answer, disposition, reach, or scope effects into command arguments. The typed command resolves those report-owned fields from its option number.
101
84
 
102
- - `resolvedRefs[].definition`, which is already resolved and needs no file read;
103
- - when a `definition` is `null`, or the three blocks would otherwise be empty, **Read** the report record (the `.data.json` at `reportPath`) and take the cited row's `statement` / `summary` / `item` from there. Do not open the full reading copy to chase a `§` number — that number is not a record coordinate;
104
- - **never invent it.** If the report genuinely does not say why, write `The report states nothing beyond the statement itself.` and go straight to the question. Fabricated background corrupts the answer it collects.
105
-
106
- Close the background with the raw source on one line, so the mapping back to the report stays visible:
107
-
108
- > Source: `C-014` — "<raw statement>"
109
-
110
- ### 3b. The picker — the report's options plus `Enter directly`
111
-
112
- One `AskUserQuestion` (single-select). Fill the slots from `options[]` in array order — the `role: recommended` entry first with its label suffixed `(Recommended)`, then the `alternative` entries — and always close with `Enter directly` as the last option. Never mark anything but the `recommended` entry as recommended.
113
-
114
- Each `label` is that option's `answer`, kept to the answer itself (1–5 words). Each `description` carries the rationale followed by the three impact axes, in this fixed order:
85
+ | User action | Value | Disposition |
86
+ |---|---|---|
87
+ | Selects an option | that option's `answer` | that option's `disposition` |
88
+ | Enters an answer | the user's text verbatim | `answer` |
89
+ | Asks for the item to be presented again | the user's request verbatim | `reframe` |
115
90
 
116
- > `<rationale>` Scope: `<scopeImpact, comma-joined>` · Added work: `<addedWork>` · Direction: `<directionChange>`
91
+ Copy `kind` from the view. A `reframe` does not satisfy the gate. If the user asks what an item means, explain only from the view and ask the same item again.
117
92
 
118
- The three axes answer three different questions: how far the choice reaches, what new work it creates, and what it overturns. Never fold them into one phrase — whichever is easiest to write ends up standing in for the other two, and the user weighs a scope change as though it were free. That is the failure this board exists to prevent.
93
+ ## Step 4: Confirm the complete response
119
94
 
120
- When an axis is empty a schema-v1 report has nowhere to record impact — write `not stated in the report` for that axis. Do not infer it, and do not read the code to reconstruct it. A guessed side effect is worse than a stated gap, because the user cannot tell the two apart.
95
+ Echo each clarification ID, kind, disposition, value, and rationale. Include any explicit plan decision or legacy report-authoring decision. Ask:
121
96
 
122
- When `options[]` carries more than three entries, keep the recommended one plus the two alternatives whose `scopeImpact` differs most from it, and say in the background text how many you left out. When it carries exactly two, the picker has three options in total — do not pad it with an invented third.
97
+ > Record it as shown above? Reply `confirmed` to publish the sidecar.
123
98
 
124
- ### 3c. Transcribe the decision, then move on
99
+ Do not start a transaction until the user clearly confirms. If the user changes an item, show the complete response again and reconfirm.
125
100
 
126
- Record one entry `{id, kind, value, rationale?, disposition}`, `kind` copied from the row `show` returned:
101
+ ## Step 5: Begin the typed transaction
127
102
 
128
- | The user picks | `value` | `disposition` |
129
- |---|---|---|
130
- | One of the `options[]` entries | that option's `answer` text, not its short label | that option's `disposition` (`answer` only when absent on a legacy option) |
131
- | `Enter directly` → their own answer | the user's utterance verbatim (rationale into `rationale`) | `answer` |
132
- | Free text asking for the item to be re-asked | what the user wants re-asked, verbatim (empty → the raw statement) | `reframe` |
103
+ ```bash
104
+ okstra user-response begin --report <reportPath> --task-key <taskKey>
105
+ ```
133
106
 
134
- A reframe is not an answer, so it does not satisfy the approval gate.
107
+ Carry the returned opaque `transaction` value exactly. Do not decode it or inspect its state file.
135
108
 
136
- If the user replies with a question instead of an answer ("what does this mean?"), record nothing: **Read** the report record for the cited row id from `contextRefs[]`, explain it in plain language, and re-ask the same item with the same options. Explain only — **do not resolve it for them**; the decision goes back to the user.
109
+ For a predefined option, pass only its one-based number from the fixed view:
137
110
 
138
- Echo one line per finished item (`[2/5] C-014 → answer: 60s`), then ask the next one. Do not summarize the whole set until Step 4.
111
+ ```bash
112
+ okstra user-response answer --transaction <transaction> --clarification-id <C-NNN> --kind <kind> --option-number <N>
113
+ ```
139
114
 
140
- ## Step 4: Echo the full sidecar back explicit "confirmed" gate
115
+ Every value, rationale, and reason body file must be a regular file under `<projectRoot>/.okstra/tmp/user-response/`; do not use an external file or a symbolic link. For a direct user answer, write the exact value there. Write the rationale to a separate Markdown file only when present. Then run:
141
116
 
142
- Once the loop has covered every open item, **before** calling `write`, **echo back** everything collected (each `id`, `disposition`, `value`, `rationale` if present, and the approval decision from Step 5 below) to the user as-is. Then ask for explicit confirmation:
117
+ ```bash
118
+ okstra user-response answer --transaction <transaction> --clarification-id <C-NNN> --kind <kind> --disposition <disposition> --value-file <value.md> [--rationale-file <rationale.md>]
119
+ ```
143
120
 
144
- > Record it as shown above? (Reply `confirmed` to write the sidecar.)
121
+ The two answer forms are mutually exclusive. The command validates that the clarification ID and kind exist and remain open in the selected report. Repeating the same answer command is safe.
145
122
 
146
- - **Never call `write`** until the user says `confirmed` (or gives clear approval).
147
- - If the user changes any item, show the echo-back again with the changed value and re-confirm.
148
- - Every `value` must be what the user picked or typed, never a wording you settled on for them — this gate guarantees that.
123
+ ## Step 6: Record an explicit decision when present
149
124
 
150
- ## Step 5: (Optional) Record the plan decision
125
+ When the user explicitly approved a plan:
151
126
 
152
- Record a decision alongside the answers only when the user stated one outright. Never infer it from the tone of the conversation.
127
+ ```bash
128
+ okstra user-response plan-decision --transaction <transaction> --status approved [--implementation-option <name>]
129
+ ```
153
130
 
154
- Approval also requires that the report's approval-blocking clarification items are **all filled with an answer**:
131
+ For `revision-requested` or `rejected`, write the user's reason verbatim to a Markdown file in that same temporary directory and pass it:
155
132
 
156
- ```
157
- --plan-decision '{"status":"approved","implementationOption":"<the option the user chose>"}'
133
+ ```bash
134
+ okstra user-response plan-decision --transaction <transaction> --status <revision-requested|rejected> --reason-file <reason.md>
158
135
  ```
159
136
 
160
- If any approval-target item is not filled with an answer, or is a reframe/hold, do not approve — tell the user the gate is still open.
137
+ Never infer a plan decision from the user's tone.
161
138
 
162
- A user who turns the plan down gets the same treatment, and the reason is mandatory the next planning run reads it to know what to change:
139
+ Only for a report whose fixed view says `Report contract: 2.0`, an explicit legacy report-authoring decision may be recorded. A reason file in that same temporary directory is always required:
163
140
 
141
+ ```bash
142
+ okstra user-response legacy-report-authoring --transaction <transaction> --status <approved|denied> --reason-file <reason.md>
164
143
  ```
165
- --plan-decision '{"status":"rejected","reason":"<the user's own words>"}'
166
- ```
167
-
168
- Use `revision-requested` instead of `rejected` when the user wants the same plan reworked rather than dropped. Either way, quote the user's reason; do not summarise it into your own.
169
144
 
170
- ## Step 6: Write the sidecar
145
+ Report contract 3.0 rejects this command because report inputs have separate owners.
171
146
 
172
- Run only after the user has confirmed the echo-back with "confirmed":
147
+ ## Step 7: Finalize once
173
148
 
174
149
  ```bash
175
- okstra user-response write --report <reportPath> --answers '<answers-json>' --plan-decision '<plan-decision-json>' --task-key <taskKey>
150
+ okstra user-response finalize --transaction <transaction>
176
151
  ```
177
152
 
178
- - `--answers` = the JSON array of `{id, kind, value, rationale?, disposition}` objects collected in Step 3.
179
- - `--plan-decision` is attached only when recording a decision in Step 5 (otherwise omit it).
180
- - `--task-key` is the value carried forward from Step 1/2.
181
- - Report the path from the returned JSON `{sidecar: <path>}` to the user. (`write` merges items when a sidecar already exists — the same `id` is overwritten with the new value.)
182
-
183
- ## Step 7: Self-describing next-step guidance
153
+ Only `finalize` publishes the sidecar. Report the returned `sidecar` path. A retry with the same transaction returns the same published result.
184
154
 
185
- Leave the following in the final output as-is:
155
+ Leave this guidance in the final answer:
186
156
 
187
- > This answer was recorded in the `user-responses/` sidecar (`<sidecar path>`). Re-running this task's `<task-type>` with `/okstra-run` auto-attaches this answer (if you approved all approval-blocking items, the next phase is `implementation`).
157
+ > This answer was recorded in the `user-responses/` sidecar (`<sidecar path>`). Re-running this task with `/okstra-run` attaches the answer to the next eligible phase.
188
158
 
189
- ## Output Rules (shared)
159
+ ## Output rules
190
160
 
191
- - Keep responses concise and in the language the user is using, unless they ask otherwise.
192
- - Give path guidance host-relative (`~/.okstra/...` or relative to the `projectRoot` preflight returned). Use repo paths only when pointing at a code source.
193
- - This skill never hand-edits a rendered report (`runs/*/reports/*.md` / `*.data.json`). Writing the `user-responses/` sidecar goes only through the `okstra user-response write` CLI.
161
+ - Keep responses in the user's language.
162
+ - Never edit a rendered report, report record, approval ledger, lead events, team state, convergence state, or report-writer narrative.
163
+ - Never edit a `user-responses/` sidecar directly. Publish it only with `user-response finalize`.
164
+ - Never create or parse structured state for these commands. Pass scalar arguments and Markdown body files only.
@@ -1,37 +1,47 @@
1
1
  # Report Writer Prompt Preamble (canonical)
2
2
 
3
- This file is the audience-specific contract for `report-writer`. Read it end-to-end. Before work, also read the shared file named by `**Worker Error Contract Path:**`; error rules live only there.
3
+ This file is the audience-specific contract for `report-writer`. Read it and the shared Worker Error Contract end-to-end.
4
+
5
+ ## Output ownership
6
+
7
+ Write only the report narrative Markdown at `**Result Path:**`, the pointer record at `**Worker Result Path:**`, and the reading audit at `**Audit sidecar path:**`.
8
+
9
+ The report narrative Markdown contains the task judgment, plan, summaries, and user explanation. It must not write or patch `final-report-*.data.json`, the approval decision ledger, activity ledger, team state, convergence state, or design-preparation input.
10
+
11
+ The following fields belong to other owners and must not appear in the narrative: `designPreparation`, `designSurfaceCoverage`, `executionStatus`, `executionRoles`, `tokenUsage`, `crossVerification`, `approvalContext`, `clarificationItems`, `agentActivity`, and `planBodyVerification`.
12
+
13
+ Do not pre-fill a future round, future gate, usage value, activity identifier, or resolution. Report assembly derives those values after their owner input exists.
4
14
 
5
15
  ## Required reading
6
16
 
7
- Read every input enumerated by the Phase 6 dispatch end-to-end: task/analysis inputs, worker results, convergence state, the instruction-set-local `final-report-template.md`, and the task-type excerpt `final-report-schema.json`. Do not pull the full repository template or schema when the scoped instruction-set copies are provided.
17
+ Read every path listed under `## Inputs` end-to-end. Full context is available for synthesis, but read access does not transfer write ownership. Preserve supplied technical meaning and do not invent missing evidence.
18
+
19
+ Write the audit sidecar before synthesis with one `- PROGRESS: <stage> <ISO-8601-UTC>` line and the required reading confirmation. Valid stages are `started`, `required-reading-complete`, `synthesis-start`, `narrative-write-start`, and `write-result-start`.
8
20
 
9
- Write Reading Confirmation to `**Audit sidecar path:**`, not the rendered final report. Resolve `.okstra/**` paths against `**Project Root:**`.
21
+ ## Narrative format
10
22
 
11
- Write `- PROGRESS: <stage> <ISO-8601-UTC>` there before reading and at least every five minutes while pending. The only valid report-writer stages are `started`, `required-reading-complete`, `synthesis-start`, `data-json-write-start`, `render-start`, and `write-result-start`.
23
+ The narrative is not free-form Markdown. A narrative file is the line `# OKSTRA Report Narrative`, then lines of exactly three shapes and nothing else:
12
24
 
13
- ## Report authoring handoff
25
+ - `- **Humanised Field Name**` — one field. Nest a child field by indenting two more spaces.
26
+ - `- Item <N>` — one array entry, numbered `1..N` with no gaps.
27
+ - `> value` — one scalar. Repeat the line for a multi-line value. Write `> _none_` for null, an empty object, or an empty array.
14
28
 
15
- - Author the data.json at `**Result Path:**` and the audit file at `**Audit sidecar path:**`.
16
- - Follow the task-type schema excerpt and Phase 6 report-writer contract. Do not perform independent analysis, edit source code, or load implementation coding-preflight resources.
17
- - Do not invoke `okstra render-final-report`. The full reading copy is rendered on demand.
18
- - Preserve source item IDs, convergence classifications, round history, and unresolved dissent; do not recompute them from intuition.
19
- - Every `clarificationItems[]` row you leave `status: open` with `blocks: approval` carries `origin` and `userConfirmation`. `origin` is `worker-finding` only when an analyser or verifier reached it on its own evidence — when the lead's dispatch prompt told you to raise it, it is `lead-directed`, whatever the workers then agreed. `userConfirmation` is what the lead reports having done about it (`asked-and-answered` / `asked-awaiting` / `deferred-no-interactive-session`); if the dispatch does not say, write `asked-awaiting` and name the gap in your return message rather than guessing. An open approval blocker stops the whole task, so a row that misreports where it came from costs a re-run. **Enforced:** `validators/validate-run.py` `_validate_open_approval_blocker_provenance`.
29
+ Blank lines are ignored. **Every other line is rejected**, including Markdown headings (`#`, `##`, `###`), a pipe table written at column 0, code fences, bare paragraphs, JSON, YAML, and JSON Pointer. A heading or table that belongs in the reader's report is written as the text of a `> ` value, never as a narrative line of its own.
20
30
 
21
- ## Anchor headers
31
+ Follow the task-specific schema order and write the prose in English.
22
32
 
23
- The generated prompt selects this file through `**Worker Preamble Path:**` and includes `**Worker Error Contract Path:**`, `**Audit sidecar path:**`, error paths, and read scope. It never includes `**Coding preflight pack:**`.
33
+ ### Top-level fields you may author
24
34
 
25
- The adjacent v2 prompt metadata supplies `participantRef`, `roleExecutionRef`, `executionLabel`, `invocationRef`, and `attempt`. Copy those values into report and audit identity fields without deriving them from the provider or model. Legacy v1 `workerId` is a read-only compatibility projection and is not written into v2 artifacts.
35
+ These are the only names allowed at the top level:
26
36
 
27
- ## Return message to the lead
37
+ `Analysis Common`, `Change Impact Analysis`, `Error Analysis`, `Feature Analysis`, `Final Verdict`, `Final Verification`, `Follow Up Tasks`, `Human Summary`, `Implementation`, `Implementation Option Selection`, `Implementation Planning`, `Improvement Discovery`, `Project Analysis`, `Rationale`, `Recommended Next Steps`, `Release Handoff`, `Requirements Discovery`, `Summary`, `Ticket Coverage`, `Verdict Card`
28
38
 
29
- Begin the inline return with the exact `**Model:** Report writer worker, <modelExecutionValue>` line from the prompt, followed by the artifact status. Never invent or abbreviate the model.
39
+ Any other top-level name is rejected however reasonable it reads — a section title copied out of a lead procedure document (`Clarification Response Carried In`, `Stage Map`, `Rollback Strategy`) is a heading in that document, not a top-level field here. Nested names come from the task's block in `schemas/final-report-v3.0.schema.json`; when a name is refused, the parser's message lists the names allowed at that exact position, so correct against that list rather than guessing a second time.
30
40
 
31
- ## Writing style
41
+ ## Pointer record
32
42
 
33
- Use concise reader-facing prose. Prefer tables when several items share a shape; reserve bullets for short standalone statements.
43
+ The pointer record names the project-relative narrative path and audit sidecar path. It does not contain the narrative, worker result corpus, or any machine-owned ledger.
34
44
 
35
- **Author the data.json in English, whatever `**Report Language:**` says.** That header is not an instruction to write in that language — it names the language the *human HTML* renders in, and you copy its value verbatim into `data.json.meta.reportLanguage`. The data.json is the English SSOT every later phase, validator and agent reads. When the value is not `en`, Phase 7 dispatches a separate translator worker that writes a sidecar the HTML renderer overlays; you never author that sidecar and never write a second language into the data.json.
45
+ ## Failure handling
36
46
 
37
- Authoring the data.json in the reader's language is rejected before anything derives from it: `okstra report-translate check-source` fails the run when Korean exceeds 20% of its prose, and the same gate runs again inside `validate-run`. The cost of getting this wrong is a full rewrite, so decide it once, up front.
47
+ If a required narrative fact is missing or contradictory, record the report-writer error and stop. If report assembly later reports another owner, do not edit that owner's input; return the failure to the named owner.
@@ -63,6 +63,7 @@
63
63
  {% for row in items %}
64
64
  {% set is_closed = row.status in ['resolved', 'obsolete'] %}
65
65
  {% set approval_context = row.approvalContext | default(None) %}
66
+ {% set resolution = row.resolution | default(None) %}
66
67
  {% set options = row.options | default([]) %}
67
68
  <article class="clarification-item" id="id-{{ row.id }}" data-response-id="{{ row.id }}" data-kind="{{ row.kind }}" data-status="{{ row.status }}">
68
69
  <p class="eyebrow">{{ row.id }} · {{ row.kind }}</p>
@@ -72,9 +73,10 @@
72
73
  <div class="approval-context" data-approval-classification="{{ approval_context.classification }}">
73
74
  <p class="eyebrow">{{ approval_context.classification }}</p>
74
75
  <p><strong>{{ t('tasks.implementation-planning.unblock-condition') }}</strong> {{ approval_context.unblockCondition | inline_code }}</p>
75
- <p><strong>{{ t('tasks.implementation-planning.agent-evidence') }}</strong>
76
- {% for activity_id in approval_context.activityIds %}<a href="#id-{{ activity_id }}">{{ activity_id }}</a>{% if not loop.last %}, {% endif %}{% endfor %}
77
- </p>
76
+ {% set check_refs = resolution.checkRefs if resolution else approval_context.activityIds | default([]) %}
77
+ {% if check_refs %}<p><strong>{{ t('tasks.implementation-planning.agent-evidence') }}</strong>
78
+ {% for activity_id in check_refs %}<a href="#id-{{ activity_id }}">{{ activity_id }}</a>{% if not loop.last %}, {% endif %}{% endfor %}
79
+ </p>{% endif %}
78
80
  </div>
79
81
  {% endif %}
80
82
  {% if options %}
@@ -85,7 +87,7 @@
85
87
  {% if option.disposition | default(None) %}<p class="clarification-option-disposition"><code>{{ option.disposition }}</code></p>{% endif %}
86
88
  <p class="clarification-option-rationale">{{ option.rationale }}</p>
87
89
  <dl class="clarification-option-impact">
88
- <dt>{{ t('macros.forms.scope-impact') }}</dt><dd>{{ option.scopeImpact | join(', ') }}</dd>
90
+ <dt>{{ t('macros.forms.scope-impact') }}</dt><dd>{% if option.reach | default(None) %}{{ option.reach }}{% if option.scopeEffects | default([]) %}, {{ option.scopeEffects | join(', ') }}{% endif %}{% else %}{{ option.scopeImpact | join(', ') }}{% endif %}</dd>
89
91
  <dt>{{ t('macros.forms.added-work') }}</dt><dd>{{ option.addedWork }}</dd>
90
92
  <dt>{{ t('macros.forms.direction-change') }}</dt><dd>{{ option.directionChange }}</dd>
91
93
  </dl>
@@ -200,10 +200,10 @@ Stage 3 ██████░░░░
200
200
  **Solution**: <…>
201
201
 
202
202
  <!-- Everything below this line is transcribed from the planning report the CLI
203
- resolved — `okstra stage-map <task-key> --json` carries each stage's
204
- `acceptance` / `exitContract` / `sliceValue` and the task-level
205
- `rollbackStrategy` / `validationChecklist` / `dependencyMigrationRisk`
206
- rows. Transcribe those rows; do not re-summarise the report body. -->
203
+ resolved — `okstra stage-map <task-key> --text` carries fixed `Stages` and
204
+ `Planning` count/name/value rows for each stage's acceptance, exit contract,
205
+ slice value, and the task-level rollback, validation, and migration-risk
206
+ fields. Transcribe those rows; do not re-summarise the report body. -->
207
207
 
208
208
  **Work Breakdown**:
209
209
 
@@ -1,6 +1,6 @@
1
1
  # Worker Error Contract (canonical)
2
2
 
3
- This audience-neutral file is the single source of truth for every initial worker's error path, sidecar schema, and write protocol. Read it end-to-end from `**Worker Error Contract Path:**` before work.
3
+ This audience-neutral file is the single source of truth for every initial worker's error path and typed write command. Read it end-to-end from `**Worker Error Contract Path:**` before work.
4
4
 
5
5
  ## Error reporting
6
6
 
@@ -12,44 +12,32 @@ Record a tool call only when its failure blocked the step you intended. A non-ze
12
12
 
13
13
  If the non-zero exit changed nothing about what you could do next, it is normal. When in doubt, record the real blocker: under-recording a real blocker is worse than one noisy entry.
14
14
 
15
- If the sidecar does not exist when a real failure occurs, create `{"schemaVersion": 1, "errors": []}` and append one entry.
16
-
17
- ### Entry schema
18
-
19
- ```json
20
- {
21
- "ts": "<ISO 8601 UTC>",
22
- "phase": "<current okstra phase>",
23
- "errorType": "tool-failure",
24
- "command": "<failed command/tool signature>",
25
- "commandKind": "bash | tool:Read | tool:Edit | mcp | ...",
26
- "exitCode": null,
27
- "durationMs": null,
28
- "message": "<one-line human summary>",
29
- "stderrExcerpt": null,
30
- "context": {
31
- "cause": "sandbox-denied | service-unavailable | auth-failed | unknown",
32
- "causeEvidence": {
33
- "targetProbe": "<command + raw output proving the target's state>",
34
- "controlProbe": "<command + raw output proving another target is reachable>"
35
- }
36
- }
37
- }
15
+ For each real failure, invoke this typed command. Replace only the angle-bracket values supplied by the dispatch prompt or observed from the failed call. Do not create a JSON file or pass JSON text.
16
+
17
+ ```bash
18
+ okstra error-log append-observed \
19
+ --out <absolute-errors-log-path> \
20
+ --task-key <task-key> --phase <phase> \
21
+ --agent <assigned-agent> --agent-role worker --model <assigned-model> \
22
+ --error-type tool-failure --command-file <failed-command-file> \
23
+ --command-kind <command-kind> --message-file <message-markdown-file> \
24
+ --cause sandbox-denied \
25
+ --evidence-file targetProbe=<target-probe-file> \
26
+ --evidence-file controlProbe=<control-probe-file>
38
27
  ```
39
28
 
40
- `context` and both `cause` fields are optional; omit `context` entirely (`null`) when there is nothing to add.
29
+ For a cause other than `sandbox-denied`, replace the cause value and omit both `--evidence-file` arguments unless you observed the required probes. Put any free-form message or probe output in the supplied Markdown file rather than relying on shell quoting.
41
30
 
42
31
  ### Rules
43
32
 
44
- - Do not add `source`, `recordedAt`, `agent`, `agentRole`, `model`, or `taskKey`; the lead supplies them when merging the sidecar.
45
- - The sidecar accepts only `errorType: "tool-failure"`. CLI wrappers write `cli-failure` directly to the run log; the lead records `contract-violation`.
46
- - To record a block (sandbox/permission) as the cause, submit `context.cause = "sandbox-denied"` together with both probes in `context.causeEvidence`. Without the probes, leave `cause` as `unknown` — and then keep `message` to what you observed (`connection refused`, `1045 access denied`), not what you infer. A block asserted in `message` prose is rejected exactly like one asserted in `cause`, so "sandbox blocked it" with `cause: unknown` fails the write too. Failing to reach a target and the target being down are not the same fact — never assert the former without checking. Only `sandbox-denied` requires evidence; `service-unavailable` and `auth-failed` do not. Each probe is stored truncated to 256 bytes, so lead with the decisive command and its output.
33
+ - Use only `--error-type tool-failure`. CLI wrappers write `cli-failure` directly to the run log; the lead records `contract-violation`.
34
+ - To record a block (sandbox/permission) as the cause, pass `--cause sandbox-denied` together with both `--evidence-file targetProbe=<target-probe-file>` and `--evidence-file controlProbe=<control-probe-file>`. Without the probes, pass `--cause unknown` — and then keep the `--message-file` content to what you observed (`connection refused`, `1045 access denied`), not what you infer. A block asserted in message prose is rejected exactly like one asserted in the cause. Failing to reach a target and the target being down are not the same fact. Only `sandbox-denied` requires evidence; `service-unavailable` and `auth-failed` do not. Each probe is stored truncated to 256 bytes, so lead with the decisive command and its output.
47
35
  - [Guideline] Put raw output in `stderrExcerpt` verbatim. Never merge several commands' output into one line, summarize it, or elide it with `...`. Once the host, port, and errno are gone, the cause cannot be recovered later.
48
36
  - Continue after recording unless the failure makes the task impossible.
49
37
 
50
38
  ### Path extraction (BLOCKING)
51
39
 
52
- Extract `**Errors log path:**` and `**Errors sidecar path:**` verbatim from the dispatch prompt. If either is absent, return the worker-specific `<SENTINEL_PREFIX>_ERRORS_PATH_MISSING` sentinel and stop. Never synthesize a path from a run-directory pattern.
40
+ Extract `**Errors log path:**` verbatim from the dispatch prompt. If it is absent, return the worker-specific `<SENTINEL_PREFIX>_ERRORS_PATH_MISSING` sentinel and stop. Never synthesize a path from a run-directory pattern.
53
41
 
54
42
  ## Path anchoring
55
43