okstra 0.174.0 → 0.176.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 (419) hide show
  1. package/README.md +18 -9
  2. package/bin/okstra +8 -4
  3. package/dist/cli-registry.d.mts +16 -0
  4. package/dist/cli-registry.mjs +560 -0
  5. package/dist/cli-registry.mjs.map +1 -0
  6. package/dist/commands/execute/agent-prompt.d.mts +1 -0
  7. package/{src → dist}/commands/execute/agent-prompt.mjs +10 -11
  8. package/dist/commands/execute/agent-prompt.mjs.map +1 -0
  9. package/dist/commands/execute/codex-dispatch.d.mts +3 -0
  10. package/dist/commands/execute/codex-dispatch.mjs +6 -0
  11. package/dist/commands/execute/codex-dispatch.mjs.map +1 -0
  12. package/dist/commands/execute/codex-run.d.mts +3 -0
  13. package/{src → dist}/commands/execute/codex-run.mjs +30 -37
  14. package/dist/commands/execute/codex-run.mjs.map +1 -0
  15. package/dist/commands/execute/convergence.d.mts +1 -0
  16. package/{src → dist}/commands/execute/convergence.mjs +15 -16
  17. package/dist/commands/execute/convergence.mjs.map +1 -0
  18. package/dist/commands/execute/error-log.d.mts +1 -0
  19. package/{src → dist}/commands/execute/error-log.mjs +2 -3
  20. package/dist/commands/execute/error-log.mjs.map +1 -0
  21. package/dist/commands/execute/git-reconcile.d.mts +1 -0
  22. package/{src → dist}/commands/execute/git-reconcile.mjs +10 -11
  23. package/dist/commands/execute/git-reconcile.mjs.map +1 -0
  24. package/dist/commands/execute/handoff.d.mts +1 -0
  25. package/{src → dist}/commands/execute/handoff.mjs +10 -11
  26. package/dist/commands/execute/handoff.mjs.map +1 -0
  27. package/dist/commands/execute/incremental-carry.d.mts +1 -0
  28. package/{src → dist}/commands/execute/incremental-carry.mjs +2 -3
  29. package/dist/commands/execute/incremental-carry.mjs.map +1 -0
  30. package/dist/commands/execute/incremental-scope.d.mts +1 -0
  31. package/{src → dist}/commands/execute/incremental-scope.mjs +2 -3
  32. package/dist/commands/execute/incremental-scope.mjs.map +1 -0
  33. package/dist/commands/execute/integrate-stages.d.mts +1 -0
  34. package/{src → dist}/commands/execute/integrate-stages.mjs +10 -11
  35. package/dist/commands/execute/integrate-stages.mjs.map +1 -0
  36. package/dist/commands/execute/pane-title.d.mts +1 -0
  37. package/dist/commands/execute/pane-title.mjs +20 -0
  38. package/dist/commands/execute/pane-title.mjs.map +1 -0
  39. package/dist/commands/execute/plan-items.d.mts +1 -0
  40. package/dist/commands/execute/plan-items.mjs +9 -0
  41. package/dist/commands/execute/plan-items.mjs.map +1 -0
  42. package/dist/commands/execute/plan-validate.d.mts +1 -0
  43. package/dist/commands/execute/plan-validate.mjs +68 -0
  44. package/dist/commands/execute/plan-validate.mjs.map +1 -0
  45. package/dist/commands/execute/plan-verify.d.mts +1 -0
  46. package/{src → dist}/commands/execute/plan-verify.mjs +13 -16
  47. package/dist/commands/execute/plan-verify.mjs.map +1 -0
  48. package/dist/commands/execute/render-bundle.d.mts +3 -0
  49. package/{src → dist}/commands/execute/render-bundle.mjs +65 -61
  50. package/dist/commands/execute/render-bundle.mjs.map +1 -0
  51. package/dist/commands/execute/run.d.mts +24 -0
  52. package/dist/commands/execute/run.mjs +196 -0
  53. package/dist/commands/execute/run.mjs.map +1 -0
  54. package/dist/commands/execute/spawn-followups.d.mts +1 -0
  55. package/{src → dist}/commands/execute/spawn-followups.mjs +6 -7
  56. package/dist/commands/execute/spawn-followups.mjs.map +1 -0
  57. package/dist/commands/execute/team.d.mts +3 -0
  58. package/{src → dist}/commands/execute/team.mjs +29 -36
  59. package/dist/commands/execute/team.mjs.map +1 -0
  60. package/dist/commands/execute/token-usage.d.mts +1 -0
  61. package/{src → dist}/commands/execute/token-usage.mjs +2 -3
  62. package/dist/commands/execute/token-usage.mjs.map +1 -0
  63. package/dist/commands/execute/wizard.d.mts +8 -0
  64. package/dist/commands/execute/wizard.mjs +191 -0
  65. package/dist/commands/execute/wizard.mjs.map +1 -0
  66. package/dist/commands/execute/worker-audit-check.d.mts +1 -0
  67. package/{src → dist}/commands/execute/worker-audit-check.mjs +11 -12
  68. package/dist/commands/execute/worker-audit-check.mjs.map +1 -0
  69. package/dist/commands/execute/worker-dispatch.d.mts +7 -0
  70. package/{src → dist}/commands/execute/worker-dispatch.mjs +34 -46
  71. package/dist/commands/execute/worker-dispatch.mjs.map +1 -0
  72. package/dist/commands/execute/worker-state.d.mts +1 -0
  73. package/{src → dist}/commands/execute/worker-state.mjs +15 -16
  74. package/dist/commands/execute/worker-state.mjs.map +1 -0
  75. package/dist/commands/execute/worktree-lookup.d.mts +1 -0
  76. package/{src → dist}/commands/execute/worktree-lookup.mjs +38 -37
  77. package/dist/commands/execute/worktree-lookup.mjs.map +1 -0
  78. package/dist/commands/execute/worktree-status.d.mts +1 -0
  79. package/{src → dist}/commands/execute/worktree-status.mjs +52 -46
  80. package/dist/commands/execute/worktree-status.mjs.map +1 -0
  81. package/dist/commands/inspect/code-review.d.mts +1 -0
  82. package/{src → dist}/commands/inspect/code-review.mjs +16 -19
  83. package/dist/commands/inspect/code-review.mjs.map +1 -0
  84. package/dist/commands/inspect/container.d.mts +1 -0
  85. package/{src → dist}/commands/inspect/container.mjs +11 -13
  86. package/dist/commands/inspect/container.mjs.map +1 -0
  87. package/dist/commands/inspect/context-cost.d.mts +1 -0
  88. package/{src → dist}/commands/inspect/context-cost.mjs +11 -13
  89. package/dist/commands/inspect/context-cost.mjs.map +1 -0
  90. package/dist/commands/inspect/design-prep.d.mts +1 -0
  91. package/{src → dist}/commands/inspect/design-prep.mjs +10 -11
  92. package/dist/commands/inspect/design-prep.mjs.map +1 -0
  93. package/dist/commands/inspect/error-report.d.mts +1 -0
  94. package/{src → dist}/commands/inspect/error-report.mjs +11 -13
  95. package/dist/commands/inspect/error-report.mjs.map +1 -0
  96. package/dist/commands/inspect/error-zip.d.mts +1 -0
  97. package/{src → dist}/commands/inspect/error-zip.mjs +11 -12
  98. package/dist/commands/inspect/error-zip.mjs.map +1 -0
  99. package/dist/commands/inspect/log-report.d.mts +1 -0
  100. package/{src → dist}/commands/inspect/log-report.mjs +11 -13
  101. package/dist/commands/inspect/log-report.mjs.map +1 -0
  102. package/dist/commands/inspect/profile-show.d.mts +1 -0
  103. package/{src → dist}/commands/inspect/profile-show.mjs +10 -11
  104. package/dist/commands/inspect/profile-show.mjs.map +1 -0
  105. package/dist/commands/inspect/recap.d.mts +1 -0
  106. package/{src → dist}/commands/inspect/recap.mjs +11 -13
  107. package/dist/commands/inspect/recap.mjs.map +1 -0
  108. package/dist/commands/inspect/resolve-task-key.d.mts +1 -0
  109. package/{src → dist}/commands/inspect/resolve-task-key.mjs +11 -13
  110. package/dist/commands/inspect/resolve-task-key.mjs.map +1 -0
  111. package/dist/commands/inspect/rollup.d.mts +1 -0
  112. package/{src → dist}/commands/inspect/rollup.mjs +11 -13
  113. package/dist/commands/inspect/rollup.mjs.map +1 -0
  114. package/dist/commands/inspect/run-audit.d.mts +1 -0
  115. package/{src → dist}/commands/inspect/run-audit.mjs +11 -12
  116. package/dist/commands/inspect/run-audit.mjs.map +1 -0
  117. package/dist/commands/inspect/set-work-status.d.mts +1 -0
  118. package/{src → dist}/commands/inspect/set-work-status.mjs +11 -13
  119. package/dist/commands/inspect/set-work-status.mjs.map +1 -0
  120. package/dist/commands/inspect/stage-map.d.mts +1 -0
  121. package/dist/commands/inspect/stage-map.mjs +110 -0
  122. package/dist/commands/inspect/stage-map.mjs.map +1 -0
  123. package/dist/commands/inspect/task-list.d.mts +1 -0
  124. package/dist/commands/inspect/task-list.mjs +103 -0
  125. package/dist/commands/inspect/task-list.mjs.map +1 -0
  126. package/dist/commands/inspect/task-show.d.mts +1 -0
  127. package/dist/commands/inspect/task-show.mjs +108 -0
  128. package/dist/commands/inspect/task-show.mjs.map +1 -0
  129. package/dist/commands/inspect/time-report.d.mts +1 -0
  130. package/{src → dist}/commands/inspect/time-report.mjs +11 -13
  131. package/dist/commands/inspect/time-report.mjs.map +1 -0
  132. package/dist/commands/inspect/usage-report.d.mts +1 -0
  133. package/{src → dist}/commands/inspect/usage-report.mjs +11 -13
  134. package/dist/commands/inspect/usage-report.mjs.map +1 -0
  135. package/dist/commands/inspect/user-response.d.mts +1 -0
  136. package/{src → dist}/commands/inspect/user-response.mjs +10 -11
  137. package/dist/commands/inspect/user-response.mjs.map +1 -0
  138. package/dist/commands/inspect/worker-liveness.d.mts +1 -0
  139. package/{src → dist}/commands/inspect/worker-liveness.mjs +11 -13
  140. package/dist/commands/inspect/worker-liveness.mjs.map +1 -0
  141. package/dist/commands/lifecycle/check-project.d.mts +21 -0
  142. package/dist/commands/lifecycle/check-project.mjs +175 -0
  143. package/dist/commands/lifecycle/check-project.mjs.map +1 -0
  144. package/dist/commands/lifecycle/config.d.mts +1 -0
  145. package/dist/commands/lifecycle/config.mjs +369 -0
  146. package/dist/commands/lifecycle/config.mjs.map +1 -0
  147. package/dist/commands/lifecycle/doctor.d.mts +10 -0
  148. package/dist/commands/lifecycle/doctor.mjs +317 -0
  149. package/dist/commands/lifecycle/doctor.mjs.map +1 -0
  150. package/dist/commands/lifecycle/install.d.mts +17 -0
  151. package/dist/commands/lifecycle/install.mjs +1077 -0
  152. package/dist/commands/lifecycle/install.mjs.map +1 -0
  153. package/dist/commands/lifecycle/migrate.d.mts +1 -0
  154. package/{src → dist}/commands/lifecycle/migrate.mjs +10 -11
  155. package/dist/commands/lifecycle/migrate.mjs.map +1 -0
  156. package/dist/commands/lifecycle/model.d.mts +1 -0
  157. package/dist/commands/lifecycle/model.mjs +22 -0
  158. package/dist/commands/lifecycle/model.mjs.map +1 -0
  159. package/dist/commands/lifecycle/paths.d.mts +1 -0
  160. package/dist/commands/lifecycle/paths.mjs +102 -0
  161. package/dist/commands/lifecycle/paths.mjs.map +1 -0
  162. package/dist/commands/lifecycle/preflight.d.mts +1 -0
  163. package/dist/commands/lifecycle/preflight.mjs +124 -0
  164. package/dist/commands/lifecycle/preflight.mjs.map +1 -0
  165. package/dist/commands/lifecycle/setup.d.mts +1 -0
  166. package/dist/commands/lifecycle/setup.mjs +297 -0
  167. package/dist/commands/lifecycle/setup.mjs.map +1 -0
  168. package/dist/commands/lifecycle/uninstall.d.mts +4 -0
  169. package/dist/commands/lifecycle/uninstall.mjs +262 -0
  170. package/dist/commands/lifecycle/uninstall.mjs.map +1 -0
  171. package/dist/commands/manager.d.mts +3 -0
  172. package/{src → dist}/commands/manager.mjs +25 -32
  173. package/dist/commands/manager.mjs.map +1 -0
  174. package/dist/commands/memory/memory.d.mts +1 -0
  175. package/dist/commands/memory/memory.mjs +569 -0
  176. package/dist/commands/memory/memory.mjs.map +1 -0
  177. package/dist/commands/pr/pr.d.mts +33 -0
  178. package/dist/commands/pr/pr.mjs +296 -0
  179. package/dist/commands/pr/pr.mjs.map +1 -0
  180. package/dist/commands/report/agent-activity.d.mts +1 -0
  181. package/{src → dist}/commands/report/agent-activity.mjs +11 -12
  182. package/dist/commands/report/agent-activity.mjs.map +1 -0
  183. package/dist/commands/report/finalize.d.mts +4 -0
  184. package/{src → dist}/commands/report/finalize.mjs +25 -32
  185. package/dist/commands/report/finalize.mjs.map +1 -0
  186. package/dist/commands/report/inject-report-index.d.mts +1 -0
  187. package/{src → dist}/commands/report/inject-report-index.mjs +6 -7
  188. package/dist/commands/report/inject-report-index.mjs.map +1 -0
  189. package/dist/commands/report/render-final-report.d.mts +1 -0
  190. package/{src → dist}/commands/report/render-final-report.mjs +6 -7
  191. package/dist/commands/report/render-final-report.mjs.map +1 -0
  192. package/dist/commands/report/render-views.d.mts +1 -0
  193. package/{src → dist}/commands/report/render-views.mjs +6 -7
  194. package/dist/commands/report/render-views.mjs.map +1 -0
  195. package/dist/commands/report/translate.d.mts +1 -0
  196. package/{src → dist}/commands/report/translate.mjs +6 -7
  197. package/dist/commands/report/translate.mjs.map +1 -0
  198. package/dist/lib/helper-scripts.d.mts +3 -0
  199. package/{src → dist}/lib/helper-scripts.mjs +11 -14
  200. package/dist/lib/helper-scripts.mjs.map +1 -0
  201. package/dist/lib/host-registry-client.d.mts +25 -0
  202. package/dist/lib/host-registry-client.mjs +152 -0
  203. package/dist/lib/host-registry-client.mjs.map +1 -0
  204. package/dist/lib/install-assets.d.mts +8 -0
  205. package/{src → dist}/lib/install-assets.mjs +17 -20
  206. package/dist/lib/install-assets.mjs.map +1 -0
  207. package/dist/lib/okstra-dirs.d.mts +4 -0
  208. package/{src → dist}/lib/okstra-dirs.mjs +3 -6
  209. package/dist/lib/okstra-dirs.mjs.map +1 -0
  210. package/dist/lib/paths.d.mts +4 -0
  211. package/dist/lib/paths.mjs +78 -0
  212. package/dist/lib/paths.mjs.map +1 -0
  213. package/dist/lib/proc.d.mts +3 -0
  214. package/dist/lib/proc.mjs +31 -0
  215. package/dist/lib/proc.mjs.map +1 -0
  216. package/dist/lib/python-helper.d.mts +8 -0
  217. package/dist/lib/python-helper.mjs +123 -0
  218. package/dist/lib/python-helper.mjs.map +1 -0
  219. package/dist/lib/runtime-manifest.d.mts +7 -0
  220. package/dist/lib/runtime-manifest.mjs +73 -0
  221. package/dist/lib/runtime-manifest.mjs.map +1 -0
  222. package/dist/lib/skill-catalog.d.mts +4 -0
  223. package/dist/lib/skill-catalog.mjs +50 -0
  224. package/dist/lib/skill-catalog.mjs.map +1 -0
  225. package/dist/lib/types.d.mts +129 -0
  226. package/dist/lib/types.mjs +2 -0
  227. package/dist/lib/types.mjs.map +1 -0
  228. package/dist/lib/version.d.mts +2 -0
  229. package/dist/lib/version.mjs +27 -0
  230. package/dist/lib/version.mjs.map +1 -0
  231. package/docs/architecture/storage-model.md +6 -2
  232. package/docs/architecture.md +29 -20
  233. package/docs/cli.md +40 -16
  234. package/docs/contributor-change-matrix.md +2 -2
  235. package/docs/for-ai/skills/okstra-inspect.md +2 -3
  236. package/docs/for-ai/skills/okstra-rollup.md +1 -0
  237. package/docs/project-structure-overview.md +72 -62
  238. package/docs/task-process/README.md +12 -8
  239. package/docs/task-process/common-flow.md +13 -16
  240. package/docs/task-process/error-analysis.md +9 -10
  241. package/docs/task-process/final-verification.md +7 -7
  242. package/docs/task-process/implementation-planning.md +9 -9
  243. package/docs/task-process/implementation.md +6 -6
  244. package/docs/task-process/release-handoff.md +8 -7
  245. package/docs/task-process/requirements-discovery.md +8 -8
  246. package/package.json +11 -5
  247. package/runtime/BUILD.json +2 -2
  248. package/runtime/agents/workers/claude-worker.md +2 -1
  249. package/runtime/agents/workers/report-writer-worker.md +3 -1
  250. package/runtime/agents/workers/translator-worker.md +3 -1
  251. package/runtime/bin/lib/okstra/cli.sh +12 -0
  252. package/runtime/bin/lib/okstra/globals.sh +3 -0
  253. package/runtime/bin/lib/okstra/interactive.sh +12 -6
  254. package/runtime/bin/lib/okstra/usage.sh +7 -6
  255. package/runtime/bin/okstra-error-log.py +27 -0
  256. package/runtime/bin/okstra-provider-exec.py +217 -5
  257. package/runtime/bin/okstra-spawn-followups.py +4 -2
  258. package/runtime/bin/okstra.sh +10 -0
  259. package/runtime/prompts/launch.template.md +2 -2
  260. package/runtime/prompts/lead/context-loader.md +1 -2
  261. package/runtime/prompts/lead/convergence.md +27 -18
  262. package/runtime/prompts/lead/okstra-lead-contract.md +6 -5
  263. package/runtime/prompts/lead/plan-body-verification.md +10 -3
  264. package/runtime/prompts/lead/report-writer.md +15 -1
  265. package/runtime/prompts/lead/team-contract.md +17 -13
  266. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  267. package/runtime/prompts/profiles/_implementation-executor.md +0 -3
  268. package/runtime/prompts/profiles/_implementation-verifier.md +3 -7
  269. package/runtime/prompts/profiles/change-impact-analysis.md +20 -0
  270. package/runtime/prompts/profiles/error-analysis.md +27 -1
  271. package/runtime/prompts/profiles/feature-analysis.md +20 -0
  272. package/runtime/prompts/profiles/final-verification.md +20 -1
  273. package/runtime/prompts/profiles/implementation-option-selection.md +20 -0
  274. package/runtime/prompts/profiles/implementation-planning.md +26 -0
  275. package/runtime/prompts/profiles/implementation.md +19 -0
  276. package/runtime/prompts/profiles/improvement-discovery.md +21 -1
  277. package/runtime/prompts/profiles/project-analysis.md +20 -0
  278. package/runtime/prompts/profiles/release-handoff.md +4 -0
  279. package/runtime/prompts/profiles/requirements-discovery.md +27 -1
  280. package/runtime/prompts/wizard/prompts.ko.json +35 -0
  281. package/runtime/python/okstra_ctl/adapters/dispatch/cli_wrapper.py +8 -0
  282. package/runtime/python/okstra_ctl/adapters/dispatch/cmux.py +8 -0
  283. package/runtime/python/okstra_ctl/adapters/dispatch/native_team.py +13 -0
  284. package/runtime/python/okstra_ctl/adapters/hosts/antigravity/adapter.py +2 -2
  285. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +25 -5
  286. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +2 -2
  287. package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +4 -1
  288. package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +2 -2
  289. package/runtime/python/okstra_ctl/adapters/hosts/kimi/adapter.py +2 -2
  290. package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +79 -11
  291. package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +95 -25
  292. package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +59 -14
  293. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +55 -9
  294. package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +51 -12
  295. package/runtime/python/okstra_ctl/adapters/runtime/__init__.py +1 -0
  296. package/runtime/python/okstra_ctl/adapters/runtime/assembly.py +27 -0
  297. package/runtime/python/okstra_ctl/adapters/runtime/cli_wrapper.py +49 -0
  298. package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +74 -0
  299. package/runtime/python/okstra_ctl/agent_activity.py +5 -1
  300. package/runtime/python/okstra_ctl/agent_invocation.py +608 -14
  301. package/runtime/python/okstra_ctl/agent_prompt_cli.py +249 -50
  302. package/runtime/python/okstra_ctl/application/open_worker.py +29 -0
  303. package/runtime/python/okstra_ctl/application/resolve_assignment.py +53 -12
  304. package/runtime/python/okstra_ctl/assignment_environment.py +102 -0
  305. package/runtime/python/okstra_ctl/assignment_resolver.py +790 -0
  306. package/runtime/python/okstra_ctl/attempt_evidence.py +342 -0
  307. package/runtime/python/okstra_ctl/convergence.py +409 -3
  308. package/runtime/python/okstra_ctl/convergence_engine.py +248 -15
  309. package/runtime/python/okstra_ctl/convergence_store.py +170 -1
  310. package/runtime/python/okstra_ctl/dispatch_core.py +1204 -155
  311. package/runtime/python/okstra_ctl/dispatch_state.py +696 -11
  312. package/runtime/python/okstra_ctl/doctor.py +14 -0
  313. package/runtime/python/okstra_ctl/domain/host.py +34 -1
  314. package/runtime/python/okstra_ctl/domain/provider.py +212 -6
  315. package/runtime/python/okstra_ctl/domain/role.py +125 -0
  316. package/runtime/python/okstra_ctl/domain/wizard/interaction.py +18 -0
  317. package/runtime/python/okstra_ctl/domain/worker_exec.py +34 -1
  318. package/runtime/python/okstra_ctl/domain/worker_role.py +13 -3
  319. package/runtime/python/okstra_ctl/domain/worker_runtime.py +44 -0
  320. package/runtime/python/okstra_ctl/domain/worker_stream.py +24 -0
  321. package/runtime/python/okstra_ctl/error_log_write.py +9 -0
  322. package/runtime/python/okstra_ctl/error_report.py +21 -1
  323. package/runtime/python/okstra_ctl/execution_identity.py +529 -0
  324. package/runtime/python/okstra_ctl/execution_manifest.py +1281 -0
  325. package/runtime/python/okstra_ctl/execution_mutation_audit.py +619 -0
  326. package/runtime/python/okstra_ctl/implementation_outcome.py +21 -5
  327. package/runtime/python/okstra_ctl/index.py +6 -2
  328. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +43 -3
  329. package/runtime/python/okstra_ctl/legacy_model_selection.py +578 -0
  330. package/runtime/python/okstra_ctl/manager_sync.py +4 -1
  331. package/runtime/python/okstra_ctl/model_cli.py +278 -0
  332. package/runtime/python/okstra_ctl/model_defaults.py +46 -0
  333. package/runtime/python/okstra_ctl/model_discovery.py +26 -7
  334. package/runtime/python/okstra_ctl/model_pool.py +501 -0
  335. package/runtime/python/okstra_ctl/models.py +47 -27
  336. package/runtime/python/okstra_ctl/mutation_recovery.py +293 -0
  337. package/runtime/python/okstra_ctl/next_phase.py +236 -0
  338. package/runtime/python/okstra_ctl/pane_title.py +151 -0
  339. package/runtime/python/okstra_ctl/ports/host_model.py +48 -17
  340. package/runtime/python/okstra_ctl/ports/worker_dispatch.py +4 -0
  341. package/runtime/python/okstra_ctl/ports/worker_runtime.py +26 -0
  342. package/runtime/python/okstra_ctl/recap.py +4 -1
  343. package/runtime/python/okstra_ctl/registry/provider_registry.py +8 -4
  344. package/runtime/python/okstra_ctl/render.py +124 -57
  345. package/runtime/python/okstra_ctl/render_final_report.py +19 -0
  346. package/runtime/python/okstra_ctl/report_contract.py +39 -0
  347. package/runtime/python/okstra_ctl/report_finalize.py +16 -0
  348. package/runtime/python/okstra_ctl/report_html/render.py +1 -0
  349. package/runtime/python/okstra_ctl/role_requirements.py +210 -0
  350. package/runtime/python/okstra_ctl/rollup.py +4 -1
  351. package/runtime/python/okstra_ctl/run.py +1210 -258
  352. package/runtime/python/okstra_ctl/run_index_row.py +7 -1
  353. package/runtime/python/okstra_ctl/stage_fix_carry.py +17 -1
  354. package/runtime/python/okstra_ctl/team.py +14 -18
  355. package/runtime/python/okstra_ctl/time_report.py +38 -4
  356. package/runtime/python/okstra_ctl/usage_identity.py +86 -0
  357. package/runtime/python/okstra_ctl/usage_report.py +15 -3
  358. package/runtime/python/okstra_ctl/wizard.py +1449 -66
  359. package/runtime/python/okstra_ctl/worker_audit_ledger.py +68 -65
  360. package/runtime/python/okstra_ctl/worker_prompt_body.py +18 -2
  361. package/runtime/python/okstra_ctl/worker_prompt_contract.py +40 -9
  362. package/runtime/python/okstra_ctl/worker_prompt_headers.py +16 -1
  363. package/runtime/python/okstra_ctl/worker_request.py +7 -1
  364. package/runtime/python/okstra_ctl/worker_runner.py +130 -5
  365. package/runtime/python/okstra_ctl/workers.py +7 -5
  366. package/runtime/python/okstra_ctl/workflow.py +18 -32
  367. package/runtime/python/okstra_ctl/worktree.py +3 -3
  368. package/runtime/python/okstra_ctl/worktree_registry.py +5 -4
  369. package/runtime/python/okstra_ctl/write_policy.py +571 -0
  370. package/runtime/python/okstra_project/state.py +54 -6
  371. package/runtime/schemas/convergence-groups-v2.0.schema.json +128 -0
  372. package/runtime/schemas/execution-manifest-v2.schema.json +340 -0
  373. package/runtime/schemas/final-report-v2.0.schema.json +68 -5
  374. package/runtime/skills/okstra-inspect/facets/recap.md +2 -0
  375. package/runtime/skills/okstra-inspect/facets/report.md +1 -1
  376. package/runtime/skills/okstra-inspect/facets/status.md +15 -13
  377. package/runtime/skills/okstra-rollup/SKILL.md +1 -0
  378. package/runtime/skills/okstra-run/SKILL.md +14 -14
  379. package/runtime/templates/implementation-worker-preamble.md +3 -18
  380. package/runtime/templates/project-docs/task-index.template.md +0 -1
  381. package/runtime/templates/report-writer-prompt-preamble.md +2 -0
  382. package/runtime/templates/reports/final-report-v2.template.md +7 -1
  383. package/runtime/templates/reports/html/base.template.html +21 -0
  384. package/runtime/templates/reports/html/i18n/en.json +4 -0
  385. package/runtime/templates/reports/html/i18n/ko.json +4 -0
  386. package/runtime/templates/reports/html/macros/forms.html +5 -4
  387. package/runtime/templates/reports/html/tasks/final-verification.template.html +1 -1
  388. package/runtime/templates/reports/html/tasks/implementation.template.html +1 -1
  389. package/runtime/templates/worker-prompt-preamble.md +6 -35
  390. package/runtime/validators/lib/fixtures.sh +49 -16
  391. package/runtime/validators/validate-run.py +486 -134
  392. package/runtime/validators/validate_session_conformance.py +25 -7
  393. package/src/cli-registry.mjs +0 -539
  394. package/src/commands/execute/codex-dispatch.mjs +0 -10
  395. package/src/commands/execute/plan-items.mjs +0 -9
  396. package/src/commands/execute/plan-validate.mjs +0 -68
  397. package/src/commands/execute/run.mjs +0 -208
  398. package/src/commands/execute/wizard.mjs +0 -167
  399. package/src/commands/inspect/stage-map.mjs +0 -98
  400. package/src/commands/inspect/task-list.mjs +0 -97
  401. package/src/commands/inspect/task-show.mjs +0 -100
  402. package/src/commands/lifecycle/check-project.mjs +0 -187
  403. package/src/commands/lifecycle/config.mjs +0 -385
  404. package/src/commands/lifecycle/doctor.mjs +0 -308
  405. package/src/commands/lifecycle/install.mjs +0 -1170
  406. package/src/commands/lifecycle/paths.mjs +0 -104
  407. package/src/commands/lifecycle/preflight.mjs +0 -125
  408. package/src/commands/lifecycle/setup.mjs +0 -333
  409. package/src/commands/lifecycle/uninstall.mjs +0 -279
  410. package/src/commands/memory/memory.mjs +0 -524
  411. package/src/commands/pr/pr.mjs +0 -261
  412. package/src/lib/host-registry-client.mjs +0 -176
  413. package/src/lib/paths.mjs +0 -86
  414. package/src/lib/proc.mjs +0 -31
  415. package/src/lib/python-helper.mjs +0 -142
  416. package/src/lib/runtime-manifest.mjs +0 -70
  417. package/src/lib/skill-catalog.mjs +0 -53
  418. package/src/lib/version.mjs +0 -20
  419. /package/{src → dist}/commands/pr/default.md +0 -0
package/docs/cli.md CHANGED
@@ -4,6 +4,8 @@
4
4
  >
5
5
  > This manual covers the phase-execution flags of `okstra.sh`. For the subcommand reference of the separate `okstra container` entry point, see [container.md](container.md).
6
6
 
7
+ The Node CLI requires Node.js 22 or newer. Its TypeScript sources are compiled from `src/**/*.mts` to `dist/**/*.mjs`; `bin/okstra` executes the compiled files. The central state helper remains `scripts/okstra-central.sh`.
8
+
7
9
  ---
8
10
 
9
11
  ## Index
@@ -28,6 +30,8 @@
28
30
  - [`--directive`](#--directive)
29
31
  - [`--fix-cycle`](#--fix-cycle)
30
32
  - [`--workers`](#--workers)
33
+ - [`--role-count`](#--role-count)
34
+ - [`--role-model`](#--role-model)
31
35
  - [`--lead-runtime`](#--lead-runtime)
32
36
  - [`--claude-model`](#--claude-model)
33
37
  - [`--lead-model`](#--lead-model)
@@ -60,7 +64,7 @@
60
64
  Base command for initial entry with full arguments:
61
65
 
62
66
  ```bash
63
- scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-runtime <host-id-or-alias>] [--lead-provider <provider>] [--lead-model <model>] [--worker-model provider=model,...] [--report-writer-provider <provider>] [--report-writer-model <model>] [--executor claude|codex|antigravity] [--critic off|claude|codex|antigravity|grok|kimi] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--base-ref <branch|tag|sha>] [--clarification-response <previous-final-report>] [--selected-direction <selection-final-report.md>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>] [--fix-cycle <yes|no>]
67
+ scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--role-count <role>=<N>] [--role-model <role>=<modelRef>] [--lead-runtime <host-id-or-alias>] [--lead-provider <provider>] [--lead-model <model>] [--worker-model provider=model,...] [--report-writer-provider <provider>] [--report-writer-model <model>] [--executor claude|codex|antigravity|grok|kimi] [--critic off|claude|codex|antigravity|grok|kimi] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--base-ref <branch|tag|sha>] [--clarification-response <previous-final-report>] [--selected-direction <selection-final-report.md>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>] [--fix-cycle <yes|no>]
64
68
  ```
65
69
 
66
70
  Analysis input ownership is narrower than the base shell command. The `/okstra-run` wizard collects `--analysis-target` and `--evidence-inputs` values and passes them internally to `node bin/okstra render-bundle`. `scripts/okstra.sh` does not accept either flag. Because `feature-analysis` requires a target, start that task type with the in-host skill; the two option sections below document the internal Node render inputs, not standalone shell options.
@@ -149,7 +153,7 @@ The lifecycle task types run in this order:
149
153
  - Primary-pass assignment: selected analyser instances are enumerated in `requiredWorkerRoles` order, then the lead rotates the primary pass across the resolved priority lenses. Provider/model names do not affect the order, and every analyser still covers every resolved lens after its primary pass.
150
154
  - Two bidirectional grilling points: an enhanced Step 4 in `okstra-brief-gen` with a budget of 8, and the lead's Phase 1.5 reflect-back with a budget of 12.
151
155
  - Validator: `validators/validate_improvement_report.py` enforces the 11-part contract for an `improvement-discovery` final report.
152
- - Because an `improvement-discovery` run is not in `PHASE_SEQUENCE`, the `--task-key` short form does not automatically populate `nextRecommendedPhase` for it.
156
+ - Because an `improvement-discovery` run is not in `PHASE_SEQUENCE`, its report has no routing field to project from, so the run leaves `workflow.nextRecommendedPhase` `pending` with no phase. The `--task-key` short form therefore cannot fill `--task-type` after one.
153
157
 
154
158
  #### Analysis sidetrack task types
155
159
 
@@ -161,7 +165,7 @@ The three read-only analysis types are independent sidetracks outside `PHASE_SEQ
161
165
  | `feature-analysis` | Trace one existing feature through flows, domain rules, state changes, external interactions, and test coverage. |
162
166
  | `change-impact-analysis` | Map the blast radius of a proposed change across preserved behavior, dependencies, tests, and operations. |
163
167
 
164
- Each one starts from a brief and produces a report only. The target project is strictly read-only: no edits, tests, builds, migrations, or deployments. A run ends at `pending-routing-decision`; it does not advance the normal phase sequence.
168
+ Each one starts from a brief and produces a report only. The target project is strictly read-only: no edits, tests, builds, migrations, or deployments. A run ends with `workflow.nextRecommendedPhase` `pending` and carrying no phase; it does not advance the normal phase sequence.
165
169
 
166
170
  ### `--analysis-target`
167
171
 
@@ -230,10 +234,10 @@ A short form that supplies `--project-id`, `--task-group`, and `--task-id` toget
230
234
  - Behavior:
231
235
  - Splits the value into the three IDs and populates `PROJECT_ID`, `TASK_GROUP`, and `TASK_ID`.
232
236
  - If the same values are also provided explicitly, they are accepted only when they match; a conflict exits immediately with an error.
233
- - If the task has a `task-manifest.json`, a missing `--task-brief` is filled from the manifest's `taskBriefPath`, and a missing `--task-type` is filled from `workflow.nextRecommendedPhase`.
237
+ - If the task has a `task-manifest.json`, a missing `--task-brief` is filled from the manifest's `taskBriefPath`, and a missing `--task-type` is filled from `workflow.nextRecommendedPhase.phase` — but only while that pointer's `status` is `ready`.
234
238
  - Without a manifest, as on initial entry, the normal missing-argument validation remains in effect and full arguments are required.
235
239
  - Explicit arguments always take precedence over manifest values.
236
- - When `nextRecommendedPhase` is `pending-routing-decision` or `done-or-follow-up`, it is not filled automatically. Supply `--task-type` explicitly or supplement the brief, then rerun the command.
240
+ - Under any other `status` — `pending`, `blocked`, or `terminal` — the pointer names no runnable phase and `--task-type` is not filled automatically. Supply `--task-type` explicitly or supplement the brief, then rerun the command.
237
241
 
238
242
  Examples:
239
243
 
@@ -407,9 +411,11 @@ scripts/okstra.sh --task-type implementation-planning ... \
407
411
 
408
412
  ### `--workers`
409
413
 
410
- Directly specifies the workers used in this run.
411
- The default is `claude,codex,report-writer`. Antigravity is optional; add it explicitly when needed, as in `--workers claude,codex,antigravity,report-writer`.
412
- When supplied, only the deduplicated worker subset is recorded.
414
+ Compatibility input only. Prefer `--role-count` and `--role-model` for launch selection.
415
+
416
+ When supplied, the CSV of provider names converts into role slots and model refs for the profile's initial cross-verification role (for example analysers or planners). It is not a provider roster picker and is not the selection unit on the wizard start screen.
417
+
418
+ If the same role is also named by `--role-model` (or other canonical role flags), the converted providers must match the model-ref provider prefixes in order and slot count. Matching values keep the canonical role models and drop the legacy constraint. Different values fail before any worktree or state file is created.
413
419
 
414
420
  Example:
415
421
 
@@ -445,7 +451,7 @@ worker roster contains Claude, Codex, or Antigravity.
445
451
 
446
452
  ### Runtime auto-detection (`auto`)
447
453
 
448
- `okstra run` defaults to `auto`. `src/lib/host-registry-client.mjs` asks the Python host registry to resolve explicit IDs and aliases, the `OKSTRA_RUNTIME_HOST` environment declaration, Claude Code skill handoff, or the external tmux claim. It fails fast when no adapter claims the session. Installed CLI presence alone never selects a host.
454
+ `okstra run` defaults to `auto`. `src/lib/host-registry-client.mts` asks the Python host registry to resolve explicit IDs and aliases, the `OKSTRA_RUNTIME_HOST` environment declaration, Claude Code skill handoff, or the external tmux claim. It fails fast when no adapter claims the session. Installed CLI presence alone never selects a host.
449
455
 
450
456
  - Inside a registered host, the installed `okstra-run` skill uses `current-session`, declares the live semantic function list, and reuses the session you are already in.
451
457
  - From a terminal, `okstra run <host-id-or-alias>` uses `spawn-process` and starts the selected host CLI. The leading word is an alias for `--lead-runtime`.
@@ -467,9 +473,25 @@ The Codex worker (`--workers codex`, `--codex-model`) and Codex lead runtime are
467
473
  > - Claude (`--lead-model` / `--claude-model` / `--report-writer-model`): `fable`, `fable-5`, `claude-fable-5`, `opus`, `opus-5`, `claude-opus-5`, `opus-4-8`, `claude-opus-4-8`, `opus-4-7`, `claude-opus-4-7`, `opus-4-6`, `claude-opus-4-6`, `sonnet`, `sonnet-5`, `claude-sonnet-5`, `sonnet-4-6`, `claude-sonnet-4-6`, `haiku`, `haiku-4-5`, `claude-haiku-4-5`, `claude-haiku-4-5-20251001`
468
474
  > - Codex (`--codex-model`): `gpt-5.6-sol`, `gpt-5.6`, `gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.3-codex`, `gpt-5.2`, `codex-auto-review`
469
475
  > - Antigravity (`--antigravity-model`): `gemini-3.1-pro` (default), `gemini-3.6-flash`, `gemini-3.5-flash`, and their space-separated aliases. The antigravity worker uses the `agy` CLI to run Gemini-family models, so model IDs retain the `gemini-*` form.
470
- > - Grok (`--worker-model grok=<model>`): `grok-build-0.1`, `grok-4.5`
476
+ > - Grok (`--worker-model grok=<model>`): `grok-4.6`, `grok-4.5`, `grok-build-0.1`
471
477
  > - Kimi (`--worker-model kimi=<model>`): `kimi-k2.7-code`, `kimi-for-coding`, `kimi-k3`, `k3`, `k3-256k` and their registered display aliases
472
478
 
479
+ ### `--role-count`
480
+
481
+ Sets how many slots open for one static role: `--role-count <role>=<N>`. Repeat the flag for each role. `N` must fall in that role's profile range `min..max`. Omit the flag to use the profile **recommended** count (not a separate roster default). Roles with `min == max` are fixed quantity and reject this flag. Dynamic roles and roles absent from the profile also reject it. `lead` is a compatibility alias for `leader`. New records write `leader`.
482
+
483
+ Each confirmed count becomes `RoleInstance` ordinals. `ModelPool` then assigns one model ref per ordinal. A pinned model is kept only when the host can bind it exactly. Roles with `min = 0` do not open slots by default; optional add steps or an explicit count above zero open them.
484
+
485
+ ### `--role-model`
486
+
487
+ Pins one model reference onto a role slot, in ordinal order: `--role-model <role>=<modelRef>`. Repeat the flag to fill later ordinals. `modelRef` is `<provider>/<model>`, for example `claude/opus-5` or `codex/gpt-5.6-sol`.
488
+
489
+ A known selectable model may be assigned to any canonical role. The same role must not receive the same model ref twice; duplicate refs in one role panel fail before any worktree or state file is created. Same provider with different models is allowed. Fewer models than the confirmed count are filled from the model-default chain. Extra models do not raise the count; set `--role-count <role>=<N>` first. Unknown roles and unknown model refs fail before side effects.
490
+
491
+ Legacy `--lead-model`, `--claude-model`, `--codex-model`, `--antigravity-model`, `--worker-model`, `--report-writer-model`, `--executor`, and `--workers` remain compatibility inputs. They convert to role-model selections. A new flag and a legacy flag that name different models (or, for `--workers`, different provider prefixes) for the same role fail.
492
+
493
+ `okstra model list [--role <role>] [--host <host>] [--json]` prints the catalog without an inference call. `okstra model default set|unset <role> ... --scope project|global` writes `modelDefaults` to `.okstra/project.json` or `~/.okstra/config.json`.
494
+
473
495
  ### `--lead-provider`
474
496
 
475
497
  Compatibility assertion for previously recorded invocations. The value must match the host-native provider: `claude` on Claude Code, `codex` on Codex, and `antigravity` on Antigravity. It is not an independent lead selector. Other providers belong in the worker roster and run through CLI wrappers; preparation rejects a cross-provider lead rather than recording one model and silently running another.
@@ -528,11 +550,11 @@ Fallback defaults are:
528
550
 
529
551
  ### `--executor`
530
552
 
531
- Selects the provider that performs the Executor role for `--task-type implementation`. The value is `claude`, `codex`, or `antigravity`; it is ignored for other task types.
553
+ Selects the provider that performs the Executor role for `--task-type implementation`. The value is `claude`, `codex`, `antigravity`, `grok`, or `kimi`; it is ignored for other task types.
532
554
 
533
555
  - Default: `OKSTRA_DEFAULT_EXECUTOR` → fallback `claude`.
534
- - The Executor is the **only worker allowed to mutate project files** in this run. The other two providers are dispatched as strict read-only verifiers in the same run.
535
- - The Executor reuses the provider's worker model flag. With `--executor codex`, its model comes from `--codex-model`, default `gpt-5.6-sol`; with `--executor antigravity`, it comes from `--antigravity-model`, default `gemini-3.1-pro`.
556
+ - The Executor is the **only worker allowed to mutate project files** in this run. The other providers are dispatched as strict read-only verifiers in the same run.
557
+ - The Executor reuses the provider's worker model flag. With `--executor codex`, its model comes from `--codex-model`, default `gpt-5.6-sol`; with `--executor antigravity`, it comes from `--antigravity-model`, default `gemini-3.1-pro`. With `--executor grok`, its model comes from `--worker-model grok=`, default `grok-4.6`.
536
558
  - All three Claude, Codex, and Antigravity verifiers are always dispatched regardless of the Executor provider. Even the verifier using the same provider runs in a separate CLI session with isolated context, preserving the self-review safeguard.
537
559
  - Codex and Antigravity mutate files through each CLI's auto-edit mode, for example `codex exec --sandbox workspace-write`, without passing through Claude-side Edit/Write tools. Mutations occur in the task worktree described below. Every `okstra-<provider>-exec.sh` entrypoint receives the worktree path as its fourth positional argument and adds it to the worker's write scope, which each provider is told as repeated `--add-dir` (Codex names the project root with `-C` and skips the repeat). Without it, the Codex `workspace-write` sandbox rejects worktree writes with EPERM.
538
560
  - **Claude Executor cwd handling**: Claude's Bash tool has no per-call cwd argument and inherits the lead session cwd. To run cwd-sensitive toolchains such as `cargo`, `npm`, `pnpm`, `bun`, `pytest`, `make`, or `go` inside the worktree, prefix the invocation with `cd {{EXECUTOR_WORKTREE_PATH}} && <cmd>`. Keep `cd` as the leading token in a single Bash call so Claude Code permission auto-allow works; do not wrap it in `bash -lc "..."` or `bash -c "..."`, which hides `cd` and causes a permission prompt on every call. Prefer a tool's working-directory option—such as `git -C <path>`, `cargo --manifest-path`, or `pytest --rootdir`—over a `cd && ` chain. Edit/Write/Read tools already use absolute paths and need no cwd handling. This rule applies only to the Claude Executor; the Codex and Antigravity wrappers inject cwd.
@@ -762,7 +784,7 @@ chmod +x ~/.local/bin/okstra-ctl
762
784
 
763
785
  ### `okstra` Node CLI — introspection subcommands
764
786
 
765
- The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and introspection commands used by skills and agents. It goes through the Node wrapper instead of invoking the Python runtime directly, so `src/lib/python-helper.mjs` wires `PYTHONPATH`.
787
+ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and introspection commands used by skills and agents. It goes through the Node wrapper instead of invoking the Python runtime directly, so `src/lib/python-helper.mts` wires `PYTHONPATH`.
766
788
 
767
789
  | Command | Purpose |
768
790
  |---|---|
@@ -770,7 +792,9 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
770
792
  | `okstra install [--runtime claude-code\|codex\|antigravity\|external\|all] [--refresh\|--dry-run\|--link <repo>]` | Install or update the runtime, templates, skills, and agents. The default runtime is `auto`; skill targets are not runtimes. `~/.agents/skills/` is always created, and Claude skills and agents are also installed when `~/.claude` exists |
771
793
  | `okstra ensure-installed [--runtime claude-code\|codex\|antigravity\|external\|all] [-q]` | Check installation state and reinstall stale assets for the same runtime. Default `auto` continues without a host signal and checks drift in the Agent skill target and any existing Claude target |
772
794
  | `okstra uninstall [--purge -y]` | Remove installed assets. By default, removes files listed by the `installed-skills.json` targets and `installed-agents.json` while preserving user data |
773
- | `okstra doctor [--runtime claude-code\|codex\|antigravity\|external\|all] [--phase <phase>] [--json]` | Diagnose the runtime, Python imports, and skill/agent installation. The `codex`, `antigravity`, and `external` runtimes omit Claude skill checks. `--phase` adds readiness checks for `implementation`, `final-verification`, `release-handoff`, or `improvement-discovery` |
795
+ | `okstra doctor [--runtime claude-code\|codex\|antigravity\|external\|all] [--phase <phase>] [--json]` | Diagnose the runtime, Python imports, skill/agent installation, and model-pool state. The JSON `modelPool` object reports pool errors, default errors, binding precision, observed model, max write boundary, and invocation downgrade reason. It never sends an inference call. The `codex`, `antigravity`, and `external` runtimes omit Claude skill checks. `--phase` adds readiness checks for `implementation`, `final-verification`, `release-handoff`, or `improvement-discovery` |
796
+ | `okstra model list [--role <role>] [--host <host>] [--json]` | List catalog models for a host and optional role. Unselectable exact bindings report `exact binding unavailable`. No inference call |
797
+ | `okstra model default set\|unset <role> ... --scope project\|global [--cwd <dir>]` | Atomically write or remove `modelDefaults` for one canonical role |
774
798
  | `okstra setup --project-id <id>` | Create or update `.okstra/project.json` in the current project |
775
799
  | `okstra check-project [--json]` | Verify that the current project is registered |
776
800
  | `okstra preflight [--runtime <name>] [--cwd <dir>] [--json]` | Single skill-preflight call combining `ensure-installed`, with silent reinstall when stale, `check-project`, and host-specific `runtimeReadiness` into one JSON response. A `claude-code` host checks project workspace trust. A `codex` current-session host verifies write access to `~/.okstra/worktrees/registry.lock`; a sandbox denial blocks before the wizard with the `switch-codex-to-full-access-and-rerun` action. `antigravity` and `external` hosts return ready without reading Claude Code state. Step 0 of every project-scoped skill converges on this command |
@@ -834,7 +858,7 @@ The convergence state lifecycle is `groups v1.0 → work v1.0 → final v1.3`; r
834
858
 
835
859
  `okstra convergence` and `okstra plan-items` are internal admin CLI families used by the lead protocol. Each is an internal admin CLI, not a user-facing skill, and their presence does not add a public skill. The former `okstra-convergence` skill remains obsolete; the installed `prompts/lead/convergence.md` and `prompts/lead/plan-body-verification.md` contracts tell the lead when to invoke these operations.
836
860
 
837
- > Every subcommand is wired to `PYTHONPATH` and `~/.okstra/lib/python` by the Python helper (`src/lib/python-helper.mjs`) spawned by `bin/okstra`. When invoking `python3 -m okstra_ctl.*` directly, you must configure `PYTHONPATH` yourself.
861
+ > Every subcommand is wired to `PYTHONPATH` and `~/.okstra/lib/python` by the Python helper (`src/lib/python-helper.mts`) spawned by `bin/okstra`. When invoking `python3 -m okstra_ctl.*` directly, you must configure `PYTHONPATH` yourself.
838
862
 
839
863
  #### `okstra design-prep`
840
864
 
@@ -5,8 +5,8 @@ Use this matrix before changing high-risk repo contracts. Update the source file
5
5
  | Change | Must update | Tests |
6
6
  |---|---|---|
7
7
  | Add CLI flag | `src/`, `scripts/okstra_ctl/run.py`, `docs/cli.md`, `prompts/wizard/` | JS CLI tests and pytest CLI contracts |
8
- | Add Node subcommand | `src/cli-registry.mjs`, `src/commands/`, `docs/cli.md`, `docs/project-structure-overview.md` | `tests-js/cli-registry.test.mjs` plus command-specific JS/Python tests |
9
- | Add public skill | `src/lib/skill-catalog.mjs`, `.claude-plugin/plugin.json`, `skills/<name>/SKILL.md`, `docs/for-ai/README.md`, `docs/project-structure-overview.md`, `README.md` | `tests-js/skill-catalog.test.mjs`, `tests/contract/test_docs_runtime_contract.py` |
8
+ | Add Node subcommand | `src/cli-registry.mts`, `src/commands/`, `docs/cli.md`, `docs/project-structure-overview.md` | `tests-js/cli-registry.test.mjs` plus command-specific JS/Python tests |
9
+ | Add public skill | `src/lib/skill-catalog.mts`, `.claude-plugin/plugin.json`, `skills/<name>/SKILL.md`, `docs/for-ai/README.md`, `docs/project-structure-overview.md`, `README.md` | `tests-js/skill-catalog.test.mjs`, `tests/contract/test_docs_runtime_contract.py` |
10
10
  | Change manager contract | `scripts/okstra_ctl/manager_*.py`, `src/commands/manager.mjs`, `skills/okstra-manager/SKILL.md`, `docs/for-ai/skills/okstra-manager.md`, `docs/cli.md`, `docs/architecture/storage-model.md` | `tests-js/manager.test.mjs`, `tests/test_okstra_manager_*.py` |
11
11
  | Add phase | `scripts/okstra_ctl/workflow.py`, `prompts/profiles/`, `validators/`, `tests/` | workflow and validation contract tests |
12
12
  | Change worker roster | `prompts/profiles/*.md`, `scripts/okstra_ctl/workers.py`, `tests/contract/test_repo_contracts.py` | worker roster contract tests |
@@ -87,7 +87,7 @@ Keep the table narrow.
87
87
  - workStatus
88
88
  - Next
89
89
 
90
- If `awaitingApproval` or `routingStatus == "pending"`, add a marker to the Next cell and explain it.
90
+ `nextRecommendedPhase` is an object `{phase, status, rationale}`. The Next cell is its `phase`, or `--` when that is empty. If `awaitingApproval`, or `nextRecommendedPhase.status` is anything but `ready`, add a marker to the Next cell and explain it.
91
91
 
92
92
  ### Specific task
93
93
 
@@ -98,9 +98,8 @@ Information to show:
98
98
  - work category
99
99
  - current phase/state
100
100
  - last completed phase
101
- - next recommended phase
101
+ - next-phase pointer: `phase` (or `--`), its `status`, its `rationale`
102
102
  - awaiting approval
103
- - routing status
104
103
  - task status, latest run status
105
104
  - latest report, resume command
106
105
  - workStatus, note
@@ -62,6 +62,7 @@ Top level:
62
62
 
63
63
  - `taskGroup` — the scope (`null` = whole project), `taskCount` — number of tasks.
64
64
  - `tasks[]` — per task: `taskKey, taskGroup, taskId, taskType, workCategory, workStatus, currentPhase, currentPhaseState, nextRecommendedPhase, latestRunStatus, updatedAt, reportPath, runCount, cpuSumMs, wallClockMs, errorCount`.
65
+ - `nextRecommendedPhase` is an object `{phase, status, rationale}`, not a string. Print `phase`, or `--` when it is empty. Never interpolate the object itself.
65
66
  - `totals` — `runs, cpuSumMs, wallClockMs, errors`, plus `byWorkStatus` / `byWorkCategory` / `byCurrentPhase` / `byTaskType` (each a `{value: count}` map).
66
67
 
67
68
  Numeric meanings (must observe):
@@ -25,7 +25,7 @@
25
25
  Current baseline:
26
26
 
27
27
  - package version: see `package.json`
28
- - Node CLI entrypoint: `bin/okstra`
28
+ - Node CLI entrypoint: `bin/okstra` (Node.js 22+)
29
29
  - Python orchestration authority: `scripts/okstra_ctl/run.py::prepare_task_bundle`
30
30
  - lifecycle: `requirements-discovery → error-analysis → implementation-option-selection → implementation-planning → implementation → final-verification → release-handoff`
31
31
  - installed skills: 13
@@ -46,7 +46,8 @@ Design principles:
46
46
  ```text
47
47
  okstra/
48
48
  ├── bin/okstra Node CLI router
49
- ├── src/ Node command modules
49
+ ├── src/ TypeScript Node command sources (`*.mts`)
50
+ ├── dist/ compiled `.mjs` CLI artifacts; generated
50
51
  ├── scripts/ Python + Bash runtime sources
51
52
  │ ├── okstra_ctl/ orchestration core
52
53
  │ ├── okstra_project/ project root / project.json resolver
@@ -145,7 +146,7 @@ Runtime/install asset changes follow this checklist:
145
146
 
146
147
  `--link <repo>` mode is for development and symlinks installed files back to repo sources.
147
148
 
148
- `src/lib/host-registry-client.mjs` is the single Node boundary for host catalog, ID/alias resolution, and readiness probes. It delegates host policy to `okstra_ctl.entrypoints.hosts`; the Claude Code adapter checks project workspace trust, while other adapters own their own checks. `okstra install` defaults to `--runtime auto`, records the request and any successful resolution in `installed-runtimes.json` schemaVersion 2, and still copies the shared runtime payload from the installed package `runtime/` tree even when host detection is unavailable. Skill targets always include the default Agent-compatible `~/.agents/skills` target, with `~/.claude/skills` also populated when `~/.claude` exists. Dynamic capabilities are probed by the selected adapter rather than frozen into the install manifest.
149
+ `src/lib/host-registry-client.mts` is the single Node boundary for host catalog, ID/alias resolution, and readiness probes. It delegates host policy to `okstra_ctl.entrypoints.hosts`; the Claude Code adapter checks project workspace trust, while other adapters own their own checks. `okstra install` defaults to `--runtime auto`, records the request and any successful resolution in `installed-runtimes.json` schemaVersion 2, and still copies the shared runtime payload from the installed package `runtime/` tree even when host detection is unavailable. Skill targets always include the default Agent-compatible `~/.agents/skills` target, with `~/.claude/skills` also populated when `~/.claude` exists. Dynamic capabilities are probed by the selected adapter rather than frozen into the install manifest.
149
150
 
150
151
  ---
151
152
 
@@ -155,62 +156,62 @@ Runtime/install asset changes follow this checklist:
155
156
 
156
157
  `bin/okstra` is a thin dynamic-import router. Every command module exports `run(args) -> Promise<number>` or a named install/uninstall runner.
157
158
 
158
- `src/` is layered: the dispatch table (`src/cli-registry.mjs`) 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}/`.
159
+ `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.
159
160
 
160
161
  | Command | Module | Role |
161
162
  |---|---|---|
162
- | `paths` | `src/commands/lifecycle/paths.mjs` | Resolve package/runtime/home paths (library at `src/lib/paths.mjs`) |
163
- | `install`, `ensure-installed` | `src/commands/lifecycle/install.mjs` | Install or refresh runtime, skills, agents, templates |
164
- | `uninstall` | `src/commands/lifecycle/uninstall.mjs` | Remove managed runtime/skills/agents, optionally purge data |
165
- | `doctor` | `src/commands/lifecycle/doctor.mjs` | Diagnose runtime and Python imports |
166
- | `setup` | `src/commands/lifecycle/setup.mjs` | Create/update `<PROJECT_ROOT>/.okstra/project.json` |
167
- | `check-project` | `src/commands/lifecycle/check-project.mjs` | Verify project registration |
168
- | `preflight` | `src/commands/lifecycle/preflight.mjs` | One-call skill preflight: ensure-installed + check-project + host-specific runtime readiness (single JSON) |
169
- | `config` | `src/commands/lifecycle/config.mjs` | Read/write project/global settings such as PR template path |
170
- | `migrate` | `src/commands/lifecycle/migrate.mjs` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
171
- | `git-reconcile` | `src/commands/execute/git-reconcile.mjs` | Reconcile stale stage SHAs after external git history changes |
172
- | `handoff` | `src/commands/execute/handoff.mjs` | Stage-group release-handoff eligibility / assemble / record helpers |
173
- | `integrate-stages` | `src/commands/execute/integrate-stages.mjs` | Merge verified stages into the task worktree and clean stage worktrees |
174
- | `task-list`, `task-show` | `src/commands/inspect/task-list.mjs`, `src/commands/inspect/task-show.mjs` | Task/run introspection for skills; `task-show` consumes the Python task read-side snapshot |
175
- | `resolve-task-key` | `src/commands/inspect/resolve-task-key.mjs` | Resolve a bare task-id to candidate task-keys from the project catalog |
176
- | `set-work-status` | `src/commands/inspect/set-work-status.mjs` | 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/*.mjs` | Read-side task runtime, wrapper log, and error aggregation helpers |
178
- | `run-audit` | `src/commands/inspect/run-audit.mjs` | 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.mjs` | 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.mjs` | 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.mjs` | Estimate task bundle file/read context cost |
182
- | `worktree-lookup` | `src/commands/execute/worktree-lookup.mjs` | Look up a task-key's registered worktree |
183
- | `worktree-status` | `src/commands/execute/worktree-status.mjs` | 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.mjs` | Check approved-plan approval marker |
185
- | `render-bundle` | `src/commands/execute/render-bundle.mjs` | Preview `prepare_task_bundle(render_only=True)` |
186
- | `profile` | `src/commands/inspect/profile-show.mjs` | 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
- | `run` | `src/commands/execute/run.mjs` | Host-aware execution front door (`auto` → Claude/Codex/Antigravity/external path selection) |
188
- | `codex-run`, `codex-dispatch` | `src/commands/execute/codex-*.mjs` | 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}.mjs` | 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.mjs` | External lead tmux-pane worker dispatch / await / teardown |
191
- | `convergence` | `src/commands/execute/convergence.mjs` | 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.mjs` | 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.mjs` | 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.mjs` | 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.mjs` | 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/*.mjs` | Render version-selected AI handoff Markdown from data.json; v1 index injection remains compatibility-only |
197
- | `wizard` | `src/commands/execute/wizard.mjs` | Drive the `okstra-run` interactive state machine, including the final outcome envelope |
198
- | `token-usage` | `src/commands/execute/token-usage.mjs` | Wrap installed Python token usage CLI |
199
- | `spawn-followups`, `error-log` | `src/commands/execute/*.mjs` | Follow-up task bundle creation and run error-log append helpers |
200
- | `memory` | `src/commands/memory/memory.mjs` | Store/find global conversation memory under `~/.okstra/memory-book` |
201
- | `pr` | `src/commands/pr/pr.mjs` | `okstra pr <template\|branches\|gen>` — PR body template store under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`), base-branch recommendation, and the `gen` JSON bundle (template + `<base>..HEAD` commits + `<base>...HEAD` diffstat) backing the okstra-pr-gen skill. Git-only; no project registration required |
202
- | `recap` | `src/commands/inspect/recap.mjs` | `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.mjs` | `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.mjs` | `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.mjs` | `okstra rollup` thin shim into `scripts/okstra_ctl/rollup.py` — read-only cross-task roll-up backing the okstra-rollup skill |
206
- | `usage-report` | `src/commands/inspect/usage-report.mjs` | `okstra usage-report` thin shim into `scripts/okstra_ctl/usage_report.py` — read-only project usage snapshot backing the okstra-usage skill |
207
- | `container` | `src/commands/inspect/container.mjs` | `bin okstra container` thin shim into `scripts/okstra_ctl/container.py` for the okstra-container-build skill |
208
- | `code-review` | `src/commands/inspect/code-review.mjs` | `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.mjs` | Thin shim into `scripts/okstra_ctl/manager_cli.py` for cross-project manager state and child launch packets |
210
-
211
- `src/lib/python-helper.mjs` centralizes Node → Python execution so command modules do not duplicate subprocess wiring.
212
-
213
- `src/lib/helper-scripts.mjs` 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/**`.
163
+ | `paths` | `src/commands/lifecycle/paths.mts` | Resolve package/runtime/home paths (library at `src/lib/paths.mts`) |
164
+ | `install`, `ensure-installed` | `src/commands/lifecycle/install.mts` | Install or refresh runtime, skills, agents, templates |
165
+ | `uninstall` | `src/commands/lifecycle/uninstall.mts` | Remove managed runtime/skills/agents, optionally purge data |
166
+ | `doctor` | `src/commands/lifecycle/doctor.mts` | Diagnose runtime and Python imports |
167
+ | `setup` | `src/commands/lifecycle/setup.mts` | Create/update `<PROJECT_ROOT>/.okstra/project.json` |
168
+ | `check-project` | `src/commands/lifecycle/check-project.mts` | Verify project registration |
169
+ | `preflight` | `src/commands/lifecycle/preflight.mts` | One-call skill preflight: ensure-installed + check-project + host-specific runtime readiness (single JSON) |
170
+ | `config` | `src/commands/lifecycle/config.mts` | Read/write project/global settings such as PR template path |
171
+ | `migrate` | `src/commands/lifecycle/migrate.mts` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
172
+ | `git-reconcile` | `src/commands/execute/git-reconcile.mts` | Reconcile stale stage SHAs after external git history changes |
173
+ | `handoff` | `src/commands/execute/handoff.mts` | Stage-group release-handoff eligibility / assemble / record helpers |
174
+ | `integrate-stages` | `src/commands/execute/integrate-stages.mts` | Merge verified stages into the task worktree and clean stage worktrees |
175
+ | `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 |
176
+ | `resolve-task-key` | `src/commands/inspect/resolve-task-key.mts` | Resolve a bare task-id to candidate task-keys from the project catalog |
177
+ | `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`) |
178
+ | `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.mts` | Read-side task runtime, wrapper log, and error aggregation helpers |
179
+ | `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`) |
180
+ | `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`) |
181
+ | `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`) |
182
+ | `context-cost` | `src/commands/inspect/context-cost.mts` | Estimate task bundle file/read context cost |
183
+ | `worktree-lookup` | `src/commands/execute/worktree-lookup.mts` | Look up a task-key's registered worktree |
184
+ | `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`) |
185
+ | `plan-validate` | `src/commands/execute/plan-validate.mts` | Check approved-plan approval marker |
186
+ | `render-bundle` | `src/commands/execute/render-bundle.mts` | Preview `prepare_task_bundle(render_only=True)` |
187
+ | `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` |
188
+ | `run` | `src/commands/execute/run.mts` | Host-aware execution front door (`auto` → Claude/Codex/Antigravity/external path selection) |
189
+ | `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 |
190
+ | `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 |
191
+ | `team` | `src/commands/execute/team.mts` | External lead tmux-pane worker dispatch / await / teardown |
192
+ | `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`) |
193
+ | `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`) |
194
+ | `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 |
195
+ | `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 |
196
+ | `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 |
197
+ | `render-final-report`, `inject-report-index` | `src/commands/report/*.mts` | Render version-selected AI handoff Markdown from data.json; v1 index injection remains compatibility-only |
198
+ | `wizard` | `src/commands/execute/wizard.mts` | Drive the `okstra-run` interactive state machine, including the final outcome envelope |
199
+ | `token-usage` | `src/commands/execute/token-usage.mts` | Wrap installed Python token usage CLI |
200
+ | `spawn-followups`, `error-log` | `src/commands/execute/*.mts` | Follow-up task bundle creation and run error-log append helpers |
201
+ | `memory` | `src/commands/memory/memory.mts` | Store/find global conversation memory under `~/.okstra/memory-book` |
202
+ | `pr` | `src/commands/pr/pr.mts` | `okstra pr <template\|branches\|gen>` — PR body template store under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`), base-branch recommendation, and the `gen` JSON bundle (template + `<base>..HEAD` commits + `<base>...HEAD` diffstat) backing the okstra-pr-gen skill. Git-only; no project registration required |
203
+ | `recap` | `src/commands/inspect/recap.mts` | `okstra recap <assemble\|record\|note>` Node wrapper backing the okstra-inspect `recap` facet — `assemble` is a read-only phase-transition summary, `record` appends one line to `recap/recap-log.jsonl`, and `note` writes an agent-authored note under `notes/` and prints the `--clarification-response` argument for a follow-up run |
204
+ | `stage-map` | `src/commands/inspect/stage-map.mts` | `okstra stage-map <task-key>` — exposes a task's implementation-planning Stage Map as JSON (`stages[].{stage_number,title,depends_on,step_count}` + consumer-state-based `doneStages[]`). If there is no Stage Map, `stages: []`. The read-side basis from which `okstra-schedule-gen` derives stage units and dependency closure |
205
+ | `design-prep` | `src/commands/inspect/design-prep.mts` | `okstra design-prep <list\|show\|write>` thin shim into `scripts/okstra_ctl/design_prep.py` — queries (`list`/`show`) the design items that implementation-planning pre-authored with AI, and records the user-confirmed responses as an append-only sidecar under `design-prep-inputs/` (`write`, `--confirmed` required). It never modifies the report snapshot |
206
+ | `rollup` | `src/commands/inspect/rollup.mts` | `okstra rollup` thin shim into `scripts/okstra_ctl/rollup.py` — read-only cross-task roll-up backing the okstra-rollup skill |
207
+ | `usage-report` | `src/commands/inspect/usage-report.mts` | `okstra usage-report` thin shim into `scripts/okstra_ctl/usage_report.py` — read-only project usage snapshot backing the okstra-usage skill |
208
+ | `container` | `src/commands/inspect/container.mts` | `bin okstra container` thin shim into `scripts/okstra_ctl/container.py` for the okstra-container-build skill |
209
+ | `code-review` | `src/commands/inspect/code-review.mts` | `okstra code-review target` thin shim into `scripts/okstra_ctl/code_review_target.py` — resolves what one implementation stage's or one branch's review reads (worktree, branch, base/head commits) and where its result file goes, for the okstra-code-review skill. Read-only; creates no directory or file |
210
+ | `manager` | `src/commands/manager.mts` | Thin shim into `scripts/okstra_ctl/manager_cli.py` for cross-project manager state and child launch packets |
211
+
212
+ `src/lib/python-helper.mts` centralizes Node → Python execution so command modules do not duplicate subprocess wiring.
213
+
214
+ `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/**`.
214
215
 
215
216
  ### 4.2 `scripts/` — Runtime source
216
217
 
@@ -257,11 +258,12 @@ Important modules:
257
258
  | `run_context.py` | Per-task mutex, run context and run-input persistence; `consumers_mutex` helper for atomic `consumers.jsonl` writes |
258
259
  | `path_hints.py` | Compact path-hint persistence + legacy context hydration — stores `run-context` / `active-run-context` in the schemaVersion `2.0` `identity` + `pathHints` compact schema, and hydrates the legacy flat path keys (`RUN_MANIFEST_RELATIVE_PATH`, `TEAM_STATE_PATH`, etc.) in memory the moment the host-side reader reads them |
259
260
  | `consumers.py` | Append-only `consumers.jsonl` writer + reader — records which `implementation` runs consumed which `implementation-planning` stage |
260
- | `implementation_outcome.py` | Artifact-derived reconstruction of the implementation phase outcome — reads `runs/implementation/carry/stage-<N>.json` + `consumers.jsonl` + the approved Stage Map to derive `phaseOutcome.implementation`, and when every stage has pass-grade carry evidence it corrects `workflow.nextRecommendedPhase` to `final-verification` (keeping the `contract-violated` audit information) |
261
+ | `implementation_outcome.py` | Artifact-derived reconstruction of the implementation phase outcome — reads `runs/implementation/carry/stage-<N>.json` + `consumers.jsonl` + the approved Stage Map to derive `phaseOutcome.implementation`, and when every stage has pass-grade carry evidence it raises `workflow.nextRecommendedPhase.status` to `ready` (keeping the `contract-violated` audit information). It never picks the phase — `phase` is left as the last stage's report routing settled it, and the status is raised only while `phase` is non-empty |
261
262
  | `paths.py` | Path/sequence computation for task/run artifacts (including recap directory/log paths) |
262
263
  | `recap.py` | deterministic backend for the okstra-inspect `recap` facet — `assemble` builds the cross-run phase transitions from the timeline, `record` append-only writes a summary/Q&A to `<task-root>/recap/recap-log.jsonl` (other task artifacts unchanged) |
263
264
  | `render.py` | task manifest, run manifest, timeline, task index, discovery, team-state, prompt/template render |
264
- | `workflow.py` | Phase sequence, allowed outputs, forbidden actions, next phase |
265
+ | `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
+ | `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 |
265
267
  | `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 |
266
268
  | `worktree.py`, `worktree_registry.py` | One worktree per task-key, branch registry, sync dirs/files/snapshots |
267
269
  | `project_meta.py`, `resolver.py`, `path_resolve.py` | Project/task/run resolution |
@@ -421,7 +423,7 @@ Optional (v1.0 backward-compatible) top-level keys:
421
423
 
422
424
  ### 4.10 `skills/`
423
425
 
424
- 13 user-facing skills (the only skills `okstra install` copies). The list SSOT is `USER_SKILL_NAMES` in `src/lib/skill-catalog.mjs`; the Claude plugin manifest and the installer both derive from it.
426
+ 13 user-facing skills (the only skills `okstra install` copies). The list SSOT is `USER_SKILL_NAMES` in `src/lib/skill-catalog.mts`; the Claude plugin manifest and the installer both derive from it.
425
427
 
426
428
  Boilerplate shared by several skills (bash invocation rule, outdated-CLI preflight, python bootstrap note) is kept canonical in `skills/_fragments/*.md` and expanded in place inside each `SKILL.md` between `<!-- BEGIN FRAGMENT: <name> -->` / `<!-- END FRAGMENT: <name> -->` markers by `tools/sync-skill-fragments.mjs` (`--check` fails on drift). Sources stay fully expanded, so `runtime/` and installed copies remain self-contained; the guards are `tests-js/skill-fragments.test.mjs` and `tests/contract/test_prompt_fragment_ownership.py`.
427
429
 
@@ -492,7 +494,7 @@ they are not published user skills.
492
494
  `prepare_task_bundle()` coordinates:
493
495
 
494
496
  1. Resolve project root and verify/upsert `project.json`.
495
- 2. Resolve profile, required workers, model assignments, executor provider.
497
+ 2. Resolve profile, required workers, role counts, `ModelPool` assignments, and the implementer provider. `lead`/`executor` remain input aliases only.
496
498
  3. Resolve task identity segments, work category, and the run sequence input needed for path allocation.
497
499
  4. Provision or reuse the task-key worktree, or the selected implementation stage worktree for stage-isolated runs.
498
500
  5. For an analysis sidetrack, resolve the immutable source commit from the provisioned worktree's `HEAD`, then resolve evidence reports, freshness, and the feature target through `analysis_inputs.py`.
@@ -543,6 +545,14 @@ For the three analysis sidetracks, the HTML view also exports an immutable-sourc
543
545
 
544
546
  Both Markdown and HTML are derived, not authoring sources. The schema is the contract.
545
547
 
548
+ ### 5.4 Role execution and model defaults
549
+
550
+ - `scripts/okstra_ctl/domain/role.py` — canonical roles and duty mapping.
551
+ - `scripts/okstra_ctl/model_pool.py` — unified catalog lookup.
552
+ - `scripts/okstra_ctl/model_cli.py` — `okstra model list` and atomic `modelDefaults` writes. No inference call.
553
+ - `scripts/okstra_ctl/pane_title.py` — pane titles from stored `executionLabel`.
554
+ - `scripts/okstra_ctl/doctor.py` — `model_pool_diagnostics()` for `okstra doctor --json`.
555
+
546
556
  ---
547
557
 
548
558
  ## 6. Post-install layout
@@ -625,7 +635,7 @@ Project-local `<PROJECT_ROOT>/.claude/settings.local.json` is provisioned as a s
625
635
  | `final-verification` | Read-only acceptance verification | `release-handoff` if accepted |
626
636
  | `release-handoff` | User-selected commit/PR handoff | done or follow-up |
627
637
 
628
- The independent analysis sidetracks do not appear in this phase sequence. `project-analysis` maps the current project, `feature-analysis` traces one existing feature, and `change-impact-analysis` maps a proposed change's impact. Each returns to `pending-routing-decision` and remains read-only, including no test or build execution.
638
+ The independent analysis sidetracks do not appear in this phase sequence. `project-analysis` maps the current project, `feature-analysis` traces one existing feature, and `change-impact-analysis` maps a proposed change's impact. Each leaves the next-phase pointer `pending` with no phase, and remains read-only, including no test or build execution.
629
639
 
630
640
  ### 7.5 Report and follow-up
631
641
 
@@ -674,4 +684,4 @@ Clarifications now live in the unified `## 1. Clarification Items` table. Deprec
674
684
 
675
685
  ---
676
686
 
677
- *Updated: 2026-07-22 · Source of truth checked against `package.json`, `bin/okstra`, `src/cli-registry.mjs`, `src/lib/skill-catalog.mjs`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
687
+ *Updated: 2026-08-18 · Source of truth checked against `package.json`, `bin/okstra`, `src/cli-registry.mts`, `src/lib/skill-catalog.mts`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
@@ -34,6 +34,8 @@ flowchart TD
34
34
 
35
35
  `okstra-run` does not call `scripts/okstra.sh`. Instead it goes through `okstra wizard` and `okstra render-bundle` and converges on the same single Python entrypoint, `prepare_task_bundle()`.
36
36
 
37
+ Launch selection is role slots and model refs, not a provider roster. The wizard shows the leader session read-only, then role counts (`min..max`, default **recommended**), then `--role-model <role>=<provider>/<model>` per slot. Roles with `min = 0` stay closed unless the user adds them. There is no provider multi-pick and no `Use defaults / Customize` fork for worker selection. `--workers` is compatibility-only. `lead` is a compatibility alias for `leader`. `executor` is a compatibility alias for `implementer`. New records write `leader` and `implementer`.
38
+
37
39
  ## 3. task-type documents
38
40
 
39
41
  | task-type | Document | One-line purpose |
@@ -67,12 +69,14 @@ flowchart TD
67
69
 
68
70
  ## 5. Quick comparison table
69
71
 
70
- | task-type | wizard special question | runtime prepare gate | lead/worker mode | next phase default |
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).
73
+
74
+ | task-type | wizard special question | runtime prepare gate | lead/worker mode | next-phase pointer |
71
75
  |---|---|---|---|---|
72
- | `requirements-discovery` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 1 round default | `pending-routing-decision` |
73
- | `error-analysis` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 2 rounds default | `implementation-option-selection` |
74
- | `implementation-option-selection` | comparison or preselected-validation context | stable brief IDs and at least three analysers | read-only candidate validation, exact coverage, separate direction confirmation | `implementation-planning` or `blocked` |
75
- | `implementation-planning` | selected-direction report for a new plan | selection report/sidecar/digest or same-task planning rerun | one-direction realization + Phase 6 plan-body verification | `implementation` after plan approval |
76
- | `implementation` | approved plan, stage multi-pick, executor | approved marker, Stage Lifecycle Snapshot, stage-key reservation, QA command deny-list | one run = one stage; executor writes in isolated stage worktree, verifiers read-only | `final-verification` |
77
- | `final-verification` | approved plan, stage pick (whole-task or single-stage) | `VERIFICATION_TARGET` resolved; whole-task auto integration/teardown or single-stage worktree reuse | whole-task may integrate stages first; analyser verification itself is read-only | `pending-release-handoff` |
78
- | `release-handoff` | handoff scope (stage-group or whole-task), PR template override/scope | Stage Lifecycle Snapshot eligibility, generated `release-handoff-input.md`, empty worker roster | single-lead; whole-task PR or stage-group collector branch/PR | `done-or-follow-up` |
76
+ | `requirements-discovery` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 1 round default | `ready` at `error-analysis` or `implementation-option-selection`; `pending` when neither is settled |
77
+ | `error-analysis` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 2 rounds default | `ready` at `implementation-option-selection`, or at `error-analysis` while the investigation continues |
78
+ | `implementation-option-selection` | comparison or preselected-validation context | stable brief IDs and at least three analysers | read-only candidate validation, exact coverage, separate direction confirmation | `ready` at `implementation-planning`, `pending` on `pending-direction-selection`, or `blocked` |
79
+ | `implementation-planning` | selected-direction report for a new plan | selection report/sidecar/digest or same-task planning rerun | one-direction realization + Phase 6 plan-body verification | `ready` at `implementation` on `plan-ready` (the plan still needs its separate approval), or at `implementation-option-selection` on `direction-invalidated` |
80
+ | `implementation` | approved plan, stage multi-pick, executor | approved marker, Stage Lifecycle Snapshot, stage-key reservation, QA command deny-list | one run = one stage; executor writes in isolated stage worktree, verifiers read-only | `ready` at the stage report's `routingRecommendation.target` — `final-verification` on a clean stage |
81
+ | `final-verification` | approved plan, stage pick (whole-task or single-stage) | `VERIFICATION_TARGET` resolved; whole-task auto integration/teardown or single-stage worktree reuse | whole-task may integrate stages first; analyser verification itself is read-only | `ready` at `release-handoff` on an `accepted` verdict, otherwise at the phase owning the defect; `terminal` on `done` |
82
+ | `release-handoff` | handoff scope (stage-group or whole-task), PR template override/scope | Stage Lifecycle Snapshot eligibility, generated `release-handoff-input.md`, empty worker roster | single-lead; whole-task PR or stage-group collector branch/PR | always `terminal` |
@@ -56,18 +56,17 @@ stateDiagram-v2
56
56
  TaskType --> BaseRef: no active worktree
57
57
  TaskType --> ImplementationExtras: implementation only
58
58
  BaseRef --> ImplementationExtras: implementation only
59
- BaseRef --> DefaultsOrCustom: non-implementation
60
- ImplementationExtras --> DefaultsOrCustom
61
- DefaultsOrCustom --> WorkersOverride: non-implementation analyser roster
62
- WorkersOverride --> Confirm: defaults
63
- DefaultsOrCustom --> ModelAndOptionalInputs: customize
64
- ModelAndOptionalInputs --> Confirm
59
+ BaseRef --> LeaderSession: non-implementation
60
+ ImplementationExtras --> LeaderSession
61
+ LeaderSession --> RoleSlots: role-count then role-model
62
+ RoleSlots --> OptionalInputs: directive / related / clarification
63
+ OptionalInputs --> Confirm
65
64
  Confirm --> EditTarget: Edit
66
65
  EditTarget --> TaskType: rewind selected step
67
66
  Confirm --> Done: Proceed
68
67
  ```
69
68
 
70
- A new task receives its brief first. If the brief frontmatter has `task-group:` and `brief-id:`, the wizard shows the task group/id as recommended picks. An existing task shows the manifest's `workflow.nextRecommendedPhase` as the recommended task-type, and if an existing brief path exists it asks whether to keep or change it.
69
+ A new task receives its brief first. If the brief frontmatter has `task-group:` and `brief-id:`, the wizard shows the task group/id as recommended picks. An existing task shows the manifest's `workflow.nextRecommendedPhase.phase` as the recommended task-type, but only while that pointer's `status` is `ready`. Under any other status the recommended slot stays empty and the list falls back to rerunning `workflow.currentPhase` plus the full task-type choices. If an existing brief path exists it asks whether to keep or change it.
71
70
 
72
71
  ## 4. render-bundle and prepare_task_bundle
73
72
 
@@ -152,20 +151,18 @@ flowchart TD
152
151
  T[task-type selected] --> W{active worktree in registry?}
153
152
  W -->|yes| Reuse[reuse existing worktree<br/>base-ref prompt skipped]
154
153
  W -->|no| Base[ask base-ref<br/>validate with git rev-parse]
155
- Base --> D{Use defaults?}
156
- Reuse --> D
157
- D -->|defaults| R{non-implementation<br/>has analyser roster?}
158
- D -->|customize| M[lead/model/directive/related/clarification prompts]
159
- R -->|yes| WO[worker multi-pick still shown]
160
- R -->|no| Confirm
161
- WO --> Confirm
162
- M --> Special{release-handoff?}
154
+ Base --> L[leader session read-only]
155
+ Reuse --> L
156
+ L --> C[role-count min..max<br/>omit uses recommended]
157
+ C --> M[role-model provider/model per slot]
158
+ M --> O[directive / related / clarification]
159
+ O --> Special{release-handoff?}
163
160
  Special -->|yes| PR[PR template override/scope]
164
161
  Special -->|no| Confirm
165
162
  PR --> Confirm
166
163
  ```
167
164
 
168
- The important point is that `Use defaults` means the model defaults. For non-implementation task-types, the worker roster question still appears even if you choose defaults. Conversely, `implementation` has no worker override question; it uses the profile default roster and executor binding.
165
+ Launch selection is role slots and model refs. The wizard does not show a provider roster multi-pick and does not fork on `Use defaults / Customize` for workers. Omitting `--role-count` keeps each static role at its profile **recommended** count within `min..max`. Duplicate model refs in the same role are rejected. `--workers` remains a CLI compatibility input only.
169
166
 
170
167
  Worktree rules differ per phase. From `requirements-discovery` through `implementation-planning`, the task-key worktree is reused. `implementation` uses the task-key worktree as an anchor but does the actual execution isolated one stage at a time in a stage-key (`stage-<N>`) worktree and the `runs/implementation/stage-<N>/` deliverables. `final-verification --stage N` reuses that implementation stage worktree as a read target, and whole-task mode auto-integrates the stage commits into the task-key worktree and then builds the verification target. The Stage Lifecycle Snapshot is a read-side view that does not change this storage structure.
171
168
 
@@ -20,19 +20,18 @@ flowchart TD
20
20
  Start[/okstra-run/] --> Common[common task identity flow]
21
21
  Common --> Type[task-type = error-analysis]
22
22
  Type --> Worktree{active worktree exists?}
23
- Worktree -->|yes| Defaults[Use defaults / Customize]
23
+ Worktree -->|yes| Leader[leader session read-only]
24
24
  Worktree -->|no| BaseRef[base-ref pick/text<br/>main recommended]
25
- BaseRef --> Defaults
26
- Defaults --> Workers[analysis worker multi-pick]
27
- Workers --> D{Use defaults?}
28
- D -->|yes| Confirm
29
- D -->|customize| M[lead/worker model prompts]
30
- M --> X[directive, related tasks, clarification]
31
- X --> Confirm
25
+ BaseRef --> Leader
26
+ Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
27
+ RoleCount --> RoleModel[role-model provider/model per slot]
28
+ RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
29
+ RoleAdd --> Extras[directive, related tasks, clarification]
30
+ Extras --> Confirm
32
31
  Confirm --> Render[render-bundle --render-only]
33
32
  ```
34
33
 
35
- The default required roster is `claude`, `codex`, `report-writer`. `antigravity` is an optional worker, and if selected it joins the analyser set.
34
+ Launch selection uses role slots and model refs only: leader is the current session (read-only), then each static role's count in `min..max` (default **recommended**; the count step is skipped when `min == max`), then one `provider/model` per slot. Roles with `min = 0` stay closed unless the user opens them with role-add (default skip). Duplicate model refs in the same role are rejected. There is no provider roster multi-pick and no `Use defaults / Customize` fork. Dynamic verifiers are not chosen at launch. `--workers` is a CLI compatibility input only, not a launch picker.
36
35
 
37
36
  ## 3. prepare_task_bundle handling
38
37
 
@@ -57,7 +56,7 @@ sequenceDiagram
57
56
 
58
57
  For canonical briefs, preflight runs before worker resolution, worktree provisioning, or report creation. A brief whose `reporter-confirmations` status is `pending` stops at this point; legacy briefs keep the compatibility path.
59
58
 
60
- The final report records its next phase in `errorAnalysis.routing.nextTaskType`. After report validation passes, workflow metadata persists that route as `nextRecommendedPhase`. A credible cause uses `implementation-option-selection`; continued investigation uses `error-analysis`. The static fallback also routes a missing or legacy error-analysis report to option selection.
59
+ The final report records its next phase in `errorAnalysis.routing.nextTaskType`. A credible cause uses `implementation-option-selection`; continued investigation uses `error-analysis`. When report validation passes, Phase 7 projects `workflow.nextRecommendedPhase` from that one field (`scripts/okstra_ctl/next_phase.py::project`) — a `ready` pointer naming it. A report that leaves the field empty leaves the pointer `pending`; there is no static fallback that supplies a phase the report did not author.
61
60
 
62
61
  ## 4. lead execution flow
63
62