okstra 0.186.6 → 0.187.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (548) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-registry.d.mts +88 -1
  3. package/dist/cli-registry.mjs +68 -111
  4. package/dist/cli-registry.mjs.map +1 -1
  5. package/dist/commands/execute/render-bundle.mjs +0 -1
  6. package/dist/commands/execute/render-bundle.mjs.map +1 -1
  7. package/dist/commands/execute/run.mjs +8 -3
  8. package/dist/commands/execute/run.mjs.map +1 -1
  9. package/dist/commands/lifecycle/check-project.mjs +1 -14
  10. package/dist/commands/lifecycle/check-project.mjs.map +1 -1
  11. package/dist/commands/lifecycle/config.mjs +38 -40
  12. package/dist/commands/lifecycle/config.mjs.map +1 -1
  13. package/dist/commands/lifecycle/doctor.d.mts +22 -7
  14. package/dist/commands/lifecycle/doctor.mjs +77 -49
  15. package/dist/commands/lifecycle/doctor.mjs.map +1 -1
  16. package/dist/commands/lifecycle/install.d.mts +12 -10
  17. package/dist/commands/lifecycle/install.mjs +104 -39
  18. package/dist/commands/lifecycle/install.mjs.map +1 -1
  19. package/dist/commands/lifecycle/paths.mjs +8 -3
  20. package/dist/commands/lifecycle/paths.mjs.map +1 -1
  21. package/dist/commands/lifecycle/preflight.mjs +2 -1
  22. package/dist/commands/lifecycle/preflight.mjs.map +1 -1
  23. package/dist/commands/lifecycle/setup.mjs +22 -36
  24. package/dist/commands/lifecycle/setup.mjs.map +1 -1
  25. package/dist/commands/lifecycle/uninstall.d.mts +4 -2
  26. package/dist/commands/lifecycle/uninstall.mjs +59 -15
  27. package/dist/commands/lifecycle/uninstall.mjs.map +1 -1
  28. package/dist/commands/memory/memory.mjs +7 -1
  29. package/dist/commands/memory/memory.mjs.map +1 -1
  30. package/dist/lib/helper-scripts.d.mts +1 -1
  31. package/dist/lib/helper-scripts.mjs +10 -18
  32. package/dist/lib/helper-scripts.mjs.map +1 -1
  33. package/dist/lib/host-config.d.mts +72 -0
  34. package/dist/lib/host-config.mjs +404 -0
  35. package/dist/lib/host-config.mjs.map +1 -0
  36. package/dist/lib/host-registry-client.d.mts +2 -2
  37. package/dist/lib/host-registry-client.mjs +0 -3
  38. package/dist/lib/host-registry-client.mjs.map +1 -1
  39. package/dist/lib/install-assets.d.mts +1 -0
  40. package/dist/lib/install-assets.mjs +4 -0
  41. package/dist/lib/install-assets.mjs.map +1 -1
  42. package/dist/lib/proc.d.mts +2 -0
  43. package/dist/lib/proc.mjs +12 -0
  44. package/dist/lib/proc.mjs.map +1 -1
  45. package/dist/lib/python-command.d.mts +2 -0
  46. package/dist/lib/python-command.mjs +52 -0
  47. package/dist/lib/python-command.mjs.map +1 -0
  48. package/dist/lib/python-helper.d.mts +2 -5
  49. package/dist/lib/python-helper.mjs +3 -52
  50. package/dist/lib/python-helper.mjs.map +1 -1
  51. package/dist/lib/runtime-payload.d.mts +23 -0
  52. package/dist/lib/runtime-payload.mjs +57 -0
  53. package/dist/lib/runtime-payload.mjs.map +1 -0
  54. package/dist/lib/types.d.mts +24 -13
  55. package/docs/architecture/storage-model.md +21 -5
  56. package/docs/architecture.md +37 -36
  57. package/docs/cli.md +55 -76
  58. package/docs/coding-rules.md +295 -0
  59. package/docs/container.md +10 -36
  60. package/docs/contributor-change-matrix.md +1 -1
  61. package/docs/for-ai/skills/okstra-code-review.md +0 -1
  62. package/docs/for-ai/skills/okstra-container-build.md +8 -41
  63. package/docs/for-ai/skills/okstra-inspect.md +4 -4
  64. package/docs/for-ai/skills/okstra-manager.md +2 -2
  65. package/docs/for-ai/skills/okstra-rollup.md +0 -1
  66. package/docs/for-ai/skills/okstra-run.md +3 -3
  67. package/docs/for-ai/skills/okstra-user-response.md +0 -1
  68. package/docs/performance-improvement-plan-v2.md +1 -1
  69. package/docs/project-structure-overview.md +62 -62
  70. package/docs/task-process/README.md +3 -3
  71. package/docs/task-process/common-flow.md +1 -1
  72. package/docs/task-process/error-analysis.md +3 -3
  73. package/docs/task-process/implementation-planning.md +3 -1
  74. package/docs/task-process/release-handoff.md +1 -1
  75. package/package.json +3 -2
  76. package/runtime/BUILD.json +2 -2
  77. package/runtime/agents/workers/claude-worker.md +6 -11
  78. package/runtime/agents/workers/report-writer-worker.md +1 -1
  79. package/runtime/bin/lib/okstra/cli.sh +4 -0
  80. package/runtime/bin/lib/okstra/globals.sh +2 -0
  81. package/runtime/bin/lib/okstra/interactive.sh +26 -173
  82. package/runtime/bin/lib/okstra/project-resolver.sh +23 -61
  83. package/runtime/bin/lib/okstra/usage.sh +3 -3
  84. package/runtime/bin/okstra-compact-reminder.sh +1 -5
  85. package/runtime/bin/okstra-error-log.py +19 -2
  86. package/runtime/bin/okstra-import-check.py +26 -0
  87. package/runtime/bin/okstra-inject-report-index.py +5 -4
  88. package/runtime/bin/okstra-provider-exec.py +22 -17
  89. package/runtime/bin/okstra-render-final-report.py +16 -6
  90. package/runtime/bin/okstra-render-report-views.py +25 -18
  91. package/runtime/bin/okstra-report-translate.py +30 -18
  92. package/runtime/bin/okstra-spawn-followups.py +4 -0
  93. package/runtime/bin/okstra-token-usage.py +3 -0
  94. package/runtime/bin/okstra.sh +4 -2
  95. package/runtime/bin/okstra_bootstrap.py +58 -0
  96. package/runtime/prompts/coding-preflight/overview.md +1 -1
  97. package/runtime/prompts/duties/planning-worker.md +1 -1
  98. package/runtime/prompts/launch.template.md +35 -9
  99. package/runtime/prompts/lead/convergence.md +96 -87
  100. package/runtime/prompts/lead/okstra-lead-contract.md +63 -12
  101. package/runtime/prompts/lead/plan-body-verification.md +65 -46
  102. package/runtime/prompts/lead/report-writer.md +34 -4
  103. package/runtime/prompts/lead/team-contract.md +4 -1
  104. package/runtime/prompts/profiles/_clarification-recommendation.md +2 -1
  105. package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
  106. package/runtime/prompts/profiles/_common-contract.md +3 -3
  107. package/runtime/prompts/profiles/_coverage-critic.md +1 -1
  108. package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
  109. package/runtime/prompts/profiles/_implementation-executor.md +3 -1
  110. package/runtime/prompts/profiles/_implementation-verifier.md +16 -2
  111. package/runtime/prompts/profiles/error-analysis.md +4 -3
  112. package/runtime/prompts/profiles/final-verification.md +2 -2
  113. package/runtime/prompts/profiles/implementation-planning.md +22 -17
  114. package/runtime/prompts/profiles/implementation.md +3 -2
  115. package/runtime/prompts/profiles/requirements-discovery.md +2 -1
  116. package/runtime/prompts/wizard/prompts.ko.json +29 -8
  117. package/runtime/python/okstra_ctl/__init__.py +6 -27
  118. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -5
  119. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +21 -2
  120. package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +3 -12
  121. package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +40 -22
  122. package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +14 -21
  123. package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +37 -20
  124. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +86 -14
  125. package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +12 -12
  126. package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +4 -7
  127. package/runtime/python/okstra_ctl/agent/__init__.py +1 -0
  128. package/runtime/python/okstra_ctl/{agent_activity.py → agent/activity.py} +12 -1
  129. package/runtime/python/okstra_ctl/{agent_invocation.py → agent/invocation.py} +34 -5
  130. package/runtime/python/okstra_ctl/agent/prompt_cli/__init__.py +19 -0
  131. package/runtime/python/okstra_ctl/agent/prompt_cli/__main__.py +11 -0
  132. package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +215 -0
  133. package/runtime/python/okstra_ctl/agent/prompt_cli/dynamic_verifier.py +155 -0
  134. package/runtime/python/okstra_ctl/agent/prompt_cli/emit.py +66 -0
  135. package/runtime/python/okstra_ctl/agent/prompt_cli/inputs.py +138 -0
  136. package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +408 -0
  137. package/runtime/python/okstra_ctl/agent/prompt_cli/results.py +197 -0
  138. package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +107 -0
  139. package/runtime/python/okstra_ctl/analysis_packet.py +47 -4
  140. package/runtime/python/okstra_ctl/approval_decisions.py +260 -8
  141. package/runtime/python/okstra_ctl/assignment_resolver.py +0 -12
  142. package/runtime/python/okstra_ctl/attempt_evidence.py +12 -24
  143. package/runtime/python/okstra_ctl/blocking_checks.py +251 -0
  144. package/runtime/python/okstra_ctl/brief_frontmatter.py +0 -7
  145. package/runtime/python/okstra_ctl/clarification_items/__init__.py +102 -0
  146. package/runtime/python/okstra_ctl/clarification_items/carry.py +224 -0
  147. package/runtime/python/okstra_ctl/clarification_items/dispositions.py +135 -0
  148. package/runtime/python/okstra_ctl/clarification_items/parsing.py +253 -0
  149. package/runtime/python/okstra_ctl/clarification_items/rows.py +115 -0
  150. package/runtime/python/okstra_ctl/clarification_items/scan.py +215 -0
  151. package/runtime/python/okstra_ctl/clarification_items/sidecars.py +211 -0
  152. package/runtime/python/okstra_ctl/cmux.py +38 -31
  153. package/runtime/python/okstra_ctl/code_review_target.py +163 -1
  154. package/runtime/python/okstra_ctl/conformance.py +23 -0
  155. package/runtime/python/okstra_ctl/container.py +38 -421
  156. package/runtime/python/okstra_ctl/context_cost.py +16 -2
  157. package/runtime/python/okstra_ctl/contract_graph_cli.py +7 -0
  158. package/runtime/python/okstra_ctl/convergence.py +101 -15
  159. package/runtime/python/okstra_ctl/convergence_critic_prompt.py +345 -0
  160. package/runtime/python/okstra_ctl/convergence_engine.py +382 -70
  161. package/runtime/python/okstra_ctl/convergence_store.py +5 -29
  162. package/runtime/python/okstra_ctl/design_prep.py +108 -12
  163. package/runtime/python/okstra_ctl/design_snapshot.py +11 -1
  164. package/runtime/python/okstra_ctl/design_surfaces.py +29 -2
  165. package/runtime/python/okstra_ctl/dispatch_core.py +102 -25
  166. package/runtime/python/okstra_ctl/dispatch_state.py +268 -39
  167. package/runtime/python/okstra_ctl/doctor_cli.py +48 -0
  168. package/runtime/python/okstra_ctl/domain/worker_exec.py +10 -5
  169. package/runtime/python/okstra_ctl/domain/worker_presentation.py +21 -1
  170. package/runtime/python/okstra_ctl/domain/worker_stream.py +52 -21
  171. package/runtime/python/okstra_ctl/domain/write_policy.py +219 -0
  172. package/runtime/python/okstra_ctl/entrypoints/hosts.py +9 -2
  173. package/runtime/python/okstra_ctl/error_log_core.py +1 -1
  174. package/runtime/python/okstra_ctl/error_report.py +14 -0
  175. package/runtime/python/okstra_ctl/error_zip.py +18 -2
  176. package/runtime/python/okstra_ctl/execution_identity.py +100 -7
  177. package/runtime/python/okstra_ctl/execution_manifest.py +67 -20
  178. package/runtime/python/okstra_ctl/execution_mutation_audit.py +90 -8
  179. package/runtime/python/okstra_ctl/final_report_paths.py +17 -0
  180. package/runtime/python/okstra_ctl/final_report_schema.py +90 -16
  181. package/runtime/python/okstra_ctl/git_reconcile.py +22 -2
  182. package/runtime/python/okstra_ctl/handoff.py +24 -1
  183. package/runtime/python/okstra_ctl/ids.py +6 -16
  184. package/runtime/python/okstra_ctl/implementation_direction.py +142 -33
  185. package/runtime/python/okstra_ctl/implementation_options.py +25 -11
  186. package/runtime/python/okstra_ctl/implementation_outcome.py +5 -2
  187. package/runtime/python/okstra_ctl/improvement_lenses.py +0 -14
  188. package/runtime/python/okstra_ctl/incremental_carry.py +69 -8
  189. package/runtime/python/okstra_ctl/incremental_scope.py +173 -12
  190. package/runtime/python/okstra_ctl/index.py +2 -2
  191. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +48 -8
  192. package/runtime/python/okstra_ctl/interactive_cli.py +223 -0
  193. package/runtime/python/okstra_ctl/json_boundary.py +10 -0
  194. package/runtime/python/okstra_ctl/listing.py +0 -91
  195. package/runtime/python/okstra_ctl/locks.py +5 -19
  196. package/runtime/python/okstra_ctl/log_report.py +14 -0
  197. package/runtime/python/okstra_ctl/manager_cli.py +22 -3
  198. package/runtime/python/okstra_ctl/manager_launch.py +4 -8
  199. package/runtime/python/okstra_ctl/material.py +2 -2
  200. package/runtime/python/okstra_ctl/migrate.py +23 -1
  201. package/runtime/python/okstra_ctl/model_cli.py +19 -5
  202. package/runtime/python/okstra_ctl/model_discovery.py +46 -47
  203. package/runtime/python/okstra_ctl/model_io/__init__.py +1 -0
  204. package/runtime/python/okstra_ctl/model_io/lines.py +163 -0
  205. package/runtime/python/okstra_ctl/model_io/references.py +370 -0
  206. package/runtime/python/okstra_ctl/model_io/renderers.py +498 -0
  207. package/runtime/python/okstra_ctl/model_io_cli.py +30 -945
  208. package/runtime/python/okstra_ctl/model_pool.py +10 -6
  209. package/runtime/python/okstra_ctl/models.py +8 -8
  210. package/runtime/python/okstra_ctl/mutation_recovery.py +5 -63
  211. package/runtime/python/okstra_ctl/next_phase.py +121 -69
  212. package/runtime/python/okstra_ctl/pane_reclaim.py +23 -0
  213. package/runtime/python/okstra_ctl/pane_title.py +11 -8
  214. package/runtime/python/okstra_ctl/path_hints.py +36 -11
  215. package/runtime/python/okstra_ctl/paths.py +76 -8
  216. package/runtime/python/okstra_ctl/plan_items.py +132 -16
  217. package/runtime/python/okstra_ctl/plan_items_cli.py +487 -36
  218. package/runtime/python/okstra_ctl/plan_run_root.py +1 -1
  219. package/runtime/python/okstra_ctl/plan_validate_cli.py +51 -0
  220. package/runtime/python/okstra_ctl/plan_verify_cli.py +80 -0
  221. package/runtime/python/okstra_ctl/prepare_error.py +20 -0
  222. package/runtime/python/okstra_ctl/prior_planning.py +157 -0
  223. package/runtime/python/okstra_ctl/profile_show.py +18 -1
  224. package/runtime/python/okstra_ctl/project_setup_cli.py +140 -0
  225. package/runtime/python/okstra_ctl/recap.py +22 -1
  226. package/runtime/python/okstra_ctl/reconcile.py +84 -0
  227. package/runtime/python/okstra_ctl/registry/host_registry.py +18 -1
  228. package/runtime/python/okstra_ctl/render.py +98 -32
  229. package/runtime/python/okstra_ctl/render_final_report.py +3 -7
  230. package/runtime/python/okstra_ctl/report_assembly.py +297 -7
  231. package/runtime/python/okstra_ctl/report_contract.py +32 -7
  232. package/runtime/python/okstra_ctl/report_finalize.py +206 -15
  233. package/runtime/python/okstra_ctl/report_html/common.py +4 -9
  234. package/runtime/python/okstra_ctl/report_html/render.py +11 -12
  235. package/runtime/python/okstra_ctl/report_html/view_models/implementation_planning.py +2 -5
  236. package/runtime/python/okstra_ctl/report_language.py +8 -4
  237. package/runtime/python/okstra_ctl/report_narrative.py +90 -3
  238. package/runtime/python/okstra_ctl/report_projections.py +8 -2
  239. package/runtime/python/okstra_ctl/report_synthesis_packet.py +258 -1
  240. package/runtime/python/okstra_ctl/report_translation.py +2 -35
  241. package/runtime/python/okstra_ctl/report_views.py +4 -22
  242. package/runtime/python/okstra_ctl/resolve_task_key.py +13 -0
  243. package/runtime/python/okstra_ctl/rollup.py +13 -0
  244. package/runtime/python/okstra_ctl/run.py +639 -138
  245. package/runtime/python/okstra_ctl/run_audit.py +13 -0
  246. package/runtime/python/okstra_ctl/run_index_row.py +0 -12
  247. package/runtime/python/okstra_ctl/seeding.py +21 -11
  248. package/runtime/python/okstra_ctl/sequence.py +1 -1
  249. package/runtime/python/okstra_ctl/session.py +64 -14
  250. package/runtime/python/okstra_ctl/set_work_status.py +18 -0
  251. package/runtime/python/okstra_ctl/stage_integrate.py +15 -1
  252. package/runtime/python/okstra_ctl/stage_ledger.py +1 -1
  253. package/runtime/python/okstra_ctl/stage_map.py +57 -11
  254. package/runtime/python/okstra_ctl/stage_map_cli.py +83 -0
  255. package/runtime/python/okstra_ctl/stage_map_view.py +65 -0
  256. package/runtime/python/okstra_ctl/stage_targets.py +3 -12
  257. package/runtime/python/okstra_ctl/task_list_cli.py +138 -0
  258. package/runtime/python/okstra_ctl/task_show_cli.py +66 -0
  259. package/runtime/python/okstra_ctl/task_target.py +4 -16
  260. package/runtime/python/okstra_ctl/team.py +49 -2
  261. package/runtime/python/okstra_ctl/time_report.py +17 -2
  262. package/runtime/python/okstra_ctl/usage_report.py +11 -0
  263. package/runtime/python/okstra_ctl/user_response.py +55 -218
  264. package/runtime/python/okstra_ctl/user_response_values.py +242 -0
  265. package/runtime/python/okstra_ctl/validation_contract.py +3 -0
  266. package/runtime/python/okstra_ctl/verification_target.py +68 -0
  267. package/runtime/python/okstra_ctl/wizard.py +457 -92
  268. package/runtime/python/okstra_ctl/worker_artifacts.py +75 -16
  269. package/runtime/python/okstra_ctl/worker_audit_check.py +22 -0
  270. package/runtime/python/okstra_ctl/worker_dispatch.py +21 -0
  271. package/runtime/python/okstra_ctl/worker_liveness.py +33 -0
  272. package/runtime/python/okstra_ctl/worker_prompt_body.py +15 -2
  273. package/runtime/python/okstra_ctl/worker_prompt_contract.py +98 -7
  274. package/runtime/python/okstra_ctl/worker_prompt_headers.py +24 -2
  275. package/runtime/python/okstra_ctl/worker_prompt_policy.py +18 -3
  276. package/runtime/python/okstra_ctl/worker_request.py +2 -1
  277. package/runtime/python/okstra_ctl/worker_runner.py +16 -9
  278. package/runtime/python/okstra_ctl/worker_state.py +16 -1
  279. package/runtime/python/okstra_ctl/workflow.py +18 -1
  280. package/runtime/python/okstra_ctl/worktree/__init__.py +92 -0
  281. package/runtime/python/okstra_ctl/worktree/cleanliness.py +89 -0
  282. package/runtime/python/okstra_ctl/worktree/decisions.py +127 -0
  283. package/runtime/python/okstra_ctl/worktree/git_ops.py +165 -0
  284. package/runtime/python/okstra_ctl/worktree/linking.py +249 -0
  285. package/runtime/python/okstra_ctl/worktree/naming.py +91 -0
  286. package/runtime/python/okstra_ctl/worktree/provision.py +385 -0
  287. package/runtime/python/okstra_ctl/worktree/sync_config.py +181 -0
  288. package/runtime/python/okstra_ctl/worktree_cli.py +75 -0
  289. package/runtime/python/okstra_ctl/worktree_lookup_cli.py +39 -0
  290. package/runtime/python/okstra_ctl/worktree_registry.py +7 -0
  291. package/runtime/python/okstra_ctl/worktree_status_cli.py +53 -0
  292. package/runtime/python/okstra_ctl/write_policy.py +90 -213
  293. package/runtime/python/okstra_project/__init__.py +0 -4
  294. package/runtime/python/okstra_project/dirs.py +2 -2
  295. package/runtime/python/okstra_project/phase_pointer.py +84 -0
  296. package/runtime/python/okstra_project/slug.py +24 -0
  297. package/runtime/python/okstra_project/state.py +22 -230
  298. package/runtime/python/okstra_token_usage/claude.py +9 -1
  299. package/runtime/python/okstra_token_usage/cli.py +3 -1
  300. package/runtime/python/okstra_token_usage/collect.py +71 -10
  301. package/runtime/python/okstra_token_usage/cursor.py +2 -0
  302. package/runtime/python/okstra_token_usage/grok.py +1 -5
  303. package/runtime/python/okstra_token_usage/paths.py +26 -0
  304. package/runtime/python/okstra_token_usage/pricing.py +19 -7
  305. package/runtime/schemas/convergence-critic-results-v1.0.schema.json +5 -0
  306. package/runtime/schemas/execution-manifest-v2.schema.json +10 -10
  307. package/runtime/schemas/final-report-v2.0.schema.json +13 -26
  308. package/runtime/schemas/final-report-v3.0.schema.json +177 -41
  309. package/runtime/schemas/report-narrative-v3.0.schema.json +3 -2
  310. package/runtime/skills/okstra-brief-gen/SKILL.md +35 -2
  311. package/runtime/skills/okstra-container-build/SKILL.md +16 -47
  312. package/runtime/skills/okstra-inspect/facets/history.md +1 -1
  313. package/runtime/skills/okstra-inspect/facets/status.md +7 -6
  314. package/runtime/skills/okstra-pr-gen/SKILL.md +1 -1
  315. package/runtime/skills/okstra-run/SKILL.md +7 -5
  316. package/runtime/templates/report-writer-prompt-preamble.md +1 -1
  317. package/runtime/templates/reports/brief.template.md +6 -2
  318. package/runtime/templates/reports/error-analysis-input.template.md +2 -0
  319. package/runtime/templates/reports/final-verification-input.template.md +2 -0
  320. package/runtime/templates/reports/html/base.template.html +13 -0
  321. package/runtime/templates/reports/html/i18n/en.json +19 -0
  322. package/runtime/templates/reports/html/i18n/ko.json +19 -0
  323. package/runtime/templates/reports/html/tasks/final-verification.template.html +2 -2
  324. package/runtime/templates/reports/html/tasks/implementation-planning.template.html +19 -9
  325. package/runtime/templates/reports/html/tasks/implementation.template.html +1 -1
  326. package/runtime/templates/reports/implementation-input.template.md +7 -1
  327. package/runtime/templates/reports/implementation-planning-input.template.md +4 -0
  328. package/runtime/templates/reports/quick-input.template.md +2 -0
  329. package/runtime/templates/reports/release-handoff-input.template.md +6 -1
  330. package/runtime/templates/reports/report.js +20 -3
  331. package/runtime/templates/reports/schedule.template.md +2 -0
  332. package/runtime/templates/reports/settings.template.json +0 -10
  333. package/runtime/templates/reports/task-brief.template.md +3 -0
  334. package/runtime/templates/reports/user-response.template.md +7 -3
  335. package/runtime/validators/checks/fixtures-01.py +57 -0
  336. package/runtime/validators/checks/fixtures-02.py +565 -0
  337. package/runtime/validators/checks/runners-01.py +108 -0
  338. package/runtime/validators/checks/validate-assets-01.py +60 -0
  339. package/runtime/validators/checks/validate-prompt-metadata-01.py +261 -0
  340. package/runtime/validators/checks/validate-tasks-01.py +46 -0
  341. package/runtime/validators/checks/validate-tasks-02.py +85 -0
  342. package/runtime/validators/checks/validate-tasks-03.py +61 -0
  343. package/runtime/validators/checks/validate-tasks-04.py +118 -0
  344. package/runtime/validators/forbidden_actions.py +73 -3
  345. package/runtime/validators/lib/common.sh +5 -0
  346. package/runtime/validators/lib/fixtures.sh +7 -591
  347. package/runtime/validators/lib/paths.sh +13 -0
  348. package/runtime/validators/lib/runners.sh +6 -104
  349. package/runtime/validators/lib/summary.sh +1 -1
  350. package/runtime/validators/lib/validate-assets.sh +6 -56
  351. package/runtime/validators/lib/validate-prompt-metadata.sh +6 -257
  352. package/runtime/validators/lib/validate-tasks.sh +9 -294
  353. package/runtime/validators/validate-implementation-plan-stages.py +4 -4
  354. package/runtime/validators/validate-run.py +1369 -2654
  355. package/runtime/validators/validate-workflow.sh +56 -16
  356. package/runtime/validators/validate_improvement_report.py +2 -1
  357. package/runtime/validators/validate_session_conformance.py +295 -49
  358. package/dist/commands/execute/agent-prompt.d.mts +0 -1
  359. package/dist/commands/execute/agent-prompt.mjs +0 -24
  360. package/dist/commands/execute/agent-prompt.mjs.map +0 -1
  361. package/dist/commands/execute/codex-dispatch.d.mts +0 -3
  362. package/dist/commands/execute/codex-dispatch.mjs +0 -6
  363. package/dist/commands/execute/codex-dispatch.mjs.map +0 -1
  364. package/dist/commands/execute/codex-run.d.mts +0 -3
  365. package/dist/commands/execute/codex-run.mjs +0 -62
  366. package/dist/commands/execute/codex-run.mjs.map +0 -1
  367. package/dist/commands/execute/convergence.d.mts +0 -1
  368. package/dist/commands/execute/convergence.mjs +0 -38
  369. package/dist/commands/execute/convergence.mjs.map +0 -1
  370. package/dist/commands/execute/error-log.d.mts +0 -1
  371. package/dist/commands/execute/error-log.mjs +0 -18
  372. package/dist/commands/execute/error-log.mjs.map +0 -1
  373. package/dist/commands/execute/git-reconcile.d.mts +0 -1
  374. package/dist/commands/execute/git-reconcile.mjs +0 -30
  375. package/dist/commands/execute/git-reconcile.mjs.map +0 -1
  376. package/dist/commands/execute/handoff.d.mts +0 -1
  377. package/dist/commands/execute/handoff.mjs +0 -31
  378. package/dist/commands/execute/handoff.mjs.map +0 -1
  379. package/dist/commands/execute/incremental-carry.d.mts +0 -1
  380. package/dist/commands/execute/incremental-carry.mjs +0 -20
  381. package/dist/commands/execute/incremental-carry.mjs.map +0 -1
  382. package/dist/commands/execute/incremental-scope.d.mts +0 -1
  383. package/dist/commands/execute/incremental-scope.mjs +0 -29
  384. package/dist/commands/execute/incremental-scope.mjs.map +0 -1
  385. package/dist/commands/execute/integrate-stages.d.mts +0 -1
  386. package/dist/commands/execute/integrate-stages.mjs +0 -24
  387. package/dist/commands/execute/integrate-stages.mjs.map +0 -1
  388. package/dist/commands/execute/pane-title.d.mts +0 -1
  389. package/dist/commands/execute/pane-title.mjs +0 -20
  390. package/dist/commands/execute/pane-title.mjs.map +0 -1
  391. package/dist/commands/execute/plan-items.d.mts +0 -1
  392. package/dist/commands/execute/plan-items.mjs +0 -9
  393. package/dist/commands/execute/plan-items.mjs.map +0 -1
  394. package/dist/commands/execute/plan-validate.d.mts +0 -1
  395. package/dist/commands/execute/plan-validate.mjs +0 -68
  396. package/dist/commands/execute/plan-validate.mjs.map +0 -1
  397. package/dist/commands/execute/plan-verify.d.mts +0 -1
  398. package/dist/commands/execute/plan-verify.mjs +0 -43
  399. package/dist/commands/execute/plan-verify.mjs.map +0 -1
  400. package/dist/commands/execute/spawn-followups.d.mts +0 -1
  401. package/dist/commands/execute/spawn-followups.mjs +0 -22
  402. package/dist/commands/execute/spawn-followups.mjs.map +0 -1
  403. package/dist/commands/execute/team.d.mts +0 -3
  404. package/dist/commands/execute/team.mjs +0 -66
  405. package/dist/commands/execute/team.mjs.map +0 -1
  406. package/dist/commands/execute/token-usage.d.mts +0 -1
  407. package/dist/commands/execute/token-usage.mjs +0 -19
  408. package/dist/commands/execute/token-usage.mjs.map +0 -1
  409. package/dist/commands/execute/worker-audit-check.d.mts +0 -1
  410. package/dist/commands/execute/worker-audit-check.mjs +0 -34
  411. package/dist/commands/execute/worker-audit-check.mjs.map +0 -1
  412. package/dist/commands/execute/worker-dispatch.d.mts +0 -7
  413. package/dist/commands/execute/worker-dispatch.mjs +0 -64
  414. package/dist/commands/execute/worker-dispatch.mjs.map +0 -1
  415. package/dist/commands/execute/worker-state.d.mts +0 -1
  416. package/dist/commands/execute/worker-state.mjs +0 -28
  417. package/dist/commands/execute/worker-state.mjs.map +0 -1
  418. package/dist/commands/execute/worktree-lookup.d.mts +0 -1
  419. package/dist/commands/execute/worktree-lookup.mjs +0 -92
  420. package/dist/commands/execute/worktree-lookup.mjs.map +0 -1
  421. package/dist/commands/execute/worktree-status.d.mts +0 -1
  422. package/dist/commands/execute/worktree-status.mjs +0 -121
  423. package/dist/commands/execute/worktree-status.mjs.map +0 -1
  424. package/dist/commands/inspect/code-review.d.mts +0 -1
  425. package/dist/commands/inspect/code-review.mjs +0 -32
  426. package/dist/commands/inspect/code-review.mjs.map +0 -1
  427. package/dist/commands/inspect/container.d.mts +0 -1
  428. package/dist/commands/inspect/container.mjs +0 -25
  429. package/dist/commands/inspect/container.mjs.map +0 -1
  430. package/dist/commands/inspect/context-cost.d.mts +0 -1
  431. package/dist/commands/inspect/context-cost.mjs +0 -25
  432. package/dist/commands/inspect/context-cost.mjs.map +0 -1
  433. package/dist/commands/inspect/design-prep.d.mts +0 -1
  434. package/dist/commands/inspect/design-prep.mjs +0 -22
  435. package/dist/commands/inspect/design-prep.mjs.map +0 -1
  436. package/dist/commands/inspect/error-report.d.mts +0 -1
  437. package/dist/commands/inspect/error-report.mjs +0 -25
  438. package/dist/commands/inspect/error-report.mjs.map +0 -1
  439. package/dist/commands/inspect/error-zip.d.mts +0 -1
  440. package/dist/commands/inspect/error-zip.mjs +0 -24
  441. package/dist/commands/inspect/error-zip.mjs.map +0 -1
  442. package/dist/commands/inspect/log-report.d.mts +0 -1
  443. package/dist/commands/inspect/log-report.mjs +0 -26
  444. package/dist/commands/inspect/log-report.mjs.map +0 -1
  445. package/dist/commands/inspect/model-io.d.mts +0 -1
  446. package/dist/commands/inspect/model-io.mjs +0 -25
  447. package/dist/commands/inspect/model-io.mjs.map +0 -1
  448. package/dist/commands/inspect/profile-show.d.mts +0 -1
  449. package/dist/commands/inspect/profile-show.mjs +0 -28
  450. package/dist/commands/inspect/profile-show.mjs.map +0 -1
  451. package/dist/commands/inspect/recap.d.mts +0 -1
  452. package/dist/commands/inspect/recap.mjs +0 -30
  453. package/dist/commands/inspect/recap.mjs.map +0 -1
  454. package/dist/commands/inspect/resolve-task-key.d.mts +0 -1
  455. package/dist/commands/inspect/resolve-task-key.mjs +0 -24
  456. package/dist/commands/inspect/resolve-task-key.mjs.map +0 -1
  457. package/dist/commands/inspect/rollup.d.mts +0 -1
  458. package/dist/commands/inspect/rollup.mjs +0 -25
  459. package/dist/commands/inspect/rollup.mjs.map +0 -1
  460. package/dist/commands/inspect/run-audit.d.mts +0 -1
  461. package/dist/commands/inspect/run-audit.mjs +0 -25
  462. package/dist/commands/inspect/run-audit.mjs.map +0 -1
  463. package/dist/commands/inspect/set-work-status.d.mts +0 -1
  464. package/dist/commands/inspect/set-work-status.mjs +0 -29
  465. package/dist/commands/inspect/set-work-status.mjs.map +0 -1
  466. package/dist/commands/inspect/stage-map.d.mts +0 -1
  467. package/dist/commands/inspect/stage-map.mjs +0 -131
  468. package/dist/commands/inspect/stage-map.mjs.map +0 -1
  469. package/dist/commands/inspect/task-list.d.mts +0 -1
  470. package/dist/commands/inspect/task-list.mjs +0 -149
  471. package/dist/commands/inspect/task-list.mjs.map +0 -1
  472. package/dist/commands/inspect/task-show.d.mts +0 -1
  473. package/dist/commands/inspect/task-show.mjs +0 -108
  474. package/dist/commands/inspect/task-show.mjs.map +0 -1
  475. package/dist/commands/inspect/time-report.d.mts +0 -1
  476. package/dist/commands/inspect/time-report.mjs +0 -24
  477. package/dist/commands/inspect/time-report.mjs.map +0 -1
  478. package/dist/commands/inspect/usage-report.d.mts +0 -1
  479. package/dist/commands/inspect/usage-report.mjs +0 -23
  480. package/dist/commands/inspect/usage-report.mjs.map +0 -1
  481. package/dist/commands/inspect/user-response.d.mts +0 -1
  482. package/dist/commands/inspect/user-response.mjs +0 -35
  483. package/dist/commands/inspect/user-response.mjs.map +0 -1
  484. package/dist/commands/inspect/worker-liveness.d.mts +0 -1
  485. package/dist/commands/inspect/worker-liveness.mjs +0 -45
  486. package/dist/commands/inspect/worker-liveness.mjs.map +0 -1
  487. package/dist/commands/lifecycle/contract-check.d.mts +0 -1
  488. package/dist/commands/lifecycle/contract-check.mjs +0 -18
  489. package/dist/commands/lifecycle/contract-check.mjs.map +0 -1
  490. package/dist/commands/lifecycle/migrate.d.mts +0 -1
  491. package/dist/commands/lifecycle/migrate.mjs +0 -30
  492. package/dist/commands/lifecycle/migrate.mjs.map +0 -1
  493. package/dist/commands/lifecycle/model.d.mts +0 -1
  494. package/dist/commands/lifecycle/model.mjs +0 -22
  495. package/dist/commands/lifecycle/model.mjs.map +0 -1
  496. package/dist/commands/manager.d.mts +0 -3
  497. package/dist/commands/manager.mjs +0 -50
  498. package/dist/commands/manager.mjs.map +0 -1
  499. package/dist/commands/report/agent-activity.d.mts +0 -1
  500. package/dist/commands/report/agent-activity.mjs +0 -20
  501. package/dist/commands/report/agent-activity.mjs.map +0 -1
  502. package/dist/commands/report/approval-decision.d.mts +0 -1
  503. package/dist/commands/report/approval-decision.mjs +0 -21
  504. package/dist/commands/report/approval-decision.mjs.map +0 -1
  505. package/dist/commands/report/design-snapshot.d.mts +0 -1
  506. package/dist/commands/report/design-snapshot.mjs +0 -19
  507. package/dist/commands/report/design-snapshot.mjs.map +0 -1
  508. package/dist/commands/report/finalize.d.mts +0 -4
  509. package/dist/commands/report/finalize.mjs +0 -64
  510. package/dist/commands/report/finalize.mjs.map +0 -1
  511. package/dist/commands/report/inject-report-index.d.mts +0 -1
  512. package/dist/commands/report/inject-report-index.mjs +0 -21
  513. package/dist/commands/report/inject-report-index.mjs.map +0 -1
  514. package/dist/commands/report/render-final-report.d.mts +0 -1
  515. package/dist/commands/report/render-final-report.mjs +0 -23
  516. package/dist/commands/report/render-final-report.mjs.map +0 -1
  517. package/dist/commands/report/render-views.d.mts +0 -1
  518. package/dist/commands/report/render-views.mjs +0 -27
  519. package/dist/commands/report/render-views.mjs.map +0 -1
  520. package/dist/commands/report/translate.d.mts +0 -1
  521. package/dist/commands/report/translate.mjs +0 -33
  522. package/dist/commands/report/translate.mjs.map +0 -1
  523. package/runtime/bin/lib/okstra/tmux-pane.sh +0 -40
  524. package/runtime/bin/lib/okstra-ctl/cmd-batch.sh +0 -59
  525. package/runtime/bin/lib/okstra-ctl/cmd-list.sh +0 -35
  526. package/runtime/bin/lib/okstra-ctl/cmd-open.sh +0 -36
  527. package/runtime/bin/lib/okstra-ctl/cmd-projects.sh +0 -26
  528. package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +0 -29
  529. package/runtime/bin/lib/okstra-ctl/cmd-reindex.sh +0 -38
  530. package/runtime/bin/lib/okstra-ctl/cmd-rerun.sh +0 -345
  531. package/runtime/bin/lib/okstra-ctl/cmd-show.sh +0 -27
  532. package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +0 -92
  533. package/runtime/bin/lib/okstra-ctl/main.sh +0 -41
  534. package/runtime/bin/lib/okstra-ctl/prepare.sh +0 -31
  535. package/runtime/bin/lib/okstra-ctl/usage.sh +0 -23
  536. package/runtime/bin/okstra-central.sh +0 -152
  537. package/runtime/bin/okstra-incremental-carry.py +0 -10
  538. package/runtime/bin/okstra-incremental-scope.py +0 -10
  539. package/runtime/bin/okstra-team-reconcile.sh +0 -36
  540. package/runtime/python/okstra_ctl/agent_prompt_cli.py +0 -1156
  541. package/runtime/python/okstra_ctl/batch.py +0 -60
  542. package/runtime/python/okstra_ctl/clarification_items.py +0 -1050
  543. package/runtime/python/okstra_ctl/container_registry.py +0 -72
  544. package/runtime/python/okstra_ctl/improvement_assignment.py +0 -61
  545. package/runtime/python/okstra_ctl/resolver.py +0 -54
  546. package/runtime/python/okstra_ctl/team_reconcile.py +0 -275
  547. package/runtime/python/okstra_ctl/tmux.py +0 -134
  548. package/runtime/python/okstra_ctl/worktree.py +0 -1099
@@ -53,8 +53,7 @@ okstra/
53
53
  │ ├── okstra_project/ project root / project.json resolver
54
54
  │ ├── okstra_token_usage/ token usage + cost accounting
55
55
  │ ├── okstra_vendor/ vendored Jinja2 / MarkupSafe (final-report rendering)
56
- │ ├── lib/okstra/ Bash helpers for okstra.sh
57
- │ └── lib/okstra-ctl/ Bash control-center subcommands
56
+ │ └── lib/okstra/ Bash helpers for okstra.sh
58
57
  ├── skills/ Claude Code skills (13); `_fragments/` holds shared marker blocks
59
58
  ├── .agents/skills/ Codex repo-local maintainer skills
60
59
  ├── .claude/skills/ Claude Code project-only mirror-sync surface
@@ -153,9 +152,13 @@ Runtime/install asset changes follow this checklist:
153
152
 
154
153
  ### 4.1 `bin/` and `src/` — Node CLI
155
154
 
156
- `bin/okstra` is a thin dynamic-import router. Every command module exports `run(args) -> Promise<number>` or a named install/uninstall runner.
155
+ `bin/okstra` is a thin dynamic-import router.
157
156
 
158
- `src/` is layered: the dispatch table (`src/cli-registry.mts`) stays at the root, shared infrastructure with no command export lives under `src/lib/`, and command modules are grouped by domain under `src/commands/{lifecycle,execute,inspect,report,memory,pr}/`. `npm run build:ts` compiles these sources to `dist/**/*.mjs`; `bin/okstra` executes the compiled output. `scripts/okstra-central.sh` remains the Bash central-state helper.
157
+ `src/cli-registry.mts` is the one routing table, and each entry routes exactly one way. A **Node-owned** command names a module and its exported `run(args) -> Promise<number>` (or a named install/uninstall runner) under `src/commands/{lifecycle,execute,memory,pr}/`; these 15 own npm layout, install manifests, and host resolution, which is knowledge Node holds. Every other command names a **python target** — a module, an installed helper script, or a validator — optionally with a fixed argv prefix and the runtime paths only Node can resolve (`--workspace-root`, `--okstra-bin`). `src/lib/python-command.mts` turns such an entry into a runner; there is no per-command TypeScript file, and `--help` reaches the python parser, which is the single author of that command's help.
158
+
159
+ `npm run build:ts` compiles these sources to `dist/**/*.mjs`; `bin/okstra` executes the compiled output.
160
+
161
+ The Module column below is where the command's behaviour lives — a `src/` module for the Node-owned ones, the routed python file for the rest.
159
162
 
160
163
  | Command | Module | Role |
161
164
  |---|---|---|
@@ -167,50 +170,50 @@ Runtime/install asset changes follow this checklist:
167
170
  | `check-project` | `src/commands/lifecycle/check-project.mts` | Verify project registration |
168
171
  | `preflight` | `src/commands/lifecycle/preflight.mts` | One-call skill preflight: ensure-installed + check-project + host-specific runtime readiness (single JSON) |
169
172
  | `config` | `src/commands/lifecycle/config.mts` | Read/write project/global settings such as PR template path |
170
- | `migrate` | `src/commands/lifecycle/migrate.mts` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
171
- | `git-reconcile` | `src/commands/execute/git-reconcile.mts` | Reconcile stale stage SHAs after external git history changes |
172
- | `handoff` | `src/commands/execute/handoff.mts` | Stage-group release-handoff eligibility / assemble / record helpers |
173
- | `integrate-stages` | `src/commands/execute/integrate-stages.mts` | Merge verified stages into the task worktree and clean stage worktrees |
174
- | `task-list`, `task-show` | `src/commands/inspect/task-list.mts`, `src/commands/inspect/task-show.mts` | Task/run introspection for skills; `task-show` consumes the Python task read-side snapshot |
175
- | `resolve-task-key` | `src/commands/inspect/resolve-task-key.mts` | Resolve a bare task-id to candidate task-keys from the project catalog |
176
- | `set-work-status` | `src/commands/inspect/set-work-status.mts` | Set a task's user-managed `workStatus` in task-manifest.json (Python: `okstra_ctl.set_work_status`) |
177
- | `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.mts` | Read-side task runtime, wrapper log, and error aggregation helpers |
178
- | `run-audit` | `src/commands/inspect/run-audit.mts` | Anomaly detection — checks run artifacts against progress invariants and reports invariant violations, read-only (Python: `okstra_ctl.run_audit`) |
179
- | `worker-liveness` | `src/commands/inspect/worker-liveness.mts` | Report whether pending workers are still alive, so the lead's poll ends a stalled wait early instead of paying the deadline (Python: `okstra_ctl.worker_liveness`) |
180
- | `worker-audit-check` | `src/commands/execute/worker-audit-check.mts` | Apply the Phase 7 worker audit-sidecar rules while the worker session is still alive, so it can fix its own citations (Python: `okstra_ctl.worker_audit_check`, rules in `okstra_ctl.worker_audit_ledger`) |
181
- | `context-cost` | `src/commands/inspect/context-cost.mts` | Estimate task bundle file/read context cost |
182
- | `worktree-lookup` | `src/commands/execute/worktree-lookup.mts` | Look up a task-key's registered worktree |
183
- | `worktree-status` | `src/commands/execute/worktree-status.mts` | Clean-worktree check over source paths only, excluding okstra's provisioned entries and nested stage worktrees (Python: `okstra_ctl.worktree.dirty_entries_excluding_okstra`) |
184
- | `plan-validate` | `src/commands/execute/plan-validate.mts` | Check approved-plan approval marker |
173
+ | `migrate` | `scripts/okstra_ctl/migrate.py` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
174
+ | `git-reconcile` | `scripts/okstra_ctl/git_reconcile.py` | Reconcile stale stage SHAs after external git history changes |
175
+ | `handoff` | `scripts/okstra_ctl/handoff.py` | Stage-group release-handoff eligibility / assemble / record helpers |
176
+ | `integrate-stages` | `scripts/okstra_ctl/stage_integrate.py` | Merge verified stages into the task worktree and clean stage worktrees |
177
+ | `task-list`, `task-show` | `scripts/okstra_ctl/task_list_cli.py`, `scripts/okstra_ctl/task_show_cli.py` | Task/run introspection for skills; `task-show` consumes the Python task read-side snapshot |
178
+ | `resolve-task-key` | `scripts/okstra_ctl/resolve_task_key.py` | Resolve a bare task-id to candidate task-keys from the project catalog |
179
+ | `set-work-status` | `scripts/okstra_ctl/set_work_status.py` | Set a task's user-managed `workStatus` in task-manifest.json (Python: `okstra_ctl.set_work_status`) |
180
+ | `time-report`, `log-report`, `error-report`, `error-zip` | `scripts/okstra_ctl/time_report.py`, `scripts/okstra_ctl/log_report.py`, `scripts/okstra_ctl/error_report.py`, `scripts/okstra_ctl/error_zip.py` | Read-side task runtime, wrapper log, and error aggregation helpers |
181
+ | `run-audit` | `scripts/okstra_ctl/run_audit.py` | Anomaly detection — checks run artifacts against progress invariants and reports invariant violations, read-only (Python: `okstra_ctl.run_audit`) |
182
+ | `worker-liveness` | `scripts/okstra_ctl/worker_liveness.py` | Report whether pending workers are still alive, so the lead's poll ends a stalled wait early instead of paying the deadline (Python: `okstra_ctl.worker_liveness`) |
183
+ | `worker-audit-check` | `scripts/okstra_ctl/worker_audit_check.py` | Apply the Phase 7 worker audit-sidecar rules while the worker session is still alive, so it can fix its own citations (Python: `okstra_ctl.worker_audit_check`, rules in `okstra_ctl.worker_audit_ledger`) |
184
+ | `context-cost` | `scripts/okstra_ctl/context_cost.py` | Estimate task bundle file/read context cost |
185
+ | `worktree-lookup` | `scripts/okstra_ctl/worktree_lookup_cli.py` | Look up a task-key's registered worktree |
186
+ | `worktree-status` | `scripts/okstra_ctl/worktree_status_cli.py` | Clean-worktree check over source paths only, excluding okstra's provisioned entries and nested stage worktrees (Python: `okstra_ctl.worktree.dirty_entries_excluding_okstra`) |
187
+ | `plan-validate` | `scripts/okstra_ctl/plan_validate_cli.py` | Check approved-plan approval marker |
185
188
  | `render-bundle` | `src/commands/execute/render-bundle.mts` | Preview `prepare_task_bundle(render_only=True)` |
186
- | `profile` | `src/commands/inspect/profile-show.mts` | Print a phase profile with `{{INCLUDE:}}` expanded and its lazy-read sidecars appended transitively, so one grep answers whether a task-type covers a rule — a top-level grep alone returns false negatives (Python: `okstra_ctl.profile_show`). Read-only, unlike `render-bundle` |
189
+ | `profile` | `scripts/okstra_ctl/profile_show.py` | Print a phase profile with `{{INCLUDE:}}` expanded and its lazy-read sidecars appended transitively, so one grep answers whether a task-type covers a rule — a top-level grep alone returns false negatives (Python: `okstra_ctl.profile_show`). Read-only, unlike `render-bundle` |
187
190
  | `run` | `src/commands/execute/run.mts` | Host-aware execution front door (`auto` → Claude/Codex/Antigravity/external path selection) |
188
- | `codex-run`, `codex-dispatch` | `src/commands/execute/codex-*.mts` | Codex lead dry-run bundle preparation; `codex-dispatch` is the compatibility alias for provider-neutral worker dispatch |
189
- | `agent-prompt`, `worker-dispatch` | `src/commands/execute/{agent-prompt,worker-dispatch}.mts` | Materialize/verify invocation prompts, record host-native specification/result links, and launch verified CLI assignments through the provider-neutral dispatcher |
190
- | `team` | `src/commands/execute/team.mts` | External lead tmux-pane worker dispatch / await / teardown |
191
- | `convergence` | `src/commands/execute/convergence.mts` | Internal admin CLI for the deterministic Phase 5.5 convergence engine (`seed`/`plan-round`/`apply-round`/`apply-critic-gaps`/`finalize`/`validate`/`example`; Python: `okstra_ctl.convergence`) |
192
- | `plan-items` | `src/commands/execute/plan-items.mts` | Internal admin CLI for deterministic plan-body item extraction and exact-match validation (`extract`/`validate`; Python: `okstra_ctl.plan_items_cli`) |
193
- | `agent-activity` | `src/commands/report/agent-activity.mts` | Thin Node shim for `okstra_ctl.agent_activity`; `append` records one run-bound activity and `project` writes the validated event projection into final-report data |
194
- | `report-finalize` | `src/commands/report/finalize.mts` | Run the whole Phase 7 post-report sequence in contractual order (Python: `okstra_ctl.report_finalize`) — the single reference point shared with the Codex lead adapter |
195
- | `render-views` | `src/commands/report/render-views.mts` | Render schema v2 data with its task-specific human template, or use the quick-report compatibility view |
196
- | `render-final-report`, `inject-report-index` | `src/commands/report/*.mts` | Render the full reading copy Markdown from data.json on demand; v1 index injection remains compatibility-only |
191
+ | `codex-run`, `codex-dispatch` | `scripts/okstra_ctl/run.py`, `scripts/okstra_ctl/worker_dispatch.py` | Codex lead dry-run bundle preparation; `codex-dispatch` is the compatibility alias for provider-neutral worker dispatch |
192
+ | `agent-prompt`, `worker-dispatch` | `scripts/okstra_ctl/agent/prompt_cli/`, `scripts/okstra_ctl/worker_dispatch.py` | Materialize/verify invocation prompts, record host-native specification/result links, and launch verified CLI assignments through the provider-neutral dispatcher |
193
+ | `team` | `scripts/okstra_ctl/team.py` | External lead worker dispatch / await / reclaim / teardown |
194
+ | `convergence` | `scripts/okstra_ctl/convergence.py` | Internal admin CLI for the deterministic Phase 5.5 convergence engine (`seed`/`plan-round`/`apply-round`/`critic-prompt`/`apply-critic-gaps`/`finalize`/`validate`/`example`; Python: `okstra_ctl.convergence`) |
195
+ | `plan-items` | `scripts/okstra_ctl/plan_items_cli.py` | Internal admin CLI for deterministic plan-body item extraction and exact-match validation (`extract`/`validate`; Python: `okstra_ctl.plan_items_cli`) |
196
+ | `agent-activity` | `scripts/okstra_ctl/agent/activity.py` | Thin Node shim for `okstra_ctl.agent.activity`; `append` records one run-bound activity and `project` writes the validated event projection into final-report data |
197
+ | `report-finalize` | `scripts/okstra_ctl/report_finalize.py` | Run the whole Phase 7 post-report sequence in contractual order (Python: `okstra_ctl.report_finalize`) — the single reference point shared with the Codex lead adapter |
198
+ | `render-views` | `scripts/okstra-render-report-views.py` | Render schema v2 data with its task-specific human template, or use the quick-report compatibility view |
199
+ | `render-final-report`, `inject-report-index` | `scripts/okstra-render-final-report.py`, `scripts/okstra-inject-report-index.py` | Render the full reading copy Markdown from data.json on demand; v1 index injection remains compatibility-only |
197
200
  | `wizard` | `src/commands/execute/wizard.mts` | Drive the `okstra-run` interactive state machine, including the final outcome envelope |
198
- | `token-usage` | `src/commands/execute/token-usage.mts` | Wrap installed Python token usage CLI |
199
- | `spawn-followups`, `error-log` | `src/commands/execute/*.mts` | Follow-up task bundle creation and run error-log append helpers |
201
+ | `token-usage` | `scripts/okstra-token-usage.py` | Wrap installed Python token usage CLI |
202
+ | `spawn-followups`, `error-log` | `scripts/okstra-spawn-followups.py`, `scripts/okstra-error-log.py` | Follow-up task bundle creation and run error-log append helpers |
200
203
  | `memory` | `src/commands/memory/memory.mts` | Store/find global conversation memory under `~/.okstra/memory-book` |
201
204
  | `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 |
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 |
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 |
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 |
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 |
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 |
209
- | `manager` | `src/commands/manager.mts` | Cross-project manager; fixed text is the default and `--json` selects machine output |
205
+ | `recap` | `scripts/okstra_ctl/recap.py` | `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 |
206
+ | `stage-map` | `scripts/okstra_ctl/stage_map_cli.py` | `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 |
207
+ | `design-prep` | `scripts/okstra_ctl/design_prep.py` | `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 |
208
+ | `rollup` | `scripts/okstra_ctl/rollup.py` | Read-only roll-up; `--text` is the fixed model projection and machine mode remains JSON |
209
+ | `usage-report` | `scripts/okstra_ctl/usage_report.py` | Read-only usage snapshot; `--text` is the fixed model projection and machine mode remains JSON |
210
+ | `container` | `scripts/okstra_ctl/container.py` | Container lifecycle shim; `--text` is the command-specific model projection and machine mode remains JSON |
211
+ | `code-review` | `scripts/okstra_ctl/code_review_target.py` | `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 |
212
+ | `manager` | `scripts/okstra_ctl/manager_cli.py` | Cross-project manager; fixed text is the default and `--json` selects machine output |
210
213
 
211
- `src/lib/python-helper.mts` centralizes Node → Python execution so command modules do not duplicate subprocess wiring.
214
+ `src/lib/python-helper.mts` centralizes Node → Python execution so nothing duplicates subprocess wiring.
212
215
 
213
- `src/lib/helper-scripts.mts` is the SSOT list of the Python helper scripts that `okstra <cmd>` subcommands front through `runInstalledScript()`. `okstra preflight` asserts every one of them resolves under `~/.okstra/bin` using the same resolver the dispatch path uses, so a stale install fails at the cheap environment gate instead of at the blocking lead step that calls it mid-run. A contract test keeps the list in step with the `scriptName:` literals in `src/commands/**`.
216
+ `src/lib/helper-scripts.mts` is the SSOT list of the Python helper scripts `okstra <cmd>` fronts through `runInstalledScript()`. `okstra preflight` asserts every one of them resolves under `~/.okstra/bin` using the same resolver the dispatch path uses, so a stale install fails at the cheap environment gate instead of at the blocking lead step that calls it mid-run. A contract test keeps the list in step with the registry's `script` targets (`PYTHON_TARGETS` in `src/cli-registry.mts`).
214
217
 
215
218
  ### 4.2 `scripts/` — Runtime source
216
219
 
@@ -219,8 +222,6 @@ Top-level scripts:
219
222
  | File | Role |
220
223
  |---|---|
221
224
  | `okstra.sh` | Bash CLI wrapper around `prepare_task_bundle`, optionally launches `claude` |
222
- | `okstra-ctl.sh` | Bash control center for list/show/open/rerun/reconcile/project commands |
223
- | `okstra-central.sh` | Central run index writer / reconciler entrypoint |
224
225
  | `okstra-{claude,codex,antigravity,grok,kimi}-exec.sh` | Worker CLI entrypoints — four lines each, `exec`ing `okstra-provider-exec.py` with the provider id. They hold no provider logic; adding a flag to one of these instead of to the provider adapter is exactly the drift this shape exists to prevent |
225
226
  | `okstra-provider-exec.py` | The one worker entrypoint: parses the shared positional contract plus `--presentation`, resolves the provider's `ExecutionStrategy` from the registry, refuses a missing CLI before any artifact is written, then hands the run to `okstra_ctl.worker_runner` |
226
227
  | `okstra-wrapper-status.py` | Standalone writer for one worker status sidecar. No longer on the dispatch path — `worker_runner.py` writes the same document in-process |
@@ -229,7 +230,7 @@ Top-level scripts:
229
230
  | `okstra-render-report-views.py` | Render schema v2 task-specific HTML directly from data.json, or a legacy view from quick Markdown |
230
231
  | `okstra-error-log.py` | Normalize worker/lead error sidecars |
231
232
  | `okstra-spawn-followups.py` | Follow-up spawning helper |
232
- | _(removed)_ | `okstra-trace-cleanup.sh` closed harness-owned worker panes with a tmux title scan. It could only work in a tmux-hosted session, and current runs are cmux, so it never closed anything; `okstra team reclaim` / `okstra team teardown` replace it by closing the panes okstra itself opened and recorded (ADR-0012) |
233
+ | _(removed)_ | `okstra-trace-cleanup.sh` closed harness-owned worker panes with a title scan that never matched a cmux surface, so it never closed anything; `okstra team reclaim` / `okstra team teardown` replace it by closing the panes okstra itself opened and recorded (ADR-0012) |
233
234
 
234
235
  ### 4.3 `scripts/okstra_ctl/` — Python orchestration core
235
236
 
@@ -238,7 +239,7 @@ Important modules:
238
239
  | Module | Role |
239
240
  |---|---|
240
241
  | `run.py` | `prepare_task_bundle()` single authority and CLI parser; for final-verification it adapts CLI stage input into `FinalVerificationTargetRequest`, maps the acquired target into render context, and owns `verification-target.md` snapshot/digest materialization before manifests and prompts are rendered |
241
- | `agent_activity.py` | Records activity rows against run-manifest identity, imports validated command evidence from worker audit sidecars, and deterministically projects the current run's `lead-events-*.jsonl` activity rows into `agentActivity[]`. Manifests without `activityContractVersion: 1` are left unchanged. |
242
+ | `agent/activity.py` | Records activity rows against run-manifest identity, imports validated command evidence from worker audit sidecars, and deterministically projects the current run's `lead-events-*.jsonl` activity rows into `agentActivity[]`. Manifests without `activityContractVersion: 1` are left unchanged. |
242
243
  | `exact_coverage.py` | Shared pure calculator for requirement coverage and scope precision in option selection and selected-direction planning |
243
244
  | `implementation_options.py` | Option-selection criteria, weighting, candidate fingerprint convergence, ranking, and semantic validation |
244
245
  | `implementation_direction.py` | Selected report/response validation, direction snapshot materialization, and selected-direction reference validation |
@@ -247,6 +248,7 @@ Important modules:
247
248
  | `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 |
248
249
  | `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
250
  | `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 |
251
+ | `prior_planning.py` | assembles the `## Prior Planning Run` packet block for an `implementation-planning` re-run entered by `--selected-direction` — resolves the newest prior planning report the way the wizard does (`RunRef.latest_under`) and carries four compact pieces: the report path, that report's `## 1. Clarification Items` rows (through `clarification_items.carried_clarification_rows`, the same narrowing the clarification carry-in uses), its Stage Map one line per stage, and the findings its convergence state left `contested` / `worker-unique`. Every piece is best-effort: an unreadable or absent artifact omits its sub-block rather than failing the run, and the report body itself is never copied |
250
252
  | `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
253
  | `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
254
  | `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; an unlinked `C-NNN` is `mode="unresolved"` (needs `--impacted`), not full. CLI: `okstra incremental-scope` |
@@ -265,9 +267,9 @@ Important modules:
265
267
  | `workflow.py` | Phase sequence (`PHASE_SEQUENCE`), per-phase allowed outputs, forbidden actions. It does not decide the next phase — that is `next_phase.py` |
266
268
  | `next_phase.py` | `workflow.nextRecommendedPhase` SSOT — the pointer's shape (`make` / `is_pointer` over `{phase, status, rationale}`, `status` ∈ `ready`/`pending`/`blocked`/`terminal`), the promotion of a legacy string pointer (`promote`), the projection of one report's routing field into a pointer (`project`), and the `ready`-only read the shell and wizard autofill share (`autofill_task_type`). There is no static phase table and no sequence walk: the next phase comes from what the report authored, and nothing else may compute one |
267
269
  | `workers.py`, `models.py` | Worker roster; `models.py` is the model catalog SSOT (`ModelSpec` per alias + `ROLE_DEFAULTS`) — add-a-model single reference point from which picker options, codex pricing, and role defaults all derive |
268
- | `worktree.py`, `worktree_registry.py` | One worktree per task-key, branch registry, sync dirs/files/snapshots |
270
+ | `worktree/`, `worktree_registry.py` | One worktree per task-key, branch registry, sync dirs/files/snapshots. The package layers the job: `naming` (path/branch strings, no disk), `sync_config` (which paths follow the checkout across), `git_ops` (the git calls), then `cleanliness` (dirty by okstra's definition), `linking` (installs the symlinks), `decisions` (answers what provisioning would do, without doing it), and `provision` — the only layer with side effects |
269
271
  | `project_meta.py`, `resolver.py`, `path_resolve.py` | Project/task/run resolution |
270
- | `clarification_items.py` | Unified §5 clarification table parser and approval blockers |
272
+ | `clarification_items/` | Unified §5 clarification table parser and approval blockers. `parsing` walks the §1 table, `dispositions` decides what an answer means (it opens nothing), `rows` reads either schema, `sidecars` handles user responses, and `scan` / `carry` build on those for the fail-closed gate read and the next run's carry-in |
271
273
  | `md_table.py` | Markdown pipe-table escape/split SSOT — the `mdcell` filter (`escape_pipes`) and the `\|`-aware `split_pipe_row`; shared by the renderer, HTML view, and validators |
272
274
  | `qa_commands.py` | QA command deny-list validation for plans |
273
275
  | `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 |
@@ -284,7 +286,7 @@ Important modules:
284
286
  | `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) |
285
287
  | `wizard.py` | `okstra-run` prompt state machine; user-facing Korean strings live in `prompts/wizard/prompts.ko.json` |
286
288
  | `wizard_stage_intent.py` | stage-related intent projection of the `okstra-run` wizard output — normalizes whole-task (`__whole_task__`) vs single/multi stage selection into render-args (`resolve_wizard_stage_intent`) |
287
- | `index.py`, `jsonl.py`, `reconcile.py`, `listing.py`, `batch.py`, `backfill.py` | `~/.okstra` run index and history operations |
289
+ | `index.py`, `jsonl.py`, `reconcile.py`, `listing.py`, `backfill.py` | `~/.okstra` run index and history operations — `record_start` (index.py) writes a run's start; the end is closed either by `settle_run_row` (reconcile.py, records a verdict the caller already knows — used by `validate-run.py`) or by `reconcile_home` (infers one from disk — used by `run._reconcile_prior_runs` as the backstop for runs that died before validation) |
288
290
  | `run_index_row.py` | single reference point for creating / slimming / hydrating a `~/.okstra` run-index row — runId SSOT, preserves projectId raw |
289
291
  | `error_report.py`, `error_log_core.py`, `error_zip.py` | backend for the okstra-inspect errors/error-zip facets — `error_log_core` is the read-only core that globs/parses/aggregates `errors-*.jsonl`, `error_report` renders the errors facet, and `error_zip` collects cross-project run directories, allowlist-anonymizes, aggregates clusters, and produces a zip |
290
292
  | `error_log_write.py` | the single writer for `errors-*.jsonl`, shared by the `okstra error-log` CLI and by `dispatch_core`, which records a wrapper's non-zero exit as a `cli-failure` in-process. Owns the agent/role/error-type allow-lists (agents derived from the provider registry) and the cause-evidence gate |
@@ -293,29 +295,27 @@ Important modules:
293
295
  | `log_report.py`, `time_report.py` | read-side backend for the okstra-inspect logs/time facets (`okstra log-report` pairs each wrapper transcript `.log` with its sibling prompt `.md` and reports both byte counts without changing legacy transcript-size fields; `okstra time-report` is per-task time aggregation) |
294
296
  | `rollup.py` | read-side backend for the okstra-rollup skill — fans the catalog out per task-group (or the whole project) and deterministically aggregates each task's run count, elapsed time (raw ms), error count, and latest report path, plus group-level totals/status, category, and phase distribution. Reuses the `time_report`/`error_log_core` functions and delegates report-body synthesis to the skill |
295
297
  | `usage_report.py` | Read-only okstra-usage backend — scans the whole current project's recent run timelines, defaults to 30 days, and returns task-type coverage, raw/billable tokens, known USD cost, CPU-sum and wall-clock milliseconds, unavailable reason counts, and unmatched pricing models |
296
- | `json_registry.py` | shared flock + atomic JSON persistence for small okstra registries (`registry_lock`/`load_registry_json`/`save_registry_json`) — shared by `container_registry` and `worktree_registry` |
298
+ | `json_registry.py` | shared flock + atomic JSON persistence for small okstra registries (`registry_lock`/`load_registry_json`/`save_registry_json`) — used by `worktree_registry` |
297
299
  | `stage_integrate.py` | whole-task stage integration (merge) + worktree teardown core (`integrate_stages`) — shared by whole-task final-verification entry, `okstra integrate-stages`, and container up |
298
300
  | `resolve_task_key.py` | shared skill helper resolving a bare task-id → `task-catalog.json` candidate entries (`okstra resolve-task-key`) |
299
301
  | `code_review_paths.py` | filesystem-layout SSOT for code-review result files — `stage_review_dir` / `branch_review_dir` plus `next_stage_review` / `next_branch_review`, which read the existing files to derive the next round's name (`stage-<NN>.md`, then `-r2`, `-r3`, …) or the next same-day sequence (`<YYYY-MM-DD>-<NN>.md`), so skill markdown never re-derives a literal review path |
300
302
  | `code_review_target.py` | `okstra code-review target` backend — argument validation and JSON shaping only. Stage mode delegates whole to `okstra_project.state.code_review_target_snapshot`; branch mode is resolved here, defaulting the diff base to the merge-base with the default branch (`refs/remotes/origin/HEAD`, else `main`/`master`). Read-only: it never creates the review directory |
301
- | `session.py`, `tmux.py`, `seeding.py`, `locks.py`, `invocation.py`, `sequence.py`, `ids.py`, `material.py` | Supporting lifecycle helpers |
303
+ | `session.py`, `seeding.py`, `locks.py`, `invocation.py`, `sequence.py`, `ids.py`, `material.py` | Supporting lifecycle helpers |
302
304
  | `pane_reclaim.py` | resolves which runs of the current project still hold a non-terminal dispatch, so the `SessionStart(compact)` hook can re-inject the pane-cleanup obligation for them. The signal is the newest `team-state` per run directory, not the central run index — an in-session run never appears there (ADR-0011). Imports the status split from the `dispatch_state.NON_TERMINAL_WORKER_STATUSES` SSOT |
303
305
  | `improvement_lenses.py` | lens enum SSOT + cap constants for the improvement-discovery phase (DEFAULT 8, ABSOLUTE 12, MIN/MAX PRIORITY 1/4, SOURCE_WORKERS) |
304
- | `improvement_assignment.py` | improvement-discovery primary-pass lens assignment — round-robins the resolved `requiredWorkerRoles` order over the resolved priority lenses (`assign_primary_lenses`) and validates the resulting map (`validate_primary_lens_assignments`). Only the primary pass rotates; every analyser still confirms the full lens set afterwards |
305
- | `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 |
306
- | `container_registry.py` | flock-guarded auxiliary index — tracks per-container-group tmux session/pane and watcher findings |
306
+ | `container.py` | the `okstra container` convergence entrypoint of the okstra-container-build public skill — `provision_container_group` + `up`/`status`/`down` dispatch, env-override synthesis, compose argv assembly, and healthcheck polling |
307
307
  | `plan_run_root.py` | shared helper deriving `approved_plan_path` → `plan_run_root` and back-tracing the task-key |
308
308
  | `manager_cli.py` | `okstra manager` Python entrypoint — purpose-specific fixed text by default, machine JSON with `--json` |
309
309
  | `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 |
310
310
  | `manager_store.py` | Manager-owned state mutation — project membership, task planning, assignment, directives, event append |
311
311
  | `manager_sync.py` | One-way child project `.okstra` snapshot reader; corrupt child state becomes row-level `error` so other children continue |
312
312
  | `manager_launch.py` | Child launch packet and manager child context renderer; records `prepared` launch metadata/events without changing project-local task state |
313
- | `agent_invocation.py` | Deep invocation-contract module — composes model assignment, common/functional duty, and task instructions; publishes immutable prompt/metadata pairs; verifies five digests; owns standalone result/completion envelopes |
314
- | `agent_prompt_cli.py` | CLI boundary for run-backed and standalone materialization/verification plus host-native dispatch and result-link records |
313
+ | `agent/invocation.py` | Deep invocation-contract module — composes model assignment, common/functional duty, and task instructions; publishes immutable prompt/metadata pairs; verifies five digests; owns standalone result/completion envelopes |
314
+ | `agent/prompt_cli/` | CLI boundary for run-backed and standalone materialization/verification plus host-native dispatch and result-link records. `inputs` resolves the path arguments this model-facing surface cannot trust and `emit` writes the result; above them `run_identity` refuses a role the run never issued and `dynamic_verifier` reserves a re-verification slot only after that role qualifies; `materialize` authors the specification, `results` links what came back, and `cli` is the argparse surface with the command's canonical USAGE epilog |
315
315
  | `dispatch_state.py` | Provider-neutral `WorkerJob`, invocation metadata validation, immutable host-native dispatch/result-link recording, and shared team-state mutation helpers |
316
316
  | `dispatch_core.py` | Backend-neutral worker dispatch core — verifies invocation metadata immediately before worker execution, then records and collects code-owned process/pane attempts shared by every lead runtime |
317
317
  | `worker_dispatch.py` | Provider-neutral deterministic dispatcher for every `runner=cli-wrapper` assignment; it never composes or rewrites a prompt |
318
- | `cmux.py` | cmux-pane worker backend — mirrors the tmux backend's contract (a worker that gets a pane frees the lead process; anything that stops a pane opening degrades quietly to the blocking wrapper, recording a surface UUID rather than a tmux pane id). Detects a usable cmux session before selecting the backend (CLI resolves + ping answers PONG + the lead's workspace is resolvable), derives placement from the workspace geometry each dispatch, relays lead/worker events to the cmux sidebar, and records the run's terminal backend in the manifest so both phases of a run land on one backend. A sandbox that hides cmux (`PermissionError` on the socket) stops dispatch with the remedy instead of degrading into the same broken fallback; a quit app (`FileNotFoundError`) still degrades |
318
+ | `cmux.py` | cmux-pane worker backend — a worker that gets a pane frees the lead process, and anything that stops a pane opening degrades quietly to the blocking wrapper. Detects a usable cmux session before selecting the backend (CLI resolves + ping answers PONG + the lead's workspace is resolvable), derives placement from the workspace geometry each dispatch, relays lead/worker events to the cmux sidebar, and records the run's terminal backend in the manifest so both phases of a run land on one backend. A sandbox that hides cmux (`PermissionError` on the socket) stops dispatch with the remedy instead of degrading into the same broken fallback; a quit app (`FileNotFoundError`) still degrades |
319
319
  | `codex_dispatch.py` | Compatibility adapter delegating `okstra codex-dispatch` to the provider-neutral `worker_dispatch` path |
320
320
  | `analysis_packet.py` | assembles the compact analysis-worker input packet for a task run from worker-owned profile sections; report/lead procedure stays outside the packet |
321
321
  | `analysis_inputs.py` | shared input boundary for `project-analysis`, `feature-analysis`, and `change-impact-analysis` — validates evidence-report identity and review status, enforces the type-to-type relation allowlist, computes `exact`/`stale` freshness, and resolves free-text or `PF-NNN` feature targets for both wizard and prepare paths |
@@ -328,7 +328,6 @@ Important modules:
328
328
  | `registry/host_registry.py`, `registry/provider_registry.py` | Discover bundled adapters plus explicit user installs under `~/.okstra/adapters/{hosts,providers}/<id>/`; project-local adapter code is outside the discovery roots |
329
329
  | `adapters/hosts/`, `adapters/providers/` | Six bundled host strategies and the independent provider catalogs; host manifests select a native provider without merging the two axes |
330
330
  | `lead_events.py` | Structured JSONL events emitted by artifact-accounted lead runtimes. Its locked append path assigns monotonic `A-NNN` identifiers to activity events in the same canonical event file. |
331
- | `team_reconcile.py` | stale team-member reconciliation at run-end teardown |
332
331
  | `worker_prompt_headers.py` | shared rendering of phase-aware worker prompt anchors (`worker_prompt_headers`): coding-preflight only for implementation and compact target identity for final-verification |
333
332
  | `worker_prompt_body.py` | provider-neutral initial analysis body/input renderer shared by Codex and external/team dispatch paths |
334
333
  | `report_language.py` | report-writer `**Report Language:**` resolution (`resolve_report_language`) — precedence project config → global config → task-brief inference, shared by both dispatchers so the stamped language does not depend on which dispatch path ran |
@@ -337,7 +336,8 @@ Important modules:
337
336
  | `initial_prompt_materialization.py` | sole owner of roster-derived initial prompt rendering, request compatibility checks, contract validation, and immutable create-if-absent publication; exposes `materialize_initial_prompts(InitialPromptMaterializationRequest) -> tuple[Path, ...]` |
338
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 |
339
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 |
340
- | `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 |
339
+ | `convergence.py` | `okstra convergence` internal CLI orchestration for `seed`, `plan-round`, `apply-round`, `critic-prompt`, `apply-critic-gaps`, `finalize`, `validate`, and `example`; it composes the reducer, store, and migration policy without duplicating their decisions |
340
+ | `convergence_critic_prompt.py` | renders the coverage-critic seed body `okstra convergence critic-prompt` prints — the Round 0 consolidated findings, one line per Phase 4 analyser (worker id, result path, its finding ids), the two mandates plus the `duplicateOf` rule, and, on an implementation-planning re-run, an already-covered index of the prior report's requirement-coverage row ids, clarification row ids, and stage titles. Ids and titles only; the prior report's body is never copied |
341
341
  | `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 |
342
342
  | `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 |
343
343
  | `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 |
@@ -356,7 +356,7 @@ Important modules:
356
356
  | `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` |
357
357
  | `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 |
358
358
  | `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 |
359
- | `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 |
359
+ | `model_io_cli.py`, `model_io/` | 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. `model_io_cli.py` is the argparse surface only; inside the package, `references` resolves paths and reads JSON, `lines` turns an already-read mapping into fixed Markdown and opens nothing, and `renderers` composes the two into one function per command |
360
360
 
361
361
  > `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.
362
362
 
@@ -451,7 +451,7 @@ Boilerplate shared by several skills (bash invocation rule, outdated-CLI preflig
451
451
  | `okstra-rollup` | yes | Cross-task roll-up — aggregate runs/time/errors across a task-group (or whole project) and synthesize a digest from the report files |
452
452
  | `okstra-usage` | yes | Read-only project usage snapshot — aggregate recent run coverage, tokens, known cost, CPU, and wall-clock time by task type (default: 30 days) |
453
453
  | `okstra-schedule-gen` | yes | Generate task-group schedule |
454
- | `okstra-container-build` | yes | Non-linear deploy tool — deploy a verified task's code as a docker compose group and watch each container (sub-commands `up` / `status` / `logs` / `stop-watcher` / `down`) |
454
+ | `okstra-container-build` | yes | Non-linear deploy tool — deploy a verified task's code as a docker compose group (sub-commands `up` / `status` / `down`) |
455
455
  | `okstra-pr-gen` | yes | Register PR body templates under `~/.okstra/template/pr/` and generate a PR description from a branch diff (drives `okstra pr template` / `branches` / `gen`). **Global skill** — needs a Git repo, not `<PROJECT_ROOT>/.okstra/project.json` |
456
456
  | `okstra-manager` | yes | Coordinate cross-project okstra tasks through manager-owned plans, assignments, sync snapshots, status, and child launch context packets |
457
457
  | `okstra-setup` | yes | Install/check runtime and register project |
@@ -473,7 +473,7 @@ These files are native Claude execution adapters, not provider-neutral LLM trans
473
473
  ### 4.12 `tests/` and `tests-e2e/`
474
474
 
475
475
  - `tests/`: pytest modules organized by production boundary. `domain/wizard/` owns wizard state and answer behavior, `application/` owns use-case and render orchestration tests, and `adapters/{hosts,host_contract,providers,dispatch,accounting}/` owns external strategy contracts. Existing `run/`, `contract/`, `report/`, `inspect/`, `worktree/`, and `handoff/` folders retain their narrower responsibilities. The shared path SSOT is `tests/_paths.py` (`REPO_ROOT`/`TESTS_DIR`/`FIXTURES`), and the repo-root `pytest.ini` adds `tests/` to the import path. Fixtures live in `tests/fixtures/`.
476
- - `tests-e2e/`: `scenario-<id>-<name>.sh` shell scenarios (record-start/reconcile, rerun, task lock, agent install, report view, etc.).
476
+ - `tests-e2e/`: `scenario-<id>-<name>.sh` shell scenarios (record-start, agent install, report view, git-reconcile squash, CLI-surface and read-only-output goldens, etc.).
477
477
  - Each behavior branch has one owning test at the lowest practical layer.
478
478
  - An end-to-end scenario must cross the public CLI or installed-runtime boundary.
479
479
  - Tests replace operating-system resources and wall-clock waits with controlled doubles.
@@ -548,7 +548,7 @@ Single-stage `final-verification --stage <N>` reuses the matching implementation
548
548
  Current report pipeline:
549
549
 
550
550
  1. Analysis workers write worker result files and the separate audit sidecars named by `Audit sidecar path`.
551
- 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`.
551
+ 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.4 when newly finalized, or an unchanged historical final schema v1.0, v1.1, v1.2, or v1.3 returned by `reuse-final`.
552
552
  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.
553
553
  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.
554
554
  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`.
@@ -26,7 +26,7 @@ flowchart TD
26
26
  W --> A[render-args]
27
27
  A --> B[okstra render-bundle<br/>--render-only]
28
28
  B --> P[prepare_task_bundle()]
29
- P --> I[instruction-set<br/>lead-execution-prompt.md]
29
+ P --> I["runs/task-type/prompts<br/>lead-execution-prompt-*.md"]
30
30
  I --> L[Current host session<br/>takes over as Okstra lead]
31
31
  L --> F[Phase 1-7 lead workflow]
32
32
  F --> O[final-report + manifests + status]
@@ -60,7 +60,7 @@ Launch selection is role slots and model refs, not a provider roster. The wizard
60
60
  | implementation stage selection/provisioning | [`scripts/okstra_ctl/implementation_stage.py`](../../scripts/okstra_ctl/implementation_stage.py) |
61
61
  | Stage Lifecycle Snapshot + stage target/base/verification policy | [`scripts/okstra_ctl/stage_targets.py`](../../scripts/okstra_ctl/stage_targets.py) |
62
62
  | phase boundary | [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py) |
63
- | task worktree | [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py) |
63
+ | task worktree | [`scripts/okstra_ctl/worktree/`](../../scripts/okstra_ctl/worktree/) |
64
64
  | stage-group handoff | [`scripts/okstra_ctl/handoff.py`](../../scripts/okstra_ctl/handoff.py) |
65
65
  | worker roster parser | [`scripts/okstra_ctl/workers.py`](../../scripts/okstra_ctl/workers.py) |
66
66
  | lead operating contract | [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md) |
@@ -69,7 +69,7 @@ Launch selection is role slots and model refs, not a provider roster. The wizard
69
69
 
70
70
  ## 5. Quick comparison table
71
71
 
72
- The last column is the `workflow.nextRecommendedPhase` pointer Phase 7 leaves behind — an object `{phase, status, rationale}`, projected from the report's own routing field. There is no static default: a run that settles no route ends `pending` with no phase. The authoring rule is stated once, in the Phase 6 checklist of [`prompts/lead/report-writer.md`](../../prompts/lead/report-writer.md).
72
+ The last column is the `workflow.nextRecommendedPhase` pointer Phase 7 leaves behind — an object `{phase, status, rationale}`, projected from the report's own routing field. There is no static default: a run that settles no route ends `pending` with no phase. The routing field's `rationale` is carried into the pointer, and the lead's closeout quotes it. The rule for authoring that field is stated once, in the Phase 6 checklist of [`prompts/lead/report-writer.md`](../../prompts/lead/report-writer.md).
73
73
 
74
74
  | task-type | wizard special question | runtime prepare gate | lead/worker mode | next-phase pointer |
75
75
  |---|---|---|---|---|
@@ -126,7 +126,7 @@ flowchart TD
126
126
  Root --> Hist[history/timeline.json]
127
127
  IS --> Profile[analysis-profile.md]
128
128
  IS --> Brief[task-brief.md]
129
- IS --> Lead[lead-execution-prompt.md]
129
+ Runs --> Lead["prompts/lead-execution-prompt-*.md"]
130
130
  Runs --> Man[manifests/run-manifest-*.json]
131
131
  Runs --> Prompts[prompts/*-worker-prompt-*.md]
132
132
  Runs --> Results[worker-results/*.md]
@@ -39,7 +39,7 @@ sequenceDiagram
39
39
  participant Skill as okstra-run
40
40
  participant Wizard as wizard.py
41
41
  participant Run as prepare_task_bundle
42
- participant WT as worktree.py
42
+ participant WT as worktree/provision.py
43
43
  participant Art as artifacts
44
44
 
45
45
  Skill->>Wizard: task-type error-analysis selected
@@ -70,7 +70,7 @@ flowchart TD
70
70
  Report --> Persist[Phase 7 persist + validate]
71
71
  ```
72
72
 
73
- The workers analyze the symptom and evidence independently. In adversarial mode, even a finding reported by multiple workers enters the verification queue instead of receiving automatic consensus. Evidence-backed counter-evidence remains in the finding's round history, so later agreement cannot turn it into full consensus. The report-writer does not analyze during Phase 4/5 but writes the final report in Phase 6.
73
+ The workers analyze the symptom and evidence independently. A finding two distinct role executions derived on their own is recorded as full consensus at Round 0 in both modes — independent co-derivation is already cross-verification, so the adversarial burden of proof applies to single-source claims. Evidence-backed counter-evidence classifies a finding `contested` in the round it lands and takes it out of the verification queue; later agreement can neither erase it nor cost another round. The report-writer does not analyze during Phase 4/5 but writes the final report in Phase 6.
74
74
 
75
75
  ## 5. Deliverables and prohibitions
76
76
 
@@ -90,7 +90,7 @@ The expected final-report content is:
90
90
  - practical next diagnostic steps
91
91
  - if there is blocking uncertainty, `## 1. Clarification Items`, usually `Blocks=next-phase`
92
92
 
93
- For `error-analysis`, the structured `errorAnalysis` object is the source of truth for the verbatim symptom, reproduction status, `EA-NNN` cause candidates and their counter-evidence, the next diagnostic, and routing. Its shape is enforced by the final-report schema; `validators/validate-run.py::_validate_error_analysis_consistency` enforces the cross-field semantics. A route to `implementation-option-selection` needs a credible referenced leading cause and `begin-option-selection`. A route back to `error-analysis` needs the sharp next diagnostic and `continue-investigation`.
93
+ For `error-analysis`, the structured `errorAnalysis` object is the source of truth for the verbatim symptom, reproduction status, `EA-NNN` cause candidates and their counter-evidence, the next diagnostic, and routing. Its shape is enforced by the final-report schema; `validators/validate-run.py::_validate_error_analysis_consistency` enforces the cross-field values — the routing target, a `leadingCauseId` naming a real cause candidate, the two `direction` fields agreeing with that target, and the single matching `phase-continuation` follow-up row. A route to `implementation-option-selection` needs a credible referenced leading cause and `begin-option-selection`. A route back to `error-analysis` needs the sharp next diagnostic and `continue-investigation`.
94
94
 
95
95
  What is prohibited is source edit, refactor, fix attempt, implementation design artifact, and running build/migration/deploy. Deferring ambiguity that could be answered from code or logs to a user question is also a defect per the profile.
96
96
 
@@ -62,7 +62,9 @@ sequenceDiagram
62
62
 
63
63
  Prepare rejects a new plan without a selected-direction report. Comparison mode requires a valid `DIRECTION SELECTION` sidecar, while preselected-validation mode uses the confirmed upstream direction without one. The normalized snapshot binds the source report, source-data digest, option ID, direction body, requirements, and invariants.
64
64
 
65
- Prepare does not name the next phase. It carries the inherited `workflow.nextRecommendedPhase` forward and lowers a `ready` pointer to `pending`, because this run has not finished and a `ready` pointer would read as an invitation to start the following phase. The pointer becomes `ready` at `implementation` when Phase 7 projects an approvable `plan-ready` outcome; `workflow.awaitingApproval` is then true until the user flips `frontmatter.approved`. A blocking plan-body gate or an open `Blocks=approval` row projects `blocked` instead, so inspect and the wizard ask the user to answer those rows rather than start implementation or loop planning.
65
+ The snapshot carries the selected direction, not the rest of that sidecar. The `C-NNN` rows the user answered on the option-selection report reach this run separately: prepare attaches the sidecars beside the selected-direction report as the run's `clarification-response.md`, the same attachment implementation gets from its approved plan.
66
+
67
+ Prepare does not name the next phase. It carries the inherited `workflow.nextRecommendedPhase` forward and lowers a `ready` pointer to `pending`, because this run has not finished and a `ready` pointer would read as an invitation to start the following phase. The pointer becomes `ready` at `implementation` when Phase 7 projects an approvable plan (`outcome: plan-ready`, or a candidate-comparison plan with no `outcome`) and no approval blocker remains; `workflow.awaitingApproval` is then true until the user flips `frontmatter.approved`. A blocking plan-body gate or an open `Blocks=approval` row projects `blocked` instead, so inspect and the wizard ask the user to answer those rows rather than start implementation or loop planning.
66
68
 
67
69
  ## 4. lead execution flow
68
70
 
@@ -218,4 +218,4 @@ A failed `git push` must not be retried with weaker safeguards. When a failure s
218
218
  - [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
219
219
  - [`scripts/okstra_ctl/pr_template.py`](../../scripts/okstra_ctl/pr_template.py)
220
220
  - [`src/commands/lifecycle/config.mjs`](../../src/commands/lifecycle/config.mjs)
221
- - [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py)
221
+ - [`scripts/okstra_ctl/worktree/`](../../scripts/okstra_ctl/worktree/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.186.6",
3
+ "version": "0.187.0",
4
4
  "description": "Host-aware multi-provider cross-verification orchestrator runtime and agent skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -19,6 +19,7 @@
19
19
  "docs/architecture.md",
20
20
  "docs/architecture/",
21
21
  "docs/cli.md",
22
+ "docs/coding-rules.md",
22
23
  "docs/container.md",
23
24
  "docs/contributor-change-matrix.md",
24
25
  "docs/follow-ups/2026-07-10-final-report-option-3.md",
@@ -38,7 +39,7 @@
38
39
  "build": "npm run build:ts && node tools/build.mjs",
39
40
  "prepack": "npm run build",
40
41
  "test:js": "node --test tests-js/*.test.mjs",
41
- "test:py": "python3 -m pytest tests/",
42
+ "test:py": "python3 tools/run-pytest-shards.py tests",
42
43
  "test:workflow": "bash validators/validate-workflow.sh",
43
44
  "test:e2e": "bash tests-e2e/run-all.sh",
44
45
  "check": "npm run build && npm run test:js && npm run test:py && npm run test:workflow && npm run test:e2e"
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.186.6",
3
- "builtAt": "2026-08-24T10:57:13.340Z",
2
+ "package": "0.187.0",
3
+ "builtAt": "2026-09-02T13:58:17.325Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -31,19 +31,14 @@ from the provider name. `lead` is a compatibility alias for `leader`.
31
31
 
32
32
  ## Execution Rules
33
33
 
34
- 1. Extract the absolute `Project Root` from the lead prompt (look for a line starting with `**Project Root:**` or `Project Root:`). If it is missing, immediately return:
35
- `CLAUDE_PROJECT_ROOT_MISSING: absolute Project Root was not provided in the lead prompt`
34
+ 1. The summon message you were invoked with carries the absolute path of your dispatch prompt document — it is not the prompt itself. Read that document COMPLETELY before doing anything else: the `Read` tool returns up to 2000 lines per call, so continue with `offset` until you have seen the last line of the file. Every later rule that says "the lead prompt" means that document. If the summon carries no path, immediately return:
35
+ `CLAUDE_PROMPT_PATH_MISSING: dispatch prompt document path was not provided`
36
36
 
37
- 2. Extract the assigned worker prompt history path from the lead prompt (look for a line starting with `Assigned worker prompt history path:`). If it is missing, immediately return:
38
- `CLAUDE_PROMPT_PATH_MISSING: assigned worker prompt history path was not provided`
39
- - If the extracted path is relative (does not start with `/`), resolve it against `Project Root` to get an absolute path. Use the absolute form everywhere below.
37
+ 2. Extract the absolute `Project Root` from the lead prompt (look for a line starting with `**Project Root:**` or `Project Root:`). If it is missing, immediately return:
38
+ `CLAUDE_PROJECT_ROOT_MISSING: absolute Project Root was not provided in the lead prompt`
40
39
 
41
- 3. Persist the exact worker prompt (received from Lead) to the absolute prompt history path before beginning analysis.
42
- - Use the absolute assigned path under the current run `prompts/` directory.
43
- - `Write` is allowed for this purpose.
44
- - Bash heredoc / redirection is also acceptable if more reliable.
45
- - Never use `/tmp/claude_prompt*.txt` as the canonical storage path.
46
- - If the parent directory does not exist yet, create it before writing.
40
+ 3. The document already lives at its own `Assigned worker prompt history path:` — the lead persisted and verified it before dispatch. Do NOT rewrite it. Check that the path you were summoned with matches that header (resolve a relative header value against `Project Root`); on a mismatch, return:
41
+ `CLAUDE_PROMPT_PATH_MISSING: summon path does not match the document's assigned prompt history path`
47
42
 
48
43
  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
44
  - **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).
@@ -26,6 +26,6 @@ The narrative must not contain `designPreparation`, `designSurfaceCoverage`, `ex
26
26
 
27
27
  The narrative is not free-form Markdown. After the line `# OKSTRA Report Narrative`, every line is one of `- **Field Name**`, `- Item <N>`, or `> value`; blank lines are ignored and **everything else is rejected** — headings (`#`, `##`, `###`), column-0 pipe tables, code fences, bare paragraphs, JSON, YAML, JSON Pointer. Put such text inside a `> ` value instead.
28
28
 
29
- Only these top-level names are allowed: `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`. A section title from a lead procedure document is not a field name. On a refusal, read the allowed names the parser lists for that position instead of guessing again.
29
+ Only these top-level names are allowed: `Analysis Common`, `Change Impact Analysis`, `End State Coverage`, `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`. A section title from a lead procedure document is not a field name. On a refusal, read the allowed names the parser lists for that position instead of guessing again.
30
30
 
31
31
  Report assembly validates every owner input and publishes the final record once. An assembly error naming another owner must be returned to that owner, not repaired in the narrative.
@@ -151,6 +151,10 @@ while [[ $# -gt 0 ]]; do
151
151
  QA_WAIVER="$(require_option_value --qa-waiver "${2-}")"
152
152
  shift 2
153
153
  ;;
154
+ --terminal-backend)
155
+ TERMINAL_BACKEND="$(require_option_value --terminal-backend "${2-}")"
156
+ shift 2
157
+ ;;
154
158
  --task-type)
155
159
  TASK_TYPE="$(require_option_value --task-type "${2-}")"
156
160
  shift 2
@@ -14,6 +14,8 @@ OKSTRA_LATEST_TASK_RELATIVE_PATH=""
14
14
  OKSTRA_TASK_CATALOG_FILE=""
15
15
  OKSTRA_TASK_CATALOG_RELATIVE_PATH=""
16
16
  RENDER_ONLY="false"
17
+ # 워커 표면 명시값. 빈 값이면 prepare 가 탐지하되 조용한 강등은 거부한다.
18
+ TERMINAL_BACKEND=""
17
19
  ASSUME_YES="false"
18
20
  RESUME_CLARIFICATION_MODE="false"
19
21
  RESUME_SESSION_MODE="false"