okstra 0.180.0 → 0.183.2

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 (223) hide show
  1. package/dist/cli-registry.mjs +16 -2
  2. package/dist/cli-registry.mjs.map +1 -1
  3. package/dist/commands/execute/render-bundle.d.mts +4 -2
  4. package/dist/commands/execute/render-bundle.mjs +46 -5
  5. package/dist/commands/execute/render-bundle.mjs.map +1 -1
  6. package/dist/commands/execute/run.mjs +11 -3
  7. package/dist/commands/execute/run.mjs.map +1 -1
  8. package/dist/commands/inspect/model-io.d.mts +1 -0
  9. package/dist/commands/inspect/model-io.mjs +25 -0
  10. package/dist/commands/inspect/model-io.mjs.map +1 -0
  11. package/dist/commands/inspect/stage-map.mjs +29 -8
  12. package/dist/commands/inspect/stage-map.mjs.map +1 -1
  13. package/dist/commands/inspect/task-list.mjs +52 -6
  14. package/dist/commands/inspect/task-list.mjs.map +1 -1
  15. package/dist/commands/inspect/user-response.mjs +14 -4
  16. package/dist/commands/inspect/user-response.mjs.map +1 -1
  17. package/dist/commands/lifecycle/check-project.d.mts +1 -0
  18. package/dist/commands/lifecycle/check-project.mjs +69 -50
  19. package/dist/commands/lifecycle/check-project.mjs.map +1 -1
  20. package/dist/commands/lifecycle/contract-check.d.mts +1 -0
  21. package/dist/commands/lifecycle/contract-check.mjs +18 -0
  22. package/dist/commands/lifecycle/contract-check.mjs.map +1 -0
  23. package/dist/commands/lifecycle/preflight.mjs +154 -51
  24. package/dist/commands/lifecycle/preflight.mjs.map +1 -1
  25. package/dist/commands/pr/pr.d.mts +1 -0
  26. package/dist/commands/pr/pr.mjs +19 -1
  27. package/dist/commands/pr/pr.mjs.map +1 -1
  28. package/dist/commands/report/agent-activity.mjs +2 -2
  29. package/dist/commands/report/translate.mjs +3 -0
  30. package/dist/commands/report/translate.mjs.map +1 -1
  31. package/dist/lib/host-registry-client.mjs +13 -9
  32. package/dist/lib/host-registry-client.mjs.map +1 -1
  33. package/docs/architecture.md +11 -0
  34. package/docs/cli.md +26 -13
  35. package/docs/container.md +6 -4
  36. package/docs/contributor-change-matrix.md +1 -1
  37. package/docs/for-ai/README.md +2 -2
  38. package/docs/for-ai/skills/okstra-brief-gen.md +5 -3
  39. package/docs/for-ai/skills/okstra-code-review.md +4 -4
  40. package/docs/for-ai/skills/okstra-container-build.md +20 -17
  41. package/docs/for-ai/skills/okstra-inspect.md +20 -23
  42. package/docs/for-ai/skills/okstra-manager.md +19 -18
  43. package/docs/for-ai/skills/okstra-memory.md +2 -2
  44. package/docs/for-ai/skills/okstra-pr-gen.md +3 -3
  45. package/docs/for-ai/skills/okstra-rollup.md +14 -13
  46. package/docs/for-ai/skills/okstra-run.md +7 -3
  47. package/docs/for-ai/skills/okstra-schedule-gen.md +15 -18
  48. package/docs/for-ai/skills/okstra-setup.md +7 -7
  49. package/docs/for-ai/skills/okstra-usage.md +5 -4
  50. package/docs/for-ai/skills/okstra-user-response.md +50 -32
  51. package/docs/project-structure-overview.md +29 -26
  52. package/docs/task-process/implementation.md +7 -4
  53. package/package.json +1 -1
  54. package/runtime/BUILD.json +2 -2
  55. package/runtime/agents/workers/claude-worker.md +4 -4
  56. package/runtime/agents/workers/report-writer-worker.md +3 -3
  57. package/runtime/agents/workers/translator-worker.md +5 -13
  58. package/runtime/bin/okstra-error-log.py +51 -11
  59. package/runtime/bin/okstra-report-translate.py +210 -23
  60. package/runtime/prompts/host-orchestration/implementation.md +1 -1
  61. package/runtime/prompts/launch.template.md +3 -7
  62. package/runtime/prompts/lead/context-loader.md +41 -141
  63. package/runtime/prompts/lead/convergence.md +8 -6
  64. package/runtime/prompts/lead/okstra-lead-contract.md +25 -35
  65. package/runtime/prompts/lead/plan-body-verification.md +187 -14
  66. package/runtime/prompts/lead/report-writer.md +20 -1
  67. package/runtime/prompts/lead/team-contract.md +8 -53
  68. package/runtime/prompts/profiles/_coding-conventions-preflight.md +3 -2
  69. package/runtime/prompts/profiles/_common-contract.md +1 -1
  70. package/runtime/prompts/profiles/_implementation-diff-review.md +1 -1
  71. package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
  72. package/runtime/prompts/profiles/final-verification.md +1 -1
  73. package/runtime/prompts/profiles/implementation-planning.md +8 -2
  74. package/runtime/prompts/profiles/release-handoff.md +0 -1
  75. package/runtime/prompts/wizard/prompts.ko.json +0 -1
  76. package/runtime/python/okstra_ctl/adapters/hosts/capability_adapter.py +69 -17
  77. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +13 -4
  78. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +6 -1
  79. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +2 -2
  80. package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +50 -5
  81. package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +2 -2
  82. package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +66 -5
  83. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +70 -2
  84. package/runtime/python/okstra_ctl/agent_activity.py +118 -35
  85. package/runtime/python/okstra_ctl/agent_invocation.py +19 -6
  86. package/runtime/python/okstra_ctl/agent_prompt_cli.py +65 -18
  87. package/runtime/python/okstra_ctl/analysis_inputs.py +5 -4
  88. package/runtime/python/okstra_ctl/analysis_packet.py +81 -1
  89. package/runtime/python/okstra_ctl/approval_decisions.py +3 -2
  90. package/runtime/python/okstra_ctl/attempt_evidence.py +2 -2
  91. package/runtime/python/okstra_ctl/backfill.py +13 -10
  92. package/runtime/python/okstra_ctl/batch.py +2 -4
  93. package/runtime/python/okstra_ctl/build_tools.py +6 -3
  94. package/runtime/python/okstra_ctl/claim_reproduction.py +101 -0
  95. package/runtime/python/okstra_ctl/clarification_items.py +27 -13
  96. package/runtime/python/okstra_ctl/cmux.py +130 -52
  97. package/runtime/python/okstra_ctl/code_review_target.py +34 -8
  98. package/runtime/python/okstra_ctl/consumers.py +5 -4
  99. package/runtime/python/okstra_ctl/container.py +103 -8
  100. package/runtime/python/okstra_ctl/context_cost.py +2 -1
  101. package/runtime/python/okstra_ctl/contract_graph.py +497 -0
  102. package/runtime/python/okstra_ctl/contract_graph_cli.py +62 -0
  103. package/runtime/python/okstra_ctl/convergence.py +338 -17
  104. package/runtime/python/okstra_ctl/convergence_engine.py +10 -18
  105. package/runtime/python/okstra_ctl/convergence_provenance.py +58 -8
  106. package/runtime/python/okstra_ctl/convergence_store.py +55 -34
  107. package/runtime/python/okstra_ctl/design_prep.py +7 -4
  108. package/runtime/python/okstra_ctl/dispatch_core.py +35 -65
  109. package/runtime/python/okstra_ctl/dispatch_state.py +134 -59
  110. package/runtime/python/okstra_ctl/doctor.py +6 -3
  111. package/runtime/python/okstra_ctl/domain/worker_presentation.py +70 -9
  112. package/runtime/python/okstra_ctl/entrypoints/hosts.py +16 -30
  113. package/runtime/python/okstra_ctl/error_log_write.py +35 -30
  114. package/runtime/python/okstra_ctl/error_report.py +26 -1
  115. package/runtime/python/okstra_ctl/error_zip.py +27 -5
  116. package/runtime/python/okstra_ctl/execution_identity.py +3 -2
  117. package/runtime/python/okstra_ctl/execution_manifest.py +7 -4
  118. package/runtime/python/okstra_ctl/final_report_schema.py +2 -2
  119. package/runtime/python/okstra_ctl/fix_cycles.py +2 -2
  120. package/runtime/python/okstra_ctl/fixed_text.py +39 -0
  121. package/runtime/python/okstra_ctl/git_reconcile.py +41 -9
  122. package/runtime/python/okstra_ctl/handoff.py +5 -4
  123. package/runtime/python/okstra_ctl/i18n.py +4 -2
  124. package/runtime/python/okstra_ctl/implementation_direction.py +22 -14
  125. package/runtime/python/okstra_ctl/implementation_outcome.py +4 -7
  126. package/runtime/python/okstra_ctl/incremental_carry.py +2 -1
  127. package/runtime/python/okstra_ctl/incremental_scope.py +8 -3
  128. package/runtime/python/okstra_ctl/index.py +8 -11
  129. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +79 -7
  130. package/runtime/python/okstra_ctl/invocation.py +3 -6
  131. package/runtime/python/okstra_ctl/json_boundary.py +366 -0
  132. package/runtime/python/okstra_ctl/json_registry.py +10 -12
  133. package/runtime/python/okstra_ctl/jsonl.py +19 -2
  134. package/runtime/python/okstra_ctl/lead_events.py +33 -1
  135. package/runtime/python/okstra_ctl/listing.py +3 -3
  136. package/runtime/python/okstra_ctl/log_report.py +24 -2
  137. package/runtime/python/okstra_ctl/manager_cli.py +92 -7
  138. package/runtime/python/okstra_ctl/manager_store.py +12 -10
  139. package/runtime/python/okstra_ctl/material.py +5 -1
  140. package/runtime/python/okstra_ctl/migrate.py +29 -25
  141. package/runtime/python/okstra_ctl/model_cli.py +3 -15
  142. package/runtime/python/okstra_ctl/model_io_cli.py +1051 -0
  143. package/runtime/python/okstra_ctl/mutation_probe.py +13 -4
  144. package/runtime/python/okstra_ctl/pane_reclaim.py +3 -2
  145. package/runtime/python/okstra_ctl/paths.py +9 -0
  146. package/runtime/python/okstra_ctl/plan_items.py +115 -4
  147. package/runtime/python/okstra_ctl/plan_items_cli.py +513 -18
  148. package/runtime/python/okstra_ctl/pr_template.py +3 -2
  149. package/runtime/python/okstra_ctl/project_meta.py +5 -7
  150. package/runtime/python/okstra_ctl/recap.py +5 -4
  151. package/runtime/python/okstra_ctl/reconcile.py +21 -27
  152. package/runtime/python/okstra_ctl/registry/host_discovery.py +3 -2
  153. package/runtime/python/okstra_ctl/registry/provider_registry.py +3 -2
  154. package/runtime/python/okstra_ctl/render.py +26 -15
  155. package/runtime/python/okstra_ctl/render_final_report.py +3 -2
  156. package/runtime/python/okstra_ctl/report_assembly.py +172 -17
  157. package/runtime/python/okstra_ctl/report_finalize.py +7 -10
  158. package/runtime/python/okstra_ctl/report_html/render.py +3 -2
  159. package/runtime/python/okstra_ctl/report_language.py +3 -2
  160. package/runtime/python/okstra_ctl/report_markdown.py +13 -1
  161. package/runtime/python/okstra_ctl/report_narrative.py +40 -8
  162. package/runtime/python/okstra_ctl/report_synthesis_packet.py +518 -0
  163. package/runtime/python/okstra_ctl/report_views.py +3 -2
  164. package/runtime/python/okstra_ctl/rollup.py +65 -4
  165. package/runtime/python/okstra_ctl/run.py +159 -56
  166. package/runtime/python/okstra_ctl/run_audit.py +3 -2
  167. package/runtime/python/okstra_ctl/run_context.py +6 -9
  168. package/runtime/python/okstra_ctl/run_index_row.py +2 -8
  169. package/runtime/python/okstra_ctl/schedule_semantics.py +5 -2
  170. package/runtime/python/okstra_ctl/schema_excerpt.py +4 -2
  171. package/runtime/python/okstra_ctl/session_transcript.py +27 -1
  172. package/runtime/python/okstra_ctl/set_work_status.py +64 -38
  173. package/runtime/python/okstra_ctl/stage_fix_carry.py +4 -2
  174. package/runtime/python/okstra_ctl/stage_map.py +26 -6
  175. package/runtime/python/okstra_ctl/stage_targets.py +3 -4
  176. package/runtime/python/okstra_ctl/team.py +2 -1
  177. package/runtime/python/okstra_ctl/team_reconcile.py +11 -2
  178. package/runtime/python/okstra_ctl/time_report.py +51 -4
  179. package/runtime/python/okstra_ctl/usage_identity.py +2 -1
  180. package/runtime/python/okstra_ctl/usage_report.py +58 -4
  181. package/runtime/python/okstra_ctl/user_response.py +1431 -66
  182. package/runtime/python/okstra_ctl/wizard.py +11 -44
  183. package/runtime/python/okstra_ctl/work_categories.py +3 -2
  184. package/runtime/python/okstra_ctl/worker_prompt_body.py +18 -7
  185. package/runtime/python/okstra_ctl/worker_prompt_contract.py +3 -2
  186. package/runtime/python/okstra_ctl/worker_runner.py +14 -12
  187. package/runtime/python/okstra_ctl/workflow.py +2 -1
  188. package/runtime/python/okstra_ctl/worktree.py +3 -2
  189. package/runtime/python/okstra_ctl/wrapper_status.py +4 -2
  190. package/runtime/python/okstra_ctl/write_policy.py +4 -2
  191. package/runtime/python/okstra_token_usage/antigravity.py +39 -12
  192. package/runtime/python/okstra_token_usage/collect.py +90 -38
  193. package/runtime/python/okstra_token_usage/grok.py +127 -0
  194. package/runtime/schemas/final-report-v2.0.schema.json +9 -0
  195. package/runtime/schemas/final-report-v3.0.schema.json +9 -0
  196. package/runtime/schemas/report-synthesis-packet-v1.0.schema.json +140 -0
  197. package/runtime/skills/okstra-brief-gen/SKILL.md +9 -7
  198. package/runtime/skills/okstra-code-review/SKILL.md +21 -11
  199. package/runtime/skills/okstra-container-build/SKILL.md +18 -18
  200. package/runtime/skills/okstra-inspect/SKILL.md +12 -11
  201. package/runtime/skills/okstra-inspect/facets/error-zip.md +8 -8
  202. package/runtime/skills/okstra-inspect/facets/errors.md +2 -2
  203. package/runtime/skills/okstra-inspect/facets/history.md +9 -14
  204. package/runtime/skills/okstra-inspect/facets/logs.md +2 -2
  205. package/runtime/skills/okstra-inspect/facets/recap.md +5 -5
  206. package/runtime/skills/okstra-inspect/facets/report.md +6 -10
  207. package/runtime/skills/okstra-inspect/facets/status.md +9 -8
  208. package/runtime/skills/okstra-inspect/facets/time.md +3 -3
  209. package/runtime/skills/okstra-manager/SKILL.md +16 -14
  210. package/runtime/skills/okstra-memory/SKILL.md +3 -3
  211. package/runtime/skills/okstra-pr-gen/SKILL.md +5 -4
  212. package/runtime/skills/okstra-rollup/SKILL.md +6 -16
  213. package/runtime/skills/okstra-run/SKILL.md +7 -7
  214. package/runtime/skills/okstra-schedule-gen/SKILL.md +21 -17
  215. package/runtime/skills/okstra-setup/SKILL.md +21 -13
  216. package/runtime/skills/okstra-setup/references/project-config.md +2 -2
  217. package/runtime/skills/okstra-usage/SKILL.md +10 -10
  218. package/runtime/skills/okstra-user-response/SKILL.md +78 -107
  219. package/runtime/templates/report-writer-prompt-preamble.md +17 -1
  220. package/runtime/templates/reports/schedule.template.md +4 -4
  221. package/runtime/templates/worker-error-contract.md +17 -29
  222. package/runtime/validators/validate-run.py +379 -63
  223. package/runtime/validators/validate_session_conformance.py +43 -7
@@ -40,10 +40,10 @@ No sub-command writes outside this machine.
40
40
  Run once before any sub-command.
41
41
 
42
42
  ```bash
43
- okstra preflight --runtime claude-code --json
43
+ okstra preflight --runtime claude-code
44
44
  ```
45
45
 
46
- The project check only sees the cwd of the Bash call. For a project that is not the cwd (a sibling repo, a monorepo subdir, or a project named in the request), `ok:false` is a false negative, not a missing setup do not stop immediately; retry with `okstra preflight --runtime claude-code --cwd <that-dir> --json` (`--cwd` is the sanctioned way to target a project without a leading `cd`). Only when that also returns `ok:false` do you guide the user to `/okstra-setup` and stop. Then use `projectRoot` as a literal value, and pass it to the sub-command CLIs that accept it (`recap`, `context-cost`, etc.) via `--cwd`/`--project-root <projectRoot>`.
46
+ The project check only sees the cwd of the Bash call. For a project that is not the cwd (a sibling repo, a monorepo subdir, or a project named in the request), `Okstra preflight: failed` can be a false negative rather than missing setup. Retry with `okstra preflight --runtime claude-code --cwd <that-dir>` (`--cwd` is the sanctioned way to target a project without a leading `cd`). Only when that also reports `Okstra preflight: failed` do you show `Reason` and `Recovery`, then stop. On `Okstra preflight: ready`, carry `Project root` as a literal value and pass it to the sub-command CLIs that accept it (`recap`, `context-cost`, etc.) via `--cwd`/`--project-root <projectRoot>`.
47
47
 
48
48
  ## intent routing
49
49
 
@@ -62,10 +62,10 @@ Many facets accept the following target forms.
62
62
  A bare task-id uses the shared resolver.
63
63
 
64
64
  ```bash
65
- okstra resolve-task-key <task-id> --project-root <projectRoot> --json
65
+ okstra model-io task-selection-input --project-root <projectRoot> --task-ref <task-id>
66
66
  ```
67
67
 
68
- Handling `matches[]`:
68
+ Handling the fixed text projection's `Match count` and repeated task lines:
69
69
 
70
70
  - 0: say it cannot be found; do not guess.
71
71
  - 1: use that `taskKey`.
@@ -75,7 +75,7 @@ Handling `matches[]`:
75
75
 
76
76
  ### Project overview
77
77
 
78
- Read `.okstra/discovery/task-catalog.json`. Do not re-open individual manifests for the overview. The catalog is the projected source.
78
+ Run `okstra model-io status-input --project-root <projectRoot>`. Its fixed text task blocks are the projected source.
79
79
 
80
80
  Sort: `updatedAt` desc, then `taskKey`.
81
81
 
@@ -91,7 +91,7 @@ Keep the table narrow.
91
91
 
92
92
  ### Specific task
93
93
 
94
- For a single task's detail, check the catalog first, then if needed read `.okstra/tasks/<group>/<id>/task-manifest.json`, `history/timeline.json`, and the latest run manifest.
94
+ For a single task's detail, run `okstra model-io status-input --project-root <projectRoot> --task-ref <task-key>` and use its named lines.
95
95
 
96
96
  Information to show:
97
97
 
@@ -117,7 +117,7 @@ Allowed values:
117
117
  - `blocked`
118
118
  - `done`
119
119
 
120
- Procedure: update via a single `okstra set-work-status <token> <status> [--note <text>] --project-root <projectRoot> --json` call — do not edit the manifest by hand. On `stage:"ambiguous"`, re-ask with `matches[]`; on `stage:"not-found"`, answer that it cannot be found.
120
+ Procedure: update via a single `okstra set-work-status <token> <status> [--note <text>] --project-root <projectRoot> --text` call — do not edit the manifest by hand. On `Stage: ambiguous`, re-ask with the listed `Match` values; on `Stage: not-found`, answer that it cannot be found.
121
121
 
122
122
  When `workStatus` is absent in a read display, infer it from the lifecycle state, but do not back-fill on read alone.
123
123
 
@@ -128,20 +128,15 @@ First branch: distinguish re-run from resume.
128
128
  - Re-run: create a new run from previous run parameters. A new run-seq is created.
129
129
  - Resume: continue an interrupted existing run. No new run-seq is created.
130
130
 
131
- If the catalog is absent, fall back to the `.okstra/tasks/*/*/task-manifest.json` glob. The disk manifest is the source of truth.
131
+ Run `okstra model-io history-input --project-root <projectRoot>` for project history, or add `--task-ref <task-key>` for one task.
132
132
 
133
- Re-run extracts `projectId`, `taskGroup`, `taskId`, `taskType`, `taskBriefPath`, workers, relatedTasks, model overrides, and so on from the source run-manifest to assemble the command. `implementation`'s `--base-ref` is not in the run-manifest but in the worktree registry, so ask for it as the situation requires.
133
+ Re-run obtains `projectId`, `taskGroup`, `taskId`, `taskType`, `taskBriefPath`, workers, related tasks, model overrides, and executor provider through `okstra model-io rerun-input --run-manifest <runManifestPath>`. Omit `implementation`'s `--base-ref` to reuse a registration; if launch reports that a base is required, ask the user.
134
134
 
135
135
  Resume checks `latestResumeCommandPath` or the timeline entry's `resumeCommandPath`, and if the file exists, guides/runs `bash <resume-command-path>`. If the path is empty or the file is missing, declare "no resume" and guide to history.3 (re-run).
136
136
 
137
137
  ## report
138
138
 
139
- report path resolution priority:
140
-
141
- 1. `latestReportRecordPath` in `.okstra/discovery/task-catalog.json`
142
- 2. `latestReportRecordPath` in the direct `task-manifest.json`
143
- 3. a specific run's `reportPath` in `history/timeline.json`
144
- 4. specific task-type fallback: `runs/<task-type>/reports/final-report-*.data.json`, including stage-isolated paths. Render a full reading copy on demand with `okstra render-final-report <that data.json>`.
139
+ Run `okstra model-io report-input --project-root <projectRoot> --task-ref <task-key>` for the latest report. For a specific run, use the `Report` line from `okstra model-io history-input --project-root <projectRoot> --task-ref <task-key>`. Render a full reading copy on demand with `okstra render-final-report <that data.json>`.
145
140
 
146
141
  Match read depth to the request (a final report is 300+ lines / 50K+ tokens). For summary/conclusion/pass questions ("summary", "just the key points", "conclusion", "did it pass?"), do not read the whole thing — read only the verdict in the `runs/<task-type-segment>/status/final-<task-type-segment>-<NNN>.status` (stage-isolated: `runs/<task-type-segment>/stage-<N>/status/`) sidecar plus the report's leading summary block. Ingest the whole file only for "the whole thing / read it all / full body". If a completion signal exists but the file does not, report it as a missing report; if it is not yet complete, show the current status and workStatus.
147
142
 
@@ -150,7 +145,7 @@ Match read depth to the request (a final report is 300+ lines / 50K+ tokens). Fo
150
145
  The CLI does the time computation. The AI does not recompute duration by hand.
151
146
 
152
147
  ```bash
153
- okstra time-report <task-key> --project-root <projectRoot> --json
148
+ okstra time-report <task-key> --project-root <projectRoot> --text
154
149
  ```
155
150
 
156
151
  Convert every `*Ms` to `HH:MM:SS` for display. `CPU sum` is the overlapping cost of lead and workers time combined, not wall-clock. Show wall-clock from `perRunWallClock` only when the user explicitly asks. For `by stage`/`per stage`/`which stage took longest`, the task-type view (the By task type table) is the default answer — do not treat it as 'not measurable'. Render the intra-run `phaseTimelines` only on an explicit request like 'Phase 1–7' / 'which phase', and when it is empty, mention it only as a footnote rather than a headline.
@@ -178,7 +173,7 @@ Interpretation points:
178
173
  wrapper sidecar log inventory:
179
174
 
180
175
  ```bash
181
- okstra log-report --project-root <projectRoot> --json
176
+ okstra log-report --project-root <projectRoot> --text
182
177
  ```
183
178
 
184
179
  Scans `.okstra/tasks/**/runs/*/prompts/*.log`. Does not delete. The cleanup command merely presents a dry-run and `-delete` pair as fenced bash.
@@ -190,21 +185,21 @@ Deleting an active run's log loses the live trace, so recommend checking `status
190
185
  Aggregate task error logs into a markdown report.
191
186
 
192
187
  ```bash
193
- okstra error-report <task-key> --project-root <projectRoot>
188
+ okstra error-report <task-key> --project-root <projectRoot> --text
194
189
  ```
195
190
 
196
- Read `reportPath`, totals, byPhase, byAgent, parseSkipped from the stdout JSON and summarize. If `reportPath` is absent and errorCount is 0, say there are no recorded error logs. Do not hide `parseSkipped > 0`.
191
+ Read the fixed `Report path`, total, phase, agent, and parse-skipped labels and summarize. If the report path is `-` and total errors is 0, say there are no recorded error logs. Do not hide a nonzero parse-skipped count.
197
192
 
198
193
  ## error-zip
199
194
 
200
195
  Bundle the machine's cross-project okstra errors into an anonymized zip.
201
196
 
202
- For the output path, recommend `lastOutputPath` from `~/.okstra/error-zip.json` first, and if absent, propose `~/okstra-error-feedback-<YYYY-MM-DD>.zip`.
197
+ Run `okstra model-io error-zip-input`. Recommend its `Previous output path` first when present; otherwise propose `~/okstra-error-feedback-<YYYY-MM-DD>.zip`.
203
198
 
204
199
  Run:
205
200
 
206
201
  ```bash
207
- okstra error-zip --out <path>
202
+ okstra error-zip --out <path> --text
208
203
  ```
209
204
 
210
205
  Summary fields:
@@ -222,12 +217,14 @@ At the end, guide the user to build a brief with the error-feedback variant of `
222
217
 
223
218
  The default is artifact mode. It builds the before/after summary and answers questions using only `.okstra/` artifacts.
224
219
 
225
- assemble:
220
+ Read the fixed recap projection:
226
221
 
227
222
  ```bash
228
- okstra recap assemble <task-key> --project-root <projectRoot>
223
+ okstra model-io recap-input --project-root <projectRoot> --task-ref <task-key>
229
224
  ```
230
225
 
226
+ Use the emitted `Run count` and repeated `Transition` fields in order. Do not parse recap JSON or open recap state files directly.
227
+
231
228
  record:
232
229
 
233
230
  ```bash
@@ -13,7 +13,8 @@ Use this to bundle okstra tasks across multiple projects into a single manager-o
13
13
  ## Execution Rules
14
14
 
15
15
  1. Every command starts with the literal `okstra`. Do not wrap it in shell variables, `$(...)`, `&&`, `eval`, or a leading env assignment.
16
- 2. JSON stdout is the source of truth. Do not reconstruct manager state or child launch args from docs/memory.
16
+ 2. The fixed CLI fields are the source of truth. Do not reconstruct manager state or child launch args from docs/memory.
17
+ Nested project, manifest, child, snapshot, and directive values use numbered count/name/value rows; carry every returned row.
17
18
  3. `--workspace-root` is owned by the Node wrapper. The CLI rejects it if the user passes it.
18
19
  4. `new project`'s `--project-root` must be an already-existing directory. It performs setup-equivalent registration only when there is no `.okstra/project.json` inside it.
19
20
  5. The public child task identity is `project-id:task-group:task-id`. The `new task --task` example shows the full key form first.
@@ -22,16 +23,16 @@ Use this to bundle okstra tasks across multiple projects into a single manager-o
22
23
  ## Command Surface
23
24
 
24
25
  ```bash
25
- okstra manager init --manager-id <manager-id> --json
26
- okstra manager discover-projects --json
27
- okstra manager new project --manager-id <manager-id> --project-id <project-id> --project-root <abs-path> [--role <role>] [--tag <tag>] --json
28
- okstra manager new task-group --manager-id <manager-id> --task-group <task-group> --json
29
- okstra manager new task --manager-id <manager-id> --task-group <task-group> --task-id <task-id> [--task <project-id:task-group:task-id> ...] [--objective <text>] [--common-brief <path>] [--progress-mode <manual|auto>] --json
30
- okstra manager task assign --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --project-id <project-id> [--child-task-id <child-task-id>] [--role <role>] [--tag <tag>] [--assignment <text>] --json
31
- okstra manager task note --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --scope <shared|project> [--project-id <project-id>] --body <text> --json
32
- okstra manager task sync --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --json
33
- okstra manager task status --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --json
34
- okstra manager task run --manager-id <manager-id> --project-id <project-id> --task-group <task-group> --task-id <task-id> [--child-task-id <child-task-id>] --json
26
+ okstra manager init --manager-id <manager-id>
27
+ okstra manager discover-projects
28
+ okstra manager new project --manager-id <manager-id> --project-id <project-id> --project-root <abs-path> [--role <role>] [--tag <tag>]
29
+ okstra manager new task-group --manager-id <manager-id> --task-group <task-group>
30
+ okstra manager new task --manager-id <manager-id> --task-group <task-group> --task-id <task-id> [--task <project-id:task-group:task-id> ...] [--objective <text>] [--common-brief <path>] [--progress-mode <manual|auto>]
31
+ okstra manager task assign --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --project-id <project-id> [--child-task-id <child-task-id>] [--role <role>] [--tag <tag>] [--assignment <text>]
32
+ okstra manager task note --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --scope <shared|project> [--project-id <project-id>] --body <text>
33
+ okstra manager task sync --manager-id <manager-id> --task-group <task-group> --task-id <task-id>
34
+ okstra manager task status --manager-id <manager-id> --task-group <task-group> --task-id <task-id>
35
+ okstra manager task run --manager-id <manager-id> --project-id <project-id> --task-group <task-group> --task-id <task-id> [--child-task-id <child-task-id>]
35
36
  ```
36
37
 
37
38
  ## Storage Model
@@ -56,13 +57,13 @@ A segment whose slug is empty (e.g. a non-ASCII task-group/task-id) uses a `u-<s
56
57
 
57
58
  ## Child launch
58
59
 
59
- `task run` does not run the child work directly; it prepares a launch packet. The key fields of the returned packet:
60
+ `task run` does not run the child work directly; it prepares a launch packet. The key fixed fields of the returned packet:
60
61
 
61
- - `taskKey`: the child's `project-id:task-group:task-id` (the public child-identity key — also recorded on the `child-launch-prepared` event)
62
- - `backend`: `tmux-child-lead` if `$TMUX` is present, otherwise `subagent-child-lead`
63
- - `workerDispatchBackend`: always `subagent` in v1
64
- - `projectRoot`: the child project root
65
- - `contextPath`: the manager child context markdown
66
- - `runArgs`: the `okstra run ... --directive "Read manager child context: ..."` args for the host launcher to use
62
+ - `Task key`: the child's `project-id:task-group:task-id` (the public child-identity key — also recorded on the `child-launch-prepared` event)
63
+ - `Backend`: `tmux-child-lead` if `$TMUX` is present, otherwise `subagent-child-lead`
64
+ - `Worker dispatch backend`: always `subagent` in v1
65
+ - `Project root`: the child project root
66
+ - `Context path`: the manager child context markdown
67
+ - every numbered `Run arg N`: the ordered `okstra run ... --directive "Read manager child context: ..."` arguments for the host launcher to use
67
68
 
68
69
  When packet creation succeeds, that child launch's status in `children.json` is updated to `prepared`, and a `child-launch-prepared` is appended to `events.jsonl`. On failure it does not modify the project-local task state.
@@ -51,7 +51,7 @@ Every memory entry belongs to a project-group. Pick the group before storing or
51
51
  Enumerate existing groups:
52
52
 
53
53
  ```bash
54
- okstra memory groups --json
54
+ okstra memory groups
55
55
  ```
56
56
 
57
57
  Recommendations:
@@ -108,7 +108,7 @@ okstra memory show "<memory-id>"
108
108
  okstra memory archive "<memory-id>"
109
109
  ```
110
110
 
111
- Prefer `--json` when you need to parse IDs. Show the user only a short summary plus the entry id/path.
111
+ Read IDs from the fixed text rows. Show the user only a short summary plus the entry id/path.
112
112
 
113
113
  ## Output rules
114
114
 
@@ -31,9 +31,9 @@ A 3-option picker via `AskUserQuestion`:
31
31
 
32
32
  ## Mode A — Generate PR
33
33
 
34
- 1. Pick a template: `okstra pr template list --json`. If empty, use the bundled default. Carry the chosen name as `<template>` (`default` for the bundled one).
35
- 2. Pick the base branch: `okstra pr branches --json`. 3-option from the top `recommended` entries plus `Enter directly`. Carry the choice as `<base>`.
36
- 3. Generation bundle: `okstra pr gen --base <base> --template <template> --json` `{base, currentBranch, templateName, template, commits, diffStat}`. Then **read the real diff honestly** (SSOT): `git diff <base>...HEAD` (large diffs section by section). Fill the placeholders from the diff and commits, describing **only actual changes**. Mark a checklist box `[x]` only when the diff supports it (tests touched → tests box, docs touched → docs box). If `commits`/`diffStat` are empty, say there is nothing to describe and stop. **Never append AI trailers/footers.**
34
+ 1. Pick a template: `okstra pr template list`. If the numbered `Templates` rows are empty, use the bundled default. Carry the chosen name as `<template>` (`default` for the bundled one).
35
+ 2. Pick the base branch: `okstra pr branches`. Build a 3-option picker from the numbered `Recommended` rows plus `Enter directly`. Carry the choice as `<base>`.
36
+ 3. Generation bundle: `okstra pr gen --base <base> --template <template>`. Read the fixed `Base`, `Current branch`, `Template name`, `Commits`, `Diff stat`, and `Template` sections. Then **read the real diff honestly** (SSOT): `git diff <base>...HEAD` (large diffs section by section). Fill the placeholders from the diff and commits, describing **only actual changes**. Mark a checklist box `[x]` only when the diff supports it (tests touched → tests box, docs touched → docs box). If `Commits` or `Diff stat` is empty, say there is nothing to describe and stop. **Never append AI trailers/footers.**
37
37
  4. Identifier allowlist for the title and body: only repo-relative source paths (optionally `path:line`), symbol names present in the diff, branch names / commit subjects / SHAs, and issue-tracker ticket ids the reviewer can open. okstra's own artifact identifiers are out of the allowlist — report item ids (`F-001`, `C-001`, `R-001`, `D-0001`, `PREP-001`), run artifact names and their `<task-type>-<seq>` suffixes, phase/stage/worker labels (`final-verification`, `stage-2`, `codex-worker`), and any path under `.okstra/`. They resolve to nothing for a reviewer; restate the substance in code terms instead of citing the id.
38
38
  5. Output and offer to create the PR: print the filled PR body as a single fenced markdown block. Ask whether to open a PR. **Only on an explicit yes**: write the body to a temp file and run `gh pr create --base <base> --title "<title>" --body-file <path>`. If `gh` is missing or unauthenticated (`gh auth status` fails), leave the text in chat and give manual-creation guidance. **No push/PR creation without the user's confirmation.**
39
39
 
@@ -37,10 +37,11 @@ Do not use it when:
37
37
  A single Bash call starting with the literal `okstra` token (not wrapped in `if`/`eval`/`$(...)`/`VAR=`/`||`/`&&`/`npx` fallback):
38
38
 
39
39
  ```bash
40
- okstra preflight --runtime claude-code --json
40
+ okstra preflight --runtime claude-code
41
41
  ```
42
42
 
43
- `ok:false` → point to `/okstra-setup` and stop. If `ok:true`, carry `projectRoot` as a literal string and proceed.
43
+ On `Okstra preflight: ready`, carry `Project root` as a literal string. On
44
+ `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop.
44
45
 
45
46
  ## scope resolution
46
47
 
@@ -51,26 +52,26 @@ okstra preflight --runtime claude-code --json
51
52
  ## CLI call
52
53
 
53
54
  ```bash
54
- okstra rollup --task-group <group> --project-root <projectRoot> --json
55
+ okstra rollup --task-group <group> --project-root <projectRoot> --text
55
56
  ```
56
57
 
57
- For the whole project, drop `--task-group`. The output is always JSON, and **all times are raw milliseconds**.
58
+ For the whole project, drop `--task-group`. The output is fixed, ordered label/value rows, and **all times are raw milliseconds**.
58
59
 
59
60
  ## Interpreting the output
60
61
 
61
- Top level:
62
+ Fixed fields:
62
63
 
63
- - `taskGroup` the scope (`null` = whole project), `taskCount` number of tasks.
64
- - `tasks[]` per task: `taskKey, taskGroup, taskId, taskType, workCategory, workStatus, currentPhase, currentPhaseState, nextRecommendedPhase, latestRunStatus, updatedAt, reportPath, runCount, cpuSumMs, wallClockMs, errorCount`.
65
- - `nextRecommendedPhase` is an object `{phase, status, rationale}`, not a string. Print `phase`, or `--` when it is empty. Never interpolate the object itself.
66
- - `totals` `runs, cpuSumMs, wallClockMs, errors`, plus `byWorkStatus` / `byWorkCategory` / `byCurrentPhase` / `byTaskType` (each a `{value: count}` map).
64
+ - `Task group` and `Task count` identify the scope.
65
+ - Numbered `Tasks` rows carry task identity, status, phase, next phase, report path, run count, CPU, wall-clock, and error count.
66
+ - `Totals runs`, `Totals CPU sum ms`, `Totals wall clock ms`, and `Totals errors` are the aggregate values.
67
+ - Numbered `Work status`, `Work category`, `Current phase`, and `Task type` rows carry the aggregate distributions.
67
68
 
68
69
  Numeric meanings (must observe):
69
70
 
70
- - `runCount` is the **total number of runs** in the timeline. `cpuSumMs`/`wallClockMs` reflect only runs that reached Phase 7 usage, so they can be `0` even when `runCount > 0`.
71
- - `cpuSumMs` is the **CPU sum** of the overlapping lead + workers, not wall-clock. Label it "CPU", and show wall-clock as `wallClockMs` only when the user explicitly asks.
72
- - `reportPath` is project-relative and may be empty (a task with no report yet).
73
- - If `taskCount` is `0`, say there are no okstra tasks in that scope and stop.
71
+ - `Run count` is the **total number of runs** in the timeline. CPU and wall-clock rows reflect only runs that reached Phase 7 usage, so they can be `0` even when run count is positive.
72
+ - `CPU sum ms` is the **CPU sum** of the overlapping lead + workers, not wall-clock.
73
+ - `Report path` is project-relative and may be `-` for a task with no report yet.
74
+ - If `Task count` is `0`, say there are no okstra tasks in that scope and stop.
74
75
 
75
76
  ## Render
76
77
 
@@ -37,10 +37,14 @@ Do not use it when:
37
37
  Resolve `<host-runtime>` from the executing harness: Claude Code → `claude-code`, Codex → `codex`, Antigravity CLI → `antigravity`, and another adapter host → `external`. This is a host capability, not a `PATH` inference or worker-provider choice. The lead provider is derived from this value and cannot be selected independently. Then make one Bash call:
38
38
 
39
39
  ```bash
40
- okstra preflight --runtime <host-runtime> --json
40
+ okstra preflight --runtime <host-runtime>
41
41
  ```
42
42
 
43
- If there is no runtime or project setup (`ok:false`), point the user to `/okstra-setup` and stop. Do not create an `export PYTHONPATH`.
43
+ On `Okstra preflight: failed`, show `Reason`, `Recovery`, `Runtime readiness`,
44
+ and every repeated `Readiness check` line, then stop. On
45
+ `Okstra preflight: ready`, require `Runtime readiness: ready`, carry the fixed
46
+ `Project root` line, and read the `Relay contract` path. Do not create an
47
+ `export PYTHONPATH`.
44
48
 
45
49
  ## Bash invocation rule
46
50
 
@@ -187,7 +191,7 @@ This picker is authored by the skill, so it is separate from the wizard-option-a
187
191
 
188
192
  When a `PrepareError` such as `Recorded stage SHAs no longer match the git history` appears, do not fix the registry/consumers by hand.
189
193
 
190
- 1. Run the `okstra git-reconcile ... --check --json` printed in the error message verbatim.
194
+ 1. Run the `okstra git-reconcile ... --check --text` printed in the error message verbatim.
191
195
  2. For each confirm item, ask the user for the current branch tip, a different ref, or abort.
192
196
  3. Run `okstra git-reconcile ... --apply --stage <N> --use-ref <ref>` with the chosen ref.
193
197
  4. Retry the failed render-bundle with the same arguments.
@@ -35,16 +35,16 @@ Do not use it for single-task status analysis or phase execution. Use `okstra-in
35
35
  Run one literal-token preflight call:
36
36
 
37
37
  ```bash
38
- okstra preflight --runtime claude-code --json
38
+ okstra preflight --runtime claude-code
39
39
  ```
40
40
 
41
- On `ok: false`, point the user to `/okstra-setup` and stop. Otherwise:
42
-
43
- 1. Read `.okstra/discovery/task-catalog.json`.
44
- 2. Resolve an explicit task-group from the invocation or host request. If none is unambiguous, ask the user to choose; never guess.
45
- 3. Lowercase the token and strip characters outside `[a-z0-9]`.
46
- 4. Apply the same transform to each catalog `taskGroupPathSegment` and compare only those normalized values.
47
- 5. Read each matched `task-manifest.json`; it is authoritative when the catalog is stale.
41
+ On `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. On
42
+ `Okstra preflight: ready`, carry the fixed `Project root` line. Resolve an
43
+ explicit task-group from the invocation or host request. If none is unambiguous,
44
+ run `okstra model-io task-selection-input --project-root <projectRoot>` and ask
45
+ the user to choose from the fixed `Task` rows; never guess. Then run
46
+ `okstra model-io schedule-input --project-root <projectRoot> --task-group <group>`
47
+ and use only its fixed task metadata rows.
48
48
 
49
49
  On zero matches, report that the task group was not found and do not create a file.
50
50
 
@@ -63,21 +63,18 @@ Do not render `workStatus` as the detailed task status. The per-task `Status` va
63
63
  For every candidate task, call:
64
64
 
65
65
  ```bash
66
- okstra stage-map <task-key> --json
66
+ okstra stage-map <task-key> --text
67
67
  ```
68
68
 
69
- The successful response has this boundary shape:
70
-
71
- ```text
72
- { ok, taskKey, taskRoot, state, sourcePlanPath,
73
- stages:[{stage_number,title,depends_on,step_count}], doneStages:[int] }
74
- ```
69
+ The successful fixed response carries `Status`, `Task key`, `Task root`, `State`,
70
+ `Source plan path`, and lossless numbered `Stages`, `Done stages`, and `Planning`
71
+ count/name/value rows.
75
72
 
76
73
  Handle each result explicitly:
77
74
 
78
- - `state: ready`: use exactly `sourcePlanPath`; do not pick a report by mtime or `latestReportRecordPath`. Select only `stages doneStages`.
79
- - `state: missing`: record an empty source and empty stage sets, mark the task `[NEEDS-PLANNING]`, and emit no forward Work Breakdown, Gantt, or day total for it.
80
- - `ok: false` or another state: stop before drafting and report the structured `stage` and `reason`. A corrupt or conflicting source must never fall back to a guessed report.
75
+ - `Status: ready`, `State: ready`: use exactly `Source plan path`; do not pick a report by mtime or `latestReportRecordPath`. Select only stages not present in the done-stage rows.
76
+ - `Status: ready`, `State: missing`: record an empty source and empty stage sets, mark the task `[NEEDS-PLANNING]`, and emit no forward Work Breakdown, Gantt, or day total for it.
77
+ - `Status: error` or another state: stop before drafting and report `Failure stage` and `Failure reason`. A corrupt or conflicting source must never fall back to a guessed report.
81
78
 
82
79
  A valid selected set is dependency-closed: every transitive prerequisite of a selected stage is either also selected or present in `doneStages`. Completed prerequisites remain evidence only and are never scheduled forward.
83
80
 
@@ -49,7 +49,7 @@ After `okstra install`, every subsequent command must begin with the literal `ok
49
49
  Allowed forms:
50
50
 
51
51
  ```bash
52
- okstra check-project --json
52
+ okstra preflight
53
53
  okstra setup --yes --project-root /abs/project --project-id my-project
54
54
  okstra doctor --runtime claude-code
55
55
  ```
@@ -62,22 +62,22 @@ Forms to avoid:
62
62
  - `$(...)` command substitution
63
63
  - okstra calls wrapped in `if`, `&&`, `||`
64
64
 
65
- Because `okstra <subcmd>` bootstraps its own Python path, do not use `okstra paths --shell` in this skill. If you need a path, run `okstra paths --json` as a separate call and read the JSON value.
65
+ Because `okstra <subcmd>` bootstraps its own Python path, do not use `okstra paths --shell` in this skill. If you need the okstra home, run `okstra paths --field home` as a separate call and carry the printed path.
66
66
 
67
67
  ## Project root resolution
68
68
 
69
69
  Run first:
70
70
 
71
71
  ```bash
72
- okstra check-project --json
72
+ okstra preflight
73
73
  ```
74
74
 
75
75
  Handle the result:
76
76
 
77
- - `ok: true`: already a registered project. Show `projectRoot`, `projectJsonPath`, `projectId` to the user and confirm whether to keep it.
78
- - `ok: false`, `stage: "resolve"`: get an absolute project root from the user and re-run `okstra check-project --cwd /abs/path --json`.
79
- - `ok: false`, `stage: "project_json_missing"`: proceed with the normal create path.
80
- - any other failure stage: show the JSON `reason` verbatim and follow the recovery the source names.
77
+ - `Okstra preflight: ready`: already a registered project. Show `Project root`, `Project JSON`, and `Project ID` to the user and confirm whether to keep it.
78
+ - `Okstra preflight: failed` with `Stage: resolve`: get an absolute project root from the user and re-run `okstra preflight --cwd /abs/path`.
79
+ - `Okstra preflight: failed` with `Stage: project_json_missing`: proceed with the normal create path.
80
+ - any other failure stage: show `Reason` verbatim and follow `Recovery`.
81
81
 
82
82
  ## Create or keep project.json
83
83
 
@@ -11,14 +11,15 @@ digest (`okstra-rollup`).
11
11
  Run preflight, resolve a positive day count (default 30), then call exactly once:
12
12
 
13
13
  ```bash
14
- okstra usage-report --days 30 --project-root <projectRoot> --json
14
+ okstra usage-report --days 30 --project-root <projectRoot> --text
15
15
  ```
16
16
 
17
17
  ## Render contract
18
18
 
19
- Render returned task-type rows and totals without recomputing them. Show Runs,
20
- Coverage, Raw tokens, Billable, Cost, CPU, and Wall. Surface unavailable reason
21
- counts and unmatched model names. Missing usage is excluded data, not zero usage.
19
+ Render the numbered `By task type` rows and fixed totals without recomputing them.
20
+ Show Runs, returned collection rate as Coverage, Raw tokens, Billable, Cost, CPU, and Wall. Surface numbered
21
+ unavailable-reason and unmatched-model rows. Missing usage is excluded data, not
22
+ zero usage.
22
23
 
23
24
  ## Boundaries
24
25
 
@@ -3,51 +3,69 @@
3
3
  ## Sources
4
4
 
5
5
  - Skill source: [`skills/okstra-user-response/SKILL.md`](../../../skills/okstra-user-response/SKILL.md)
6
- - Response core (CLI): [`scripts/okstra_ctl/user_response.py`](../../../scripts/okstra_ctl/user_response.py)
7
- - Node wrapper: [`src/commands/inspect/user-response.mjs`](../../../src/commands/inspect/user-response.mjs)
6
+ - Response core: [`scripts/okstra_ctl/user_response.py`](../../../scripts/okstra_ctl/user_response.py)
7
+ - Node wrapper: [`src/commands/inspect/user-response.mts`](../../../src/commands/inspect/user-response.mts)
8
8
 
9
9
  ## Purpose
10
10
 
11
- `okstra-user-response` answers the **unresolved clarification questions** an okstra run left behind (the open `C-*` rows under the final report's `## 1. Clarification Items`) **in-session**, and records those answers as a `runs/<type>/user-responses/` sidecar. The next `/okstra-run` auto-attaches this sidecar via `--clarification-response`.
11
+ `okstra-user-response` answers unresolved `C-*` clarification items and records explicit plan decisions without hand-editing a report or sidecar. The user selects or writes every answer. Publication changes only the user-owned `runs/<task-type>/user-responses/` sidecar.
12
12
 
13
- **Core principle the skill never picks an answer for the user.** It builds the option board — background, a self-contained question, the report's options with their impact, `Enter directly` — and the user alone picks from it; every `value` is what the user chose or typed. It does not call `write` until the user has explicitly confirmed (`confirmed`).
13
+ The model-facing reads are fixed text. Do not use the automation-compatible JSON reads to drive a conversation. Do not open the final-report record directly.
14
14
 
15
- **Second principle one question at a time.** Never batch two clarification items into one question, and never dump the whole open list at the user.
15
+ | Command | Purpose |
16
+ |---|---|
17
+ | `okstra user-response list-view --home <home> --project <projectId> --limit 3` | List tasks that still need clarification answers or a plan decision. |
18
+ | `okstra user-response show-view --report <reportPath> --project-root <projectRoot>` | Show open questions, choices, impact, approval context, plan candidates, and current state after validating project ownership. |
19
+ | `okstra user-response begin --report <reportPath> --task-key <taskKey>` | Open a typed transaction and return an opaque id. |
20
+ | `okstra user-response answer ...` | Add one validated answer to the draft. |
21
+ | `okstra user-response plan-decision ...` | Record an explicit plan decision. |
22
+ | `okstra user-response legacy-report-authoring ...` | Record contract 2.0 report-authoring permission. |
23
+ | `okstra user-response finalize --transaction <transaction>` | Merge and atomically publish the sidecar. |
16
24
 
17
- Distinguish it from starting a run (`okstra-run`), inspecting a finished task (`okstra-inspect`), and generating a brief (`okstra-brief-gen`).
25
+ The legacy `list` and `show` JSON commands remain for automation compatibility. They are not model-facing reads.
18
26
 
19
- ## Sub-commands
27
+ ## Flow
20
28
 
21
- | Sub-command | What it does |
22
- |---|---|
23
- | `list` | List tasks that still have approval-open clarification (newest report first) |
24
- | `show` | Expand one report's open `C-*` rows (statement + options + contextRefs) |
25
- | `write` | Record the collected answers (+ optional approval) as a `user-responses/` sidecar |
29
+ 1. Run `okstra preflight --runtime claude-code`. On `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. On `Okstra preflight: ready`, carry `Project root` and `Project ID`, then run `okstra paths --field home`.
30
+ 2. Select a task from `list-view`.
31
+ 3. Read only `show-view --report <reportPath> --project-root <projectRoot>` for report facts.
32
+ 4. Ask one open clarification at a time.
33
+ 5. Echo the complete response and require an explicit `confirmed` before opening a transaction.
34
+ 6. Begin the transaction, add answers and decisions, then finalize it.
26
35
 
27
- ## Preflight
36
+ Each `options[]` row displays `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`. Contract 3.0 additionally displays `reach`, `scopeEffects`, and row-level `approvalContext`. Show `scopeImpact`, `addedWork`, and `directionChange` in that order. If the view says `not stated in the report`, repeat that text and never infer a value.
28
37
 
29
- A single Bash call with the literal `okstra` token (not wrapped):
38
+ When the user selects a predefined option, pass only the fixed view's one-based option number. Python resolves that option's `disposition`, answer, reach, and scope effects from the validated report:
30
39
 
31
40
  ```bash
32
- okstra preflight --runtime claude-code --json
41
+ okstra user-response answer --transaction <transaction> --clarification-id <C-NNN> --kind <kind> --option-number <N>
33
42
  ```
34
43
 
35
- `ok:true` carry `projectRoot` and `projectId` as literals. `ok:false` point to `/okstra-setup` and stop (retry a specific directory with `--cwd <dir>` a leading `cd` breaks the permission match). Then resolve home once: `okstra paths --field home` → paste it literally into `--home`.
44
+ Every value, rationale, and reason body file must be a regular file under `<projectRoot>/.okstra/tmp/user-response/`; external files and symbolic links are rejected. For direct input, write the user's exact words there and use the mutually exclusive direct form:
36
45
 
37
- ## Flow
46
+ ```bash
47
+ okstra user-response answer --transaction <transaction> --clarification-id <C-NNN> --kind <kind> --disposition <answer|reframe> --value-file <value.md> [--rationale-file <rationale.md>]
48
+ ```
49
+
50
+ Record a plan decision only when the user states it explicitly. Any reason file stays in that same temporary directory:
51
+
52
+ ```bash
53
+ okstra user-response plan-decision --transaction <transaction> --status approved [--implementation-option <candidate-name>]
54
+ okstra user-response plan-decision --transaction <transaction> --status <revision-requested|rejected> --reason-file <reason.md>
55
+ ```
56
+
57
+ The implementation option must match a candidate printed by `show-view`. A report with no open clarification can still require this decision.
58
+
59
+ Contract 2.0 alone supports legacy report-authoring permission. Its reason file stays in that same temporary directory:
60
+
61
+ ```bash
62
+ okstra user-response legacy-report-authoring --transaction <transaction> --status <approved|denied> --reason-file <reason.md>
63
+ ```
64
+
65
+ Finish with:
66
+
67
+ ```bash
68
+ okstra user-response finalize --transaction <transaction>
69
+ ```
38
70
 
39
- 1. **list**: `okstra user-response list --home <home> --project <projectId> --limit 3` → an array of `{taskKey, taskType, seq, reportPath, reportMtime, openBlockerCount, openApprovalCount, unreadable}` (`openBlockerCount` = open rows with `Blocks` in `{approval, next-phase}`; `openApprovalCount` = the `approval`-only subset). If the array is empty, stop with "no open clarification". A 3-option picker (top recommendations + the final option always "Enter directly" for pasting a `reportPath`/`task-key` directly). `unreadable:true` is a §1 format drift — flag it with `⚠` and do not proceed (do not fabricate rows).
40
- 2. **show (data fetch, not a presentation step)**: `okstra user-response show --report <reportPath>` → `rows[]` of `{id, kind, blocks, status, statement, expectedForm, options, contextRefs, resolvedRefs}`. Each `options[]` entry is `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`; `resolvedRefs` carries the `definition` of record coordinates such as `RB-002`. A leftover `§4.7` stays unresolved. Activity-contract v1 approval options carry the gate action in `disposition`. A legacy schema-v1 report has nowhere to record impact or a gate action, so those fields arrive empty. Do not print `rows` at the user and **do not paste the raw `statement` as the question** — announce only `<N> open items — I'll go through them one at a time.`
41
- 3. **ask, one item at a time**: iterate the rows in report order, **one item per `AskUserQuestion` call**, headed `[n/N] C-014 — blocks: approval gate`. Per item:
42
- - **Background first**, in the message text above the picker, 3–6 lines: (a) *Situation* — what the run was doing when it stopped here; (b) *What is undecided* — the fork, internal tokens expanded inline from `resolvedRefs[].definition`, plus what is stuck (`approval` → the approval gate stays shut and `implementation` cannot start; `next-phase` → the next phase cannot begin); (c) *What changes with your answer*. Source it from `resolvedRefs[].definition`, else **Read** the report record (`.data.json`) for the cited row id; **never invent it** — say the report is silent instead. Do not chase a `§` number on the full reading copy. Close with `Source: C-014 — "<raw statement>"`.
43
- - **Picker: the row's `options[]` plus `Enter directly`** — slots follow array order, the `role: recommended` entry first with its label suffixed `(Recommended)`, `Enter directly` always last. Each `label` is the option's `answer`; each `description` is `<rationale> — Scope: <scopeImpact> · Added work: <addedWork> · Direction: <directionChange>`, in that fixed order. Never fold the three axes into one phrase. An empty axis is written `not stated in the report` — never inferred. More than three entries: keep the recommended one plus the two alternatives whose `scopeImpact` differs most, and say how many were left out. Never mark anything but `recommended` as recommended.
44
- - **Transcribe**: an `options[]` pick → `value` = that option's `answer` text and `disposition` = that option's `disposition` (`answer` only when absent on a legacy option); `Enter directly` → the user's utterance verbatim, `disposition:"answer"`; free text asking for a re-ask → `disposition:"reframe"` (does not satisfy the approval gate). A question back from the user records nothing — **Read** the ref, explain, re-ask the same item with the same options. Echo `[n/N] C-014 → answer: …` and move on. Each item's JSON: `{id, kind, value, rationale?, disposition}`.
45
- 4. **echo → confirmed gate**: before `write`, echo the whole collection (each `id`·`disposition`·`value`·`rationale`·approval) as-is and get explicit confirmation. Never `write` before `confirmed`. On any change, re-echo and re-confirm.
46
- 5. **plan decision (optional)**: only when the user stated one outright. Approval also needs the approval-blocking items **all filled with an answer**: `--plan-decision '{"status":"approved","implementationOption":"<selected option>"}'`. If any item is unfilled/reframe, do not approve and say the gate is still open. A turn-down takes the same flag with a mandatory reason: `--plan-decision '{"status":"rejected","reason":"<the user's own words>"}'` (`revision-requested` when the same plan should be reworked).
47
- 6. **write**: `okstra user-response write --report <reportPath> --answers '<json>' [--plan-decision '<json>'] --task-key <taskKey>` → report the returned `{sidecar:<path>}`. (When a same-named sidecar exists, the same `id` is overwritten with the new value and merged.)
48
-
49
- ## Output Rules
50
-
51
- - Concise, in the language the user is using.
52
- - Give path guidance host-relative (`~/.okstra/...` or relative to `projectRoot`). Use repo paths only when pointing at a code source.
53
- - **Never hand-edit a rendered report** (`runs/*/reports/*.md` / `*.data.json`). Sidecar recording goes only through the `okstra user-response write` CLI.
71
+ Do not decode the transaction id. Do not inspect transaction state. Do not hand-edit report records, rendered reports, or sidecars.