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
@@ -35,16 +35,16 @@ Do not use it for single-task status analysis or phase execution. Use `okstra-in
35
35
  Run one literal-token preflight call:
36
36
 
37
37
  ```bash
38
- okstra preflight --runtime claude-code --json
38
+ okstra preflight --runtime claude-code
39
39
  ```
40
40
 
41
- On `ok: false`, point the user to `/okstra-setup` and stop. Otherwise:
42
-
43
- 1. Read `.okstra/discovery/task-catalog.json`.
44
- 2. Resolve an explicit task-group from the invocation or host request. If none is unambiguous, ask the user to choose; never guess.
45
- 3. Lowercase the token and strip characters outside `[a-z0-9]`.
46
- 4. Apply the same transform to each catalog `taskGroupPathSegment` and compare only those normalized values.
47
- 5. Read each matched `task-manifest.json`; it is authoritative when the catalog is stale.
41
+ On `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. On
42
+ `Okstra preflight: ready`, carry the fixed `Project root` line. Resolve an
43
+ explicit task-group from the invocation or host request. If none is unambiguous,
44
+ run `okstra model-io task-selection-input --project-root <projectRoot>` and ask
45
+ the user to choose from the fixed `Task` rows; never guess. Then run
46
+ `okstra model-io schedule-input --project-root <projectRoot> --task-group <group>`
47
+ and use only its fixed task metadata rows.
48
48
 
49
49
  On zero matches, report that the task group was not found and do not create a file.
50
50
 
@@ -63,21 +63,18 @@ Do not render `workStatus` as the detailed task status. The per-task `Status` va
63
63
  For every candidate task, call:
64
64
 
65
65
  ```bash
66
- okstra stage-map <task-key> --json
66
+ okstra stage-map <task-key> --text
67
67
  ```
68
68
 
69
- The successful response has this boundary shape:
70
-
71
- ```text
72
- { ok, taskKey, taskRoot, state, sourcePlanPath,
73
- stages:[{stage_number,title,depends_on,step_count}], doneStages:[int] }
74
- ```
69
+ The successful fixed response carries `Status`, `Task key`, `Task root`, `State`,
70
+ `Source plan path`, and lossless numbered `Stages`, `Done stages`, and `Planning`
71
+ count/name/value rows.
75
72
 
76
73
  Handle each result explicitly:
77
74
 
78
- - `state: ready`: use exactly `sourcePlanPath`; do not pick a report by mtime or `latestReportRecordPath`. Select only `stages doneStages`.
79
- - `state: missing`: record an empty source and empty stage sets, mark the task `[NEEDS-PLANNING]`, and emit no forward Work Breakdown, Gantt, or day total for it.
80
- - `ok: false` or another state: stop before drafting and report the structured `stage` and `reason`. A corrupt or conflicting source must never fall back to a guessed report.
75
+ - `Status: ready`, `State: ready`: use exactly `Source plan path`; do not pick a report by mtime or `latestReportRecordPath`. Select only stages not present in the done-stage rows.
76
+ - `Status: ready`, `State: missing`: record an empty source and empty stage sets, mark the task `[NEEDS-PLANNING]`, and emit no forward Work Breakdown, Gantt, or day total for it.
77
+ - `Status: error` or another state: stop before drafting and report `Failure stage` and `Failure reason`. A corrupt or conflicting source must never fall back to a guessed report.
81
78
 
82
79
  A valid selected set is dependency-closed: every transitive prerequisite of a selected stage is either also selected or present in `doneStages`. Completed prerequisites remain evidence only and are never scheduled forward.
83
80
 
@@ -49,7 +49,7 @@ After `okstra install`, every subsequent command must begin with the literal `ok
49
49
  Allowed forms:
50
50
 
51
51
  ```bash
52
- okstra check-project --json
52
+ okstra preflight
53
53
  okstra setup --yes --project-root /abs/project --project-id my-project
54
54
  okstra doctor --runtime claude-code
55
55
  ```
@@ -62,22 +62,22 @@ Forms to avoid:
62
62
  - `$(...)` command substitution
63
63
  - okstra calls wrapped in `if`, `&&`, `||`
64
64
 
65
- Because `okstra <subcmd>` bootstraps its own Python path, do not use `okstra paths --shell` in this skill. If you need a path, run `okstra paths --json` as a separate call and read the JSON value.
65
+ Because `okstra <subcmd>` bootstraps its own Python path, do not use `okstra paths --shell` in this skill. If you need the okstra home, run `okstra paths --field home` as a separate call and carry the printed path.
66
66
 
67
67
  ## Project root resolution
68
68
 
69
69
  Run first:
70
70
 
71
71
  ```bash
72
- okstra check-project --json
72
+ okstra preflight
73
73
  ```
74
74
 
75
75
  Handle the result:
76
76
 
77
- - `ok: true`: already a registered project. Show `projectRoot`, `projectJsonPath`, `projectId` to the user and confirm whether to keep it.
78
- - `ok: false`, `stage: "resolve"`: get an absolute project root from the user and re-run `okstra check-project --cwd /abs/path --json`.
79
- - `ok: false`, `stage: "project_json_missing"`: proceed with the normal create path.
80
- - any other failure stage: show the JSON `reason` verbatim and follow the recovery the source names.
77
+ - `Okstra preflight: ready`: already a registered project. Show `Project root`, `Project JSON`, and `Project ID` to the user and confirm whether to keep it.
78
+ - `Okstra preflight: failed` with `Stage: resolve`: get an absolute project root from the user and re-run `okstra preflight --cwd /abs/path`.
79
+ - `Okstra preflight: failed` with `Stage: project_json_missing`: proceed with the normal create path.
80
+ - any other failure stage: show `Reason` verbatim and follow `Recovery`.
81
81
 
82
82
  ## Create or keep project.json
83
83
 
@@ -11,14 +11,15 @@ digest (`okstra-rollup`).
11
11
  Run preflight, resolve a positive day count (default 30), then call exactly once:
12
12
 
13
13
  ```bash
14
- okstra usage-report --days 30 --project-root <projectRoot> --json
14
+ okstra usage-report --days 30 --project-root <projectRoot> --text
15
15
  ```
16
16
 
17
17
  ## Render contract
18
18
 
19
- Render returned task-type rows and totals without recomputing them. Show Runs,
20
- Coverage, Raw tokens, Billable, Cost, CPU, and Wall. Surface unavailable reason
21
- counts and unmatched model names. Missing usage is excluded data, not zero usage.
19
+ Render the numbered `By task type` rows and fixed totals without recomputing them.
20
+ Show Runs, returned collection rate as Coverage, Raw tokens, Billable, Cost, CPU, and Wall. Surface numbered
21
+ unavailable-reason and unmatched-model rows. Missing usage is excluded data, not
22
+ zero usage.
22
23
 
23
24
  ## Boundaries
24
25
 
@@ -3,51 +3,69 @@
3
3
  ## Sources
4
4
 
5
5
  - Skill source: [`skills/okstra-user-response/SKILL.md`](../../../skills/okstra-user-response/SKILL.md)
6
- - Response core (CLI): [`scripts/okstra_ctl/user_response.py`](../../../scripts/okstra_ctl/user_response.py)
7
- - Node wrapper: [`src/commands/inspect/user-response.mjs`](../../../src/commands/inspect/user-response.mjs)
6
+ - Response core: [`scripts/okstra_ctl/user_response.py`](../../../scripts/okstra_ctl/user_response.py)
7
+ - Node wrapper: [`src/commands/inspect/user-response.mts`](../../../src/commands/inspect/user-response.mts)
8
8
 
9
9
  ## Purpose
10
10
 
11
- `okstra-user-response` answers the **unresolved clarification questions** an okstra run left behind (the open `C-*` rows under the final report's `## 1. Clarification Items`) **in-session**, and records those answers as a `runs/<type>/user-responses/` sidecar. The next `/okstra-run` auto-attaches this sidecar via `--clarification-response`.
11
+ `okstra-user-response` answers unresolved `C-*` clarification items and records explicit plan decisions without hand-editing a report or sidecar. The user selects or writes every answer. Publication changes only the user-owned `runs/<task-type>/user-responses/` sidecar.
12
12
 
13
- **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 does not call `write` until the user has explicitly confirmed (`confirmed`).
13
+ The model-facing reads are fixed text. Do not use the automation-compatible JSON reads to drive a conversation. Do not open the final-report record directly.
14
14
 
15
- **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.
15
+ | Command | Purpose |
16
+ |---|---|
17
+ | `okstra user-response list-view --home <home> --project <projectId> --limit 3` | List tasks that still need clarification answers or a plan decision. |
18
+ | `okstra user-response show-view --report <reportPath> --project-root <projectRoot>` | Show open questions, choices, impact, approval context, plan candidates, and current state after validating project ownership. |
19
+ | `okstra user-response begin --report <reportPath> --task-key <taskKey>` | Open a typed transaction and return an opaque id. |
20
+ | `okstra user-response answer ...` | Add one validated answer to the draft. |
21
+ | `okstra user-response plan-decision ...` | Record an explicit plan decision. |
22
+ | `okstra user-response legacy-report-authoring ...` | Record contract 2.0 report-authoring permission. |
23
+ | `okstra user-response finalize --transaction <transaction>` | Merge and atomically publish the sidecar. |
16
24
 
17
- Distinguish it from starting a run (`okstra-run`), inspecting a finished task (`okstra-inspect`), and generating a brief (`okstra-brief-gen`).
25
+ The legacy `list` and `show` JSON commands remain for automation compatibility. They are not model-facing reads.
18
26
 
19
- ## Sub-commands
27
+ ## Flow
20
28
 
21
- | Sub-command | What it does |
22
- |---|---|
23
- | `list` | List tasks that still have approval-open clarification (newest report first) |
24
- | `show` | Expand one report's open `C-*` rows (statement + options + contextRefs) |
25
- | `write` | Record the collected answers (+ optional approval) as a `user-responses/` sidecar |
29
+ 1. Run `okstra preflight --runtime claude-code`. On `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. On `Okstra preflight: ready`, carry `Project root` and `Project ID`, then run `okstra paths --field home`.
30
+ 2. Select a task from `list-view`.
31
+ 3. Read only `show-view --report <reportPath> --project-root <projectRoot>` for report facts.
32
+ 4. Ask one open clarification at a time.
33
+ 5. Echo the complete response and require an explicit `confirmed` before opening a transaction.
34
+ 6. Begin the transaction, add answers and decisions, then finalize it.
26
35
 
27
- ## Preflight
36
+ Each `options[]` row displays `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`. Contract 3.0 additionally displays `reach`, `scopeEffects`, and row-level `approvalContext`. Show `scopeImpact`, `addedWork`, and `directionChange` in that order. If the view says `not stated in the report`, repeat that text and never infer a value.
28
37
 
29
- A single Bash call with the literal `okstra` token (not wrapped):
38
+ When the user selects a predefined option, pass only the fixed view's one-based option number. Python resolves that option's `disposition`, answer, reach, and scope effects from the validated report:
30
39
 
31
40
  ```bash
32
- okstra preflight --runtime claude-code --json
41
+ okstra user-response answer --transaction <transaction> --clarification-id <C-NNN> --kind <kind> --option-number <N>
33
42
  ```
34
43
 
35
- `ok:true` carry `projectRoot` and `projectId` as literals. `ok:false` point to `/okstra-setup` and stop (retry a specific directory with `--cwd <dir>` a leading `cd` breaks the permission match). Then resolve home once: `okstra paths --field home` → paste it literally into `--home`.
44
+ Every value, rationale, and reason body file must be a regular file under `<projectRoot>/.okstra/tmp/user-response/`; external files and symbolic links are rejected. For direct input, write the user's exact words there and use the mutually exclusive direct form:
36
45
 
37
- ## Flow
46
+ ```bash
47
+ okstra user-response answer --transaction <transaction> --clarification-id <C-NNN> --kind <kind> --disposition <answer|reframe> --value-file <value.md> [--rationale-file <rationale.md>]
48
+ ```
49
+
50
+ Record a plan decision only when the user states it explicitly. Any reason file stays in that same temporary directory:
51
+
52
+ ```bash
53
+ okstra user-response plan-decision --transaction <transaction> --status approved [--implementation-option <candidate-name>]
54
+ okstra user-response plan-decision --transaction <transaction> --status <revision-requested|rejected> --reason-file <reason.md>
55
+ ```
56
+
57
+ The implementation option must match a candidate printed by `show-view`. A report with no open clarification can still require this decision.
58
+
59
+ Contract 2.0 alone supports legacy report-authoring permission. Its reason file stays in that same temporary directory:
60
+
61
+ ```bash
62
+ okstra user-response legacy-report-authoring --transaction <transaction> --status <approved|denied> --reason-file <reason.md>
63
+ ```
64
+
65
+ Finish with:
66
+
67
+ ```bash
68
+ okstra user-response finalize --transaction <transaction>
69
+ ```
38
70
 
39
- 1. **list**: `okstra user-response list --home <home> --project <projectId> --limit 3` → an array of `{taskKey, taskType, seq, reportPath, reportMtime, openBlockerCount, openApprovalCount, unreadable}` (`openBlockerCount` = open rows with `Blocks` in `{approval, next-phase}`; `openApprovalCount` = the `approval`-only subset). If the array is empty, stop with "no open clarification". A 3-option picker (top recommendations + the final option always "Enter directly" for pasting a `reportPath`/`task-key` directly). `unreadable:true` is a §1 format drift — flag it with `⚠` and do not proceed (do not fabricate rows).
40
- 2. **show (data fetch, not a presentation step)**: `okstra user-response show --report <reportPath>` → `rows[]` of `{id, kind, blocks, status, statement, expectedForm, options, contextRefs, resolvedRefs}`. Each `options[]` entry is `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`; `resolvedRefs` carries the `definition` of record coordinates such as `RB-002`. A leftover `§4.7` stays unresolved. Activity-contract v1 approval options 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. Do not print `rows` at the user and **do not paste the raw `statement` as the question** — announce only `<N> open items — I'll go through them one at a time.`
41
- 3. **ask, one item at a time**: iterate the rows in report order, **one item per `AskUserQuestion` call**, headed `[n/N] C-014 — blocks: approval gate`. Per item:
42
- - **Background first**, in the message text above the picker, 3–6 lines: (a) *Situation* — what the run was doing when it stopped here; (b) *What is undecided* — the fork, internal tokens expanded inline from `resolvedRefs[].definition`, plus what is stuck (`approval` → the approval gate stays shut and `implementation` cannot start; `next-phase` → the next phase cannot begin); (c) *What changes with your answer*. Source it from `resolvedRefs[].definition`, else **Read** the report record (`.data.json`) for the cited row id; **never invent it** — say the report is silent instead. Do not chase a `§` number on the full reading copy. Close with `Source: C-014 — "<raw statement>"`.
43
- - **Picker: the row's `options[]` plus `Enter directly`** — slots follow array order, the `role: recommended` entry first with its label suffixed `(Recommended)`, `Enter directly` always last. Each `label` is the option's `answer`; each `description` is `<rationale> — Scope: <scopeImpact> · Added work: <addedWork> · Direction: <directionChange>`, in that fixed order. Never fold the three axes into one phrase. An empty axis is written `not stated in the report` — never inferred. More than three entries: keep the recommended one plus the two alternatives whose `scopeImpact` differs most, and say how many were left out. Never mark anything but `recommended` as recommended.
44
- - **Transcribe**: an `options[]` pick → `value` = that option's `answer` text and `disposition` = that option's `disposition` (`answer` only when absent on a legacy option); `Enter directly` → the user's utterance verbatim, `disposition:"answer"`; free text asking for a re-ask → `disposition:"reframe"` (does not satisfy the approval gate). A question back from the user records nothing — **Read** the ref, explain, re-ask the same item with the same options. Echo `[n/N] C-014 → answer: …` and move on. Each item's JSON: `{id, kind, value, rationale?, disposition}`.
45
- 4. **echo → confirmed gate**: before `write`, echo the whole collection (each `id`·`disposition`·`value`·`rationale`·approval) as-is and get explicit confirmation. Never `write` before `confirmed`. On any change, re-echo and re-confirm.
46
- 5. **plan decision (optional)**: only when the user stated one outright. Approval also needs the approval-blocking items **all filled with an answer**: `--plan-decision '{"status":"approved","implementationOption":"<selected option>"}'`. If any item is unfilled/reframe, do not approve and say the gate is still open. A turn-down takes the same flag with a mandatory reason: `--plan-decision '{"status":"rejected","reason":"<the user's own words>"}'` (`revision-requested` when the same plan should be reworked).
47
- 6. **write**: `okstra user-response write --report <reportPath> --answers '<json>' [--plan-decision '<json>'] --task-key <taskKey>` → report the returned `{sidecar:<path>}`. (When a same-named sidecar exists, the same `id` is overwritten with the new value and merged.)
48
-
49
- ## Output Rules
50
-
51
- - Concise, in the language the user is using.
52
- - Give path guidance host-relative (`~/.okstra/...` or relative to `projectRoot`). Use repo paths only when pointing at a code source.
53
- - **Never hand-edit a rendered report** (`runs/*/reports/*.md` / `*.data.json`). Sidecar recording goes only through the `okstra user-response write` CLI.
71
+ Do not decode the transaction id. Do not inspect transaction state. Do not hand-edit report records, rendered reports, or sidecars.
@@ -58,7 +58,6 @@ okstra/
58
58
  ├── skills/ Claude Code skills (13); `_fragments/` holds shared marker blocks
59
59
  ├── .agents/skills/ Codex repo-local maintainer skills
60
60
  ├── .claude/skills/ Claude Code project-only mirror-sync surface
61
- ├── .claude/settings.json Claude Code project-only mirror-sync surface
62
61
  ├── .codex/hooks.json Codex project lifecycle hooks
63
62
  ├── agents/ native Claude execution-adapter definitions
64
63
  ├── prompts/ launch/profile contracts, duty catalog, wizard prompt JSON
@@ -67,7 +66,7 @@ okstra/
67
66
  ├── validators/ run / brief / schedule / view validators
68
67
  ├── tools/build.mjs source → runtime sync
69
68
  ├── tools/sync-skill-fragments.mjs expand shared fragment blocks into skills/*/SKILL.md
70
- ├── tools/korean-sources/ maintainer-only Korean mirror sync engine
69
+ ├── tools/korean-sources/ maintainer-only Korean mirror drift report
71
70
  ├── config/korean-sources.json configured English Markdown source roots
72
71
  ├── runtime/ generated install payload; do not edit directly
73
72
  ├── tests/ pytest unit suite
@@ -199,15 +198,15 @@ Runtime/install asset changes follow this checklist:
199
198
  | `token-usage` | `src/commands/execute/token-usage.mts` | Wrap installed Python token usage CLI |
200
199
  | `spawn-followups`, `error-log` | `src/commands/execute/*.mts` | Follow-up task bundle creation and run error-log append helpers |
201
200
  | `memory` | `src/commands/memory/memory.mts` | Store/find global conversation memory under `~/.okstra/memory-book` |
202
- | `pr` | `src/commands/pr/pr.mts` | `okstra pr <template\|branches\|gen>` — PR body template store under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`), base-branch recommendation, and the `gen` JSON bundle (template + `<base>..HEAD` commits + `<base>...HEAD` diffstat) backing the okstra-pr-gen skill. Git-only; no project registration required |
201
+ | `pr` | `src/commands/pr/pr.mts` | `okstra pr <template\|branches\|gen>` — PR body template store under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`), base-branch recommendation, and a fixed-text generation bundle for the okstra-pr-gen skill. `--json` preserves the template + `<base>..HEAD` commits + `<base>...HEAD` diffstat machine contract. Git-only; no project registration required |
203
202
  | `recap` | `src/commands/inspect/recap.mts` | `okstra recap <assemble\|record\|note>` Node wrapper backing the okstra-inspect `recap` facet — `assemble` is a read-only phase-transition summary, `record` appends one line to `recap/recap-log.jsonl`, and `note` writes an agent-authored note under `notes/` and prints the `--clarification-response` argument for a follow-up run |
204
203
  | `stage-map` | `src/commands/inspect/stage-map.mts` | `okstra stage-map <task-key>` — exposes a task's implementation-planning Stage Map as JSON (`stages[].{stage_number,title,depends_on,step_count}` + consumer-state-based `doneStages[]`). If there is no Stage Map, `stages: []`. The read-side basis from which `okstra-schedule-gen` derives stage units and dependency closure |
205
204
  | `design-prep` | `src/commands/inspect/design-prep.mts` | `okstra design-prep <list\|show\|write>` thin shim into `scripts/okstra_ctl/design_prep.py` — queries (`list`/`show`) the design items that implementation-planning pre-authored with AI, and records the user-confirmed responses as an append-only sidecar under `design-prep-inputs/` (`write`, `--confirmed` required). It never modifies the report snapshot |
206
- | `rollup` | `src/commands/inspect/rollup.mts` | `okstra rollup` thin shim into `scripts/okstra_ctl/rollup.py` read-only cross-task roll-up backing the okstra-rollup skill |
207
- | `usage-report` | `src/commands/inspect/usage-report.mts` | `okstra usage-report` thin shim into `scripts/okstra_ctl/usage_report.py` read-only project usage snapshot backing the okstra-usage skill |
208
- | `container` | `src/commands/inspect/container.mts` | `bin okstra container` thin shim into `scripts/okstra_ctl/container.py` for the okstra-container-build skill |
205
+ | `rollup` | `src/commands/inspect/rollup.mts` | Read-only roll-up; `--text` is the fixed model projection and machine mode remains JSON |
206
+ | `usage-report` | `src/commands/inspect/usage-report.mts` | Read-only usage snapshot; `--text` is the fixed model projection and machine mode remains JSON |
207
+ | `container` | `src/commands/inspect/container.mts` | Container lifecycle shim; `--text` is the command-specific model projection and machine mode remains JSON |
209
208
  | `code-review` | `src/commands/inspect/code-review.mts` | `okstra code-review target` thin shim into `scripts/okstra_ctl/code_review_target.py` — resolves what one implementation stage's or one branch's review reads (worktree, branch, base/head commits) and where its result file goes, for the okstra-code-review skill. Read-only; creates no directory or file |
210
- | `manager` | `src/commands/manager.mts` | Thin shim into `scripts/okstra_ctl/manager_cli.py` for cross-project manager state and child launch packets |
209
+ | `manager` | `src/commands/manager.mts` | Cross-project manager; fixed text is the default and `--json` selects machine output |
211
210
 
212
211
  `src/lib/python-helper.mts` centralizes Node → Python execution so command modules do not duplicate subprocess wiring.
213
212
 
@@ -247,10 +246,11 @@ Important modules:
247
246
  | `stage_targets.py` | Stage readiness/verification policy SSOT — from the Stage Lifecycle Snapshot (`consumers.jsonl` ledger + carry sidecar backfill + active registry reservation) it decides which stage is runnable, which commit it branches from, and what final-verification checks. `acquire_final_verification_target()` acquires the ledger, registry, worktree, Git, and optional whole-task integration facts behind one task-key mutex and returns a typed target without render-context coupling. `order_stage_closure` topologically sorts (Kahn) the dependency closure of the wizard's multi-selected stage set to produce the unattended `chain-stages` chaining order |
248
247
  | `stage_fix_carry.py` | fix-run carry derivation for a re-run on an `implementation` stage whose latest final-report data.json carries verifier `FAIL` verdicts — collects the previous report path, previous run HEAD, failed verifiers, carried blocking findings, and a routing recommendation, which `run.py` renders into the analysis profile through the `{{FIX_RUN_CONTEXT}}` token. A first run, or a re-run after `PASS`, yields no carry and renders the token empty |
249
248
  | `stage_reconcile.py` | best-effort git reconciliation shared by the stage prepare flow (delegates to `git_reconcile.auto_reconcile`; advisory — failures are only reported to stderr, the dependency gate stays authoritative) |
249
+ | `stage_ledger.py` | assembles the Stage Ledger handed to plan authoring — "what is already built" from the carry sidecar's plan, "which stage numbers are used" from the latest plan (ADR-0015 append-only, judged on the latest plan's `max`); it only joins `stage_targets` (status/lifecycle) and `stage_map` (source-of-stage) and serialises, owning no verdict. Carries `sourcePlan`/`latestPlan` and surfaces `planDivergence`; when the ledger cannot be read it emits the reason in plain text under the same heading instead of omitting the block |
250
250
  | `design_surfaces.py` | deterministic detection of an `implementation-planning` stage's design surface — matches the stage's file-path tokens/suffixes/patterns and action wording via `SurfaceRule` to derive which design input the stage needs among domain contract, DB/table schema, external interface, transaction/consistency, transformation mapping, lifecycle, rollout/observability, and manual user test, plus its evidence (`TriggerEvidence`). An unmappable structure raises `DesignSurfaceError` |
251
251
  | `design_prep.py` | fingerprint / materialize / resolve backend for design-preparation requests (CLI: `okstra design-prep <list\|show\|write>`) — computes an assessment fingerprint from the approved planning snapshot's `ASSESSMENT_FIELDS`, idempotently writes an Okstra-owned request under `design-prep-requests/`, and resolves the highest-revision append-only user response under `design-prep-inputs/` whose fingerprint matches as the effective response. Keeps the three authorities (report snapshot / Okstra request / user input) separate and never modifies the report or existing revisions. Sidecar I/O is protected by a directory-fd anchor + flock |
252
252
  | `incremental_scope.py` | incremental re-verification decision for an `implementation-planning` clarification re-run (deterministic pure function) — reads the dependency graph from the previous run data.json's `implementationPlanning.stageMap` and returns `mode="incremental"` only when the base-ref SHA is unchanged and the affected stages' `downstream_stage_closure` is at most half of all stages. CLI: `okstra incremental-scope` |
253
- | `incremental_carry.py` | carry merge for an incremental re-run — merges the previous run's plan-item verdicts that this run does not re-verify into the current data.json with a `carriedForwardFromSeq` tag. On `schemaVersion` drift it exits non-zero with `CarryError` to force a full fallback. CLI: `okstra incremental-carry` |
253
+ | `incremental_carry.py` | carry merge for an incremental re-run — verifies unchanged carried stage rows and merges their previous plan-item verdicts into the convergence-owned v3 plan state with a `carriedForwardFromSeq` tag. The historical v2 data.json form remains readable. Ownership, scope, or schema drift exits non-zero with `CarryError`. CLI: `okstra incremental-carry` |
254
254
  | `build_tools.py` | allowlist SSOT for deciding whether a plan's command cell invokes the project build toolchain (`npm`/`pytest`/`cargo`/`gradle`/… behind transparent leaders like `sudo`/`env`). The planning worktree has no dependencies installed, so `validators/validate-run.py` uses this to warn (advisory) when a toolchain stage declares no install precondition. Intentionally an allowlist, not a denylist, so unknown tokens go undetected rather than firing on `grep`/`sed` in every plan |
255
255
  | `stage_citations.py` | shared grammar SSOT for reading the Stage Map stage numbers a prose cell cites (`Stages 1, 2, and 3`, ranges, etc.). One definition serves two readers that must not drift — the coverage check in `validators/validate-run.py` proving every stage traces to a requirement, and `incremental_scope.py`'s back-trace resolving which stages an answered clarification touches |
256
256
  | `self_mock_signals.py` | self-mock signal SSOT — language-keyed regexes (`SIGNALS`), the `EXT_TO_LANG` extension map, and the waiver-matching mechanics both gates share — `selfmock_path_key` (the one path-normalization), `waiver_entry_key` (the `(file, line, <discriminator>)` triple, with the hand-typed line coerced to `int`) and `partition_waived_entries` (the split into still-failing vs waived). Gate A passes the discriminator `signal`, gate B `mutant`; one definition means the two cannot disagree about whether a waiver matches a finding. The signals are each ported from a `prompts/coding-preflight/languages/<lang>.md` "Self-mock signals to refuse" bullet with the source `doc_keyword` retained so a drift guard fails when doc and module diverge. Patterns stay deliberately narrow (only the "stub the subject's own method, then assert the stub" shape and reaching into the subject's privates; subject identity is never inferred beyond the literal `sut` token). The static detector `validators/detect_self_mock.py`, the drift guard and `mutation_probe.py` MUST import from here; four documented shapes needing subject identity no regex has are left to the mutation gate (`mutation_probe.py`) |
@@ -272,7 +272,13 @@ Important modules:
272
272
  | `qa_commands.py` | QA command deny-list validation for plans |
273
273
  | `conformance.py` | validates task-level Tier 3 manifests, parses `QA-RESULT`, detects diff capability surfaces, and reduces results to PASS/ADVISORY/BLOCKING; DB/HTTP/external non-PASS is user-owned advisory while local IO and contract defects remain blocking, enforced by `scripts/okstra_ctl/conformance.py::decide_conformance_gate` and `validators/validate-run.py::_validate_conformance`. Also the single definition of the plan's `Conformance tests:` declaration format (`parse_conformance_tests`, `malformed_conformance_stages`), read both at the approval boundary (`run.py::_validate_approved_plan`) and at the end of an implementation run (`validators/validate-run.py`) so the two cannot disagree |
274
274
  | `pr_template.py` | PR body template resolution for release-handoff |
275
- | `report_views.py`, `render_final_report.py`, `final_report_schema.py` | Final-report contract: schema v2 data independently produces the full reading copy Markdown and human HTML |
275
+ | `report_views.py`, `render_final_report.py`, `final_report_schema.py` | Final-report render layer: from the assembled `data.json` (schema v2 or v3) it independently produces the full reading copy Markdown and human HTML; both schema versions render the reading copy from `final-report-v2.template.md` (schema v3 reuses the v2 template for read/render compatibility) |
276
+ | `report_inputs.py` | Report contract 3.0 role-input path + single-owner registry — resolves each owning role's input artifact from the manifest (`narrative` → report-writer, `approval-decisions` → lead, `agent-activity` → activity ledger, `execution-status` → team-state, `convergence`) |
277
+ | `report_assembly.py` | Validates the role-owned report inputs and publishes the contract 3.0 record once (assembled in a temp file, then atomically promoted); a bad input aborts with owner / artifact path / field path / reason and preserves the existing `data.json` |
278
+ | `report_projections.py` | Pure projections turning role-owned execution inputs (agent activity, execution status, convergence, design, token usage) into canonical final-report fragments |
279
+ | `report_narrative.py` | Lossless read/write contract for the report-writer-owned narrative Markdown (`report-narrative-<task-type>-<seq>.md`) — the only artifact the report-writer authors under contract 3.0 |
280
+ | `approval_decisions.py` | Lead-owned approval-decision input ledger — `disposition` (`select`/`accept-risk`/`request-revision`/`reject`), reach, scope effect, and classification invariants (`correctness-critical`/`noncritical-dissent`/`user-decision`) |
281
+ | `design_snapshot.py` | Builds the design-surface-detector-owned snapshot from the report narrative — reproducible design surfaces plus conservative `PREP-NNN` preparation items (delegates surface detection to `design_surfaces.py`) |
276
282
  | `report_markdown.py` | Schema-ordered Markdown serialisation of a data.json subtree for the full reading copy — headings, tables for uniform row sets, prose for narrative fields; field order read from the schema, not from the mapping |
277
283
  | `final_report_paths.py`, `report_view_artifacts.py` | Path-helper SSOT for the final-report markdown/data.json pair and the generated view artifacts (HTML view, user-responses directory) |
278
284
  | `wizard.py` | `okstra-run` prompt state machine; user-facing Korean strings live in `prompts/wizard/prompts.ko.json` |
@@ -298,7 +304,7 @@ Important modules:
298
304
  | `container.py` | the `okstra container` convergence entrypoint of the okstra-container-build public skill — `provision_container_group` + `up`/`status`/`logs`/`stop-watcher`/`down` dispatch, env-override synthesis, compose argv assembly, and per-container watcher startup |
299
305
  | `container_registry.py` | flock-guarded auxiliary index — tracks per-container-group tmux session/pane and watcher findings |
300
306
  | `plan_run_root.py` | shared helper deriving `approved_plan_path` → `plan_run_root` and back-tracing the task-key |
301
- | `manager_cli.py` | `okstra manager` Python entrypoint — manager init/discover/new/task subcommands and JSON output |
307
+ | `manager_cli.py` | `okstra manager` Python entrypoint — purpose-specific fixed text by default, machine JSON with `--json` |
302
308
  | `manager_paths.py` | Manager state path SSOT under `~/.okstra/managers/<manager-id>/`; slug fallback uses `u-<sha1-prefix>` when a safe segment would be empty |
303
309
  | `manager_store.py` | Manager-owned state mutation — project membership, task planning, assignment, directives, event append |
304
310
  | `manager_sync.py` | One-way child project `.okstra` snapshot reader; corrupt child state becomes row-level `error` so other children continue |
@@ -331,18 +337,25 @@ Important modules:
331
337
  | `convergence_engine.py` | pure `ConvergenceEngine` reducer — seeds Round 0 working state, plans roster-aware rounds, applies structured outcomes and one critic-gap batch, finalizes schema v1.3, and validates replayable state without dispatch or filesystem ownership |
332
338
  | `convergence_store.py`, `convergence_migration.py` | atomic JSON persistence plus legacy/new-engine seed decisions; valid terminal finals are reused, while invalid state requires byte-preserving archival before restart |
333
339
  | `convergence.py` | `okstra convergence` internal CLI orchestration for `seed`, `plan-round`, `apply-round`, `apply-critic-gaps`, `finalize`, `validate`, and `example`; it composes the reducer, store, and migration policy without duplicating their decisions |
334
- | `plan_items.py`, `plan_items_cli.py` | deterministic extraction of the report-writer data.json `P-*` plan-item queue plus the `okstra plan-items extract` / `validate` / `seed` / `collect-verdicts` / `apply-verdicts` / `derivations` adapter |
340
+ | `plan_items.py`, `plan_items_cli.py` | deterministic extraction of the report-writer narrative `P-*` plan-item queue plus the `okstra plan-items extract` / `validate` / `seed` / `collect-verdicts` / `apply-verdicts` / `derivations` adapter; v2 data.json remains a read input |
341
+ | `claim_reproduction.py` | reproduces a plan-body single-vote `fact` claim before it can block on one vote — runs the declared probe (`path-exists` / `path-absent` / `literal-present` / `literal-absent` / `citations-differ`) inside the resolved project root and returns `reproduced` / `not-reproduced` / `not-runnable`, which `plan-items apply-verdicts --run-manifest` writes into `reproductionResult` (always overwriting the worker-sent value so a verifier cannot score its own claim). A `judgement` claim, or a `fact` that does not reproduce, takes the quorum route |
335
342
  | `plan_derivations.py` | the supersession sweep `_common-contract.md` requires an author to do by hand — extracts the symbols, paths, and ids an answered clarification names and reports every plan string that mentions one. Advisory: it locates candidates and never judges which are now false |
336
343
  | `scope_provenance.py` | single source of truth for the scope-provenance grammar every phase-emitted requirement must declare, shared by `validators/validate-run.py` and `validators/validate_fanout.py` so the planning report and fan-out packets cannot drift |
337
344
  | `worker_artifact_paths.py` | canonical worker artifact path derivation (e.g. `audit_sidecar_rel` inserts `-audit-` after the first `-worker-` token), so dispatch and validation agree on non-canonical-path rejection |
338
345
  | `report_finalize.py` | Phase 7 post-report sequence **SSOT** — runs `check-source` → `token-usage` → `render-views` → `spawn-followups` → `validate-run` in that load-bearing order, stops at the first non-zero exit and names the failing step — except `token-usage`, whose failure defers so the later steps still produce their artifacts. Both lead paths converge here: the Codex adapter calls it in-process (`codex_dispatch`), a Claude-led run reaches it through `okstra report-finalize`. Neither reimplements the sequence |
339
346
  | `wrapper_status.py` | worker wrapper status sidecar reader — the host-side reader of the sidecar `worker_runner.py` writes. `is_terminal` is the one question it answers for the dispatch record and the pane reclaim: does `stage` read `exited` |
340
347
  | `worker_runner.py` | runs one worker CLI and records what happened — shared by every provider entrypoint. Owns the `selectors` pump over the child's streams, the stream-arrival idle watchdog (`killpg` on breach), the run-wide progress cap on the log copy, and the status sidecar's whole life. A run that dies after launch still closes its sidecar, so `worker_liveness` never reads a dead worker as running |
348
+ | `session_transcript.py` | worker session transcript — one line per event (time, speaker, body) with a run-wide progress-line cap (`LOG_LINE_CAP`, elision notice) so a single-file dispatch's tool echo cannot dominate the project's `.okstra/` bytes; the fixed shape lets a later lead write share the same file |
349
+ | `domain/worker_presentation.py` | provider-output presentation strategy — decides whether to merge stderr into stdout and who receives each stream's lines, so "do not interpret" is a first-class option and the screen does not silently blank when a provider changes its output format |
341
350
  | `worker_request.py` | assembles the `WorkerExecRequest` every strategy then takes on trust: resolved paths, the write scope in the order the CLIs are told it (project root → stage tree → the tree's git-common-dir), the verifier's toolchain grants, and the role's idle budget |
342
351
  | `domain/worker_exec.py` | the provider axis' vocabulary — `WorkerExecRequest`, `ExecCommand`, `ExecutionPolicy`, the `ExecutionStrategy` protocol, and `PolicySupport`, by which a provider that *cannot* express the policy must say so rather than silently run without it |
343
352
  | `domain/worker_stream.py` | the normalised event vocabulary (`Text` / `ToolCall` / `ToolResult` / `Denial` / `Result`) plus its three pure projections: `format_live` (one readable row per event, for the pane), `format_log` (the same plus bodies, for the archive), `final_text` (the closing message alone). Also `content_block_events`, the normaliser for the wire shape keyed on `type` with `message.content` blocks, which three providers share. No files, no clock |
344
353
  | `domain/worker_role.py` | per-role execution budgets — the 1500s/600s idle pair lives here once instead of being re-declared in each wrapper |
345
354
  | `task_target.py` | shared helper resolving `task-key → (task_root, project_root)` (`resolve_task_root`) |
355
+ | `contract_graph.py`, `contract_graph_cli.py` | runtime-contract graph loader + cross-reference/dependency-closure validator and its `okstra contract-check --root <dir> (--profile\|--operation)` CLI boundary. Loads the agent contract schemas (`common`/`role`/`duty`/`profile`/`operation`), validates known role capabilities, and reports the dependency closure with per-file `path`/`schemaVersion`/`sha256`; an invalid contract raises `ContractGraphError` |
356
+ | `json_boundary.py` | strict JSON persistence boundaries for okstra-owned artifacts — a sealed `ExternalJsonSource` (validated producer + path) is the only way owned JSON is read, and `JsonBoundaryError` names artifact / reason / path when a write cannot satisfy its contract; the SSOT that keeps the model out of internal JSON key/path authorship |
357
+ | `fixed_text.py` | shared scalar-line format for the model-facing fixed-text projections — `scalar` neutralises complex values and control characters, `line` renders one static-labelled Markdown list row, and `value_lines` losslessly flattens a JSON-shaped value into fixed name/order/value rows |
358
+ | `model_io_cli.py` | renders purpose-scoped fixed Markdown input from okstra-owned JSON for the model boundary — resolves the current run/project through the run manifest (`validated_run_authority`, `canonical_run_state_artifact`) and emits only each command's allow-listed fields in fixed order instead of expanding arbitrary nested objects |
346
359
 
347
360
  > `i18n.py` (the final-report i18n dictionary loader + Jinja2 lookup) is an intentionally undocumented internal helper — it is a render helper that users and contributors do not need to know about in the canonical docs, so it is excluded from the module map.
348
361
 
@@ -358,7 +371,7 @@ Project resolver and read-only state helpers:
358
371
 
359
372
  Token/cost accounting:
360
373
 
361
- - provider adapters: `claude.py`, `codex.py`, `antigravity.py`
374
+ - provider adapters: `claude.py`, `codex.py`, `antigravity.py`, `grok.py` (`grok.py` reads the Grok Build session docs under `~/.grok/sessions/<percent-encoded-cwd>/`, taking cumulative tokens from the last `params.update.usage.modelUsage` snapshot in `updates.jsonl`)
362
375
  - aggregation: `collect.py`, `blocks.py`, `jsonl_io.py`, `paths.py`
363
376
  - incremental scan cache: `cursor.py` (`$OKSTRA_HOME/cache/token-usage/` byte cursor + usage event extracts; bypass with `--no-cache`)
364
377
  - pricing: `pricing.py`
@@ -397,7 +410,7 @@ Token/cost accounting:
397
410
 
398
411
  ### 4.8 `schemas/`
399
412
 
400
- `schemas/final-report-v2.0.schema.json` is the current final-report data.json contract. The report-writer worker writes `final-report-<task-type>-<seq>.data.json`; independent renderers produce the full reading copy Markdown and task-specific human HTML.
413
+ `schemas/final-report-v3.0.schema.json` is the current final-report data.json contract. The report-writer worker writes only the narrative Markdown. Report assembly combines it with the role-owned machine inputs and atomically publishes `final-report-<task-type>-<seq>.data.json`; independent renderers produce the full reading copy Markdown and task-specific human HTML. `schemas/final-report-v2.0.schema.json` is the historical read contract.
401
414
 
402
415
  The deterministic convergence inputs are `schemas/convergence-groups-v1.0.schema.json`, `schemas/convergence-round-results-v1.0.schema.json`, and `schemas/convergence-critic-results-v1.0.schema.json`. `tools/build.mjs` syncs the entire source `schemas/` directory to `runtime/schemas/`; these JSON Schema files are runtime contracts, not Markdown publication-inventory entries.
403
416
 
@@ -466,24 +479,23 @@ These files are native Claude execution adapters, not provider-neutral LLM trans
466
479
 
467
480
  ### 4.13 `tools/korean-sources/`
468
481
 
469
- The maintainer-only Korean review-mirror lifecycle has one stateful public
470
- boundary: `lifecycle.mjs`. `cli.mjs` and `hooks.mjs` are adapters that call it;
471
- they do not reconstruct observations or transitions. `config.mjs` and
472
- `markdown.mjs` remain pure configuration and protected-Markdown validators.
482
+ The maintainer-only Korean review mirrors. The tool reports which mirrors have
483
+ drifted and checks a translation's structure; a maintainer session does the
484
+ translating and the writing. Nothing here observes edits or runs on its own.
473
485
 
474
486
  | File | Role |
475
487
  |---|---|
476
- | `lifecycle.mjs` | Public lifecycle seam: bootstrap, inspect, evidence transitions, and reviewed-packet application |
477
- | `lifecycle-store.mjs` | Versioned lifecycle store, canonical JSON IDs, v1 migration, and repository lock |
478
- | `lifecycle-observation.mjs` | Current source/mirror snapshots, rename detection, and derived change observations |
479
- | `lifecycle-evidence.mjs` | Decision, direction, review-packet, semantic-confirmation, and approval validation |
480
- | `lifecycle-application.mjs` | Allowed packet operations, journaled idempotent apply, and completion verification |
481
- | `lifecycle-index.mjs` | Korean mirror `.project-docs/INDEX.md` row validation and updates |
482
-
483
- Maintainers follow `tools/korean-sources/workflow.md` through observation,
484
- conditional direction, review packet, semantic confirmation, conditional
485
- approval, and apply. The paired local skills only delegate to that workflow;
486
- they are not published user skills.
488
+ | `cli.mjs` | The three commands: `status`, `validate --source`, `mark --source` |
489
+ | `baseline.mjs` | Drift report and the source/mirror hash pair recorded at the last sync |
490
+ | `config.mjs` | `config/korean-sources.json` validation and source↔mirror path mapping |
491
+ | `markdown.mjs` | Protected-Markdown structure comparison behind `validate` |
492
+ | `path-safety.mjs` | Symlink-refusing repository reads and atomic writes |
493
+
494
+ Source and mirror hold the same document in two languages, so they never hash
495
+ alike and drift cannot be read from the two files alone. `mark` records the pair
496
+ of hashes in `.project-docs/ko-sources/.sync-baseline.json`, which is the only
497
+ state the tool keeps. Maintainers follow `tools/korean-sources/workflow.md`; the
498
+ paired local skills only delegate to it and are not published user skills.
487
499
 
488
500
  ---
489
501
 
@@ -535,7 +547,7 @@ Current report pipeline:
535
547
 
536
548
  1. Analysis workers write worker result files and the separate audit sidecars named by `Audit sidecar path`.
537
549
  2. The lead writes semantic groups; the convergence engine persists working state, per-round plans/results, an optional critic transition, and then a validated `state/convergence-<task-type>-<seq>.json` terminal state: schema v1.3 when newly finalized, or an unchanged historical final schema v1.0, v1.1, or v1.2 returned by `reuse-final`.
538
- 3. Report-writer worker writes `reports/final-report-<task-type>-<seq>.data.json` against the current schema v2 contract, including `humanSummary` and one task-type deliverable.
550
+ 3. Report-writer worker writes `worker-results/report-writer-narrative-<task-type>-<seq>.md`, including `humanSummary` and one task-type deliverable; Phase 7 later assembles the schema v3 report record.
539
551
  4. For implementation-planning, `okstra plan-items extract` creates the complete `P-*` queue, `validate` proves it still matches data.json, and the analyser instances run the separate plan-body verification round.
540
552
  5. Token usage substitution fills usage/cost cells in the report record. The full reading copy is rendered on demand with `okstra render-final-report` from `templates/reports/final-report-v2.template.md`.
541
553
  6. `scripts/okstra-render-report-views.py` independently selects one of eleven dedicated task templates and emits human-facing HTML directly from the same data.json; run validation checks the record and the human HTML. A quick Markdown input retains its legacy conditional path.
@@ -652,7 +664,7 @@ When changing code, keep these docs in sync:
652
664
  - New report field/section: update schema, template, report-writer worker, validator tests, this file's report model if user-visible.
653
665
  - New phase/profile behavior: update `prompts/profiles/*`, `docs/architecture.md`, `docs/cli.md`, and `README.md` if user-facing.
654
666
 
655
- Edit English canonical Markdown sources directly. After changing a path registered in `config/korean-sources.json`, process the local Korean mirror queue with `$sync-korean-sources` or `/sync-korean-sources`. `.project-docs/ko-sources/**` is maintainer-local only: it is neither published nor committed.
667
+ Edit English canonical Markdown sources directly; nothing asks you to touch the Korean mirror in the same change. A maintainer session reconciles the mirrors on its own schedule with `$sync-korean-sources` or `/sync-korean-sources`, which begins by reading `node tools/korean-sources/cli.mjs status`. `.project-docs/ko-sources/**` is maintainer-local only: it is neither published nor committed.
656
668
 
657
669
  ---
658
670
 
@@ -683,4 +695,4 @@ Clarifications now live in the unified `## 1. Clarification Items` table. Deprec
683
695
 
684
696
  ---
685
697
 
686
- *Updated: 2026-08-18 · Source of truth checked against `package.json`, `bin/okstra`, `src/cli-registry.mts`, `src/lib/skill-catalog.mts`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
698
+ *Updated: 2026-08-23 · Source of truth checked against `package.json`, `bin/okstra`, `src/cli-registry.mts`, `src/lib/skill-catalog.mts`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
@@ -76,7 +76,7 @@ flowchart TD
76
76
  A --> G[Round 0 grouping]
77
77
  G --> C[Reducer queue + analyser-instance re-verification]
78
78
  C --> Critic[Optional critic gap reducer transition]
79
- Critic --> RW[Phase 6 report-writer data.json]
79
+ Critic --> RW[Phase 6 report-writer narrative]
80
80
  RW --> Extract[Deterministic plan-item extraction]
81
81
  Extract --> PBV[Phase 6 sub-step<br/>Plan-body verifier round]
82
82
  PBV --> Gate{gate result}
@@ -86,7 +86,7 @@ flowchart TD
86
86
  NoApproval --> P7
87
87
  ```
88
88
 
89
- The artifact sequence is worker results and `Audit sidecar path` → Round 0 grouping → reducer-owned finding queue → analyser-instance re-verification → optional critic transition → report-writer data.json → deterministic plan-item extraction → plan-body verifier round → Phase 7 persistence/finalization. Phase 7 calls `okstra report-finalize`; token substitution produces the canonical Markdown render, followed by HTML render, follow-up materialization, and `validate-run`. The reducer queues only non-consensus findings; it does not send every complete worker result to every other worker.
89
+ The artifact sequence is worker results and `Audit sidecar path` → Round 0 grouping → reducer-owned finding queue → analyser-instance re-verification → optional critic transition → report-writer narrative → deterministic plan-item extraction → plan-body verifier round → single report assembly → Phase 7 rendering and validation. Phase 7 calls `okstra report-finalize`; it collects usage into team state, assembles `data.json`, renders Markdown and HTML, materializes follow-ups, and runs `validate-run`. The reducer queues only non-consensus findings; it does not send every complete worker result to every other worker.
90
90
 
91
91
  Plan-body verification uses a different queue from Phase 5.5. Phase 5.5 verifies worker findings, and the Phase 6 sub-step re-verifies the consolidated plan body produced by the report-writer at the `P-*` plan-item level. The lead must create that queue through `okstra plan-items extract` and prove it is complete with `okstra plan-items validate` before dispatch.
92
92
 
@@ -53,10 +53,13 @@ here because they were previously readable only by tracing the runtime sources.
53
53
  Clarification Items` rows — the `user-response-*.md` sidecars under
54
54
  `runs/implementation-planning/user-responses/`, a sibling of the directory holding the
55
55
  plan itself — are collected into `instruction-set/clarification-response.md`. Those
56
- sidecars are written by the user, not by the report renderer: the report HTML's `Export
57
- user response` button downloads a file the user then saves there, and `okstra
58
- user-response write` writes one directly. The renderer at most pre-creates that
59
- directory empty so the user does not have to; it never puts a sidecar in it.
56
+ sidecars are written by the user, not by the report renderer. The report HTML's `Export
57
+ user response` button downloads a file the user then saves there. The in-session flow
58
+ reads `user-response list-view` and `user-response show-view --report <path>
59
+ --project-root <root>`, then uses `user-response begin`, typed `user-response answer`
60
+ and decision commands, and `user-response finalize` to publish the sidecar. The
61
+ renderer at most pre-creates that directory empty so the user does not
62
+ have to; it never puts a sidecar in it.
60
63
  The plan document is *not* copied: it reaches the run as the `--approved-plan` path and
61
64
  the executor re-reads it there. An explicit `--clarification-response` wins when given;
62
65
  the automatic attachment is the fallback for an implementation run that supplies none
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.179.2",
3
+ "version": "0.183.2",
4
4
  "description": "Host-aware multi-provider cross-verification orchestrator runtime and agent skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.179.2",
3
- "builtAt": "2026-08-20T11:20:27.145Z",
2
+ "package": "0.183.2",
3
+ "builtAt": "2026-08-23T08:48:03.022Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -48,7 +48,7 @@ from the provider name. `lead` is a compatibility alias for `leader`.
48
48
  4. Anchor all file operations to the absolute `Project Root` from the lead prompt. Use absolute paths — do NOT rely on inherited cwd. Never use `cd` to change directory.
49
49
  - **Executor exception (implementation phase only):** when this worker is dispatched as the `Executor` and the lead prompt provides an `EXECUTOR_WORKTREE_PATH` that differs from the session's inherited cwd, cwd-sensitive Bash commands (`cargo *`, `npm *`, `pnpm *`, `bun *`, `pytest`, `make *`, `go *`, language-toolchain test/build commands) MUST be prefixed with `cd <EXECUTOR_WORKTREE_PATH> && ` in the same Bash invocation — e.g. `cd /Users/.../worktrees/foo && cargo test -p bar`. Do NOT wrap the whole thing in `bash -lc "..."` or `bash -c "..."`; pass the chained command directly to the Bash tool so the leading `cd` token remains visible to the permission layer. The `cd` is scoped to the single Bash subshell and does not mutate the session's shell state, so this does not conflict with the "never use cd" rule above (which prevents the worker from drifting the session cwd across calls).
50
50
  - **Executor coding-conventions preflight (BLOCKING, before your first `Edit` / `Write`):** when dispatched as the `Executor`, you MUST run the coding-conventions preflight defined in the executor sidecar (`prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") before writing any code. Use this worker prompt's `**Coding preflight pack:**` anchor header; read that pack's `overview.md` and `clean-code.md`, then follow the routed pack's language → framework → architecture stages, iterating every rule and loading every matching resource (for example `frameworks/node-server.md` and `architectures/hexagonal.md` when their conditions match). The preflight pack is a runtime resource, not an auto-invoked skill; read the files via the Read tool by absolute path.
51
- - **Executor post-write gates (BLOCKING, before your final commit / before claiming done):** the same dispatch prompt carries two gate blocks the lead appends after the preflight — `Pre-commit diff review sweep` (`prompts/profiles/_implementation-diff-review.md`) and `Implementation self-check` (`prompts/profiles/_implementation-self-check.md`). Execute both and record their coverage lines in your worker result exactly as the blocks specify. The codex/antigravity wrappers refuse to launch when an executor prompt lacks these blocks (`*_POSTWRITE_GATE_MISSING`); this worker runs in-process with no wrapper gate, so the contract lands on you directly — if either block is missing from your dispatch prompt, record a `tool-failure` in the errors sidecar and tell the lead to re-dispatch with the blocks included instead of skipping the gates.
51
+ - **Executor post-write gates (BLOCKING, before your final commit / before claiming done):** the same dispatch prompt carries two gate blocks the lead appends after the preflight — `Pre-commit diff review sweep` (`prompts/profiles/_implementation-diff-review.md`) and `Implementation self-check` (`prompts/profiles/_implementation-self-check.md`). Execute both and record their coverage lines in your worker result exactly as the blocks specify. The codex/antigravity wrappers refuse to launch when an executor prompt lacks these blocks (`*_POSTWRITE_GATE_MISSING`); this worker runs in-process with no wrapper gate, so the contract lands on you directly — if either block is missing, record a typed `tool-failure` through `okstra error-log append-observed` and tell the lead to re-dispatch with the blocks included.
52
52
  - **Verifier QA-gate exception:** verifier roles MAY use the same `cd <WORKTREE> && <cmd>` shape when executing project-declared `qaCommands` (lint / format / typecheck / test) from `project.json`, since those commands are cwd-sensitive by nature. Outside the QA gate, verifiers still read with absolute paths only — do NOT use `cd` for file inspection.
53
53
  - **Shell commands must not be able to prompt:** this worker runs inside the host session, so its Bash calls see the user's own shell, where `cp`, `mv`, and `rm` are commonly aliased to their `-i` form. The confirmation that alias raises has nobody to answer it and the dispatch hangs until it is killed. Invoke these as `command cp` / `command mv` / `command rm` — alias expansion is skipped and the tool behaves exactly as written. Do not reach for `-f` instead; it also changes what the tool does on failure (`rm -f` reports success on a path that never existed).
54
54
  - **No extra chaining beyond `cd && cmd`:** the permission matcher only allows the exact two-segment shape `cd <PATH> && <single-command>`. Do NOT append additional pipes, semicolons, redirects, or `&&` chains — e.g. `cd ... && cargo test ... 2>&1 | tail -20; echo "exit:$?"` will trigger a permission prompt every dispatch because the trailing `| tail`, `; echo`, and `2>&1` tokens disqualify the prefix match against `Bash(cargo:*)`. Let Claude Code capture the full stdout/stderr and exit code natively — do not post-process with `tail`, `head`, or `echo "exit:$?"`. If output truncation is genuinely needed, run the command first and read the result in a separate tool call.
@@ -61,7 +61,7 @@ from the provider name. `lead` is a compatibility alias for `leader`.
61
61
 
62
62
  Before producing any output, you MUST:
63
63
 
64
- 1. Extract `**Worker Preamble Path:**` and `**Worker Error Contract Path:**` from the lead prompt and Read both selected files end-to-end with one full-file `Read` each. The preamble owns audience procedure; the error contract owns sidecar schema and write rules. Never replace the selected path with a hard-coded analysis preamble.
64
+ 1. Extract `**Worker Preamble Path:**` and `**Worker Error Contract Path:**` from the lead prompt and Read both selected files end-to-end with one full-file `Read` each. The preamble owns audience procedure; the error contract owns typed error-log write rules. Never replace the selected path with a hard-coded analysis preamble.
65
65
  2. Read every primary input file the lead enumerated under `## Inputs` (or equivalent heading) end-to-end, following the selected preamble. Analysis workers normally receive `analysis-packet.md`; implementation workers receive their role sidecar and approved deliverable inputs.
66
66
  3. When the prompt carries `**Evidence ledger:** required-v1`, follow the selected preamble's `Evidence read ledger` procedure for every claim-evidence file you open. Do not invent a separate audit-row format here.
67
67
 
@@ -91,13 +91,13 @@ After your `Write` to the assigned worker-results file (path provided by Lead as
91
91
  The `**Model:**` line precedes whatever you return — analysis status above, or a convergence reverify verdict summary.
92
92
  2. Do NOT perform additional `Read`, `Grep`, `Glob`, MCP, or self-review tool calls after the file is written.
93
93
  3. Do NOT rewrite the worker-results file with `Write` more than once. If a correction is genuinely required, perform a single `Edit` and then return immediately.
94
- 4. The only exception is recording a `tool-failure` in the errors sidecar when a post-Write failure is itself the failure being reported — return immediately after that single sidecar append.
94
+ 4. The only exception is recording a `tool-failure` with the typed error-log command when a post-Write failure is itself the failure being reported — return immediately after that command.
95
95
 
96
96
  If you find yourself thinking "let me double-check section 3" or "I should read one more file to be safer" after the Write succeeded — stop. Convergence (Phase 5.5) and the Report writer worker (Phase 6) will reconcile gaps across all three workers; over-investing in single-worker depth at the expense of returning quickly is a net loss for the run.
97
97
 
98
98
  ## Error reporting
99
99
 
100
- Record your own tool failures per the file selected by `**Worker Error Contract Path:**`: extract `**Errors sidecar path:**` from the dispatch prompt (return `CLAUDE_WORKER_ERRORS_PATH_MISSING` without proceeding if absent), then append `tool-failure` entries exactly as that shared contract requires. This worker has no external CLI, so MCP and Bash failures use the same sidecar protocol.
100
+ Record your own tool failures per the file selected by `**Worker Error Contract Path:**`: extract `**Errors log path:**` from the dispatch prompt (return `CLAUDE_WORKER_ERRORS_PATH_MISSING` without proceeding if absent), then invoke its typed `okstra error-log append-observed` command. This worker has no external CLI, so MCP and Bash failures use the same typed protocol.
101
101
 
102
102
  ## Notes
103
103