okstra 0.174.0 → 0.175.1

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 (374) 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 +4 -0
  232. package/docs/architecture.md +7 -1
  233. package/docs/cli.md +26 -6
  234. package/docs/contributor-change-matrix.md +2 -2
  235. package/docs/project-structure-overview.md +16 -7
  236. package/docs/task-process/README.md +2 -0
  237. package/docs/task-process/implementation-planning.md +1 -1
  238. package/docs/task-process/implementation.md +1 -1
  239. package/package.json +11 -5
  240. package/runtime/BUILD.json +2 -2
  241. package/runtime/agents/workers/claude-worker.md +2 -1
  242. package/runtime/agents/workers/report-writer-worker.md +3 -1
  243. package/runtime/agents/workers/translator-worker.md +3 -1
  244. package/runtime/bin/lib/okstra/cli.sh +12 -0
  245. package/runtime/bin/lib/okstra/globals.sh +3 -0
  246. package/runtime/bin/lib/okstra/usage.sh +4 -4
  247. package/runtime/bin/okstra-error-log.py +27 -0
  248. package/runtime/bin/okstra-provider-exec.py +217 -5
  249. package/runtime/bin/okstra.sh +10 -0
  250. package/runtime/prompts/lead/convergence.md +27 -18
  251. package/runtime/prompts/lead/okstra-lead-contract.md +3 -1
  252. package/runtime/prompts/lead/plan-body-verification.md +10 -3
  253. package/runtime/prompts/lead/team-contract.md +1 -1
  254. package/runtime/prompts/profiles/change-impact-analysis.md +16 -0
  255. package/runtime/prompts/profiles/error-analysis.md +20 -0
  256. package/runtime/prompts/profiles/feature-analysis.md +16 -0
  257. package/runtime/prompts/profiles/final-verification.md +16 -0
  258. package/runtime/prompts/profiles/implementation-option-selection.md +16 -0
  259. package/runtime/prompts/profiles/implementation-planning.md +20 -0
  260. package/runtime/prompts/profiles/implementation.md +15 -0
  261. package/runtime/prompts/profiles/improvement-discovery.md +16 -0
  262. package/runtime/prompts/profiles/project-analysis.md +16 -0
  263. package/runtime/prompts/profiles/release-handoff.md +4 -0
  264. package/runtime/prompts/profiles/requirements-discovery.md +20 -0
  265. package/runtime/prompts/wizard/prompts.ko.json +18 -0
  266. package/runtime/python/okstra_ctl/adapters/dispatch/cli_wrapper.py +8 -0
  267. package/runtime/python/okstra_ctl/adapters/dispatch/cmux.py +8 -0
  268. package/runtime/python/okstra_ctl/adapters/dispatch/native_team.py +13 -0
  269. package/runtime/python/okstra_ctl/adapters/hosts/antigravity/adapter.py +2 -2
  270. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +25 -5
  271. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +2 -2
  272. package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +4 -1
  273. package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +2 -2
  274. package/runtime/python/okstra_ctl/adapters/hosts/kimi/adapter.py +2 -2
  275. package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +79 -11
  276. package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +95 -25
  277. package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +59 -14
  278. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +55 -9
  279. package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +51 -12
  280. package/runtime/python/okstra_ctl/agent_activity.py +5 -1
  281. package/runtime/python/okstra_ctl/agent_invocation.py +608 -14
  282. package/runtime/python/okstra_ctl/agent_prompt_cli.py +249 -50
  283. package/runtime/python/okstra_ctl/application/resolve_assignment.py +53 -12
  284. package/runtime/python/okstra_ctl/assignment_environment.py +102 -0
  285. package/runtime/python/okstra_ctl/assignment_resolver.py +790 -0
  286. package/runtime/python/okstra_ctl/attempt_evidence.py +342 -0
  287. package/runtime/python/okstra_ctl/convergence.py +409 -3
  288. package/runtime/python/okstra_ctl/convergence_engine.py +248 -15
  289. package/runtime/python/okstra_ctl/convergence_store.py +170 -1
  290. package/runtime/python/okstra_ctl/dispatch_core.py +1092 -63
  291. package/runtime/python/okstra_ctl/dispatch_state.py +696 -11
  292. package/runtime/python/okstra_ctl/doctor.py +14 -0
  293. package/runtime/python/okstra_ctl/domain/host.py +32 -1
  294. package/runtime/python/okstra_ctl/domain/provider.py +212 -6
  295. package/runtime/python/okstra_ctl/domain/role.py +125 -0
  296. package/runtime/python/okstra_ctl/domain/wizard/interaction.py +13 -0
  297. package/runtime/python/okstra_ctl/domain/worker_exec.py +34 -1
  298. package/runtime/python/okstra_ctl/domain/worker_role.py +13 -3
  299. package/runtime/python/okstra_ctl/domain/worker_stream.py +24 -0
  300. package/runtime/python/okstra_ctl/error_log_write.py +9 -0
  301. package/runtime/python/okstra_ctl/error_report.py +21 -1
  302. package/runtime/python/okstra_ctl/execution_identity.py +529 -0
  303. package/runtime/python/okstra_ctl/execution_manifest.py +1281 -0
  304. package/runtime/python/okstra_ctl/execution_mutation_audit.py +619 -0
  305. package/runtime/python/okstra_ctl/index.py +6 -2
  306. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +43 -3
  307. package/runtime/python/okstra_ctl/legacy_model_selection.py +490 -0
  308. package/runtime/python/okstra_ctl/model_cli.py +278 -0
  309. package/runtime/python/okstra_ctl/model_defaults.py +46 -0
  310. package/runtime/python/okstra_ctl/model_discovery.py +26 -7
  311. package/runtime/python/okstra_ctl/model_pool.py +501 -0
  312. package/runtime/python/okstra_ctl/models.py +47 -27
  313. package/runtime/python/okstra_ctl/mutation_recovery.py +293 -0
  314. package/runtime/python/okstra_ctl/pane_title.py +151 -0
  315. package/runtime/python/okstra_ctl/ports/host_model.py +48 -17
  316. package/runtime/python/okstra_ctl/ports/worker_dispatch.py +4 -0
  317. package/runtime/python/okstra_ctl/registry/provider_registry.py +8 -4
  318. package/runtime/python/okstra_ctl/render.py +78 -10
  319. package/runtime/python/okstra_ctl/render_final_report.py +19 -0
  320. package/runtime/python/okstra_ctl/report_contract.py +39 -0
  321. package/runtime/python/okstra_ctl/report_finalize.py +16 -0
  322. package/runtime/python/okstra_ctl/report_html/render.py +1 -0
  323. package/runtime/python/okstra_ctl/role_requirements.py +217 -0
  324. package/runtime/python/okstra_ctl/run.py +1207 -258
  325. package/runtime/python/okstra_ctl/run_index_row.py +7 -1
  326. package/runtime/python/okstra_ctl/time_report.py +38 -4
  327. package/runtime/python/okstra_ctl/usage_identity.py +86 -0
  328. package/runtime/python/okstra_ctl/usage_report.py +15 -3
  329. package/runtime/python/okstra_ctl/wizard.py +1253 -62
  330. package/runtime/python/okstra_ctl/worker_audit_ledger.py +68 -65
  331. package/runtime/python/okstra_ctl/worker_request.py +7 -1
  332. package/runtime/python/okstra_ctl/worker_runner.py +130 -5
  333. package/runtime/python/okstra_ctl/workers.py +7 -5
  334. package/runtime/python/okstra_ctl/write_policy.py +571 -0
  335. package/runtime/schemas/convergence-groups-v2.0.schema.json +128 -0
  336. package/runtime/schemas/execution-manifest-v2.schema.json +340 -0
  337. package/runtime/schemas/final-report-v2.0.schema.json +25 -0
  338. package/runtime/skills/okstra-run/SKILL.md +9 -9
  339. package/runtime/templates/report-writer-prompt-preamble.md +2 -0
  340. package/runtime/templates/reports/final-report-v2.template.md +7 -1
  341. package/runtime/templates/reports/html/base.template.html +21 -0
  342. package/runtime/templates/reports/html/i18n/en.json +4 -0
  343. package/runtime/templates/reports/html/i18n/ko.json +4 -0
  344. package/runtime/templates/worker-prompt-preamble.md +6 -2
  345. package/runtime/validators/lib/fixtures.sh +49 -16
  346. package/runtime/validators/validate-run.py +429 -35
  347. package/runtime/validators/validate_session_conformance.py +25 -7
  348. package/src/cli-registry.mjs +0 -539
  349. package/src/commands/execute/codex-dispatch.mjs +0 -10
  350. package/src/commands/execute/plan-items.mjs +0 -9
  351. package/src/commands/execute/plan-validate.mjs +0 -68
  352. package/src/commands/execute/run.mjs +0 -208
  353. package/src/commands/execute/wizard.mjs +0 -167
  354. package/src/commands/inspect/stage-map.mjs +0 -98
  355. package/src/commands/inspect/task-list.mjs +0 -97
  356. package/src/commands/inspect/task-show.mjs +0 -100
  357. package/src/commands/lifecycle/check-project.mjs +0 -187
  358. package/src/commands/lifecycle/config.mjs +0 -385
  359. package/src/commands/lifecycle/doctor.mjs +0 -308
  360. package/src/commands/lifecycle/install.mjs +0 -1170
  361. package/src/commands/lifecycle/paths.mjs +0 -104
  362. package/src/commands/lifecycle/preflight.mjs +0 -125
  363. package/src/commands/lifecycle/setup.mjs +0 -333
  364. package/src/commands/lifecycle/uninstall.mjs +0 -279
  365. package/src/commands/memory/memory.mjs +0 -524
  366. package/src/commands/pr/pr.mjs +0 -261
  367. package/src/lib/host-registry-client.mjs +0 -176
  368. package/src/lib/paths.mjs +0 -86
  369. package/src/lib/proc.mjs +0 -31
  370. package/src/lib/python-helper.mjs +0 -142
  371. package/src/lib/runtime-manifest.mjs +0 -70
  372. package/src/lib/skill-catalog.mjs +0 -53
  373. package/src/lib/version.mjs +0 -20
  374. /package/{src → dist}/commands/pr/default.md +0 -0
@@ -0,0 +1,529 @@
1
+ """Provider-neutral execution identity value objects and versioned readers."""
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import json
6
+ from collections.abc import Mapping
7
+ from dataclasses import dataclass, field
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ from .domain.provider import HostModelBinding, ServedModelAttestation
12
+ from .domain.worker_exec import WorkerWriteCapability
13
+
14
+
15
+ V2_SCHEMA_VERSION = "2.0"
16
+ EXECUTION_IDENTITY_VERSION = 2
17
+ _V1_SCHEMA_VERSIONS = {1, "1", "1.0"}
18
+ _V2_IDENTITY_KEYS = frozenset({
19
+ "executionIdentityVersion",
20
+ "participantAssignments",
21
+ "roleExecutions",
22
+ "invocations",
23
+ "attempts",
24
+ "attemptEvidenceSeals",
25
+ "mutationRecoveryDecisions",
26
+ "roleExecutionIndex",
27
+ "staticParticipantAssignments",
28
+ "staticRoleExecutions",
29
+ "dynamicRolePolicy",
30
+ })
31
+
32
+
33
+ class ExecutionManifestError(ValueError):
34
+ """Raised when execution identity state is ambiguous or inconsistent."""
35
+
36
+
37
+ @dataclass(frozen=True)
38
+ class ParticipantAssignment:
39
+ participant_ref: str
40
+ provider: str
41
+ model_ref: str | None
42
+ model_id: str
43
+ runner: str
44
+ host_runtime: str
45
+ host_model_value: str | None
46
+ session_ref: str | None
47
+ window_ref: str | None
48
+ worker_write_capability: WorkerWriteCapability | None
49
+ entry_mode: str
50
+ status: str
51
+
52
+ def to_payload(self) -> dict[str, Any]:
53
+ return {
54
+ "participantRef": self.participant_ref,
55
+ "provider": self.provider,
56
+ "modelRef": self.model_ref,
57
+ "modelId": self.model_id,
58
+ "runner": self.runner,
59
+ "hostRuntime": self.host_runtime,
60
+ "hostModelValue": self.host_model_value,
61
+ "sessionRef": self.session_ref,
62
+ "windowRef": self.window_ref,
63
+ "workerWriteCapability": _capability_payload(
64
+ self.worker_write_capability
65
+ ),
66
+ "entryMode": self.entry_mode,
67
+ "status": self.status,
68
+ }
69
+
70
+
71
+ @dataclass(frozen=True)
72
+ class RoleExecution:
73
+ role_execution_ref: str
74
+ participant_ref: str
75
+ source_role_execution_ref: str | None
76
+ role: str
77
+ provider: str
78
+ model_ref: str | None
79
+ model_id: str
80
+ ordinal: int
81
+ execution_label: str
82
+ model_spec_digest: str | None
83
+ binding: HostModelBinding | None
84
+ served_model_attestation: ServedModelAttestation
85
+ status: str
86
+
87
+ def to_payload(self) -> dict[str, Any]:
88
+ return {
89
+ "roleExecutionRef": self.role_execution_ref,
90
+ "participantRef": self.participant_ref,
91
+ "sourceRoleExecutionRef": self.source_role_execution_ref,
92
+ "role": self.role,
93
+ "provider": self.provider,
94
+ "modelRef": self.model_ref,
95
+ "modelId": self.model_id,
96
+ "ordinal": self.ordinal,
97
+ "executionLabel": self.execution_label,
98
+ "modelSpecDigest": self.model_spec_digest,
99
+ "binding": _binding_payload(self.binding),
100
+ "servedModelAttestation": _attestation_payload(
101
+ self.served_model_attestation
102
+ ),
103
+ "status": self.status,
104
+ }
105
+
106
+
107
+ @dataclass(frozen=True)
108
+ class Invocation:
109
+ invocation_ref: str
110
+ participant_ref: str
111
+ role_execution_ref: str
112
+ source_invocation_ref: str | None
113
+ recovery_ref: str | None
114
+ duty_id: str
115
+ dispatch_kind: str
116
+ round: int
117
+ input_digest: str
118
+ write_policy: Mapping[str, Any]
119
+ write_policy_digest: str
120
+ write_enforcement: Mapping[str, Any]
121
+
122
+ def to_payload(self) -> dict[str, Any]:
123
+ return {
124
+ "invocationRef": self.invocation_ref,
125
+ "participantRef": self.participant_ref,
126
+ "roleExecutionRef": self.role_execution_ref,
127
+ "sourceInvocationRef": self.source_invocation_ref,
128
+ "recoveryRef": self.recovery_ref,
129
+ "dutyId": self.duty_id,
130
+ "dispatchKind": self.dispatch_kind,
131
+ "round": self.round,
132
+ "inputDigest": self.input_digest,
133
+ "writePolicy": dict(self.write_policy),
134
+ "writePolicyDigest": self.write_policy_digest,
135
+ "writeEnforcement": dict(self.write_enforcement),
136
+ }
137
+
138
+
139
+ @dataclass(frozen=True)
140
+ class Attempt:
141
+ invocation_ref: str
142
+ attempt: int
143
+ started_at: str
144
+ finished_at: str | None
145
+ status: str
146
+ result_path: str | None
147
+ error_path: str | None
148
+ change_summary: Mapping[str, Any]
149
+ evidence_seal_ref: str | None
150
+
151
+ def to_payload(self) -> dict[str, Any]:
152
+ return {
153
+ "invocationRef": self.invocation_ref,
154
+ "attempt": self.attempt,
155
+ "startedAt": self.started_at,
156
+ "finishedAt": self.finished_at,
157
+ "status": self.status,
158
+ "resultPath": self.result_path,
159
+ "errorPath": self.error_path,
160
+ "changeSummary": dict(self.change_summary),
161
+ "evidenceSealRef": self.evidence_seal_ref,
162
+ }
163
+
164
+
165
+ @dataclass(frozen=True)
166
+ class ExecutionManifest:
167
+ entry_mode: str
168
+ participant_assignments: tuple[ParticipantAssignment, ...] = ()
169
+ role_executions: tuple[RoleExecution, ...] = ()
170
+ invocations: tuple[Invocation, ...] = ()
171
+ attempts: tuple[Attempt, ...] = ()
172
+ attempt_evidence_seals: tuple[Mapping[str, Any], ...] = ()
173
+ mutation_recovery_decisions: tuple[Mapping[str, Any], ...] = ()
174
+ legacy: bool = False
175
+ legacy_payload: Mapping[str, Any] = field(default_factory=dict, compare=False)
176
+
177
+ def to_payload(self) -> dict[str, Any]:
178
+ return {
179
+ "schemaVersion": V2_SCHEMA_VERSION,
180
+ "executionIdentityVersion": EXECUTION_IDENTITY_VERSION,
181
+ "entryMode": self.entry_mode,
182
+ "participantAssignments": [
183
+ row.to_payload() for row in self.participant_assignments
184
+ ],
185
+ "roleExecutions": [row.to_payload() for row in self.role_executions],
186
+ "invocations": [row.to_payload() for row in self.invocations],
187
+ "attempts": [row.to_payload() for row in self.attempts],
188
+ "attemptEvidenceSeals": list(self.attempt_evidence_seals),
189
+ "mutationRecoveryDecisions": list(self.mutation_recovery_decisions),
190
+ }
191
+
192
+
193
+ @dataclass(frozen=True)
194
+ class IdentitySurface:
195
+ surface: str
196
+ legacy: bool
197
+ payload: Mapping[str, Any]
198
+
199
+
200
+ def execution_label(role: str, provider: str, model_id: str, ordinal: int) -> str:
201
+ return f"{role}-{provider}-{model_id}-{ordinal}"
202
+
203
+
204
+ def execution_identity_for_ref(
205
+ manifest: ExecutionManifest, ref: str
206
+ ) -> RoleExecution:
207
+ """Resolve one canonical role execution for state, usage, errors and activity views."""
208
+ match = next(
209
+ (row for row in manifest.role_executions if row.role_execution_ref == ref),
210
+ None,
211
+ )
212
+ if match is None:
213
+ raise ExecutionManifestError(f"unknown roleExecutionRef: {ref}")
214
+ return match
215
+
216
+
217
+ def stored_execution_label(row: Mapping[str, Any]) -> str:
218
+ """Return the stored label; do not parse it into role/provider/model."""
219
+ label = row.get("executionLabel")
220
+ if not isinstance(label, str) or not label.strip():
221
+ raise ExecutionManifestError("executionLabel is missing")
222
+ return label
223
+
224
+
225
+ STORED_IDENTITY_KEYS = (
226
+ "participantRef",
227
+ "roleExecutionRef",
228
+ "invocationRef",
229
+ "attempt",
230
+ "executionLabel",
231
+ )
232
+
233
+
234
+ def stored_identity(payload: Mapping[str, Any] | None) -> dict[str, Any]:
235
+ """Copy stored identity fields. Never infer them from labels."""
236
+ if not isinstance(payload, Mapping):
237
+ return {}
238
+ copied: dict[str, Any] = {}
239
+ for key in STORED_IDENTITY_KEYS:
240
+ if key not in payload:
241
+ continue
242
+ value = payload[key]
243
+ if value in (None, ""):
244
+ continue
245
+ copied[key] = value
246
+ if "executionLabel" in copied:
247
+ copied["executionLabel"] = stored_execution_label(copied)
248
+ return copied if "roleExecutionRef" in copied or "executionLabel" in copied else {}
249
+
250
+
251
+ def reject_partial_v2_payload(payload: Mapping[str, Any]) -> None:
252
+ present = [key for key in _V2_IDENTITY_KEYS if key in payload]
253
+ if not present:
254
+ return
255
+ required = (
256
+ "executionIdentityVersion",
257
+ "participantAssignments",
258
+ "roleExecutions",
259
+ "invocations",
260
+ "attempts",
261
+ )
262
+ missing = [key for key in required if key not in payload]
263
+ if missing:
264
+ raise ExecutionManifestError(
265
+ "partial v2 execution identity payload is rejected: "
266
+ + ", ".join(missing)
267
+ )
268
+
269
+
270
+ def model_spec_digest(
271
+ model_spec: Mapping[str, Any] | object,
272
+ binding: HostModelBinding,
273
+ *,
274
+ write_policy_digest: str | None = None,
275
+ served_model_attestation: ServedModelAttestation | None = None,
276
+ ) -> str:
277
+ """Digest preparation facts; invocation policy and observations are excluded."""
278
+ del write_policy_digest, served_model_attestation
279
+ canonical = {
280
+ "modelSpec": _canonical_model_spec(model_spec),
281
+ "binding": _binding_payload(binding),
282
+ }
283
+ encoded = json.dumps(
284
+ canonical, sort_keys=True, separators=(",", ":"), ensure_ascii=False
285
+ ).encode("utf-8")
286
+ return "sha256:" + hashlib.sha256(encoded).hexdigest()
287
+
288
+
289
+ def read_identity_surface(path: Path, *, surface: str) -> IdentitySurface:
290
+ payload = _read_json_object(path)
291
+ return identity_surface_from_payload(payload, surface=surface)
292
+
293
+
294
+ def identity_surface_from_payload(
295
+ payload: Mapping[str, Any],
296
+ *,
297
+ surface: str,
298
+ ) -> IdentitySurface:
299
+ version = payload.get("schemaVersion")
300
+ has_v2_identity = bool(_V2_IDENTITY_KEYS.intersection(payload))
301
+ if version == V2_SCHEMA_VERSION and surface == "run-manifest":
302
+ reject_partial_v2_payload(payload)
303
+ if version in _V1_SCHEMA_VERSIONS:
304
+ if has_v2_identity:
305
+ raise ExecutionManifestError("mixed execution identity version")
306
+ return IdentitySurface(surface, True, payload)
307
+ if version != V2_SCHEMA_VERSION:
308
+ raise ExecutionManifestError(f"unsupported execution identity schema: {version!r}")
309
+ if payload.get("executionIdentityVersion") != EXECUTION_IDENTITY_VERSION:
310
+ raise ExecutionManifestError("mixed execution identity version")
311
+ required = _surface_required_keys(surface)
312
+ if any(key not in payload for key in required):
313
+ raise ExecutionManifestError("mixed execution identity version")
314
+ if surface == "task-manifest":
315
+ validate_task_role_execution_index(payload)
316
+ return IdentitySurface(surface, False, payload)
317
+
318
+
319
+ def validate_task_role_execution_index(payload: Mapping[str, Any]) -> None:
320
+ rows = payload.get("roleExecutionIndex")
321
+ if not isinstance(rows, list):
322
+ raise ExecutionManifestError("roleExecutionIndex must be an array")
323
+ required_keys = {"runRef", "roleExecutionRef"}
324
+ seen: set[tuple[str, str]] = set()
325
+ for index, row in enumerate(rows):
326
+ if not isinstance(row, Mapping):
327
+ raise ExecutionManifestError(
328
+ f"roleExecutionIndex[{index}] must be an object"
329
+ )
330
+ if set(row) != required_keys:
331
+ raise ExecutionManifestError(
332
+ f"roleExecutionIndex[{index}] must contain exactly "
333
+ "runRef and roleExecutionRef"
334
+ )
335
+ run_ref = _required_index_text(row, "runRef", index)
336
+ role_ref = _required_index_text(row, "roleExecutionRef", index)
337
+ pair = (run_ref, role_ref)
338
+ if pair in seen:
339
+ raise ExecutionManifestError(
340
+ f"roleExecutionIndex contains a duplicate pair: {run_ref}, {role_ref}"
341
+ )
342
+ seen.add(pair)
343
+
344
+
345
+ def synthesize_v1_execution_view(payload: Mapping[str, Any]) -> ExecutionManifest:
346
+ assignments = _legacy_assignments(payload)
347
+ participants: list[ParticipantAssignment] = []
348
+ roles: list[RoleExecution] = []
349
+ role_ordinals: dict[str, int] = {}
350
+ for index, assignment in enumerate(assignments, start=1):
351
+ participant, role = _legacy_identity_rows(assignment, index, role_ordinals)
352
+ participants.append(participant)
353
+ roles.append(role)
354
+ return ExecutionManifest(
355
+ entry_mode="legacy",
356
+ participant_assignments=tuple(participants),
357
+ role_executions=tuple(roles),
358
+ legacy=True,
359
+ legacy_payload=dict(payload),
360
+ )
361
+
362
+
363
+ def _legacy_assignments(payload: Mapping[str, Any]) -> list[Mapping[str, Any]]:
364
+ assignments: list[Mapping[str, Any]] = []
365
+ lead = payload.get("leadAssignment")
366
+ if isinstance(lead, Mapping):
367
+ assignments.append({"role": "leader", **lead})
368
+ workers = payload.get("workerAssignments")
369
+ if isinstance(workers, list):
370
+ assignments.extend(row for row in workers if isinstance(row, Mapping))
371
+ return assignments
372
+
373
+
374
+ def _legacy_identity_rows(
375
+ assignment: Mapping[str, Any],
376
+ index: int,
377
+ role_ordinals: dict[str, int],
378
+ ) -> tuple[ParticipantAssignment, RoleExecution]:
379
+ role = _canonical_legacy_role(str(assignment.get("role") or "analyser"))
380
+ role_ordinals[role] = role_ordinals.get(role, 0) + 1
381
+ ordinal = role_ordinals[role]
382
+ provider = str(assignment.get("provider") or "unknown")
383
+ model_id = str(
384
+ assignment.get("modelExecutionValue") or assignment.get("model") or "unknown"
385
+ )
386
+ participant_ref = f"legacy-participant-{index:03d}"
387
+ participant = ParticipantAssignment(
388
+ participant_ref=participant_ref,
389
+ provider=provider,
390
+ model_ref=None,
391
+ model_id=model_id,
392
+ runner=str(assignment.get("runner") or "legacy"),
393
+ host_runtime=str(assignment.get("hostRuntime") or "legacy"),
394
+ host_model_value=_optional_text(assignment.get("hostModelValue")),
395
+ session_ref=_optional_text(assignment.get("sessionId")),
396
+ window_ref=_optional_text(assignment.get("windowId")),
397
+ worker_write_capability=None,
398
+ entry_mode="legacy",
399
+ status="legacy",
400
+ )
401
+ role_row = RoleExecution(
402
+ role_execution_ref=f"legacy-role-exec-{role}-{ordinal:03d}",
403
+ participant_ref=participant_ref,
404
+ source_role_execution_ref=None,
405
+ role=role,
406
+ provider=provider,
407
+ model_ref=None,
408
+ model_id=model_id,
409
+ ordinal=ordinal,
410
+ execution_label=execution_label(role, provider, model_id, ordinal),
411
+ model_spec_digest=None,
412
+ binding=None,
413
+ served_model_attestation=ServedModelAttestation.unknown(),
414
+ status="legacy",
415
+ )
416
+ return participant, role_row
417
+
418
+
419
+ def _canonical_legacy_role(role: str) -> str:
420
+ return {"lead": "leader", "executor": "implementer"}.get(role, role)
421
+
422
+
423
+ def _canonical_model_spec(model_spec: Mapping[str, Any] | object) -> dict[str, Any]:
424
+ if isinstance(model_spec, Mapping):
425
+ return {key: _canonical_value(value) for key, value in model_spec.items()}
426
+ fields = {
427
+ "modelRef": str(getattr(model_spec, "model_ref")),
428
+ "providerId": getattr(model_spec, "provider_id"),
429
+ "modelId": getattr(getattr(model_spec, "model_ref"), "model_id"),
430
+ "displayName": getattr(model_spec, "display_name"),
431
+ "executionValue": getattr(model_spec, "execution_value"),
432
+ "aliases": getattr(model_spec, "aliases"),
433
+ "versionKind": getattr(model_spec, "version_kind"),
434
+ "channelFamily": getattr(model_spec, "channel_family"),
435
+ "supportedRoles": getattr(model_spec, "supported_roles"),
436
+ "selectable": getattr(model_spec, "selectable"),
437
+ "pricing": getattr(model_spec, "pricing"),
438
+ }
439
+ return {key: _canonical_value(value) for key, value in fields.items()}
440
+
441
+
442
+ def _canonical_value(value: Any) -> Any:
443
+ if isinstance(value, (set, frozenset, tuple)):
444
+ return sorted(value) if all(isinstance(item, str) for item in value) else list(value)
445
+ return value
446
+
447
+
448
+ def _binding_payload(binding: HostModelBinding | None) -> dict[str, Any] | None:
449
+ if binding is None:
450
+ return None
451
+ return {
452
+ "runner": binding.runner,
453
+ "catalogExecutionValue": binding.catalog_execution_value,
454
+ "resolvedExecutionValue": binding.resolved_execution_value,
455
+ "hostModelValue": binding.host_model_value,
456
+ "bindingFidelity": binding.binding_fidelity,
457
+ "workerWriteCapability": _capability_payload(
458
+ binding.worker_write_capability
459
+ ),
460
+ }
461
+
462
+
463
+ def _attestation_payload(attestation: ServedModelAttestation) -> dict[str, Any]:
464
+ return {
465
+ "observedModel": attestation.observed_model,
466
+ "normalizedModelRef": attestation.normalized_model_ref,
467
+ "level": attestation.level,
468
+ "source": attestation.source,
469
+ }
470
+
471
+
472
+ def _capability_payload(
473
+ capability: WorkerWriteCapability | None,
474
+ ) -> dict[str, str] | None:
475
+ if capability is None:
476
+ return None
477
+ return {"maxBoundaryPrecision": capability.max_boundary_precision}
478
+
479
+
480
+ def _read_json_object(path: Path) -> dict[str, Any]:
481
+ try:
482
+ payload = json.loads(path.read_text(encoding="utf-8"))
483
+ except (OSError, json.JSONDecodeError) as exc:
484
+ raise ExecutionManifestError(f"cannot read execution identity: {path}") from exc
485
+ if not isinstance(payload, dict):
486
+ raise ExecutionManifestError("execution identity surface must be an object")
487
+ return payload
488
+
489
+
490
+ def _surface_required_keys(surface: str) -> tuple[str, ...]:
491
+ required = {
492
+ "task-manifest": ("roleExecutionIndex",),
493
+ "run-manifest": (
494
+ "entryMode",
495
+ "participantAssignments",
496
+ "roleExecutions",
497
+ "invocations",
498
+ "attempts",
499
+ "attemptEvidenceSeals",
500
+ "mutationRecoveryDecisions",
501
+ ),
502
+ "input-snapshot": (
503
+ "staticParticipantAssignments",
504
+ "staticRoleExecutions",
505
+ "dynamicRolePolicy",
506
+ ),
507
+ }
508
+ try:
509
+ return required[surface]
510
+ except KeyError as exc:
511
+ raise ExecutionManifestError(f"unknown execution identity surface: {surface}") from exc
512
+
513
+
514
+ def _required_index_text(
515
+ row: Mapping[str, Any],
516
+ key: str,
517
+ index: int,
518
+ ) -> str:
519
+ value = row.get(key)
520
+ if not isinstance(value, str) or not value.strip():
521
+ raise ExecutionManifestError(
522
+ f"roleExecutionIndex[{index}].{key} must be a non-empty string"
523
+ )
524
+ return value
525
+
526
+
527
+ def _optional_text(value: object) -> str | None:
528
+ text = str(value or "").strip()
529
+ return text or None