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
@@ -0,0 +1,31 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "feature-analysis",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "analyser",
8
+ "dutyId": "analysis-worker",
9
+ "min": 2,
10
+ "recommended": 3,
11
+ "max": 5
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "report-writer",
16
+ "dutyId": "report-writer",
17
+ "min": 1,
18
+ "recommended": 1,
19
+ "max": 1
20
+ },
21
+ {
22
+ "mode": "dynamic",
23
+ "roleId": "verifier",
24
+ "dutyId": "reverification-worker",
25
+ "sourceRoleIds": [
26
+ "analyser"
27
+ ],
28
+ "activation": "per-selected-source"
29
+ }
30
+ ]
31
+ }
@@ -1,25 +1,5 @@
1
1
  # Feature Analysis Profile
2
2
 
3
- ```yaml
4
- roles:
5
- - role: analyser
6
- min: 2
7
- recommended: 3
8
- max: 5
9
- duty: analysis-worker
10
- - role: report-writer
11
- min: 1
12
- recommended: 1
13
- max: 1
14
- duty: report-writer
15
- - role: verifier
16
- min: 0
17
- recommended: 0
18
- max: 0
19
- duty: reverification-worker
20
- dynamic: true
21
- ```
22
-
23
3
  - Purpose: analyse a confirmed feature target's behavior, rules, state changes, external calls, and test coverage scope without designing or changing an implementation
24
4
  - Required workers:
25
5
  - claude
@@ -0,0 +1,30 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "final-verification",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "verifier",
8
+ "dutyId": "acceptance-verifier",
9
+ "min": 2,
10
+ "recommended": 2,
11
+ "max": 5
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "critic",
16
+ "dutyId": "acceptance-critic",
17
+ "min": 0,
18
+ "recommended": 1,
19
+ "max": 1
20
+ },
21
+ {
22
+ "mode": "static",
23
+ "roleId": "report-writer",
24
+ "dutyId": "report-writer",
25
+ "min": 1,
26
+ "recommended": 1,
27
+ "max": 1
28
+ }
29
+ ]
30
+ }
@@ -1,24 +1,5 @@
1
1
  # Final Verification Profile
2
2
 
3
- ```yaml
4
- roles:
5
- - role: verifier
6
- min: 2
7
- recommended: 2
8
- max: 5
9
- duty: acceptance-verifier
10
- - role: critic
11
- min: 0
12
- recommended: 1
13
- max: 1
14
- duty: acceptance-critic
15
- - role: report-writer
16
- min: 1
17
- recommended: 1
18
- max: 1
19
- duty: report-writer
20
- ```
21
-
22
3
  - Purpose: judge the delivered implementation on three axes before final acceptance — does it cover every requirement (under-delivery), does it carry work no requirement asked for (over-delivery), and does it actually do what it claims (defects, and tests that verify nothing). Whether the run followed okstra's own procedure is not one of the axes: the runtime and `validators/validate-run.py` own that, and a finding about it is not an acceptance judgement
23
4
  - Required workers:
24
5
  - claude
@@ -49,8 +30,8 @@ roles:
49
30
  - Pre-verification entry gate (resolved & enforced by `okstra render-bundle` prep — the lead does NOT recompute it):
50
31
  - the verification target (scope / worktree / base / stages / source reports / diff stat) is injected as the `VERIFICATION_TARGET` block. The lead MUST treat it as authoritative and MUST NOT re-pick a target from the brief.
51
32
  - **whole-task scope** (`--stage auto`, default): prep has already verified every Stage Map stage is `status:done` in `consumers.jsonl`, every done stage's `head_commit` is an ancestor of the task worktree HEAD (all stage branches merged), and the worktree is clean outside `.okstra/`. If any check failed the run never started (PrepareError); a started whole-task run is therefore a fully-merged, clean target.
52
- - **whole-task is a mutating phase, not a read-only one.** On entry, whole-task mode auto-merges (with `--no-ff`) the done stages not yet merged into the task branch to create an integration commit. The stage worktrees are NOT removed on entry: they are reclaimed after the verdict, by the Phase 7 `teardown-stages` step, and only when the verdict clears the work for release (`accepted`, or `conditional-accept` with no condition blocking release). A `blocked` verdict therefore leaves every stage worktree in place, so the rework it routes to can start immediately. The stage branches are kept as the reviewable stack (the target of `okstra handoff local-checkout --stage <N>`). If a merge conflict occurs it reports the conflicting files and aborts (the user resolves them manually and retries). A stage worktree with uncommitted changes remaining is preserved. Therefore the "fully-merged, clean target" the entry gate above refers to is the state after this auto-integration step completes, and whole-task final-verification must be treated as a mutating phase that creates the integration commit.
53
- - **single-stage scope** (`--stage N`): prep verified stage N is `status:done` and its isolated stage worktree exists and is clean. Other stages' state is irrelevant. A single-stage run is a partial verification: it MUST NOT recommend plain `release-handoff`, but MAY recommend `release-handoff(stage-group)` when the verdict is `accepted` — the stage becomes PR-eligible for a stage-group handoff.
33
+ - **whole-task mutates only when it has to.** When one stage branch already contains every other done stage's commit — the usual shape of a linear plan, since each stage branches from its predecessor's done commit — that branch IS the whole task, and verification runs in that stage's worktree with no merge at all (`stage_targets.containing_stage`). Only when the stage graph has several tips does entry auto-merge (with `--no-ff`) the done stages into the task branch to create an integration commit; that case is the mutating one. The stage worktrees are NOT removed on entry: they are reclaimed after the verdict, by the Phase 7 `teardown-stages` step, and only when the verdict clears the work for release (`accepted`, or `conditional-accept` with no condition blocking release). A `blocked` verdict therefore leaves every stage worktree in place, so the rework it routes to can start immediately. The stage branches are kept as the reviewable stack (the target of `okstra handoff local-checkout --stage <N>`). If a merge conflict occurs it reports the conflicting files and aborts (the user resolves them manually and retries). A stage worktree with uncommitted changes remaining is preserved. Therefore the "fully-merged, clean target" the entry gate above refers to is the state after this auto-integration step completes, and whole-task final-verification must be treated as a mutating phase that creates the integration commit.
34
+ - **single-stage scope** (`--stage N`): prep verified stage N is `status:done` and its isolated stage worktree exists and is clean. Other stages' state is irrelevant. A single-stage run is a partial verification of one stage, and that is exactly the unit release-handoff ships: an `accepted` verdict here makes the stage PR-eligible, so `release-handoff` is the routing target. It says nothing about any other stage.
54
35
  - the lead still captures `git status --short` from the injected worktree to confirm the analysis ran against the delivered work-tree state; an unexpected divergence (dirty tree outside `.okstra/`, missing worktree) is a `tool-failure`, not a silent proceed.
55
36
  - Worker verification procedure:
56
37
  - **Target confirmation:** analyse the injected target and nothing else. Read `verification-target.md` for the stage/report mapping and the complete diff stat. Prepare fixed that target and `validators/validate-run.py` `_validate_verification_target_match` re-checks the report against its digest, so the procedure to follow here is simply: if the worktree you can see does not match the injected target, record a `tool-failure` — never reselect a target.
@@ -84,7 +65,7 @@ roles:
84
65
  - **Validation Evidence**: for every requirement in the originating plan or task brief, cite the artifact (commit SHA, test output, log line, MCP SELECT result) that demonstrates coverage. Paraphrased "verified" claims without an artifact are rejected.
85
66
  - **Read-only command log**: any pre-existing test/validation command touched during this run MUST be listed with its exact command line and one honest status — `executed` (ran; carries its exit code) / `advisory` (external Tier 3 did not PASS; carries observed/expected results and remains user-owned) / `env-unavailable` (should run but cannot in this environment — missing replica DB, container, or service; carries the reason, never a faked pass) / `not-configured` (no such qa-command tier) / `rejected` (a mutating/denied token — skipped, carries the denied token). A check that could not run locally is recorded as `env-unavailable` or `advisory` according to the external QA policy — never silently dropped and never reported as `executed` with an invented exit code. Mutating-command prohibition is the shared read-only boundary (see Non-goals); it is not restated per row.
86
67
  - **Could-not-verify roll-up (§5.8.9)**: the template mechanically aggregates every not-confirmed check into one scannable list — `gap` requirement-coverage rows, `advisory` / `not-configured` / `env-unavailable` / `rejected` command rows, and `blocked` manual tests. You do not hand-author it, but you MUST give those rows their honest status so nothing unverified hides across sections: a check silently recorded as `executed`/`covered` will not surface in the roll-up. This is okstra's answer to "say what could not be verified this run."
87
- - **Routing recommendation**: `finalVerification.routingRecommendation` is an **object** with exactly two fields — `target`, one value of the enum below, and `rationale`, the sentence tying that choice to the verdict and the blocker list. Free routing prose is not the field; a target named only in the prose does not route the task, because Phase 7 projects `workflow.nextRecommendedPhase` from `target` alone. The seven allowed targets are `release-handoff`, `release-handoff(stage-group)`, `error-analysis`, `implementation-option-selection`, `implementation-planning`, `implementation`, and `done`. Both `release-handoff` forms are allowed ONLY when the verdict is release-ready — `accepted`, or `conditional-accept` with every condition declaring `blocksReleaseHandoff: false`. Plain `release-handoff` is additionally allowed ONLY when the verification scope (the `Verification scope:` line of the injected `VERIFICATION_TARGET` block, recorded as the report's `verificationScope` field) is `whole-task`; a release-ready `single-stage` run routes to `release-handoff(stage-group)` (or `implementation` / `done`) instead. `done` ends the lifecycle here. Enforcement: `schemas/final-report-v2.0.schema.json` rejects a `target` outside the enum, a missing `rationale`, and a string in place of the object; `validators/validate-run.py` rejects a missing `target`, a verdict that is not release-ready routed to either `release-handoff` form (naming the condition ids that block it), and a `single-stage` report whose routing cites plain `release-handoff`.
68
+ - **Routing recommendation**: `finalVerification.routingRecommendation` is an **object** with exactly two fields — `target`, one value of the enum below, and `rationale`, the sentence tying that choice to the verdict and the blocker list. Free routing prose is not the field; a target named only in the prose does not route the task, because Phase 7 projects `workflow.nextRecommendedPhase` from `target` alone. The eight allowed targets are `release-handoff`, `release-handoff(stage-group)`, `final-verification`, `error-analysis`, `implementation-option-selection`, `implementation-planning`, `implementation`, and `done`. `final-verification` re-runs this phase on the same head and is for exactly one situation: every remaining blocker is an environment or configuration fault whose cause this report already names — a `qaCommands` entry pointing at a path that no longer exists, a missing credential, a stale fixture — so nothing in the code, the plan, or the selected direction is being re-decided. Name the repair in the `rationale`. When any blocker needs a code, plan, or direction change, route to the phase that owns that change instead; routing a defect you have not diagnosed back into this phase re-runs the verification that already failed. Both `release-handoff` forms are allowed ONLY when the verdict is release-ready — `accepted`, or `conditional-accept` with every condition declaring `blocksReleaseHandoff: false`. Either verification scope may route there: release-handoff opens one PR per stage, so a release-ready `single-stage` run is the evidence for that stage's PR, and `release-handoff(stage-group)` is only a scope qualifier that projects onto the same phase. `done` ends the lifecycle here. Enforcement: `schemas/final-report-v2.0.schema.json` rejects a `target` outside the enum, a missing `rationale`, and a string in place of the object; `validators/validate-run.py` rejects a missing `target` and a verdict that is not release-ready routed to either `release-handoff` form (naming the condition ids that block it).
88
69
  - **Verified-row recording** (single-stage scope only): when the verdict is release-ready, the lead MUST run `okstra handoff record-verified --plan-run-root <plan-run-root> --stage <N> --report-path <final-report.md path> --data-json <final-report data.json path>` and quote the command + exit code in the report. The helper checks the latest verification manifest, task/stage identity, report pointer, prepared target, and recorded implementation commit. It records the captured commit and original verdict, including conditional acceptance conditions. A missing target or mismatched commit requires re-verification. Recording happens before final validation; eligibility is granted only after that verification passes validation. **Enforced:** `okstra_ctl.handoff_verification` validates the evidence, and `validators/validate-run.py` `_validate_verified_row_recorded` requires a `verified` row matching this report, captured commit, and verdict.
89
70
  - Clarification request policy (phase-specific addendum — shared policy is in `_common-contract.md`):
90
71
  - populate `## 1. Clarification Items` only when a blocker hinges on information only the user can supply (deployment intent, intended target environment, business-rule interpretation); use `Blocks=next-phase` for items that gate continuing to release-handoff
@@ -75,13 +75,14 @@
75
75
  ],
76
76
  "release-handoff": [
77
77
  "entering this phase when the cited final-verification `Verdict Token` is `conditional-accept` or `blocked`, or when no final-verification report is cited",
78
- "local commit commands of any kind (`git add`, `git commit`, `git restore --staged`, `git stash`), and any direct `git merge` / `git rebase` run by the lead. The single exception is the merge commits `okstra handoff assemble` itself creates on the collector branch — the lead never merges by hand.",
78
+ "local commit commands of any kind (`git add`, `git commit`, `git restore --staged`, `git stash`), and any direct `git merge` / `git rebase` / `git rebase --onto` / `git cherry-pick` / `git commit --amend` run by the lead. The single exception is the merge commits `okstra handoff pr-plan` itself creates on a `merge-base` branch — the lead never merges by hand. Rewriting a stage branch breaks the PR stack that sits on it.",
79
79
  "any git push variant that rewrites remote history, regardless of intent or whether the user said \"force it\": `git push --force`, `git push --force-with-lease`, `git push -f`, `git push +<refspec>`, or any other history-rewriting invocation",
80
- "pushing directly to a base branch — i.e. `git push origin <branch>` where `<branch>` is `main`, `master`, `prod`, `preprod`, `staging`, `dev`, or the branch the user chose as the PR base in this run. The only permitted push target is the current feature branch.",
80
+ "pushing directly to a release base branch — i.e. `git push origin <branch>` where `<branch>` is `main`, `master`, `prod`, `preprod`, `staging`, `dev`, or the branch the user chose as the release base in this run. The only permitted push targets are the branches `okstra handoff pr-plan` listed for this run (each stage `head_branch`, and any `merge-base` branch).",
81
81
  "bypassing repo safeguards: `--no-verify` / `-n` on `git push`, bypassing GPG signing, disabling safeguards via equivalent flags, or any hook bypass.",
82
82
  "release-publishing commands: `gh release create`, `gh release edit`, `npm publish`, `cargo publish`, `pip publish`, `twine upload`, `docker push`, `terraform apply`, `kubectl apply` against any non-local cluster.",
83
83
  "source-code edits, refactors, or any modification to files outside the run's own artifact directories (`reports/`, `prompts/`, `state/`, `manifests/`, `worker-results/`, `status/`, `sessions/`). The diff being shipped MUST be exactly what the prior `implementation` run produced; release-handoff packages it, it does not re-author it.",
84
- "executing any mutating command the user did NOT select. Examples: opening a PR when the user picked `local checkout`; pushing when the user picked `skip`; switching the PR base branch silently after the user already chose one.",
84
+ "executing any mutating command the user did NOT select. Examples: opening a PR when the user picked `local checkout`; pushing when the user picked `skip`; switching the release base branch silently after the user already chose one; opening a PR for a stage outside `HANDOFF_STAGES`.",
85
+ "squash-merging, or instructing anyone to squash-merge, a stage PR — and `gh pr merge` in any form. A squash replaces the commits the next stage's PR base points at, so the stack breaks; the PR body states merge-commit-or-rebase and the lead never merges.",
85
86
  "retrying a failed git / gh command with weaker safety flags. If `git push` fails with non-fast-forward, the lead MUST stop, explain the failure to the user, and ask for instructions — it MUST NOT add `--force`.",
86
87
  "worker dispatch of any kind, or any other parallel sub-agent fan-out. This phase runs entirely under the Okstra lead.",
87
88
  "silently treating an unrecognised user reply as one of the menu options. If the user's answer does not match a presented choice, re-ask the question verbatim."
@@ -0,0 +1,31 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "implementation-option-selection",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "designer",
8
+ "dutyId": "direction-selection-worker",
9
+ "min": 3,
10
+ "recommended": 3,
11
+ "max": 5
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "report-writer",
16
+ "dutyId": "report-writer",
17
+ "min": 1,
18
+ "recommended": 1,
19
+ "max": 1
20
+ },
21
+ {
22
+ "mode": "dynamic",
23
+ "roleId": "verifier",
24
+ "dutyId": "reverification-worker",
25
+ "sourceRoleIds": [
26
+ "designer"
27
+ ],
28
+ "activation": "per-selected-source"
29
+ }
30
+ ]
31
+ }
@@ -1,25 +1,5 @@
1
1
  # Implementation Option Selection Profile
2
2
 
3
- ```yaml
4
- roles:
5
- - role: designer
6
- min: 3
7
- recommended: 3
8
- max: 5
9
- duty: direction-selection-worker
10
- - role: report-writer
11
- min: 1
12
- recommended: 1
13
- max: 1
14
- duty: report-writer
15
- - role: verifier
16
- min: 0
17
- recommended: 0
18
- max: 0
19
- duty: reverification-worker
20
- dynamic: true
21
- ```
22
-
23
3
  - Purpose: compare feasible implementation directions before planning, preserving a read-only record of the evidence and trade-offs that selects the direction to plan
24
4
  - Required workers:
25
5
  - claude
@@ -0,0 +1,40 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "implementation-planning",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "planner",
8
+ "dutyId": "planning-worker",
9
+ "min": 2,
10
+ "recommended": 2,
11
+ "max": 5
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "critic",
16
+ "dutyId": "scope-critic",
17
+ "min": 0,
18
+ "recommended": 1,
19
+ "max": 1
20
+ },
21
+ {
22
+ "mode": "static",
23
+ "roleId": "report-writer",
24
+ "dutyId": "report-writer",
25
+ "min": 1,
26
+ "recommended": 1,
27
+ "max": 1
28
+ },
29
+ {
30
+ "mode": "dynamic",
31
+ "roleId": "verifier",
32
+ "dutyId": "reverification-worker",
33
+ "sourceRoleIds": [
34
+ "critic",
35
+ "planner"
36
+ ],
37
+ "activation": "per-selected-source"
38
+ }
39
+ ]
40
+ }
@@ -1,34 +1,11 @@
1
1
  # Implementation Planning Profile
2
2
 
3
+ Keep `commandOrObservation` executable when the checklist calls for a command. Put explanations and existing-helper citations in the checklist's `check` text, outside the command. Do not append prose after a semicolon. The plan-item renderer separates legacy `existing helper: <file>:<lines>` suffixes, and `verification-target` supplies the same executable command to every verifier.
4
+
3
5
  Validation commands are executable inputs: preserve their newlines, quotes, and code bodies. Use frozen dependency installation (`npm ci`, `pnpm install --frozen-lockfile`, or the package manager's equivalent). Name QA scripts with absolute task-artifact paths when a command runs from a stage worktree; `.okstra/tasks/...` relative to that worktree does not point to the project task. `stage_validation_executability_errors` enforces command restrictions at planning validation, implementation entry, and report preflight, including advisory plan-body runs.
4
6
 
5
7
  Plan for the actual worktree layout before approval. Shared documentation directories can be links to the main checkout. Choose a build command compatible with those links (for example, an installed Next.js version may provide `next build --webpack`); verify the available option rather than assuming it. Do not plan for a verifier to move links or repair its environment. Compare negative-case assertions with the brief and the script body: a requirement to cache existing assets does not establish that missing assets should be cached. Record any changed expectation in a new plan revision; preserve the earlier approved plan.
6
8
 
7
- ```yaml
8
- roles:
9
- - role: planner
10
- min: 2
11
- recommended: 2
12
- max: 5
13
- duty: planning-worker
14
- - role: critic
15
- min: 0
16
- recommended: 1
17
- max: 1
18
- duty: scope-critic
19
- - role: report-writer
20
- min: 1
21
- recommended: 1
22
- max: 1
23
- duty: report-writer
24
- - role: verifier
25
- min: 0
26
- recommended: 0
27
- max: 0
28
- duty: reverification-worker
29
- dynamic: true
30
- ```
31
-
32
9
  - Purpose: turn an upstream-selected direction into an executable plan; legacy reruns may retain candidate comparison
33
10
  - Required workers:
34
11
  - claude
@@ -69,8 +46,8 @@ roles:
69
46
  - flag any requirement that is ambiguous, contradictory, or missing success criteria — register each one as a row in the report's `## 1. Clarification Items` table with `Blocks=approval` instead of guessing
70
47
  - read `<PROJECT_ROOT>/.okstra/glossary.md` and `<PROJECT_ROOT>/.okstra/decisions/` titles if present. Absent okstra memory files are the normal state — do not error. Treat the brief's `terminology:*` resolutions from `requirements-discovery` (if any) as authoritative; if missing, resolve any remaining fuzzy term as a `Blocks=approval` clarification row.
71
48
  - **Stage Ledger (read before drafting the Stage Map):** when this task already has a plan on disk, the analysis packet carries a `## Stage Ledger` JSON block listing every stage with its `status` (`done` / `active` / `ready` / `blocked`), `dependsOn`, and done commit. It states what exists, not what to plan. Two rules follow from it:
72
- - A stage whose `status` is `done` is already implemented and will not be executed again. Carry its plan body forward as written; do not rewrite its steps, and do not fold its work into a new stage.
73
- - Every stage number in the ledger is taken. A new stage takes the next number after the highest one listed; numbers are never reused or reordered. **Not yet machine-enforced** — the validator for this rule lands with the plan-amendment feature.
49
+ - A stage whose `status` is `done` is already implemented and will not be executed again. Declare it in this report's `stages[]` and `stageMap[]` with its plan body copied forward as written; do not rewrite its steps, and do not fold its work into a new stage. Its plan items are `observed`, not `in-scope` (`okstra_ctl.plan_items.stage_scope_bucket`), so re-declaring it adds no verification load. A carried body is also not re-judged: the planning conformance gate skips a stage the consumer ledger records as `done`, and report assembly issues no design-prep request for one (`okstra_ctl.design_prep.materialize_design_prep_requests`). A rule that widened since that stage shipped cannot be satisfied by a body you are forbidden to rewrite.
50
+ - Every stage number in the ledger is taken. This report declares every one of them — rows run `1..N` with no gap — and a new stage takes the next number after the highest one listed; numbers are never reused or reordered. A report that declares only its new stages satisfies neither rule and is refused twice over. **Enforced:** `okstra_ctl.stage_map._validate_stage_numbers` rejects the gap in every published plan it parses, so `okstra prepare` refuses the implementation run (`okstra_ctl.run._parse_stage_map_into_ctx`) and the Stage Ledger of every later run reads as `unreadable`; `validators/validate-implementation-plan-stages.py` check **S2** reports the same defect at authoring time. Cancelling a stage you no longer want is not yet expressible — that lands with the plan-amendment feature — so an unstarted stage you drop still keeps its number and body here.
74
51
  - The ledger answers two questions from two sources, and the block names both. `sourcePlan` is the plan the completed stages were actually built against; `latestPlan` is the plan the `stages` list came from and is therefore the numbering authority. When they differ, the completed work followed the former and the highest taken number comes from the latter.
75
52
  - A `planDivergence` entry means one of two things: the two plans disagree about a stage that is already `done` — the same number naming different work, or a completed stage the latest plan no longer declares — or the plan the completed stages were built against could not be read at all, so that comparison never ran. Both block the same way: do not pick one of the two plans yourself; register it as a `Blocks=approval` clarification row and assign no new stage number until it is resolved. Completed stages built against an *earlier* plan are not a divergence — that is the normal shape of an amended plan and the ledger folds it silently.
76
53
  - The block is absent ONLY on a task's first planning run. Its absence then means there is no prior plan, not that no stage is done. When the ledger could not be read, the packet names the source and reason. Continue planning to repair unambiguous dependency notation in the new report, retaining every stage number and title and every completed stage body. Record the original and corrected values with their source. Do not overwrite the prior report or select an older plan. Assign no new stage number until the corrected Stage Map validates; unresolved dependency meaning remains a blocker. The preparation behavior is covered by `tests/run/test_stage_ledger_prepare.py`; preservation of author intent remains a review guideline.
@@ -110,7 +87,7 @@ roles:
110
87
  - Phase 5.5 finding convergence runs in **adversarial mode** for this phase (`convergence.adversarial=true`). Verifiers actively try to refute each worker finding (requirement gap / risk / plan item) by re-inspecting its cited evidence; the burden of proof sits on the claim. See `prompts/lead/convergence.md` §"Adversarial Verification Mode".
111
88
  - §5.5.9 plan-body verification runs with an **adversarial posture** (`prompts/lead/plan-body-verification.md` §"Adversarial plan-body posture"): verifiers open and confirm every cited path / command and put the burden of proof on the plan. The gate threshold is majority-based for kinds `b`/`c`/`e`, but a single `DISAGREE` blocks on its own for the concrete, safety-critical kind `a` (path/symbol mismatch) — and `f` on `P-Req-*` items. `P-Var-*` items are excepted from the kind-`a` exception: a variation-point defect takes a majority. Rollback ordering (`d`) is advisory and never blocks the gate — a rollback is executed by a human, not by okstra's workers or verifiers. A majority also needs ≥2 participating votes, so a lone dissent whose peer returned a non-result does not block on a majority-gated kind (see that contract's §"Adversarial plan-body posture").
112
89
  - **Incremental re-verification scope (clarification re-runs):** when the lead's `okstra incremental-scope` decision is `mode == "incremental"` (procedure in `prompts/launch.template.md` §"Clarification Response Carried In"), workers re-analyze ONLY the stages listed in `reverify_stages` (the downstream closure of the impacted stages). Workers MUST NOT re-open, re-score, or re-judge any stage in `carry_stages` — those stages' prior plan-item verdicts are carried forward verbatim, and a worker never overwrites a carried verdict with its own judgement. When the decision is `mode == "full"` (the default), every stage is re-analyzed as usual.
113
- - **Single incremental-scope decision:** the lead calls `okstra incremental-scope` once the inputs are complete, passing the answered `C-NNN` ids through `--answered-clarifications`, changed design-preparation IDs through `--prep-items`, and any lead-resolved stage numbers through `--impacted`; the CLI unions all three before applying the existing dependency closure and cutoff. The clarification ids are resolved to stages by the CLI from the prior report's own `planItems[].clarificationId` and `blocked C-NNN` coverage links — the lead does not map answers to stage numbers. An answer that changes the selected planning payload, Stage Map, or execution approach is not a local impact: pass `--full-reason`, which is the only structural path that still forces `mode == "full"`. A clarification id that traces to no stage returns `mode == "unresolved"` — ask the user for stage numbers and call again with `--impacted`; do not treat it as full and do not silently drop the id. **When this run only ADDS stages** — every prior stage is `done` and none of them is being re-opened — there are no stage numbers to give: pass `--carry-all-reason` instead. Pinning any prior stage as impacted makes `incremental-carry` demand it from the current snapshot, which no longer holds it (a `done` stage is not in this run's narrative), so that path has no answer that works. `--carry-all-reason` still applies the base-ref check: if the branch moved, the decision degrades to `full` because the prior stages are no longer "as written". Unknown PREP IDs or invalid `stageRefs` still return an explicit full decision instead of being guessed. When the wizard pin is `auto` and the CLI returns `mode == "incremental"`, keep it — do not upgrade to full. When the user pinned a scope at the wizard (`REVERIFY_SCOPE_MODE` / `REVERIFY_SCOPE_STAGES` in `prompts/launch.template.md` §"Clarification Response Carried In" step 0), that pin is an input to this same call — `full` supplies the `--full-reason`, `carry-all` supplies the `--carry-all-reason`, and pinned stage numbers join `--impacted` — never a bypass of the CLI's closure and cutoff.
90
+ - **Single incremental-scope decision:** the lead calls `okstra incremental-scope` once the inputs are complete, passing the answered `C-NNN` ids through `--answered-clarifications`, changed design-preparation IDs through `--prep-items`, and any lead-resolved stage numbers through `--impacted`; the CLI unions all three before applying the existing dependency closure and cutoff. The clarification ids are resolved to stages by the CLI from the prior report's own `planItems[].clarificationId` and `blocked C-NNN` coverage links — the lead does not map answers to stage numbers. An answer that changes the selected planning payload, Stage Map, or execution approach is not a local impact: pass `--full-reason`, which is the only structural path that still forces `mode == "full"`. A clarification id that traces to no stage returns `mode == "unresolved"` — ask the user for stage numbers and call again with `--impacted`; do not treat it as full and do not silently drop the id. **When this run only ADDS stages** — every prior stage is `done` and none of them is being re-opened — there are no stage numbers to give: pass `--carry-all-reason` instead. Pinning any prior stage as impacted makes `incremental-carry` demand plan-item verdicts from the current snapshot, which no longer holds them (a `done` stage's plan items are `observed`, so they are never dispatched or scored in this run), so that path has no answer that works. The stage's own row is still declared in the narrative — that is the numbering rule above, not a re-verification. `--carry-all-reason` still applies the base-ref check: if the branch moved, the decision degrades to `full` because the prior stages are no longer "as written". Unknown PREP IDs or invalid `stageRefs` still return an explicit full decision instead of being guessed. When the wizard pin is `auto` and the CLI returns `mode == "incremental"`, keep it — do not upgrade to full. When the user pinned a scope at the wizard (`REVERIFY_SCOPE_MODE` / `REVERIFY_SCOPE_STAGES` in `prompts/launch.template.md` §"Clarification Response Carried In" step 0), that pin is an input to this same call — `full` supplies the `--full-reason`, `carry-all` supplies the `--carry-all-reason`, and pinned stage numbers join `--impacted` — never a bypass of the CLI's closure and cutoff.
114
91
  - **Stage-aware carry:** for an incremental decision, `okstra incremental-scope` writes the decision to the record this run's manifest names in `incrementalDecisionPath`. The report writer's duty to copy each `carry_stages` stage row unchanged is not stated here — it is generated into that writer's own authoring contract from the same record, with this run's stage numbers in it (`okstra_ctl.report_synthesis_packet.ReportSynthesisPacket._carry_instructions`). After plan-item seeding, run `okstra incremental-carry --cur-narrative ... --state ... --out-state ...` against that record. The helper rejects a changed or missing carried stage and copies prior `P-Step-*` / `P-Prep-*` verdicts for `carry_stages`, plus unchanged `P-Val-*` / `P-Req-*` / `P-Rb-*` rows whose extract `contentHash` still matches. It rewrites `dispatchQueue` and the sibling `plan-items-*.json` so the next prompt does not re-score a carried checklist row. Overlap, omissions, and canonical conflicts return `CarryError`. On that error, discard the partial state and run full re-verification.
115
92
  {{INCLUDE:_coverage-critic.md}}
116
93
  - Non-goals:
@@ -178,7 +155,7 @@ roles:
178
155
  - **Clean-tree assertions use `okstra worktree-status --check-clean`.** A bare `git status --porcelain` is never empty there, so an assertion built on one fails on okstra's scaffolding rather than on the stage's work. The okstra command asks the same question over source paths only and exits 1 when dirty, so it stands alone as a step's assertion: `okstra worktree-status --check-clean`. Validator S13 rejects the bare form. Do not add a `git tag stage-<N>-exit` to the step. Stage completion records the commit in the consumer ledger without creating or moving git tags.
179
156
  - **Never read an `.okstra/` artifact back out of a git object.** `.okstra/**` is gitignored and never committed — the executor aborts a commit that stages an ignored path and the verifier reports a committed `.okstra` path as a branch defect — so `git cat-file -e <tag>:.okstra/…`, `git show <tag>:.okstra/…`, and every variant of that read can never resolve, at any tag, in any stage. A later stage that needs a QA artifact reads it from the working tree or receives it through the carry sidecar / verifier result; do not design a stage contract around one being reachable from a tag. Validator S12 rejects the read.
180
157
  - **Per-stage conformance declaration (mandatory one line, in the stage section — same placement freedom as `TDD exemption:`):** the stage MUST carry exactly one of:
181
- - `Conformance tests: stage-<N> — <task_root>/qa/scripts/stage-<N>.<ext> (requires=[db|io|http|external,...])` — declare that a Tier3 verification script will prove this stage's upstream requirements (brief / requirements-discovery / error-analysis / improvement-discovery → this stage's `Acceptance`) hold against **real** DB rows, real endpoints, or the real external API — NOT mocks. This phase emits the line and the `requires` set only. Do NOT write `<task_root>/qa/scripts/stage-<N>.*` and do NOT add a `runCommand` or `conformance-manifest.json` entry here — the matching `implementation` stage run creates the script file and the manifest `runCommand`. A plan that declares tests with no script file on disk is valid at this gate. The data.json `conformanceTests` value carries only the remainder after the `Conformance tests: stage-<N> — ` prefix — never the `stage-<N> — ` label itself (report assembly strips a leftover label at publication, and the implementation entry gate rejects one).
158
+ - `Conformance tests: stage-<N> — <task_root>/qa/scripts/stage-<N>.<ext> (requires=[db|io|http|external,...])` — declare that a Tier3 verification script will prove this stage's upstream requirements (brief / requirements-discovery / error-analysis / improvement-discovery → this stage's `Acceptance`) hold against **real** DB rows, real endpoints, or the real external API — NOT mocks. This phase emits the line and the `requires` set only. Do NOT write `<task_root>/qa/scripts/stage-<N>.*` and do NOT add a `runCommand` or `conformance-manifest.json` entry here — the matching `implementation` stage run creates the script file and the manifest `runCommand`. A plan that declares tests with no script file on disk is valid at this gate. The data.json `conformanceTests` value carries only the remainder after the `Conformance tests: stage-<N> — ` prefix — never the `stage-<N> — ` label itself (report assembly strips a leftover label at publication, and the implementation entry gate rejects one). The `requires` set MUST cover every surface the stage's own `stepwiseExecution[].plannedPaths` touch — a controller is `http`, a repository or query is `db` — because the implementation run's diff-surface check demands them after the work is done, when the approved plan can no longer change (2026-09-22, dev-10860: `requires=[io]` over a planned `catalog.controller.ts`). **Enforced at planning:** `validators/validate-run.py` `_validate_planning_conformance_declared` runs the implementation gate's surface patterns over those paths (`okstra_ctl.conformance.declared_stage_surface_gaps`) and fails the planning run on a missing surface. A stage the consumer ledger records as `done` is skipped — its body is carried, not authored, and cannot be corrected here.
182
159
  - `Conformance exemption: <reason>` — only for stages that touch no db/io/http/external surface, or where unit tests fully cover the increment. Exemption stays a planning declaration; do not move it to implementation. (If the eventual `implementation` diff actually touches one of those surfaces, `validate-run.py`'s diff-surface cross-check is BLOCKING — an exemption cannot hide a real db/io/http/external change.) **Enforced at planning:** `validators/validate-run.py` `_validate_planning_conformance_declared` runs the same surface patterns over the exempted stage's `stepwiseExecution[].plannedPaths` (`okstra_ctl.conformance.exempt_stage_surface_conflicts`) and fails the planning run — a plan that exempts a stage while planning a `*repository*` / `*.controller.*` / `*migration*` path is corrected here, where the plan is still editable, not after the implementation is done (observed 2026-09-09, dev-10784 Stage 2).
183
160
  - **External QA outcome guideline:** after satisfying the S11 declaration above, a line whose `requires` contains
184
161
  `db`, `http`, or `external` should name those capabilities here so the later `runCommand` can be written against them.
@@ -0,0 +1,30 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "implementation",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "implementer",
8
+ "dutyId": "implementation-executor",
9
+ "min": 1,
10
+ "recommended": 1,
11
+ "max": 1
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "verifier",
16
+ "dutyId": "implementation-verifier",
17
+ "min": 2,
18
+ "recommended": 2,
19
+ "max": 3
20
+ },
21
+ {
22
+ "mode": "static",
23
+ "roleId": "report-writer",
24
+ "dutyId": "report-writer",
25
+ "min": 1,
26
+ "recommended": 1,
27
+ "max": 1
28
+ }
29
+ ]
30
+ }
@@ -1,24 +1,5 @@
1
1
  # Implementation Profile
2
2
 
3
- ```yaml
4
- roles:
5
- - role: implementer
6
- min: 1
7
- recommended: 1
8
- max: 1
9
- duty: implementation-executor
10
- - role: verifier
11
- min: 2
12
- recommended: 2
13
- max: 3
14
- duty: implementation-verifier
15
- - role: report-writer
16
- min: 1
17
- recommended: 1
18
- max: 1
19
- duty: report-writer
20
- ```
21
-
22
3
  - Purpose: realise the approved `implementation-planning` deliverable as actual source changes, with cross-model verification, while keeping the run reversible
23
4
  - **Run-level fixed cost:** the verifier set, Phase 5.5 convergence, and the Phase 6 report-writer run exactly once per implementation run, over this run's single stage diff — never once per step.
24
5
  - **Fix run (profile carries a "Fix-Run Carry" block):** the executor's scope is the carried blocking findings plus the previous routing recommendation — it MUST NOT re-execute plan steps the previous run completed. Verifiers apply the "Fix-run incremental scope" section of `_implementation-verifier.md`; the report writer applies "Fix-run incremental authoring" in `report-writer.md`. The full validation-command re-run is NOT reduced.
@@ -53,7 +34,7 @@ roles:
53
34
  - Base ref: `{{EXECUTOR_WORKTREE_BASE_REF}}` — canonical `<base>` for every `git diff` / `git log` in this run. Independent stages start from the common anchor (the task-key worktree HEAD, fixed once at first stage entry); dependent stages start from the predecessor done commit or the verified merged task worktree head.
54
35
  - Provisioning note: `{{EXECUTOR_WORKTREE_NOTE}}`
55
36
  - Treat the working-tree path as `project_root` for the duration of this run. Do NOT mutate the caller's original checkout. cwd-sensitive Bash commands MUST be prefixed `cd {{EXECUTOR_WORKTREE_PATH}} && ` in the same Bash invocation (never `bash -lc "..."` wrappers — see executor sidecar for full rules).
56
- - Lifecycle: kept after the run completes as this stage's evidence worktree. Later stages get their own stage worktrees. Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` → drop the stage-key registry entry (`<task-key>#stage-<N>`). Exception: whole-task `final-verification` auto-merges every done stage and removes its worktree directory (`stage_integrate.integrate_stages`, `teardown=True`) — do not promise the user the worktree survives past that point. The stage BRANCH does survive: it is kept so the stack stays reviewable and `okstra handoff local-checkout --stage <N>` still has a target.
37
+ - Lifecycle: kept after the run completes as this stage's evidence worktree. Later stages get their own stage worktrees. Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` → drop the stage-key registry entry (`<task-key>#stage-<N>`). Exception: whole-task `final-verification` removes the stage worktree directory after its verdict clears the work for release (`stage_integrate.integrate_stages`, `teardown=True`; it also merges the done stages into the task branch, unless one stage branch already contains them all) — do not promise the user the worktree survives past that point. The stage BRANCH does survive: it is kept so the stack stays reviewable and `okstra handoff local-checkout --stage <N>` still has a target.
57
38
  - Approval gate (phase-specific addendum to shared authority rule):
58
39
  - the pre-implementation gate's recorded user approval marker is the only authorised approval gate at this phase — proceed once it is satisfied without further external coordination.
59
40
  - Forbidden actions — universal (any occurrence → terminal status `contract-violated`):
@@ -0,0 +1,31 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "improvement-discovery",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "analyser",
8
+ "dutyId": "discovery-worker",
9
+ "min": 3,
10
+ "recommended": 3,
11
+ "max": 5
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "report-writer",
16
+ "dutyId": "report-writer",
17
+ "min": 1,
18
+ "recommended": 1,
19
+ "max": 1
20
+ },
21
+ {
22
+ "mode": "dynamic",
23
+ "roleId": "verifier",
24
+ "dutyId": "reverification-worker",
25
+ "sourceRoleIds": [
26
+ "analyser"
27
+ ],
28
+ "activation": "per-selected-source"
29
+ }
30
+ ]
31
+ }
@@ -1,25 +1,5 @@
1
1
  # Improvement Discovery Profile
2
2
 
3
- ```yaml
4
- roles:
5
- - role: analyser
6
- min: 3
7
- recommended: 3
8
- max: 5
9
- duty: discovery-worker
10
- - role: report-writer
11
- min: 1
12
- recommended: 1
13
- max: 1
14
- duty: report-writer
15
- - role: verifier
16
- min: 0
17
- recommended: 0
18
- max: 0
19
- duty: reverification-worker
20
- dynamic: true
21
- ```
22
-
23
3
  - Purpose: scan a codebase scope through a fixed lens whitelist and surface ranked improvement candidates with multi-worker consensus classification
24
4
  - Required workers:
25
5
  - claude
@@ -0,0 +1,31 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "project-analysis",
4
+ "roles": [
5
+ {
6
+ "mode": "static",
7
+ "roleId": "analyser",
8
+ "dutyId": "analysis-worker",
9
+ "min": 2,
10
+ "recommended": 3,
11
+ "max": 5
12
+ },
13
+ {
14
+ "mode": "static",
15
+ "roleId": "report-writer",
16
+ "dutyId": "report-writer",
17
+ "min": 1,
18
+ "recommended": 1,
19
+ "max": 1
20
+ },
21
+ {
22
+ "mode": "dynamic",
23
+ "roleId": "verifier",
24
+ "dutyId": "reverification-worker",
25
+ "sourceRoleIds": [
26
+ "analyser"
27
+ ],
28
+ "activation": "per-selected-source"
29
+ }
30
+ ]
31
+ }
@@ -1,25 +1,5 @@
1
1
  # Project Analysis Profile
2
2
 
3
- ```yaml
4
- roles:
5
- - role: analyser
6
- min: 2
7
- recommended: 3
8
- max: 5
9
- duty: analysis-worker
10
- - role: report-writer
11
- min: 1
12
- recommended: 1
13
- max: 1
14
- duty: report-writer
15
- - role: verifier
16
- min: 0
17
- recommended: 0
18
- max: 0
19
- duty: reverification-worker
20
- dynamic: true
21
- ```
22
-
23
3
  - Purpose: map a bounded project area so later work can navigate components, dependencies, entry points, repositories, and external integrations without changing the source
24
4
  - Required workers:
25
5
  - claude
@@ -0,0 +1,5 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "id": "release-handoff",
4
+ "roles": []
5
+ }