okstra 0.201.3 → 0.204.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 (273) hide show
  1. package/README.md +3 -3
  2. package/dist/cli-registry.mjs +7 -7
  3. package/dist/cli-registry.mjs.map +1 -1
  4. package/dist/commands/lifecycle/install.mjs +50 -124
  5. package/dist/commands/lifecycle/install.mjs.map +1 -1
  6. package/dist/commands/lifecycle/setup.mjs +15 -0
  7. package/dist/commands/lifecycle/setup.mjs.map +1 -1
  8. package/dist/commands/memory/memory.mjs +41 -8
  9. package/dist/commands/memory/memory.mjs.map +1 -1
  10. package/dist/lib/citation-guidance.d.mts +21 -0
  11. package/dist/lib/citation-guidance.mjs +79 -0
  12. package/dist/lib/citation-guidance.mjs.map +1 -0
  13. package/dist/lib/install-assets.mjs +3 -0
  14. package/dist/lib/install-assets.mjs.map +1 -1
  15. package/dist/lib/runtime-manifest.mjs +2 -1
  16. package/dist/lib/runtime-manifest.mjs.map +1 -1
  17. package/dist/lib/types.d.mts +2 -1
  18. package/docs/architecture/storage-model.md +17 -10
  19. package/docs/architecture.md +26 -20
  20. package/docs/cli.md +16 -13
  21. package/docs/contributor-change-matrix.md +3 -2
  22. package/docs/performance-improvement-plan-v2.md +2 -3
  23. package/docs/project-structure-overview.md +38 -9
  24. package/docs/task-process/README.md +1 -1
  25. package/docs/task-process/common-flow.md +1 -1
  26. package/docs/task-process/final-verification.md +3 -1
  27. package/docs/task-process/implementation.md +1 -1
  28. package/docs/task-process/release-handoff.md +36 -39
  29. package/package.json +1 -2
  30. package/runtime/BUILD.json +2 -2
  31. package/runtime/agents/common.json +28 -0
  32. package/runtime/agents/operations/code-review.json +6 -0
  33. package/runtime/agents/operations/report-translation.json +6 -0
  34. package/runtime/agents/operations/schedule-verification.json +6 -0
  35. package/runtime/agents/roles/analyser.json +18 -0
  36. package/runtime/agents/roles/critic.json +18 -0
  37. package/runtime/agents/roles/designer.json +18 -0
  38. package/runtime/agents/roles/implementer.json +20 -0
  39. package/runtime/agents/roles/leader.json +20 -0
  40. package/runtime/agents/roles/planner.json +18 -0
  41. package/runtime/agents/roles/report-writer.json +19 -0
  42. package/runtime/agents/roles/translator.json +19 -0
  43. package/runtime/agents/roles/verifier.json +18 -0
  44. package/runtime/bin/lib/okstra/usage.sh +5 -5
  45. package/runtime/prompts/duties/acceptance-critic.json +32 -0
  46. package/runtime/prompts/duties/acceptance-verifier.json +32 -0
  47. package/runtime/prompts/duties/analysis-worker.json +32 -0
  48. package/runtime/prompts/duties/code-reviewer.json +32 -0
  49. package/runtime/prompts/duties/diagnosis-worker.json +32 -0
  50. package/runtime/prompts/duties/direction-selection-worker.json +32 -0
  51. package/runtime/prompts/duties/discovery-worker.json +32 -0
  52. package/runtime/prompts/duties/implementation-executor.json +32 -0
  53. package/runtime/prompts/duties/implementation-verifier.json +32 -0
  54. package/runtime/prompts/duties/lead.json +32 -0
  55. package/runtime/prompts/duties/planning-worker.json +36 -0
  56. package/runtime/prompts/duties/report-writer.json +32 -0
  57. package/runtime/prompts/duties/reverification-worker.json +32 -0
  58. package/runtime/prompts/duties/schedule-verifier.json +32 -0
  59. package/runtime/prompts/duties/scope-critic.json +32 -0
  60. package/runtime/prompts/duties/technical-verification-worker.json +32 -0
  61. package/runtime/prompts/duties/translator.json +32 -0
  62. package/runtime/prompts/launch.template.md +3 -2
  63. package/runtime/prompts/lead/adapters/cmux.md +1 -1
  64. package/runtime/prompts/lead/convergence.md +4 -4
  65. package/runtime/prompts/lead/okstra-lead-contract.md +115 -6
  66. package/runtime/prompts/lead/plan-body-verification.md +6 -6
  67. package/runtime/prompts/lead/report-writer.md +3 -3
  68. package/runtime/prompts/profiles/_common-contract.md +2 -2
  69. package/runtime/prompts/profiles/_implementation-executor.md +4 -1
  70. package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
  71. package/runtime/prompts/profiles/change-impact-analysis.json +31 -0
  72. package/runtime/prompts/profiles/change-impact-analysis.md +0 -20
  73. package/runtime/prompts/profiles/error-analysis.json +39 -0
  74. package/runtime/prompts/profiles/error-analysis.md +0 -25
  75. package/runtime/prompts/profiles/feature-analysis.json +31 -0
  76. package/runtime/prompts/profiles/feature-analysis.md +0 -20
  77. package/runtime/prompts/profiles/final-verification.json +30 -0
  78. package/runtime/prompts/profiles/final-verification.md +3 -22
  79. package/runtime/prompts/profiles/forbidden-actions.json +4 -3
  80. package/runtime/prompts/profiles/implementation-option-selection.json +31 -0
  81. package/runtime/prompts/profiles/implementation-option-selection.md +0 -20
  82. package/runtime/prompts/profiles/implementation-planning.json +40 -0
  83. package/runtime/prompts/profiles/implementation-planning.md +6 -29
  84. package/runtime/prompts/profiles/implementation.json +30 -0
  85. package/runtime/prompts/profiles/implementation.md +1 -20
  86. package/runtime/prompts/profiles/improvement-discovery.json +31 -0
  87. package/runtime/prompts/profiles/improvement-discovery.md +0 -20
  88. package/runtime/prompts/profiles/project-analysis.json +31 -0
  89. package/runtime/prompts/profiles/project-analysis.md +0 -20
  90. package/runtime/prompts/profiles/release-handoff.json +5 -0
  91. package/runtime/prompts/profiles/release-handoff.md +71 -73
  92. package/runtime/prompts/profiles/requirements-discovery.json +39 -0
  93. package/runtime/prompts/profiles/requirements-discovery.md +0 -25
  94. package/runtime/prompts/profiles/technical-verification.json +39 -0
  95. package/runtime/prompts/profiles/technical-verification.md +0 -25
  96. package/runtime/prompts/wizard/prompts.ko.json +12 -17
  97. package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +1 -0
  98. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +3 -0
  99. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/manifest.json +1 -1
  100. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -3
  101. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/worker-session.md +108 -0
  102. package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -0
  103. package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +2 -0
  104. package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +2 -0
  105. package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +8 -1
  106. package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +8 -0
  107. package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +23 -6
  108. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +6 -2
  109. package/runtime/python/okstra_ctl/agent/invocation.py +168 -113
  110. package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +120 -0
  111. package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +107 -2
  112. package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +0 -49
  113. package/runtime/python/okstra_ctl/analysis_packet.py +4 -1
  114. package/runtime/python/okstra_ctl/application/open_worker.py +6 -1
  115. package/runtime/python/okstra_ctl/assignment_resolver.py +16 -5
  116. package/runtime/python/okstra_ctl/cmux.py +69 -20
  117. package/runtime/python/okstra_ctl/code_review_target.py +16 -8
  118. package/runtime/python/okstra_ctl/conformance.py +43 -0
  119. package/runtime/python/okstra_ctl/consumers.py +6 -3
  120. package/runtime/python/okstra_ctl/container.py +31 -8
  121. package/runtime/python/okstra_ctl/context_cost.py +11 -15
  122. package/runtime/python/okstra_ctl/contract_refreeze.py +156 -0
  123. package/runtime/python/okstra_ctl/convergence_critic_prompt.py +4 -6
  124. package/runtime/python/okstra_ctl/convergence_provenance.py +81 -18
  125. package/runtime/python/okstra_ctl/design_prep.py +34 -1
  126. package/runtime/python/okstra_ctl/dispatch_core.py +53 -27
  127. package/runtime/python/okstra_ctl/domain/host.py +5 -0
  128. package/runtime/python/okstra_ctl/domain/worker_runtime.py +10 -0
  129. package/runtime/python/okstra_ctl/error_report.py +4 -3
  130. package/runtime/python/okstra_ctl/execution_manifest.py +71 -18
  131. package/runtime/python/okstra_ctl/execution_mutation_audit.py +21 -21
  132. package/runtime/python/okstra_ctl/handoff.py +167 -277
  133. package/runtime/python/okstra_ctl/implementation_stage.py +9 -0
  134. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +113 -0
  135. package/runtime/python/okstra_ctl/lead_progress.py +1 -1
  136. package/runtime/python/okstra_ctl/legacy_model_selection.py +2 -2
  137. package/runtime/python/okstra_ctl/manager_cli.py +175 -14
  138. package/runtime/python/okstra_ctl/manager_launch.py +41 -19
  139. package/runtime/python/okstra_ctl/manager_paths.py +22 -3
  140. package/runtime/python/okstra_ctl/manager_split.py +474 -0
  141. package/runtime/python/okstra_ctl/manager_store.py +331 -21
  142. package/runtime/python/okstra_ctl/manager_sync.py +37 -16
  143. package/runtime/python/okstra_ctl/manager_view.py +217 -0
  144. package/runtime/python/okstra_ctl/model_discovery.py +30 -0
  145. package/runtime/python/okstra_ctl/model_io/lines.py +14 -1
  146. package/runtime/python/okstra_ctl/model_io/renderers.py +4 -3
  147. package/runtime/python/okstra_ctl/models.py +1 -1
  148. package/runtime/python/okstra_ctl/next_phase.py +16 -6
  149. package/runtime/python/okstra_ctl/operation_invocation.py +86 -0
  150. package/runtime/python/okstra_ctl/option_comparison.py +168 -0
  151. package/runtime/python/okstra_ctl/path_hints.py +9 -0
  152. package/runtime/python/okstra_ctl/paths.py +3 -0
  153. package/runtime/python/okstra_ctl/plan_items_cli.py +6 -1
  154. package/runtime/python/okstra_ctl/profile_show.py +42 -1
  155. package/runtime/python/okstra_ctl/qa_commands.py +15 -0
  156. package/runtime/python/okstra_ctl/registry/host_discovery.py +20 -12
  157. package/runtime/python/okstra_ctl/registry/host_registry.py +11 -0
  158. package/runtime/python/okstra_ctl/render.py +50 -0
  159. package/runtime/python/okstra_ctl/report_contract.py +1 -1
  160. package/runtime/python/okstra_ctl/report_finalize.py +13 -6
  161. package/runtime/python/okstra_ctl/report_html/view_models/final_verification.py +2 -21
  162. package/runtime/python/okstra_ctl/report_html/view_models/release_handoff.py +21 -3
  163. package/runtime/python/okstra_ctl/report_html/visualizations.py +0 -5
  164. package/runtime/python/okstra_ctl/report_synthesis_packet.py +177 -17
  165. package/runtime/python/okstra_ctl/report_translation.py +2 -1
  166. package/runtime/python/okstra_ctl/report_translation_dispatch.py +69 -9
  167. package/runtime/python/okstra_ctl/role_requirements.py +142 -129
  168. package/runtime/python/okstra_ctl/rollup.py +3 -1
  169. package/runtime/python/okstra_ctl/run.py +76 -29
  170. package/runtime/python/okstra_ctl/schedule_semantics.py +17 -6
  171. package/runtime/python/okstra_ctl/stage_fix_carry.py +23 -4
  172. package/runtime/python/okstra_ctl/stage_integrate.py +178 -18
  173. package/runtime/python/okstra_ctl/stage_map.py +16 -2
  174. package/runtime/python/okstra_ctl/stage_targets.py +209 -43
  175. package/runtime/python/okstra_ctl/team.py +22 -13
  176. package/runtime/python/okstra_ctl/time_report.py +2 -1
  177. package/runtime/python/okstra_ctl/usage_report.py +3 -1
  178. package/runtime/python/okstra_ctl/verification_target.py +13 -2
  179. package/runtime/python/okstra_ctl/wizard/confirmation.py +3 -9
  180. package/runtime/python/okstra_ctl/wizard/ids.py +1 -1
  181. package/runtime/python/okstra_ctl/wizard/registry.py +1 -1
  182. package/runtime/python/okstra_ctl/wizard/state.py +3 -5
  183. package/runtime/python/okstra_ctl/wizard/steps_plan.py +3 -23
  184. package/runtime/python/okstra_ctl/worker_prompt_contract.py +5 -1
  185. package/runtime/python/okstra_ctl/worker_prompt_headers.py +35 -7
  186. package/runtime/python/okstra_ctl/worker_prompt_policy.py +66 -48
  187. package/runtime/python/okstra_ctl/workflow.py +1 -1
  188. package/runtime/python/okstra_ctl/worktree/__init__.py +3 -1
  189. package/runtime/python/okstra_ctl/worktree/naming.py +9 -0
  190. package/runtime/python/okstra_ctl/worktree_registry.py +38 -9
  191. package/runtime/python/okstra_token_usage/pricing.py +6 -4
  192. package/runtime/schemas/agent-common-v1.schema.json +34 -0
  193. package/runtime/schemas/agent-duty-v1.schema.json +38 -0
  194. package/runtime/schemas/agent-operation-v1.schema.json +11 -0
  195. package/runtime/schemas/agent-profile-v1.schema.json +46 -0
  196. package/runtime/schemas/agent-role-v1.schema.json +29 -0
  197. package/runtime/schemas/final-report-v2.0.schema.json +118 -97
  198. package/runtime/schemas/final-report-v3.0.schema.json +118 -97
  199. package/runtime/skills/okstra-brief-gen/SKILL.md +84 -4
  200. package/runtime/skills/okstra-chat/SKILL.md +2 -2
  201. package/runtime/skills/okstra-code-review/SKILL.md +23 -9
  202. package/runtime/skills/okstra-container-build/SKILL.md +10 -10
  203. package/runtime/skills/okstra-inspect/SKILL.md +1 -1
  204. package/runtime/skills/okstra-inspect/facets/cost.md +1 -1
  205. package/runtime/skills/okstra-inspect/facets/error-zip.md +9 -9
  206. package/runtime/skills/okstra-inspect/facets/errors.md +16 -16
  207. package/runtime/skills/okstra-inspect/facets/logs.md +7 -7
  208. package/runtime/skills/okstra-inspect/facets/recap.md +2 -2
  209. package/runtime/skills/okstra-inspect/facets/report.md +1 -1
  210. package/runtime/skills/okstra-inspect/facets/status.md +4 -3
  211. package/runtime/skills/okstra-inspect/facets/time.md +11 -10
  212. package/runtime/skills/okstra-manager/SKILL.md +70 -5
  213. package/runtime/skills/okstra-pr-gen/SKILL.md +6 -5
  214. package/runtime/skills/okstra-rollup/SKILL.md +5 -5
  215. package/runtime/skills/okstra-run/SKILL.md +32 -13
  216. package/runtime/skills/okstra-schedule-gen/SKILL.md +19 -14
  217. package/runtime/skills/okstra-setup/SKILL.md +21 -10
  218. package/runtime/skills/okstra-setup/references/project-config.md +7 -6
  219. package/runtime/skills/okstra-usage/SKILL.md +1 -1
  220. package/runtime/skills/okstra-user-response/SKILL.md +1 -1
  221. package/runtime/templates/manager/view.template.html +109 -0
  222. package/runtime/templates/report-writer-prompt-preamble.md +8 -0
  223. package/runtime/templates/reports/brief.template.md +14 -4
  224. package/runtime/templates/reports/html/i18n/en.json +7 -4
  225. package/runtime/templates/reports/html/i18n/ko.json +7 -4
  226. package/runtime/templates/reports/html/tasks/final-verification.template.html +2 -2
  227. package/runtime/templates/reports/html/tasks/release-handoff.template.html +8 -5
  228. package/runtime/templates/reports/i18n/en.json +1 -1
  229. package/runtime/templates/reports/md/tasks/release-handoff.template.md +1 -1
  230. package/runtime/templates/reports/release-handoff-input.template.md +6 -4
  231. package/runtime/templates/translator-prompt-preamble.md +36 -0
  232. package/runtime/validators/checks/validate-assets-01.py +7 -8
  233. package/runtime/validators/validate-brief.py +77 -2
  234. package/runtime/validators/validate-implementation-plan-stages.py +2 -1
  235. package/runtime/validators/validate-run.py +59 -9
  236. package/runtime/validators/validate-schedule.py +9 -0
  237. package/docs/for-ai/README.md +0 -68
  238. package/docs/for-ai/skills/okstra-brief-gen.md +0 -262
  239. package/docs/for-ai/skills/okstra-chat.md +0 -34
  240. package/docs/for-ai/skills/okstra-code-review.md +0 -57
  241. package/docs/for-ai/skills/okstra-container-build.md +0 -129
  242. package/docs/for-ai/skills/okstra-inspect.md +0 -262
  243. package/docs/for-ai/skills/okstra-manager.md +0 -69
  244. package/docs/for-ai/skills/okstra-memory.md +0 -126
  245. package/docs/for-ai/skills/okstra-pr-gen.md +0 -49
  246. package/docs/for-ai/skills/okstra-rollup.md +0 -114
  247. package/docs/for-ai/skills/okstra-run.md +0 -250
  248. package/docs/for-ai/skills/okstra-schedule-gen.md +0 -240
  249. package/docs/for-ai/skills/okstra-setup.md +0 -158
  250. package/docs/for-ai/skills/okstra-usage.md +0 -29
  251. package/docs/for-ai/skills/okstra-user-response.md +0 -72
  252. package/runtime/agents/workers/claude-worker.md +0 -128
  253. package/runtime/agents/workers/report-writer-worker.md +0 -37
  254. package/runtime/agents/workers/translator-worker.md +0 -63
  255. package/runtime/prompts/duties/acceptance-critic.md +0 -44
  256. package/runtime/prompts/duties/acceptance-verifier.md +0 -44
  257. package/runtime/prompts/duties/analysis-worker.md +0 -44
  258. package/runtime/prompts/duties/code-reviewer.md +0 -44
  259. package/runtime/prompts/duties/common.md +0 -39
  260. package/runtime/prompts/duties/diagnosis-worker.md +0 -44
  261. package/runtime/prompts/duties/direction-selection-worker.md +0 -44
  262. package/runtime/prompts/duties/discovery-worker.md +0 -44
  263. package/runtime/prompts/duties/implementation-executor.md +0 -44
  264. package/runtime/prompts/duties/implementation-verifier.md +0 -44
  265. package/runtime/prompts/duties/lead.md +0 -44
  266. package/runtime/prompts/duties/planning-worker.md +0 -52
  267. package/runtime/prompts/duties/report-writer.md +0 -44
  268. package/runtime/prompts/duties/reverification-worker.md +0 -44
  269. package/runtime/prompts/duties/schedule-verifier.md +0 -44
  270. package/runtime/prompts/duties/scope-critic.md +0 -44
  271. package/runtime/prompts/duties/technical-verification-worker.md +0 -44
  272. package/runtime/prompts/duties/translator.md +0 -44
  273. package/runtime/python/okstra_ctl/pane_title.py +0 -154
@@ -905,110 +905,103 @@
905
905
  "description": "RENDER_IF taskType == release-handoff. §5.6 deliverables.",
906
906
  "required": [
907
907
  "handoffScope",
908
+ "sourceVerificationReports",
908
909
  "featureBranchState",
909
910
  "userSelections",
910
911
  "localCheckoutOutcome",
911
912
  "executedCommands",
912
913
  "commitList",
913
914
  "mergeConflictProbe",
914
- "pullRequestOutcome",
915
+ "pullRequestOutcomes",
915
916
  "routingRecommendation",
916
917
  "userNarrative"
917
918
  ],
918
919
  "additionalProperties": false,
919
- "allOf": [
920
- {
921
- "if": {
922
- "properties": {
923
- "handoffScope": {
924
- "properties": {
925
- "mode": {
926
- "const": "stage-group"
927
- }
928
- },
929
- "required": [
930
- "mode"
931
- ]
932
- }
933
- },
934
- "required": [
935
- "handoffScope"
936
- ]
937
- },
938
- "then": {
939
- "required": [
940
- "sourceVerificationReports"
941
- ]
942
- },
943
- "else": {
944
- "required": [
945
- "sourceVerificationReport"
946
- ]
947
- }
948
- }
949
- ],
950
920
  "properties": {
951
921
  "handoffScope": {
952
922
  "type": "object",
953
923
  "required": [
954
- "mode"
924
+ "stages",
925
+ "releaseBase"
955
926
  ],
956
927
  "additionalProperties": false,
957
- "description": "Which shape of handoff this was. 'whole-task' turns the verified task branch into one PR; 'stage-group' merges a user-selected subset of verified stages into a collector branch and opens the PR from that. Without it a reader cannot tell one report from the other, and in stage-group mode cannot tell which stages shipped — the branch name alone does not say.",
928
+ "description": "What this handoff delivered. One stage is one PR, so the stage list is the PR list, and `stagePlan` is the only place a reader learns which branch each PR sat on — and therefore in what order the stack must be merged.",
958
929
  "properties": {
959
- "mode": {
960
- "enum": [
961
- "whole-task",
962
- "stage-group"
963
- ]
964
- },
965
930
  "stages": {
966
931
  "type": "array",
932
+ "minItems": 1,
967
933
  "items": {
968
934
  "type": "integer",
969
935
  "minimum": 1
970
936
  }
971
937
  },
972
- "collectorBranch": {
973
- "type": "string"
938
+ "releaseBase": {
939
+ "type": "string",
940
+ "minLength": 1,
941
+ "description": "The base branch the user picked for the run. A stage that sits on another stage does NOT target it — see stagePlan[].baseBranch."
974
942
  },
975
- "mergeCommits": {
943
+ "stagePlan": {
976
944
  "type": "array",
977
- "description": "Assemble's merge commit SHAs, in the order the stages were merged into the collector branch. Without them the collector branch's contents cannot be traced back to the stages that produced them once the branch moves on.",
945
+ "description": "`okstra handoff pr-plan` output, one row per stage. Without it the merge order of a stacked PR set cannot be reconstructed once the branches move.",
978
946
  "items": {
979
- "type": "string",
980
- "minLength": 7
947
+ "type": "object",
948
+ "required": [
949
+ "stage",
950
+ "headBranch",
951
+ "baseKind",
952
+ "baseBranch"
953
+ ],
954
+ "additionalProperties": false,
955
+ "properties": {
956
+ "stage": {
957
+ "type": "integer",
958
+ "minimum": 1
959
+ },
960
+ "headBranch": {
961
+ "type": "string",
962
+ "minLength": 1
963
+ },
964
+ "headCommit": {
965
+ "type": "string"
966
+ },
967
+ "baseKind": {
968
+ "enum": [
969
+ "release-base",
970
+ "stage",
971
+ "merge-base"
972
+ ]
973
+ },
974
+ "baseBranch": {
975
+ "type": "string",
976
+ "minLength": 1
977
+ },
978
+ "baseCommit": {
979
+ "type": "string"
980
+ },
981
+ "baseStages": {
982
+ "type": "array",
983
+ "description": "The predecessor stages this row's base carries. Empty for a release-base row.",
984
+ "items": {
985
+ "type": "integer",
986
+ "minimum": 1
987
+ }
988
+ },
989
+ "baseMergeCommits": {
990
+ "type": "array",
991
+ "description": "Merge commits pr-plan created on a merge-base branch. The only commits release-handoff is allowed to produce.",
992
+ "items": {
993
+ "type": "string",
994
+ "minLength": 7
995
+ }
996
+ }
997
+ }
981
998
  }
982
- },
983
- "dependencyClosureVerdict": {
984
- "type": "string",
985
- "minLength": 1,
986
- "description": "Whether the selected stages are closed under their dependencies, and on what basis. A stage-group PR that ships a stage without its predecessor is the failure this records."
987
- }
988
- }
989
- },
990
- "sourceVerificationReport": {
991
- "type": "object",
992
- "description": "whole-task mode: the one final-verification report this handoff ships. Required unless handoffScope.mode is stage-group.",
993
- "required": [
994
- "path",
995
- "verdictTokenQuote"
996
- ],
997
- "additionalProperties": false,
998
- "properties": {
999
- "path": {
1000
- "type": "string",
1001
- "minLength": 1
1002
- },
1003
- "verdictTokenQuote": {
1004
- "type": "string",
1005
- "minLength": 1
1006
999
  }
1007
1000
  }
1008
1001
  },
1009
1002
  "sourceVerificationReports": {
1010
1003
  "type": "array",
1011
- "description": "stage-group mode: one row per selected stage, because that handoff ships several verified stages and a single report path cannot say which stage each verdict belongs to.",
1004
+ "description": "One row per selected stage. Each stage ships its own PR under its own verdict, so a single report path cannot say which stage a verdict belongs to.",
1012
1005
  "minItems": 1,
1013
1006
  "items": {
1014
1007
  "type": "object",
@@ -1048,6 +1041,11 @@
1048
1041
  "checked-out"
1049
1042
  ]
1050
1043
  },
1044
+ "stage": {
1045
+ "type": "integer",
1046
+ "minimum": 1,
1047
+ "description": "The stage whose branch was checked out. Checkout is per stage, so a branch name without it leaves the reader matching branch suffixes by hand."
1048
+ },
1051
1049
  "branch": {
1052
1050
  "type": "string"
1053
1051
  },
@@ -1173,6 +1171,14 @@
1173
1171
  "userChoice": {
1174
1172
  "type": "string"
1175
1173
  },
1174
+ "conflictingStages": {
1175
+ "type": "array",
1176
+ "description": "The stages whose head did not merge cleanly into their own PR base. The probe runs per stage, so a bare path list cannot say which PR is affected.",
1177
+ "items": {
1178
+ "type": "integer",
1179
+ "minimum": 1
1180
+ }
1181
+ },
1176
1182
  "conflictingPaths": {
1177
1183
  "type": "array",
1178
1184
  "items": {
@@ -1181,32 +1187,41 @@
1181
1187
  }
1182
1188
  }
1183
1189
  },
1184
- "pullRequestOutcome": {
1185
- "type": "object",
1186
- "required": [
1187
- "kind"
1188
- ],
1189
- "additionalProperties": false,
1190
- "properties": {
1191
- "kind": {
1192
- "enum": [
1193
- "no-action",
1194
- "created",
1195
- "reused",
1196
- "skipped"
1197
- ]
1198
- },
1199
- "url": {
1200
- "type": "string"
1201
- },
1202
- "title": {
1203
- "type": "string"
1204
- },
1205
- "baseBranch": {
1206
- "type": "string"
1207
- },
1208
- "reason": {
1209
- "type": "string"
1190
+ "pullRequestOutcomes": {
1191
+ "type": "array",
1192
+ "description": "One row per selected stage — one stage is one PR. A single outcome object cannot say which stage was created, reused or skipped.",
1193
+ "items": {
1194
+ "type": "object",
1195
+ "additionalProperties": false,
1196
+ "required": [
1197
+ "stage",
1198
+ "kind"
1199
+ ],
1200
+ "properties": {
1201
+ "stage": {
1202
+ "type": "integer",
1203
+ "minimum": 1
1204
+ },
1205
+ "kind": {
1206
+ "enum": [
1207
+ "no-action",
1208
+ "created",
1209
+ "reused",
1210
+ "skipped"
1211
+ ]
1212
+ },
1213
+ "url": {
1214
+ "type": "string"
1215
+ },
1216
+ "title": {
1217
+ "type": "string"
1218
+ },
1219
+ "baseBranch": {
1220
+ "type": "string"
1221
+ },
1222
+ "reason": {
1223
+ "type": "string"
1224
+ }
1210
1225
  }
1211
1226
  }
1212
1227
  },
@@ -1582,6 +1597,7 @@
1582
1597
  "enum": [
1583
1598
  "release-handoff",
1584
1599
  "release-handoff(stage-group)",
1600
+ "final-verification",
1585
1601
  "error-analysis",
1586
1602
  "implementation-option-selection",
1587
1603
  "implementation-planning",
@@ -9839,6 +9855,11 @@
9839
9855
  ],
9840
9856
  "additionalProperties": false,
9841
9857
  "properties": {
9858
+ "stage": {
9859
+ "type": "integer",
9860
+ "minimum": 1,
9861
+ "description": "Which stage's PR carries this commit. One stage is one PR, so a flat commit list across several stages cannot be attributed without it."
9862
+ },
9842
9863
  "shortSha": {
9843
9864
  "type": "string",
9844
9865
  "minLength": 7
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: okstra-brief-gen
3
3
  description: Use when the user wants to generate a task brief file for okstra from a requirements document, an existing markdown file, an issue-tracker ticket (Linear / Jira / GitHub / Notion), a link URL, conversation context, or short user input. Produces the markdown brief consumed by `okstra-run` Step 5 (task-brief). Trigger words include "okstra brief", "make a brief", "generate a brief", "make a brief from requirements", "make an okstra input", "write a task brief", "brief from this ticket", "brief from this link".
4
+ disable-model-invocation: true
4
5
  ---
5
6
 
6
7
  # okstra-brief-gen
@@ -153,6 +154,40 @@ and retain the explicit free-text follow-up where this skill specifies one.
153
154
 
154
155
  ## Step 1: Choose input source
155
156
 
157
+ ### Capture contract (binds every sub-flow below)
158
+
159
+ `Source Material` is the one section a later phase can fall back to when a
160
+ derived section reads wrong, so it carries the source whole. Three rules hold
161
+ for every variant and every source type below.
162
+
163
+ 1. **Capture in full.** Length is never a reason to excerpt, summarize, or
164
+ restructure. A source too long to be comfortable in the conversation is
165
+ still written into the brief in full. "In full" is measured against the
166
+ source the reporter named, not against the file that happens to contain
167
+ it: when they point at one section of a larger document — a backlog item,
168
+ one `## Cross-Repo Carry — <repo>` appendix — that section is what must
169
+ arrive whole, and `ref` names the containing file and the heading. Taking
170
+ a section the reporter did not name is the same failure as dropping half
171
+ of one they did.
172
+ 2. **Capture the record, not only the body.** What the record is, per source
173
+ type:
174
+
175
+ | Source type | Captured into `## Source Material` |
176
+ |---|---|
177
+ | `File` | the entire file, or the named section whole when the reporter pointed at one |
178
+ | `Issue tracker ticket` | title, description body, every comment, status, labels, assignee, and linked / child issue references — plus the remaining response metadata |
179
+ | `Link URL` | title and full body text, quotes and examples included |
180
+ | `User input` | the utterance as typed, or the conversation's key utterances quoted |
181
+ | `Error feedback` | the chosen cluster's anonymized error records |
182
+
183
+ 3. **What the tool could not deliver is recorded, never silently dropped.** A
184
+ truncated fetch, an attachment the API hands back as a signed link, an
185
+ embed the response carries as an opaque node, a body behind auth — each one
186
+ gets a `conversion-block:` row in `## Open Questions` naming what is
187
+ missing and where it lives. A bracketed note inside the captured block
188
+ helps the reader, but it does not replace that row: the row is what a later
189
+ phase sees when it asks whether the source arrived complete.
190
+
156
191
  ### 1.0. brief variant
157
192
 
158
193
  `AskUserQuestion` (single-select):
@@ -456,7 +491,7 @@ to Source Material body, not to the filename):
456
491
  Validate the full `<ticket-id>-<file-title>` slug: must have at least one
457
492
  alphanumeric character after slugification. Apply Step 2c on collision.
458
493
 
459
- **Enforced:** `validators/validate-brief.py` checks the brief's filename and its task-group directory segment against the slugified frontmatter `task-group`, and rejects a Source Material section whose entry does not match the source it names.
494
+ **Enforced:** `validators/validate-brief.py` checks the brief's filename and its task-group directory segment against the slugified frontmatter `task-group`.
460
495
 
461
496
  ### 2c. Collision handling
462
497
 
@@ -553,7 +588,7 @@ empty or trivially thin **after** reading Source Material verbatim, ask **at
553
588
  most one** `AskUserQuestion` to fill it. Never ask about sections already
554
589
  covered by the source material.
555
590
 
556
- **Enforced:** `validators/validate-brief.py` fails a brief whose required section is missing, is left as a template placeholder (`is_placeholder`), or carries only the template's own example lines (`is_template_example`) — so a section skipped here does not pass as filled.
591
+ **Enforced:** `validators/validate-brief.py` fails a brief whose required section is missing, has a blank body (`check_variant_required_sections`), or still carries the template's `<...>` text (`check_template_scaffold`). `## Source Material` is exempt from the template-text check because it holds the reporter's words verbatim.
557
592
 
558
593
  ### Sharpening pass (bounded grill)
559
594
 
@@ -854,11 +889,56 @@ The required-key set (`type`, `brief-id`, `parent-id`, `ticket-id`,
854
889
  Step 6.6. The byte-for-byte field shape remains the job of
855
890
  `~/.okstra/templates/reports/brief.template.md`.
856
891
 
892
+ ### Source requirement sweep (run before asking for approval)
893
+
894
+ Source Material holds the reporter's words, but every later phase reads the
895
+ derived sections. A requirement that is captured and then never carried into a
896
+ derived section is invisible from that point on, and no downstream phase can
897
+ recover it — it has no id to map and no heading to cite. Close that gap here,
898
+ while the source is still in front of you.
899
+
900
+ Read `## Source Material` from its first line to its last and list every
901
+ **requirement unit** it holds:
902
+
903
+ - an imperative or a request ("switch to S3", "il faudrait les extraire")
904
+ - a checklist row, whatever its box state
905
+ - a condition or a threshold ("only under 50 MB", "daily, not continuous")
906
+ - a prohibition ("never overwrite a non-empty value")
907
+ - a decision the reporter states as still open ("to be decided: who is alerted")
908
+ - a number the reporter gives as a target or a bound
909
+
910
+ Give every unit exactly one destination, and write it there before you ask for
911
+ approval:
912
+
913
+ | Unit | Destination |
914
+ |---|---|
915
+ | Runtime behaviour an okstra phase can reach by changing repository files | `## Expected Behavior` |
916
+ | Behaviour that must survive the change unchanged | `## Preserved Behavior` |
917
+ | Artifact state the finished work must leave behind | `## Expected Outcome` |
918
+ | A must-pass point a person or live infrastructure owns | `## External Gates` |
919
+ | A limit, a deadline, or an untouchable area | `## Constraints` |
920
+ | A decision the reporter left open | `## Open Questions` |
921
+ | Deliberately not part of this task | `## Constraints`, as `out of scope: <unit> — <why>` |
922
+
923
+ No unit may end the sweep without a destination. `out of scope:` is the only
924
+ way to drop one, and it costs a line that names the reason — an omission
925
+ nobody wrote down cannot be told apart from an oversight when the run later
926
+ misses it. A unit whose destination is genuinely unclear is an
927
+ `## Open Questions` `general:` row, not a silent drop.
928
+
929
+ The sweep reads the source; it does not interview the user. It runs after
930
+ Step 4's question budget is spent and adds no questions of its own — a gap it
931
+ surfaces is filled from Source Material, or parked in `## Open Questions`.
932
+
857
933
  Echo the file path back on one line. Show the rendered brief to the user
858
- inline and ask:
934
+ inline, and directly above the approval question show the sweep as a table —
935
+ one row per requirement unit, its destination section, and for an end-state
936
+ unit the `EB-` / `PB-` / `EO-` id it became. That table is what lets the
937
+ reporter check their own list in one pass. Then ask:
859
938
 
860
939
  `AskUserQuestion`: `"Proceed with this brief?"` — options `Save` / `Edit`.
861
- On `Edit`, return to Step 4 for the section to revise.
940
+ On `Edit`, return to Step 4 for the section to revise; a unit the user reports
941
+ missing returns to this sweep instead.
862
942
 
863
943
  ## Step 6: Recommend next okstra phase
864
944
 
@@ -8,7 +8,7 @@ description: Use when the user wants to create or join a global okstra chat room
8
8
  Cross-session rooms in the global okstra home. Not a project task artifact.
9
9
  Do not write JSON. Call `okstra chat` and read its fixed text.
10
10
 
11
- Rooms are independent of tasks and runs. A participant is this host session.
11
+ Rooms are independent of tasks and runs. A participant is a display name that this host session joins with; the CLI does not tie the name to a session, so every command acts as whichever member `--as` names.
12
12
  The display name is typed at join. Do not invent a default name.
13
13
 
14
14
  ## When to use
@@ -114,5 +114,5 @@ The whole room, including messages not addressed to you. Log does not move the c
114
114
 
115
115
  - Call only `okstra chat`. Do not open files under the chat store.
116
116
  - Do not treat chat rows as evidence for a finding, verdict, or assignment.
117
- - Workers may run the same commands with `--name` and `--as`. Joining is optional.
117
+ - Workers may run the same commands: `join` with `--name`, then the rest with `--as`. Taking part is optional, but `send`, `unread`, `inbox`, `log`, and `ack` fail with `not a member` until that name has joined.
118
118
  - Do not generate a display name from the provider, model, or execution label.
@@ -109,7 +109,7 @@ pass task manifests, target-CLI JSON, or arbitrary JSON fields to a reviewer.
109
109
  2. Collect the diff from the work directory chosen in Step 1 — `git -C <workdir> diff --name-status <baseCommit>..<headCommit>` for the file list, and `git -C <workdir> diff <baseCommit>..<headCommit>` for the hunks. Before trusting that range, run `git -C <workdir> rev-list --count <headCommit>..<baseCommit>`: anything but `0` is the rewritten-history case in the Exceptions table. An empty diff skips Steps 3–3.5 (also in Exceptions).
110
110
  3. **Route the packs once, here — and fix both absolute paths the briefs carry.** `okstra paths --field home` prints the okstra home; read `<okstraHome>/prompts/coding-preflight/overview.md` and walk all three stages of its routed resource selection over the changed-file list. The result is the applied pack list — the absolute paths reviewers will read. This routing happens exactly once per run; no reviewer repeats it.
111
111
 
112
- The second path is this skill's own calibration file. A subagent has no "next to this file" coordinate, so the brief must spell it out: the installed skill home is `~/.claude/skills/okstra-code-review/`, making the literal path `~/.claude/skills/okstra-code-review/references/review-calibration.md` — the same string whether the skill was copied in or dev-linked. Carry it, together with the pack list, into every Step 3 brief.
112
+ The second path is this skill's own calibration file. A subagent has no "next to this file" coordinate, so the brief must spell it out: `okstra install` writes this skill to `~/.agents/skills/okstra-code-review/` on every machine (and to `~/.claude/skills/` only when `~/.claude` exists), making the literal path `~/.agents/skills/okstra-code-review/references/review-calibration.md` — the same string whether the skill was copied in or dev-linked. Carry it, together with the pack list, into every Step 3 brief.
113
113
  4. Build the cells per `references/census-rules.md` and print, in this response: one cell table per axis, the exclusion list with a reason on every entry, and the applied pack list.
114
114
  5. Restate both completion criteria and show they hold: censused files + exclusions = files in the diff, and every hunk maps to a censused function or to file-level code.
115
115
 
@@ -119,23 +119,37 @@ A large census is never truncated. Report the cell count and confirm before disp
119
119
 
120
120
  ## Step 3 — Materialize and dispatch four reviewers in parallel
121
121
 
122
- Every reviewer and later gap-fill is a separate auditable standalone invocation. Before dispatch, create
122
+ Ask the runtime what this operation runs — do not choose the role, the providers, or the reviewer count
123
+ here:
124
+
125
+ ```
126
+ okstra agent-prompt resolve-operation --operation code-review
127
+ ```
128
+
129
+ It prints the duty, the role, the reviewer count, and one `slot` line per reviewer carrying that slot's
130
+ provider and model. The contract owns those values (`agents/operations/code-review.json`), so a machine
131
+ with too few distinct models fails here rather than quietly running fewer reviewers. Dispatch exactly the
132
+ slots it prints.
133
+
134
+ Every reviewer and later gap-fill is a separate auditable standalone invocation. For each slot, create
123
135
  `.okstra/agent-invocations/code-review/<invocation-id>.instructions.md` from that reviewer's brief, then run
124
- `okstra agent-prompt materialize` with `--purpose code-review`, `--audience code-reviewer`, and the canonical
125
- `.prompt.md` path beside it. Pass the current host runtime, selected provider, and `--model-role analyser`;
126
- the returned assignment is authoritative. Run `okstra agent-prompt verify` against the returned
127
- `metadataPath` before invoking any model.
136
+ `okstra agent-prompt materialize` with `--purpose code-review`, `--audience <dutyId>`, that slot's
137
+ `--provider` and `--model <modelRef>`, and the canonical `.prompt.md` path beside it; the returned
138
+ assignment is authoritative. Run `okstra agent-prompt verify` against the returned `metadataPath` before
139
+ invoking any model.
128
140
 
129
141
  For a native host call, pass the verified prompt body and `hostModelValue`. For a deterministic provider
130
- process, run `okstra worker-dispatch` with the verified prompt path and `modelExecutionValue`; never
131
- substitute one model value for the other. Dispatch the four verified calls in parallel when the host supports
142
+ process, run the provider wrapper `~/.okstra/bin/okstra-<provider>-exec.sh <projectRoot> <modelExecutionValue> <prompt-path>`
143
+ with the verified prompt path (`okstra worker-dispatch` dispatches only a run manifest's assignments, not a
144
+ standalone prompt). The wrapper records the provider's output in the prompt path with `.md` replaced by
145
+ `.log`. Never substitute one model value for the other. Dispatch the four verified calls in parallel when the host supports
132
146
  it. Every brief carries:
133
147
 
134
148
  - the diff, plus the work directory path so the reviewer can read whole files for context
135
149
  - the project layout in one or two lines (where source, tests, and — if the routing found one — domain / ports / adapters live)
136
150
  - **its own axis's cell list**, verbatim from the census
137
151
  - the absolute paths of the packs its axis reads (from step 2's routing)
138
- - the calibration path, written out in full as Step 2 fixed it — `~/.claude/skills/okstra-code-review/references/review-calibration.md`. The verdict format, the severity points, and the rules for a legitimate `clean` are defined there, not in the brief; a reviewer that cannot open this file cannot return a usable verdict, so never hand it a relative path or a "next to the skill" hint
152
+ - the calibration path, written out in full as Step 2 fixed it — `~/.agents/skills/okstra-code-review/references/review-calibration.md`. The verdict format, the severity points, and the rules for a legitimate `clean` are defined there, not in the brief; a reviewer that cannot open this file cannot return a usable verdict, so never hand it a relative path or a "next to the skill" hint
139
153
 
140
154
  Each axis is **one rule group**, so a cell is `target × <axis>` — never `target × <individual rule>`. The reviewer names the specific rule it found violated inside the verdict's `rule` field, and one cell may carry findings from several rules of its group.
141
155
 
@@ -6,13 +6,13 @@ description: |
6
6
 
7
7
  # OKSTRA Container Build
8
8
 
9
- Single entry point for the okstra user-test container runtime. okstra provisions a docker-compose group from an `implementation` task's worktree (the `docker-compose.yml` at the worktree root), and labels it with the task's run-trace so later sub-commands can find the group. This skill drives that lifecycle. Sub-commands:
9
+ Single entry point for the okstra user-test container runtime. okstra provisions a docker-compose group from an `implementation` task's worktree (the `docker-compose.yml` at the worktree root), and labels every service with `okstra.task-key`, `okstra.project-name`, and `okstra.run-trace`; `status` finds the group by its `okstra.project-name` label. This skill drives that lifecycle. Sub-commands:
10
10
 
11
11
  | Sub-command | What it does |
12
12
  |---|---|
13
13
  | `up` | Integrate the task's stages into the worktree, run `docker compose up -d`, and poll healthchecks. |
14
- | `status` | Query the running containers for a task-key (by run-trace label). |
15
- | `down` | Tear down the containers (label query); `--all` covers every container group in the project. |
14
+ | `status` | List the task's containers in any state (by `okstra.project-name` label). |
15
+ | `down` | Tear down the task's compose project by name; `--all` covers every task in the project that has a container deploy state. |
16
16
 
17
17
  ## Step 0: Preflight (shared)
18
18
 
@@ -69,8 +69,8 @@ Every sub-command needs a **task-key** (`<project-id>:<task-group>:<task-id>`)
69
69
  Brings up the task's container group: integrates the implementation stages into the task worktree, synthesizes the compose env override, runs `docker compose up -d`, and polls healthchecks.
70
70
 
71
71
  **Preconditions** (state them if unmet, do not guess):
72
- - The task must be an `implementation` task whose worktree is registered in `~/.okstra/worktrees/registry.json`. If `up` fails with "task worktree is not in the registry" → the task has no implementation worktree yet; tell the user to run the `implementation` phase first.
73
- - The worktree root must contain a `docker-compose.yml`. If `up` fails with "there is no ... at the worktree root" → no compose file shipped with this task; surface the message verbatim.
72
+ - The task's worktree must be registered in `~/.okstra/worktrees/registry.json`, and the task must have a done `implementation-planning` run. `up` does not check the task type. If `up` refuses because the task-key's worktree is not in the registry → surface the message verbatim; the task has no worktree yet, so the user runs a phase of the task (normally `implementation`) first.
73
+ - The worktree root must contain a `docker-compose.yml`. If `up` refuses because the worktree root has no `docker-compose.yml` → no compose file shipped with this task; surface the message verbatim.
74
74
  - Every stage declared in the approved plan's Stage Map must be `done`. `up` integrates the whole task, so a partially-finished task (e.g. only stage 1 of 3 done) is refused rather than deployed as if complete (gate in `stage_targets.py`, shared with whole-task `final-verification`). If `up` fails with `final-verification(whole-task): stage N not done — run implementation --stage N first`, surface that message verbatim and tell the user to finish the named stage via the `implementation` phase with `--stage N`.
75
75
 
76
76
  Run:
@@ -81,13 +81,13 @@ okstra container up --project-root <projectRoot> --task-key <task-key> --text
81
81
 
82
82
  Read the fixed output fields and report the provisioned services. If a service failed its healthcheck, the call surfaces the failing services and the `docker compose ... logs` line to inspect — relay that line; do not invent your own.
83
83
 
84
- After a successful `up`, run the `status --text` command below and read its numbered container `ports` fields to tell the user how to reach the running build. Also explain that `okstra container status <task-key>` / `okstra container down <task-key>` manage it from here. For *what to verify* once it is up, point the user to the implementation report's §5.7.9 Manual User Test (Draft) — its steps and expected results are the manual test script for this build.
84
+ After a successful `up`, run the `status --text` command below and read its numbered container `ports` fields to tell the user how to reach the running build. Also explain that `okstra container status --project-root <projectRoot> --task-key <task-key>` / `okstra container down --project-root <projectRoot> --task-key <task-key>` manage it from here. For *what to verify* once it is up, point the user to the implementation report's §5.7.9 Manual User Test (Draft) — its steps and expected results are the manual test script for this build.
85
85
 
86
86
  ---
87
87
 
88
88
  ## status
89
89
 
90
- Reports the running containers, queried by the run-trace label — the source of truth for "is it up".
90
+ Reports the task's containers, queried by the `okstra.project-name` label with `docker ps -a` — so stopped and exited containers are listed too. The label query is the source of truth for "is it up".
91
91
 
92
92
  ```bash
93
93
  okstra container status --project-root <projectRoot> --task-key <task-key> --text
@@ -98,9 +98,9 @@ Read the fixed `Project name` and numbered `Container` fields and report:
98
98
  | Field | Meaning |
99
99
  |---|---|
100
100
  | `projectName` | the compose project name (label group) |
101
- | `containers` | running containers found by label — empty array means nothing is up |
101
+ | `containers` | containers found by label, in any state — empty array means no container exists; a non-empty list is up only where `state` is `running` |
102
102
 
103
- If `containers` is empty, say the group is not running and offer `up`.
103
+ If `containers` is empty, or no container's `state` is `running`, say the group is not running and offer `up`.
104
104
 
105
105
  To follow a service's live logs, the user runs `docker compose -p <projectName> logs -f <service>` (get `<projectName>` from `status`).
106
106
 
@@ -108,7 +108,7 @@ To follow a service's live logs, the user runs `docker compose -p <projectName>
108
108
 
109
109
  ## down
110
110
 
111
- Tears down the container group — removes the containers found by the run-trace label.
111
+ Tears down the container group by compose project name — no label query. `--all` finds its targets from the tasks that have a `container/deploy-state.json`.
112
112
 
113
113
  Single task:
114
114
 
@@ -11,7 +11,7 @@ and direct completion records are available to status, recap, group context, and
11
11
  For an explicit status change, dispatch to status.4 before catalog-only task selection.
12
12
  An unregistered brief will not appear in that selection yet.
13
13
 
14
- Single read-side entry point for okstra runtime inspection plus the one status mutation that belongs here (`workStatus`) and read-derived artifact rendering (`errors` report). Each sub-command's full procedure lives in a lazily loaded facet file — after dispatch, Read exactly the one facet you need.
14
+ Single read-side entry point for okstra runtime inspection plus the one status mutation that belongs here (`workStatus`) and read-derived artifact rendering (`errors` report). One more write sits underneath: the task-key lookup used by `time-report`, `context-cost`, `error-report`, `recap record`, `recap note`, and `model-io recap-input --task-group` self-heals a finished implementation phase — when a task's current phase is `implementation`, it appends a `done` row to `runs/implementation-planning/consumers.jsonl` for each stage whose carry file is complete but has no settled row, and when every stage of the latest plan has a `done` row and a pass-grade carry it marks the phase completed in `task-manifest.json` (`workflow`, `phaseOutcome.implementation`) and refreshes the catalog entry. `status-input`, `history-input`, `report-input`, and task-scope `recap-input` do not take that path. Each sub-command's full procedure lives in a lazily loaded facet file — after dispatch, Read exactly the one facet you need.
15
15
 
16
16
  | Sub-command | Facet file | What it does |
17
17
  |---|---|---|
@@ -6,7 +6,7 @@ Loaded lazily by the dispatch table in `SKILL.md` (core). Shared rules — Step
6
6
 
7
7
  Trigger phrases: "okstra context-cost", "context cost", "context-cost", "read cost", "artifact cost", "task bundle cost", "agent read cost".
8
8
 
9
- Read-only estimate of how much file/context surface a prepared task bundle asks the lead, analysis workers, and report-writer to absorb. This sub-command does **not** mutate task artifacts.
9
+ Estimate of how much file/context surface a prepared task bundle asks the lead, analysis workers, and report-writer to absorb. This sub-command does **not** mutate task artifacts itself; a task-key target goes through the lookup that may self-heal a finished implementation phase (see `SKILL.md`).
10
10
 
11
11
  ### cost.1 — Resolve target
12
12
 
@@ -28,14 +28,14 @@ okstra error-zip --out <resolved-path> --text
28
28
 
29
29
  Use the fixed text labels and report:
30
30
 
31
- | Field | Source |
31
+ | Field | Label |
32
32
  |---|---|
33
- | Output zip | `outPath` |
34
- | Total errors | `errorCount` |
35
- | Logs (runs) | `runCount` |
36
- | Unreachable runs | `unreachableRuns` |
37
- | Cluster count | `clusterCount` |
38
- | Project count | `projectCount` |
39
-
40
- - If `unreachableRuns > 0`, surface it (no silent omission).
33
+ | Output zip | `Output zip` |
34
+ | Total errors | `Total errors` |
35
+ | Logs (runs) | `Run count` |
36
+ | Unreachable runs | `Unreachable runs` |
37
+ | Cluster count | `Cluster count` |
38
+ | Project count | `Project count` |
39
+
40
+ - If `Unreachable runs` > 0, surface it (no silent omission).
41
41
  - End with the next step: "To fix okstra itself with this zip, build a brief with the error-feedback variant of `/okstra-brief-gen`, then run `okstra-run --task-type error-analysis` in the okstra repo."