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.
- package/README.md +3 -3
- package/dist/cli-registry.mjs +7 -7
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/lifecycle/install.mjs +50 -124
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/lifecycle/setup.mjs +15 -0
- package/dist/commands/lifecycle/setup.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +41 -8
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/citation-guidance.d.mts +21 -0
- package/dist/lib/citation-guidance.mjs +79 -0
- package/dist/lib/citation-guidance.mjs.map +1 -0
- package/dist/lib/install-assets.mjs +3 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/runtime-manifest.mjs +2 -1
- package/dist/lib/runtime-manifest.mjs.map +1 -1
- package/dist/lib/types.d.mts +2 -1
- package/docs/architecture/storage-model.md +17 -10
- package/docs/architecture.md +26 -20
- package/docs/cli.md +16 -13
- package/docs/contributor-change-matrix.md +3 -2
- package/docs/performance-improvement-plan-v2.md +2 -3
- package/docs/project-structure-overview.md +38 -9
- package/docs/task-process/README.md +1 -1
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/final-verification.md +3 -1
- package/docs/task-process/implementation.md +1 -1
- package/docs/task-process/release-handoff.md +36 -39
- package/package.json +1 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/common.json +28 -0
- package/runtime/agents/operations/code-review.json +6 -0
- package/runtime/agents/operations/report-translation.json +6 -0
- package/runtime/agents/operations/schedule-verification.json +6 -0
- package/runtime/agents/roles/analyser.json +18 -0
- package/runtime/agents/roles/critic.json +18 -0
- package/runtime/agents/roles/designer.json +18 -0
- package/runtime/agents/roles/implementer.json +20 -0
- package/runtime/agents/roles/leader.json +20 -0
- package/runtime/agents/roles/planner.json +18 -0
- package/runtime/agents/roles/report-writer.json +19 -0
- package/runtime/agents/roles/translator.json +19 -0
- package/runtime/agents/roles/verifier.json +18 -0
- package/runtime/bin/lib/okstra/usage.sh +5 -5
- package/runtime/prompts/duties/acceptance-critic.json +32 -0
- package/runtime/prompts/duties/acceptance-verifier.json +32 -0
- package/runtime/prompts/duties/analysis-worker.json +32 -0
- package/runtime/prompts/duties/code-reviewer.json +32 -0
- package/runtime/prompts/duties/diagnosis-worker.json +32 -0
- package/runtime/prompts/duties/direction-selection-worker.json +32 -0
- package/runtime/prompts/duties/discovery-worker.json +32 -0
- package/runtime/prompts/duties/implementation-executor.json +32 -0
- package/runtime/prompts/duties/implementation-verifier.json +32 -0
- package/runtime/prompts/duties/lead.json +32 -0
- package/runtime/prompts/duties/planning-worker.json +36 -0
- package/runtime/prompts/duties/report-writer.json +32 -0
- package/runtime/prompts/duties/reverification-worker.json +32 -0
- package/runtime/prompts/duties/schedule-verifier.json +32 -0
- package/runtime/prompts/duties/scope-critic.json +32 -0
- package/runtime/prompts/duties/technical-verification-worker.json +32 -0
- package/runtime/prompts/duties/translator.json +32 -0
- package/runtime/prompts/launch.template.md +3 -2
- package/runtime/prompts/lead/adapters/cmux.md +1 -1
- package/runtime/prompts/lead/convergence.md +4 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +115 -6
- package/runtime/prompts/lead/plan-body-verification.md +6 -6
- package/runtime/prompts/lead/report-writer.md +3 -3
- package/runtime/prompts/profiles/_common-contract.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +4 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
- package/runtime/prompts/profiles/change-impact-analysis.json +31 -0
- package/runtime/prompts/profiles/change-impact-analysis.md +0 -20
- package/runtime/prompts/profiles/error-analysis.json +39 -0
- package/runtime/prompts/profiles/error-analysis.md +0 -25
- package/runtime/prompts/profiles/feature-analysis.json +31 -0
- package/runtime/prompts/profiles/feature-analysis.md +0 -20
- package/runtime/prompts/profiles/final-verification.json +30 -0
- package/runtime/prompts/profiles/final-verification.md +3 -22
- package/runtime/prompts/profiles/forbidden-actions.json +4 -3
- package/runtime/prompts/profiles/implementation-option-selection.json +31 -0
- package/runtime/prompts/profiles/implementation-option-selection.md +0 -20
- package/runtime/prompts/profiles/implementation-planning.json +40 -0
- package/runtime/prompts/profiles/implementation-planning.md +6 -29
- package/runtime/prompts/profiles/implementation.json +30 -0
- package/runtime/prompts/profiles/implementation.md +1 -20
- package/runtime/prompts/profiles/improvement-discovery.json +31 -0
- package/runtime/prompts/profiles/improvement-discovery.md +0 -20
- package/runtime/prompts/profiles/project-analysis.json +31 -0
- package/runtime/prompts/profiles/project-analysis.md +0 -20
- package/runtime/prompts/profiles/release-handoff.json +5 -0
- package/runtime/prompts/profiles/release-handoff.md +71 -73
- package/runtime/prompts/profiles/requirements-discovery.json +39 -0
- package/runtime/prompts/profiles/requirements-discovery.md +0 -25
- package/runtime/prompts/profiles/technical-verification.json +39 -0
- package/runtime/prompts/profiles/technical-verification.md +0 -25
- package/runtime/prompts/wizard/prompts.ko.json +12 -17
- package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +1 -0
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +3 -0
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/manifest.json +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -3
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/worker-session.md +108 -0
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -0
- package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +8 -1
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +8 -0
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +23 -6
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +6 -2
- package/runtime/python/okstra_ctl/agent/invocation.py +168 -113
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +120 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +107 -2
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +0 -49
- package/runtime/python/okstra_ctl/analysis_packet.py +4 -1
- package/runtime/python/okstra_ctl/application/open_worker.py +6 -1
- package/runtime/python/okstra_ctl/assignment_resolver.py +16 -5
- package/runtime/python/okstra_ctl/cmux.py +69 -20
- package/runtime/python/okstra_ctl/code_review_target.py +16 -8
- package/runtime/python/okstra_ctl/conformance.py +43 -0
- package/runtime/python/okstra_ctl/consumers.py +6 -3
- package/runtime/python/okstra_ctl/container.py +31 -8
- package/runtime/python/okstra_ctl/context_cost.py +11 -15
- package/runtime/python/okstra_ctl/contract_refreeze.py +156 -0
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +4 -6
- package/runtime/python/okstra_ctl/convergence_provenance.py +81 -18
- package/runtime/python/okstra_ctl/design_prep.py +34 -1
- package/runtime/python/okstra_ctl/dispatch_core.py +53 -27
- package/runtime/python/okstra_ctl/domain/host.py +5 -0
- package/runtime/python/okstra_ctl/domain/worker_runtime.py +10 -0
- package/runtime/python/okstra_ctl/error_report.py +4 -3
- package/runtime/python/okstra_ctl/execution_manifest.py +71 -18
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +21 -21
- package/runtime/python/okstra_ctl/handoff.py +167 -277
- package/runtime/python/okstra_ctl/implementation_stage.py +9 -0
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +113 -0
- package/runtime/python/okstra_ctl/lead_progress.py +1 -1
- package/runtime/python/okstra_ctl/legacy_model_selection.py +2 -2
- package/runtime/python/okstra_ctl/manager_cli.py +175 -14
- package/runtime/python/okstra_ctl/manager_launch.py +41 -19
- package/runtime/python/okstra_ctl/manager_paths.py +22 -3
- package/runtime/python/okstra_ctl/manager_split.py +474 -0
- package/runtime/python/okstra_ctl/manager_store.py +331 -21
- package/runtime/python/okstra_ctl/manager_sync.py +37 -16
- package/runtime/python/okstra_ctl/manager_view.py +217 -0
- package/runtime/python/okstra_ctl/model_discovery.py +30 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +14 -1
- package/runtime/python/okstra_ctl/model_io/renderers.py +4 -3
- package/runtime/python/okstra_ctl/models.py +1 -1
- package/runtime/python/okstra_ctl/next_phase.py +16 -6
- package/runtime/python/okstra_ctl/operation_invocation.py +86 -0
- package/runtime/python/okstra_ctl/option_comparison.py +168 -0
- package/runtime/python/okstra_ctl/path_hints.py +9 -0
- package/runtime/python/okstra_ctl/paths.py +3 -0
- package/runtime/python/okstra_ctl/plan_items_cli.py +6 -1
- package/runtime/python/okstra_ctl/profile_show.py +42 -1
- package/runtime/python/okstra_ctl/qa_commands.py +15 -0
- package/runtime/python/okstra_ctl/registry/host_discovery.py +20 -12
- package/runtime/python/okstra_ctl/registry/host_registry.py +11 -0
- package/runtime/python/okstra_ctl/render.py +50 -0
- package/runtime/python/okstra_ctl/report_contract.py +1 -1
- package/runtime/python/okstra_ctl/report_finalize.py +13 -6
- package/runtime/python/okstra_ctl/report_html/view_models/final_verification.py +2 -21
- package/runtime/python/okstra_ctl/report_html/view_models/release_handoff.py +21 -3
- package/runtime/python/okstra_ctl/report_html/visualizations.py +0 -5
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +177 -17
- package/runtime/python/okstra_ctl/report_translation.py +2 -1
- package/runtime/python/okstra_ctl/report_translation_dispatch.py +69 -9
- package/runtime/python/okstra_ctl/role_requirements.py +142 -129
- package/runtime/python/okstra_ctl/rollup.py +3 -1
- package/runtime/python/okstra_ctl/run.py +76 -29
- package/runtime/python/okstra_ctl/schedule_semantics.py +17 -6
- package/runtime/python/okstra_ctl/stage_fix_carry.py +23 -4
- package/runtime/python/okstra_ctl/stage_integrate.py +178 -18
- package/runtime/python/okstra_ctl/stage_map.py +16 -2
- package/runtime/python/okstra_ctl/stage_targets.py +209 -43
- package/runtime/python/okstra_ctl/team.py +22 -13
- package/runtime/python/okstra_ctl/time_report.py +2 -1
- package/runtime/python/okstra_ctl/usage_report.py +3 -1
- package/runtime/python/okstra_ctl/verification_target.py +13 -2
- package/runtime/python/okstra_ctl/wizard/confirmation.py +3 -9
- package/runtime/python/okstra_ctl/wizard/ids.py +1 -1
- package/runtime/python/okstra_ctl/wizard/registry.py +1 -1
- package/runtime/python/okstra_ctl/wizard/state.py +3 -5
- package/runtime/python/okstra_ctl/wizard/steps_plan.py +3 -23
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +5 -1
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +35 -7
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +66 -48
- package/runtime/python/okstra_ctl/workflow.py +1 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +3 -1
- package/runtime/python/okstra_ctl/worktree/naming.py +9 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +38 -9
- package/runtime/python/okstra_token_usage/pricing.py +6 -4
- package/runtime/schemas/agent-common-v1.schema.json +34 -0
- package/runtime/schemas/agent-duty-v1.schema.json +38 -0
- package/runtime/schemas/agent-operation-v1.schema.json +11 -0
- package/runtime/schemas/agent-profile-v1.schema.json +46 -0
- package/runtime/schemas/agent-role-v1.schema.json +29 -0
- package/runtime/schemas/final-report-v2.0.schema.json +118 -97
- package/runtime/schemas/final-report-v3.0.schema.json +118 -97
- package/runtime/skills/okstra-brief-gen/SKILL.md +84 -4
- package/runtime/skills/okstra-chat/SKILL.md +2 -2
- package/runtime/skills/okstra-code-review/SKILL.md +23 -9
- package/runtime/skills/okstra-container-build/SKILL.md +10 -10
- package/runtime/skills/okstra-inspect/SKILL.md +1 -1
- package/runtime/skills/okstra-inspect/facets/cost.md +1 -1
- package/runtime/skills/okstra-inspect/facets/error-zip.md +9 -9
- package/runtime/skills/okstra-inspect/facets/errors.md +16 -16
- package/runtime/skills/okstra-inspect/facets/logs.md +7 -7
- package/runtime/skills/okstra-inspect/facets/recap.md +2 -2
- package/runtime/skills/okstra-inspect/facets/report.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +4 -3
- package/runtime/skills/okstra-inspect/facets/time.md +11 -10
- package/runtime/skills/okstra-manager/SKILL.md +70 -5
- package/runtime/skills/okstra-pr-gen/SKILL.md +6 -5
- package/runtime/skills/okstra-rollup/SKILL.md +5 -5
- package/runtime/skills/okstra-run/SKILL.md +32 -13
- package/runtime/skills/okstra-schedule-gen/SKILL.md +19 -14
- package/runtime/skills/okstra-setup/SKILL.md +21 -10
- package/runtime/skills/okstra-setup/references/project-config.md +7 -6
- package/runtime/skills/okstra-usage/SKILL.md +1 -1
- package/runtime/skills/okstra-user-response/SKILL.md +1 -1
- package/runtime/templates/manager/view.template.html +109 -0
- package/runtime/templates/report-writer-prompt-preamble.md +8 -0
- package/runtime/templates/reports/brief.template.md +14 -4
- package/runtime/templates/reports/html/i18n/en.json +7 -4
- package/runtime/templates/reports/html/i18n/ko.json +7 -4
- package/runtime/templates/reports/html/tasks/final-verification.template.html +2 -2
- package/runtime/templates/reports/html/tasks/release-handoff.template.html +8 -5
- package/runtime/templates/reports/i18n/en.json +1 -1
- package/runtime/templates/reports/md/tasks/release-handoff.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +6 -4
- package/runtime/templates/translator-prompt-preamble.md +36 -0
- package/runtime/validators/checks/validate-assets-01.py +7 -8
- package/runtime/validators/validate-brief.py +77 -2
- package/runtime/validators/validate-implementation-plan-stages.py +2 -1
- package/runtime/validators/validate-run.py +59 -9
- package/runtime/validators/validate-schedule.py +9 -0
- package/docs/for-ai/README.md +0 -68
- package/docs/for-ai/skills/okstra-brief-gen.md +0 -262
- package/docs/for-ai/skills/okstra-chat.md +0 -34
- package/docs/for-ai/skills/okstra-code-review.md +0 -57
- package/docs/for-ai/skills/okstra-container-build.md +0 -129
- package/docs/for-ai/skills/okstra-inspect.md +0 -262
- package/docs/for-ai/skills/okstra-manager.md +0 -69
- package/docs/for-ai/skills/okstra-memory.md +0 -126
- package/docs/for-ai/skills/okstra-pr-gen.md +0 -49
- package/docs/for-ai/skills/okstra-rollup.md +0 -114
- package/docs/for-ai/skills/okstra-run.md +0 -250
- package/docs/for-ai/skills/okstra-schedule-gen.md +0 -240
- package/docs/for-ai/skills/okstra-setup.md +0 -158
- package/docs/for-ai/skills/okstra-usage.md +0 -29
- package/docs/for-ai/skills/okstra-user-response.md +0 -72
- package/runtime/agents/workers/claude-worker.md +0 -128
- package/runtime/agents/workers/report-writer-worker.md +0 -37
- package/runtime/agents/workers/translator-worker.md +0 -63
- package/runtime/prompts/duties/acceptance-critic.md +0 -44
- package/runtime/prompts/duties/acceptance-verifier.md +0 -44
- package/runtime/prompts/duties/analysis-worker.md +0 -44
- package/runtime/prompts/duties/code-reviewer.md +0 -44
- package/runtime/prompts/duties/common.md +0 -39
- package/runtime/prompts/duties/diagnosis-worker.md +0 -44
- package/runtime/prompts/duties/direction-selection-worker.md +0 -44
- package/runtime/prompts/duties/discovery-worker.md +0 -44
- package/runtime/prompts/duties/implementation-executor.md +0 -44
- package/runtime/prompts/duties/implementation-verifier.md +0 -44
- package/runtime/prompts/duties/lead.md +0 -44
- package/runtime/prompts/duties/planning-worker.md +0 -52
- package/runtime/prompts/duties/report-writer.md +0 -44
- package/runtime/prompts/duties/reverification-worker.md +0 -44
- package/runtime/prompts/duties/schedule-verifier.md +0 -44
- package/runtime/prompts/duties/scope-critic.md +0 -44
- package/runtime/prompts/duties/technical-verification-worker.md +0 -44
- package/runtime/prompts/duties/translator.md +0 -44
- package/runtime/python/okstra_ctl/pane_title.py +0 -154
|
@@ -6,7 +6,7 @@ Loaded lazily by the dispatch table in `SKILL.md` (core). Shared rules — Step
|
|
|
6
6
|
|
|
7
7
|
Trigger phrases: "okstra errors", "error report", "error summary", "gather the errors", "clean up failure logs".
|
|
8
8
|
|
|
9
|
-
Aggregate a task's okstra-run error logs (`runs/*/logs/errors-*.jsonl`, lead-observed + worker-reported) into a timestamped markdown report and summarize it. This sub-command renders a **read-derived artifact** (a `.md` file)
|
|
9
|
+
Aggregate a task's okstra-run error logs (`runs/*/logs/errors-*.jsonl`, lead-observed + worker-reported) into a timestamped markdown report and summarize it. This sub-command renders a **read-derived artifact** (a `.md` file) and never edits task state itself (`task-manifest.json`, catalog, timeline); a task-key target goes through the lookup that may self-heal a finished implementation phase (see `SKILL.md`).
|
|
10
10
|
|
|
11
11
|
### errors.1 — Resolve target
|
|
12
12
|
|
|
@@ -32,28 +32,28 @@ For a task-root path, run `okstra error-report <path>` directly. Do not parse th
|
|
|
32
32
|
|
|
33
33
|
Use the fixed text labels and report:
|
|
34
34
|
|
|
35
|
-
| Field |
|
|
35
|
+
| Field | Label |
|
|
36
36
|
|---|---|
|
|
37
|
-
| Report file | `
|
|
38
|
-
| Total errors | `
|
|
39
|
-
| Logs (runs) | `
|
|
40
|
-
| By errorType | `
|
|
41
|
-
| By source | `
|
|
42
|
-
| By phase | `
|
|
43
|
-
| By agent | `
|
|
44
|
-
| Parse-skipped lines | `
|
|
45
|
-
|
|
46
|
-
- If `
|
|
37
|
+
| Report file | `Report path` (project-root-relative `.md`) |
|
|
38
|
+
| Total errors | `Total errors` |
|
|
39
|
+
| Logs (runs) | `Run count` |
|
|
40
|
+
| By errorType | `Error type <name>` lines (tool-failure / cli-failure / contract-violation) |
|
|
41
|
+
| By source | `Source <name>` lines (lead-observed / worker-reported) |
|
|
42
|
+
| By phase | `Phase <name>` lines |
|
|
43
|
+
| By agent | `Agent <name>` lines |
|
|
44
|
+
| Parse-skipped lines | `Parse skipped` |
|
|
45
|
+
|
|
46
|
+
- If `Report path` is `-` AND `Total errors` is 0: report `This task has no recorded error logs.` and do not claim a file was written.
|
|
47
47
|
- Otherwise show the `.md` path and offer to read it.
|
|
48
|
-
- If `
|
|
48
|
+
- If `Parse skipped` > 0, surface it (do not silently hide malformed lines).
|
|
49
49
|
|
|
50
50
|
### errors — Output template
|
|
51
51
|
|
|
52
52
|
```markdown
|
|
53
53
|
## okstra Error Report — <task-key>
|
|
54
54
|
|
|
55
|
-
- Report: `<
|
|
56
|
-
- Total errors: <N> across <
|
|
55
|
+
- Report: `<Report path-or-->`
|
|
56
|
+
- Total errors: <N> across <Run count> log(s)
|
|
57
57
|
- By type: <tool-failure: a, cli-failure: b, ...>
|
|
58
58
|
- By source: <lead-observed: x, worker-reported: y>
|
|
59
59
|
|
|
@@ -65,5 +65,5 @@ Use the fixed text labels and report:
|
|
|
65
65
|
|---|---:|
|
|
66
66
|
| codex-worker | 2 |
|
|
67
67
|
|
|
68
|
-
<If
|
|
68
|
+
<If Parse skipped > 0: "⚠ Parse-skipped lines: <N>">
|
|
69
69
|
```
|
|
@@ -25,21 +25,21 @@ okstra log-report --project-root <projectRoot> --text
|
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Scans `<projectRoot>/.okstra/tasks/**/runs/*/prompts/*.log` and returns fixed labeled text (sizes are **raw bytes**, mtimes **epoch seconds**):
|
|
28
|
-
-
|
|
29
|
-
- `
|
|
30
|
-
- `
|
|
28
|
+
- Top-level total labels — `File count`, `Total bytes`, `Task count` (plus `Prompt bytes`, `Transcript bytes`, `Paired file count`)
|
|
29
|
+
- Repeated `## Log` blocks, size desc (widen with `--top <N>`) — `Task key`, `Phase`, `Worker`, `Sequence`, `Size bytes`, `Modified epoch`, `Path`
|
|
30
|
+
- Repeated `## Task total` blocks, total-size desc — `Task key`, `File count`, `Total bytes`, `Oldest epoch`, `Newest epoch`
|
|
31
31
|
|
|
32
|
-
If `
|
|
32
|
+
If the top-level `File count` is 0, report `No worker log files found under <projectRoot>` and stop.
|
|
33
33
|
|
|
34
34
|
### logs.2 — Summary tables
|
|
35
35
|
|
|
36
36
|
Render from the CLI output (format bytes → KB/MB; epoch → `Nd`/`Nh` relative to now):
|
|
37
37
|
|
|
38
|
-
**Table A — Top largest logs** (from `
|
|
38
|
+
**Table A — Top largest logs** (from the `## Log` blocks): `| # | Task | Phase | Worker | Seq | Size | Age | Path |`.
|
|
39
39
|
|
|
40
|
-
**Table B — Per-task totals** (from `
|
|
40
|
+
**Table B — Per-task totals** (from the `## Task total` blocks): `| Task Key | Files | Total Size | Oldest | Newest |`.
|
|
41
41
|
|
|
42
|
-
**Footer:** `Total: <
|
|
42
|
+
**Footer:** `Total: <File count> files, <Total bytes→MB> across <Task count> tasks under <PROJECT_ROOT>`.
|
|
43
43
|
|
|
44
44
|
### logs.3 — Suggested cleanup commands
|
|
45
45
|
|
|
@@ -6,7 +6,7 @@ Loaded lazily by the dispatch table in `SKILL.md` (core). Shared rules — Step
|
|
|
6
6
|
|
|
7
7
|
Trigger phrases: "okstra recap", "recap", "work summary", "summarize this task", "before/after summary", "explain this work", "task question".
|
|
8
8
|
|
|
9
|
-
On top of the `.okstra` artifacts accumulated for a single task-id — or for every task of one task-group — (a) produce a before/after summary and (b) answer free-form questions about that work. By default it reads only the `.okstra/` subtree (artifact mode). It expands to code mode only when the user explicitly asks to look at the code changes too. This sub-command performs the `recap-log.jsonl` append, the `notes/` note authoring (recap.5), and the group-context reconciliation that note triggers (recap.6); it never
|
|
9
|
+
On top of the `.okstra` artifacts accumulated for a single task-id — or for every task of one task-group — (a) produce a before/after summary and (b) answer free-form questions about that work. By default it reads only the `.okstra/` subtree (artifact mode). It expands to code mode only when the user explicitly asks to look at the code changes too. This sub-command performs the `recap-log.jsonl` append, the `notes/` note authoring (recap.5), and the group-context reconciliation that note triggers (recap.6); it never edits `task-manifest.json` / catalog / timeline itself (`recap record` / `recap note` with a task-key target, and `recap-input --task-group`, go through the lookup that may self-heal a finished implementation phase — see `SKILL.md`), and it touches `group-context.md` only in the authored sections above the `<!-- okstra:task-memory:begin -->` marker.
|
|
10
10
|
|
|
11
11
|
### recap.1 — Resolve target
|
|
12
12
|
|
|
@@ -144,7 +144,7 @@ Write the body to the scratchpad as markdown first, then pass it with `--body-fi
|
|
|
144
144
|
**self-check rules (there is no validator, so you keep them yourself):**
|
|
145
145
|
|
|
146
146
|
1. **Do not hand-edit a rendered report** (`*.md` / `*.data.json` / `*.html` under `runs/*/reports/`). Report assembly regenerates those artifacts, so write findings to `notes/` instead.
|
|
147
|
-
2. **Do not author a `user-responses/` file or apply `created-by: user`.** That is the user's decision, and writing it for them forges a decision the user never made. If your evidence supports a particular answer, write that in `notes/` and leave the decision to the user. The one exception is the echo-back confirmation flow of the `okstra-user-response` skill — there the user makes the decision in-session and the CLI is merely a transcription channel, so
|
|
147
|
+
2. **Do not author a `user-responses/` file or apply `created-by: user`.** That is the user's decision, and writing it for them forges a decision the user never made. If your evidence supports a particular answer, write that in `notes/` and leave the decision to the user. The one exception is the echo-back confirmation flow of the `okstra-user-response` skill — there the user makes the decision in-session and the CLI is merely a transcription channel, so publishing the `created-by: user` sidecar through that skill's `begin` → `answer` → `finalize` transaction is legitimate (`okstra user-response` has no `write` command). This exception holds only after the user has explicitly confirmed "correct", and only for verbatim input.
|
|
148
148
|
3. **Do not write to okstra-managed directories** (`runs/`, `instruction-set/`, `history/`, `recap/`, `.okstra/decisions/`). `notes/` is the only agent-owned lane. `recap/recap-log.jsonl` is the exception — write it, but not by hand; only via the `okstra recap record` CLI.
|
|
149
149
|
4. **`notes/` is inert to okstra** — no run reads it automatically. After writing, relay the `clarificationResponseArg` the CLI printed (e.g. `--clarification-response <notePath>`) to the user verbatim, telling them it only takes effect when the next run is executed with that argument.
|
|
150
150
|
|
|
@@ -10,7 +10,7 @@ Trigger phrases: "find report", "show report for", "read the okstra report", "co
|
|
|
10
10
|
|
|
11
11
|
task-key format: `<project-id>:<task-group>:<task-id>`.
|
|
12
12
|
|
|
13
|
-
**Normalization:** task-key matching is lowercase. Disk segments are slugified (lowercase + non-alphanumeric runs → `-`) per `scripts/okstra_ctl/ids.py:
|
|
13
|
+
**Normalization:** task-key matching is lowercase. Disk segments are slugified (lowercase + non-alphanumeric runs → `-`) per `slugify_task_segment` (`scripts/okstra_ctl/ids.py:78`); the `model-io` projections build task paths with `okstra_project.slugify` (`scripts/okstra_project/slug.py:16`), which applies the same rule. Catalog lookup is case-insensitive; file path assembly uses slugified segments.
|
|
14
14
|
|
|
15
15
|
Run `okstra model-io report-input --project-root <projectRoot> --task-ref
|
|
16
16
|
<task-key>` and use `Latest report`. For a specific date, run `okstra model-io
|
|
@@ -100,7 +100,7 @@ The status response always includes one of:
|
|
|
100
100
|
4. **Restart current phase** — only when there is nothing to answer: `latestReportRecordPath` is empty, or the open-item count is zero and `latestRunStatus` is `contract-violated`. Only an allowlisted blocking-class failure produces that status; findings demoted to `validation.advisories` leave the run passed and are not a reason to re-run. The task can be re-run with the same `task-key` and current `taskType`.
|
|
101
101
|
Branches 5–7 are decided by `workflow.nextRecommendedPhase.status` when `awaitingApproval` is false — one status, one branch:
|
|
102
102
|
|
|
103
|
-
5. **Start next phase** — `status` is `ready` and `awaitingApproval` is false. Propose `nextRecommendedPhase.phase` as the next run's `--task-type` and quote its `rationale` as the reason. This is the only status under which a named phase may be launched without a prior approval ask, so it is the only branch that proposes a run. A `ready` pointer to `release-handoff` already implies
|
|
103
|
+
5. **Start next phase** — `status` is `ready` and `awaitingApproval` is false. Propose `nextRecommendedPhase.phase` as the next run's `--task-type` and quote its `rationale` as the reason. This is the only status under which a named phase may be launched without a prior approval ask, so it is the only branch that proposes a run. A `ready` pointer to `release-handoff` already implies a final-verification verdict of `accepted`, or `conditional-accept` with every condition declaring `blocksReleaseHandoff: false` (the report validator refuses that routing target otherwise), so do not re-gate it here.
|
|
104
104
|
6. **Need more information** — `status` is `pending` (the last run did not settle where this task goes next) or `blocked` (it did settle, and the answer is that something outside the run has to change first). Neither proposes a run, and a leftover `phase` name does not change that — `prepare` keeps the name when it lowers a pointer to `pending`, so read `status`, not the emptiness of `phase`. Show the `rationale`, and for `blocked` state what it names as the obstacle. After `implementation-planning`, branch 3 already owns the routing: the `C-NNN` answers come first, and planning is not re-run until they exist.
|
|
105
105
|
7. **Task complete (terminal)** — `status` is `terminal`: the task lifecycle ends here. This is **not** a "next phase" — do not propose a new okstra run. Surface the latest report and ask the user whether any follow-up task should be opened separately.
|
|
106
106
|
|
|
@@ -112,8 +112,9 @@ This includes briefs whose tasks have never run. Call this command directly with
|
|
|
112
112
|
token; do not require a catalog match or a prior `okstra-run`. The command resolves the brief
|
|
113
113
|
and registers it when needed. For "do this small task directly and record completion", perform
|
|
114
114
|
the authorized work, then record `done` with `--note` or `--note-file` containing the changes,
|
|
115
|
-
verification results or reasons checks were not run, and remaining limitations.
|
|
116
|
-
|
|
115
|
+
verification results or reasons checks were not run, and remaining limitations. `set-work-status`
|
|
116
|
+
refuses a direct completion whose note is empty (`test_okstra_set_work_status.py`); it does not
|
|
117
|
+
check the note's content, so including those three parts is on you.
|
|
117
118
|
|
|
118
119
|
Read `Direct work record` alongside `Work status`. A direct result is user-recorded work,
|
|
119
120
|
not a passed cross-verification run. The command shares the result in group context and
|
|
@@ -19,20 +19,21 @@ okstra time-report <task-key> --project-root <projectRoot> --text
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Returns fixed labeled text (all durations are **raw milliseconds**):
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
- `
|
|
25
|
-
- `
|
|
26
|
-
-
|
|
22
|
+
- Top-level total labels — `Total runs`, `Total lead ms`, `Total workers ms`, `Total CPU sum ms`
|
|
23
|
+
- Repeated `## Task type` blocks — `Task type`, `Runs`, `Lead ms`, `Workers ms`, `CPU sum ms`
|
|
24
|
+
- Repeated `## Worker` blocks — `Task type`, `Worker ID`, `Agents` (comma-separated agent labels that differ from the worker ID), `Runs`, `Total ms`, `Average ms`; only workers with a nonzero run appear
|
|
25
|
+
- Repeated `## Run wall clock` blocks — `Run timestamp`, `Task type`, `Wall clock ms` (max `endedAt` − min `startedAt` per run)
|
|
26
|
+
- Repeated `## Phase` blocks, one per phase marker — `Run timestamp`, `Task type`, `Phase`, `First at`, `Wall ms to next`
|
|
27
|
+
- Repeated `## Unavailable run` blocks — `Run timestamp`, `Task type`, `Reason` for runs with no Phase-7 durations (never summed into totals)
|
|
27
28
|
|
|
28
29
|
### time.3 — Render
|
|
29
30
|
|
|
30
|
-
Convert every
|
|
31
|
+
Convert every `ms` label to `HH:MM:SS` (zero-pad; never show raw ms). `## Task type` blocks are already in chronological (first-appearance) order.
|
|
31
32
|
|
|
32
|
-
- **By task type** — `| Task type | Runs | CPU sum | Lead | Workers |` from `
|
|
33
|
-
- **Per worker** (per task type) — `| Worker | Runs | Total | Avg/run |` from `
|
|
34
|
-
- **Phase breakdown** — "by stage"/"per stage"/"which stage took longest" in okstra most often means the **lifecycle stage (task-type)** view, which the *By task type* table above already answers — lead with that table, do not treat the request as unanswerable. Render the intra-run phase timeline only when the user clearly means within-a-run phases ("which phase", "Phase 1~7", "phase timeline"): one table per run from `
|
|
35
|
-
- If `
|
|
33
|
+
- **By task type** — `| Task type | Runs | CPU sum | Lead | Workers |` from the `## Task type` blocks, plus a total row from the `Total …` labels. `CPU sum` (= Lead + Workers) overlaps because workers run inside the lead's window — it is *not* wall-clock. Surface wall-clock only when the user explicitly asks, from the `## Run wall clock` blocks.
|
|
34
|
+
- **Per worker** (per task type) — `| Worker | Runs | Total | Avg/run |` from the `## Worker` blocks. Render the worker as bare `Worker ID` when `Agents` is `-`, else `<Worker ID> (agent1, agent2)`.
|
|
35
|
+
- **Phase breakdown** — "by stage"/"per stage"/"which stage took longest" in okstra most often means the **lifecycle stage (task-type)** view, which the *By task type* table above already answers — lead with that table, do not treat the request as unanswerable. Render the intra-run phase timeline only when the user clearly means within-a-run phases ("which phase", "Phase 1~7", "phase timeline"): one table per run from the `## Phase` blocks grouped by `Run timestamp`: `| Phase | Start | Wall to next |` using `First at`/`Wall ms to next` (`-` → `--`). When there is no `## Phase` block, do **not** headline "not measurable" — the By-task-type table is the stage answer; mention the missing intra-run markers only as a trailing footnote.
|
|
36
|
+
- If any `## Unavailable run` block exists, append a trailing note listing each run with its reason. Never fold them into totals.
|
|
36
37
|
- Show the resolved `<task-key>` in the heading.
|
|
37
38
|
|
|
38
39
|
```markdown
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-manager
|
|
3
|
-
description: Use when the user wants to manage okstra work across multiple project roots, register or discover projects under a manager, create or update a shared manager task, sync project child-task status into manager state, or launch a child task from manager context. Trigger words include "okstra manager", "okstra-manager", "multiple projects", "cross-project", "group projects together", "manager task".
|
|
3
|
+
description: Use when the user wants to manage okstra work across multiple project roots, register or discover projects under a manager, create or update a shared manager task, sync project child-task status into manager state, split a Linear project or issue into per-project scoped briefs, or launch a child task from manager context. Trigger words include "okstra manager", "okstra-manager", "multiple projects", "cross-project", "group projects together", "manager task", "split this Linear project", "brief per project".
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: true
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# OKSTRA Manager
|
|
@@ -22,25 +24,88 @@ okstra manager init --manager-id <manager-id>
|
|
|
22
24
|
okstra manager discover-projects
|
|
23
25
|
okstra manager new project --manager-id <manager-id> --project-id <project-id> --project-root <abs-path> [--role <role>] [--tag <tag>]
|
|
24
26
|
okstra manager new task-group --manager-id <manager-id> --task-group <task-group>
|
|
25
|
-
okstra manager new task --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --task <project-id:task-group:task-id>
|
|
27
|
+
okstra manager new task --manager-id <manager-id> --task-group <task-group> --task-id <task-id> [--task <project-id:task-group:task-id>]
|
|
26
28
|
okstra manager task status --manager-id <manager-id> --task-group <task-group> --task-id <task-id>
|
|
27
29
|
okstra manager task sync --manager-id <manager-id> --task-group <task-group> --task-id <task-id>
|
|
28
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>]
|
|
29
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>
|
|
30
32
|
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>]
|
|
33
|
+
okstra manager task split --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --plan <split-plan.json> [--overwrite]
|
|
34
|
+
okstra manager list managers
|
|
35
|
+
okstra manager list projects --manager-id <manager-id>
|
|
36
|
+
okstra manager list task-groups --manager-id <manager-id>
|
|
37
|
+
okstra manager list tasks --manager-id <manager-id>
|
|
38
|
+
okstra manager task update --manager-id <manager-id> --task-group <task-group> --task-id <task-id> [--objective <text>] [--common-brief <path>] [--progress-mode <manual|auto>]
|
|
39
|
+
okstra manager task remove-child --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --project-id <project-id> [--child-task-id <child-task-id>] [--confirm]
|
|
40
|
+
okstra manager remove project --manager-id <manager-id> --project-id <project-id> [--confirm]
|
|
41
|
+
okstra manager remove task --manager-id <manager-id> --task-group <task-group> --task-id <task-id> [--confirm]
|
|
42
|
+
okstra manager remove task-group --manager-id <manager-id> --task-group <task-group> [--confirm]
|
|
43
|
+
okstra manager view --manager-id <manager-id>
|
|
31
44
|
```
|
|
32
45
|
|
|
33
46
|
- Public child task identity is `project-id:task-group:task-id`.
|
|
47
|
+
- `--task` on `new task` is optional and repeatable; without it the task is created with no children.
|
|
34
48
|
- `okstra manager new task --task ...` should prefer the full child key form above. The CLI also accepts shorthand under the command's `--task-group`, but the full key is the public form to show users.
|
|
35
49
|
- When a manager task id differs from the actual child task id for a specific project, pass `--child-task-id <child-task-id>` to `task assign` and `task run`.
|
|
36
50
|
|
|
51
|
+
## Removal Rule
|
|
52
|
+
|
|
53
|
+
`remove project`, `remove task`, `remove task-group` and `task remove-child` change nothing without `--confirm`; they print what would be removed (`Removed: no — dry run`). Run the command without `--confirm` first, show the user the listed project, path, tasks or kept children, and rerun with `--confirm` only after the user approves that exact target. These commands touch manager files only; project `.okstra/` state and briefs written by `task split` stay.
|
|
54
|
+
|
|
55
|
+
- `remove project` unregisters the project and keeps its child tasks. `task status` shows them with `project linked: no`, the view marks them `unlinked`, and `task run` refuses them until the project is registered again with `new project`.
|
|
56
|
+
- `task update` changes only the fields given and needs no confirmation. `new task` still refuses to change an existing task's objective, common brief or progress mode.
|
|
57
|
+
|
|
58
|
+
## Tracker Split
|
|
59
|
+
|
|
60
|
+
Use this when one Linear project, or one parent issue, covers work in several registered projects and each project needs its own brief. A Linear project can point at several projects, and one issue can too; every (issue, project) pair gets its own brief and child task.
|
|
61
|
+
|
|
62
|
+
1. Run `okstra manager list projects --manager-id <manager-id>`. These are the only valid targets. Register a missing repo with `okstra manager new project ...` first.
|
|
63
|
+
2. Fetch from the Linear MCP: the project (`get_project`) and its issues (`list_issues` filtered by that project), then each issue with `get_issue`, including sub-issues and blocking or related links. If the Linear tools are missing, load them once with `ToolSearch`; if they are still missing, ask the user to paste the bodies. Never invent ticket content.
|
|
64
|
+
3. For each issue, propose target projects from evidence: labels, team, repository names or paths in the body. Confirm with `AskUserQuestion` (multi-select, recommended projects first, reason in each description).
|
|
65
|
+
4. For each (issue, project) pair, draft the scope: the part of the issue this project implements. Confirm it with `AskUserQuestion` offering one or two drafts plus a custom-input option. A pair without scope is rejected by the CLI.
|
|
66
|
+
5. Author each pair's brief fields under the okstra-brief-gen brief contract: bodies verbatim, `EB-NNN` / `PB-NNN` / `EO-NNN` items as `<id> <observable condition> — verify: <how>`, anything without an observation method under `externalGates`, and `openQuestions` rows prefixed `general:`, `terminology:`, `intent-check:`, `conversion-block:` or `adr-candidate:`.
|
|
67
|
+
6. Write the plan JSON below with the Write tool to a scratch path outside the project roots, then run `okstra manager task split ... --plan <path>`.
|
|
68
|
+
- `split plan rejected` or `rendered briefs failed validate-brief`: fix the named fields and run it again. Nothing was written.
|
|
69
|
+
- `briefs already exist with different content`: show the listed paths and ask before adding `--overwrite`, which replaces hand edits. Adding issues to an earlier split changes every brief's Related Task Graph, so existing briefs are listed too.
|
|
70
|
+
7. Each `Brief N task key` is `<project-id>:<task-group>:<child-task-id>`. Start one with `okstra manager task run ... --project-id <project-id> --child-task-id <child-task-id>` and follow the Child Launch Rule. The packet already carries `--task-brief`, and `--task-type` until the child task exists.
|
|
71
|
+
|
|
72
|
+
Plan JSON (`schemaVersion` 1). `source.kind` is `project` or `issue`; `recommendedPhase` is `requirements-discovery` (default), `error-analysis` or `improvement-discovery`; `relations[].relation` uses the brief Related Task Graph values; list fields may be omitted.
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"schemaVersion": 1,
|
|
77
|
+
"source": {"kind": "project", "ref": "<Linear URL>", "title": "<title>", "fetchedVia": "<tool>", "fetchedAt": "YYYY-MM-DD HH:MM", "body": "<verbatim>"},
|
|
78
|
+
"issues": [
|
|
79
|
+
{
|
|
80
|
+
"ticketId": "LIN-12", "title": "<title>", "url": "<Linear URL>", "fetchedVia": "<tool>", "fetchedAt": "YYYY-MM-DD HH:MM", "body": "<verbatim>",
|
|
81
|
+
"relations": [{"relation": "blocked-by", "to": "LIN-11", "source": "<where the link came from>", "impact": "<what the next phase must keep>"}],
|
|
82
|
+
"assignments": [
|
|
83
|
+
{
|
|
84
|
+
"projectId": "<registered project id>", "scope": ["<work in this project>"], "outOfScope": [],
|
|
85
|
+
"recommendedPhase": "requirements-discovery",
|
|
86
|
+
"context": "<text>", "problem": "<text>", "desiredOutcome": "<text>",
|
|
87
|
+
"expectedBehavior": [], "preservedBehavior": [], "expectedOutcome": [],
|
|
88
|
+
"externalGates": [], "constraints": [], "openQuestions": []
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The CLI writes each brief to `<projectRoot>/.okstra/briefs/<group-slug>/<ticketId>-<file-title>.md` (`<group-slug>` is the task group lowercased, with each run of characters other than `a-z` and `0-9` replaced by `-`, so `Upload V2` becomes `upload-v2`) with a `## Project Scope` section: this project's scope, `outOfScope`, and the scope of every other project the same issue went to. It validates every brief with the brief validator before writing any file, registers the child tasks, and keeps the plan at `split-plan.json` in the manager task directory.
|
|
97
|
+
|
|
98
|
+
## Overview Page
|
|
99
|
+
|
|
100
|
+
When the user wants to see a manager at a glance, run `okstra manager task sync ...` for each task listed by `okstra manager list tasks ...` whose snapshot must be current, then run `okstra manager view --manager-id <manager-id>` and give the user the returned `View URL`. The page reads manager files only, so each task shows the state of its last sync and prints its own sync command.
|
|
101
|
+
|
|
37
102
|
## Child Launch Rule
|
|
38
103
|
|
|
39
104
|
For launching child work:
|
|
40
105
|
|
|
41
106
|
1. Run `okstra manager task sync ...` if the manager snapshot must be refreshed first.
|
|
42
107
|
2. Run `okstra manager task run ...`.
|
|
43
|
-
3. Read the returned fixed fields `Backend`, `Worker dispatch backend`, `Project root`, `Context path`,
|
|
44
|
-
4.
|
|
108
|
+
3. Read the returned fixed fields `Backend`, `Worker dispatch backend`, `Project root`, `Context path`, `Run command`, every numbered `Run arg N`, and `Shell command`.
|
|
109
|
+
4. Give the user the `Shell command` line verbatim and tell them to run it in a new terminal. It starts the installed launcher in the child project: the launcher fills the task type and brief from the child task manifest or asks for them, prepares the run with the manager context directive, and starts the child lead as a separate host process (`Backend` `spawn-process`).
|
|
45
110
|
|
|
46
|
-
|
|
111
|
+
Do not run the `Shell command` through this session's Bash tool: it opens an interactive host session. Do not rebuild it from `Run arg N` or swap in `okstra run`, which drops the task inputs and the directive for a lead host.
|
|
@@ -61,10 +61,10 @@ the user states explicitly wins verbatim; never rewrite it.
|
|
|
61
61
|
okstra pr template list
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
- If
|
|
64
|
+
- If it prints template names (one per line), present a picker: 1–2 recommended templates from
|
|
65
65
|
the list, plus `Default template` (the bundled default), plus `Enter directly`
|
|
66
66
|
last.
|
|
67
|
-
- If
|
|
67
|
+
- If it prints `(no templates)`, tell the user the bundled default template will be used.
|
|
68
68
|
|
|
69
69
|
Carry the chosen template name as `<template>` (`default` for the bundled one).
|
|
70
70
|
|
|
@@ -74,8 +74,9 @@ Carry the chosen template name as `<template>` (`default` for the bundled one).
|
|
|
74
74
|
okstra pr branches
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
It prints the recommended base branches one per line, current branch excluded, or `(no branches)`.
|
|
78
|
+
Present a 3-option base picker from the first two printed branches plus `Enter directly` last; with
|
|
79
|
+
`(no branches)`, ask for the base directly. Carry the choice as `<base>`.
|
|
79
80
|
|
|
80
81
|
### A3. Build the generation bundle and fill the template
|
|
81
82
|
|
|
@@ -94,7 +95,7 @@ git diff <base>...HEAD
|
|
|
94
95
|
For a large diff, read it in sections. Fill the `template` placeholders from the
|
|
95
96
|
diff and commits: describe only what actually changed. Mark checklist boxes
|
|
96
97
|
`[x]` only when the diff supports them (tests touched → tests box, docs touched →
|
|
97
|
-
docs box). If `
|
|
98
|
+
docs box). If the `Commits`/`Diff stat` sections print `-` (empty), tell the user there is nothing to
|
|
98
99
|
describe and stop. **Never** append AI trailers/footers.
|
|
99
100
|
|
|
100
101
|
### A3b. Identifier allowlist for the body
|
|
@@ -8,7 +8,7 @@ description: |
|
|
|
8
8
|
|
|
9
9
|
Cross-task roll-up: collect every catalog task's run results (optionally scoped to one task-group) and summarize them together. The `rollup` CLI does all deterministic aggregation — counts, time sums, error tallies, status/category/phase distributions. You resolve scope, call it, render the table, and synthesize the prose digest from the report files. **Never recompute totals or re-tally by hand** — the CLI is the SSOT for the numbers.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The skill itself writes nothing. `okstra rollup` resolves every catalog task by task-key, and that lookup self-heals a finished implementation phase. When a task's current phase is `implementation`, that lookup appends a `done` row to `runs/implementation-planning/consumers.jsonl` for each stage whose carry file is complete but has no settled row, and when every stage of the latest plan has a `done` row and a pass-grade carry it marks the phase completed in `task-manifest.json` (`workflow`, `phaseOutcome.implementation`) and refreshes that task's catalog entry. Nothing else is written.
|
|
12
12
|
|
|
13
13
|
## Step 0: Preflight
|
|
14
14
|
|
|
@@ -56,15 +56,15 @@ Convert each returned `ms` label to `HH:MM:SS` (zero-pad; never show raw ms). CP
|
|
|
56
56
|
**workStatus:** done 1 · in-progress 1 **category:** bugfix 1 · feature 1
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
Render `Report` as `✓` when the corresponding `Task N report path`
|
|
59
|
+
Render `Report` as `✓` when the corresponding `Task N report path` holds a path, else `—`. An absent path prints as `-`. Use the numbered fixed labels and total labels verbatim; do not re-count tasks.
|
|
60
60
|
|
|
61
61
|
## Step 4: Synthesize the digest (the summary)
|
|
62
62
|
|
|
63
63
|
This is the skill's value-add over a bare table. When the user asked to "summarize"/"digest"/"organize" (the common case), produce a short cross-task narrative:
|
|
64
64
|
|
|
65
|
-
1. For each task
|
|
66
|
-
2. Above the per-task lines, write a 2–4 sentence group-level synthesis: what was delivered across the group, where the open work sits (use `
|
|
67
|
-
3. Cite each per-task claim with
|
|
65
|
+
1. For each task whose `Task N report path` is not `-` and whose file exists under `<projectRoot>/<Task N report path>`, read it and write a 1–2 line summary of what it accomplished and its recommended next step.
|
|
66
|
+
2. Above the per-task lines, write a 2–4 sentence group-level synthesis: what was delivered across the group, where the open work sits (use the `Work status N name/count` and `Current phase N name/count` lines), and any error hot-spots (tasks with a high `Task N errors`).
|
|
67
|
+
3. Cite each per-task claim with its `Task N report path` value so the reader can open it.
|
|
68
68
|
|
|
69
69
|
For tasks with no report, state the current phase/workStatus instead of inventing a summary — do not read non-report artifacts to fill the gap.
|
|
70
70
|
|
|
@@ -32,10 +32,10 @@ Every wizard call returns JSON. The two shapes you'll see:
|
|
|
32
32
|
"progress": { "index": 5, "total": 11, "remaining": 6 } } }
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Every non-terminal `next` carries a `progress` object (`done` / `aborted` omit it). It holds `index` (1-based number of the **current screen**; pick_group counts as one screen), `total` (the wizard's forward estimate of the full screen count — may grow by a few when the user opens a branch, e.g. role-add or extra role-model slots), `remaining` (`total − index`), and **`label`** — the ready-to-render marker the wizard already composed (e.g. `Step 10/11 · 1
|
|
35
|
+
Every non-terminal `next` carries a `progress` object (`done` / `aborted` omit it). It holds `index` (1-based number of the **current screen**; pick_group counts as one screen), `total` (the wizard's forward estimate of the full screen count — may grow by a few when the user opens a branch, e.g. role-add or extra role-model slots), `remaining` (`total − index`), and **`label`** — the ready-to-render marker the wizard already composed (e.g. `Step 10/11 · 앞으로 1 스텝 남음`, or `Step 11/11 · 마지막 단계` on the final screen; the suffix is Korean whatever the report language). **Always suffix the rendered prompt with `progress.label` verbatim** — see Step 3. Do not recompute the marker or decide "final step" yourself; only the wizard knows whether more screens follow.
|
|
36
36
|
|
|
37
37
|
```json
|
|
38
|
-
{ "ok": false, "error": "approved plan has
|
|
38
|
+
{ "ok": false, "error": "approved plan §1 has 1 unresolved `Blocks=approval` row(s); ...",
|
|
39
39
|
"current": { "step": "approved_plan", "kind": "text", "label": "..." } }
|
|
40
40
|
```
|
|
41
41
|
|
|
@@ -61,7 +61,7 @@ The final `confirm` step is a normal `pick` step with three options — `Proceed
|
|
|
61
61
|
|
|
62
62
|
Never invent additional questions. **Never drop, hide, merge, reorder, or truncate** a `pick` / `pick_group` option — relay every `options[]` entry, including entries that carry a `(default)` / `(recommended)` suffix. Do not collapse a multi-option pick into a "recommended + Enter directly / Other" shortlist. The wizard's arrays are the complete authoritative choice sets, regardless of the current host UI's usual option limit. The run-prompt recommendation rule (1–2 recommendations + Enter directly) shapes the **option set** only for prompts this skill authors itself, never for wizard-provided options — you may not add, drop, or reorder a wizard option to produce a shortlist. It does not excuse you from recommending: before relaying a wizard step whose answer turns on something readable (the carried report, the sidecar the user already wrote, the prior Stage Map), read it, put what you found in the question body, and name which of the wizard's own options you recommend and why. Relaying a step with no context and no recommendation hands the whole question back to the user — see the lifecycle core contract "Asking the user (BLOCKING)".
|
|
63
63
|
|
|
64
|
-
**One recommendation, shown in one place, and it is option 1.** The option carrying `recommended: true` is what this run computed, and the wizard already placed it first —
|
|
64
|
+
**One recommendation, shown in one place, and it is option 1.** The option carrying `recommended: true` is what this run computed, and the wizard already placed it first — except on model-selection steps (`role-models:*`, `role-model:*`), which keep provider display order, so the flagged model may sit anywhere in the list. Append ` (추천)` to that option's label when you render it, and to no other. A checkbox step (`multi: true`) may flag several leading options: they are the recommended set, rendered the same way. Your prose recommendation names one of the flagged options. If you believe a different option is right, do not quietly recommend it in prose while the flagged one still reads as recommended on screen: say you disagree, name both, and let the user pick. When no option carries the flag, the run computed nothing for this step — recommend one from what you read and mark that one, and do not present the first option as a default just because it is first. **Enforced:** `scripts/okstra_ctl/wizard/state.py` `Prompt.__post_init__` refuses a step whose free-input option is not last, whose single-select recommendation is not exactly one option, whose recommendation is not placed first on a single-select step or is not the leading run on a checkbox step (both position checks are skipped on `role-models:*` / `role-model:*` steps), or that marks the free-input / abort escape as a recommendation.
|
|
65
65
|
|
|
66
66
|
## Step 1: Preflight
|
|
67
67
|
|
|
@@ -168,13 +168,13 @@ okstra wizard init \
|
|
|
168
168
|
--available-function <each-additional-function-in-the-effective-intersection>
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
Output: the same `{ok, next}` JSON described above. The first `next` is
|
|
171
|
+
Output: the same `{ok, next}` JSON described above. The first `next` is `step: "report_language"` when `.okstra/project.json` has no `reportLanguage` value; otherwise it is `step: "task_pick"`, except that when the brand-new option is the only `task_pick` choice, `init` answers it itself and the first `next` is the task-group step.
|
|
172
172
|
|
|
173
173
|
## Step 3: Run the prompt loop
|
|
174
174
|
|
|
175
175
|
Repeat until `next.kind == "done"` (or `"aborted"` — terminal cancel, see "How the wizard talks to you"):
|
|
176
176
|
|
|
177
|
-
1. **Render** the prompt according to `next.interaction.kind` using the relay rules above. For a native kind, invoke the `function` string from that same `interactions` entry — the Claude Code picker, the Grok picker, and the Codex picker are different names, and substituting one for another is a relay-contract failure. **Always append the progress marker to the rendered question label**: suffix it with ` (<next.progress.label>)` — render `progress.label` exactly as the wizard sent it, never recompute it. Example: label `Step 8/11 · 3
|
|
177
|
+
1. **Render** the prompt according to `next.interaction.kind` using the relay rules above. For a native kind, invoke the `function` string from that same `interactions` entry — the Claude Code picker, the Grok picker, and the Codex picker are different names, and substituting one for another is a relay-contract failure. **Always append the progress marker to the rendered question label**: suffix it with ` (<next.progress.label>)` — render `progress.label` exactly as the wizard sent it, never recompute it. Example: label `Step 8/11 · 앞으로 3 스텝 남음` → `Select a model (Step 8/11 · 앞으로 3 스텝 남음)`. Re-prompts after `ok: false` reuse `current.progress.label` the same way. The progress marker is presentation-only — never send it back to the wizard as part of an answer. **The rendered question is the last thing you emit in that turn.** Every host streams assistant text in emission order, so an echo, a restatement, a rationale, or a status line emitted after the question call renders *below* the picker and pushes the question away from where the user answers. Say whatever you need to say before the call, then call and stop.
|
|
178
178
|
**One pending interaction per wizard state.** For native interactions, display the question and options only through the selected question tool, not as a second text list. An asynchronous acknowledgement such as `{accepted: true}` means the question is pending, not answered. Wait for the actual user reply; do not repeat the tool call or fetch and render the same step again while waiting. If ending the turn while awaiting a reply, do not restate the question in the final message. Re-prompt only on explicit user edits or a validation error after submitting an actual answer. This is a lead relay instruction; wizard state validation does not deduplicate host UI emissions.
|
|
179
179
|
2. **Submit** the answer — call `okstra wizard step` with the literal state-file path from Step 2 and the literal user answer (no shell variables, no `$(...)`):
|
|
180
180
|
```bash
|
|
@@ -186,7 +186,7 @@ Repeat until `next.kind == "done"` (or `"aborted"` — terminal cancel, see "How
|
|
|
186
186
|
```bash
|
|
187
187
|
okstra wizard step --state-file /var/folders/.../okstra-wizard.AbCd.json --answer ""
|
|
188
188
|
```
|
|
189
|
-
Omitting `--answer` entirely is forbidden. The wizard
|
|
189
|
+
Omitting `--answer` entirely is forbidden. The wizard does not read a missing `--answer` flag as "submit empty": without `--answer` or `--no-submit`, `wizard step` returns `ok: false` naming `--answer` and exits 2, and the step is not submitted. Submitting `--answer ""` is the only way to advance past an intentionally-blank step (e.g. "use phase default").
|
|
190
190
|
|
|
191
191
|
**Escaping rule**: if the literal answer contains `"`, escape each occurrence as `\"` inside the double-quoted argument. Empty values must still be `--answer ""` — the flag itself is mandatory, even when the value is empty.
|
|
192
192
|
|
|
@@ -204,9 +204,9 @@ That is the entire interactive flow. The wizard handles:
|
|
|
204
204
|
- analysis-input sub-flow — `project-analysis` has no target or evidence step. `feature-analysis` runs `project_evidence_pick` / `project_evidence`, then `analysis_target_pick` / `analysis_target`; the target is required even when the user skips project evidence. `change-impact-analysis` runs `feature_evidence_pick` / `feature_evidence`, then `project_evidence_pick` / `project_evidence`. The evidence steps show accepted compatible reports first and retain direct-path entry; do not invent a different relation or reorder these steps,
|
|
205
205
|
- base-ref pick + git rev-parse validation (skipped when reusing an active worktree),
|
|
206
206
|
- `implementation`-only sub-flow: approved-plan path (frontmatter `approved: true` check) + stage pick (`auto` = the earliest incomplete stage whose dependencies are satisfied, or a specific stage number). Implementer slots use role-count / role-model like every other role (`executor` is only a compatibility alias for `implementer`). When an approved plan is selected and a `## PLAN DECISION` sidecar carrying `Status: approved`, exported from the report — matching the plan on source-report·seq — is detected in that run's sibling `user-responses/`, the approve-confirm step expands to 3 options (`yes_apply` recommended: approve + apply the option as exported / `yes` approve only / `no` abort) — `yes_apply` validates the option against the plan's `optionCandidates` before applying it via the existing approval·option path,
|
|
207
|
-
- `release-handoff`-only sub-flow: after the approved plan auto-resolves, a `handoff_stage_pick` multi-select — choose
|
|
207
|
+
- `release-handoff`-only sub-flow: after the approved plan auto-resolves, a `handoff_stage_pick` multi-select — choose the eligible stages to open a PR for, one PR per stage; the result goes out as render-args' `stages` key (csv; empty takes every eligible stage),
|
|
208
208
|
- launch selection after identity/worktree steps: one screen per static role, in profile order. A role that can run several instances (`max > 1`) is a checkbox step `role-models:<role>` (`multi: true`) — the number of models checked is the number of instances, there is no separate count question; the label states the profile range and recommended count, every executable candidate is listed on that one screen (defaults first, the recommended set flagged), and when the list exceeds the host's native checkbox limit the runtime either splits it into several checkbox questions on one `pick_group` screen (interaction plan `native-group`; the question steps are `role-models:<role>#1`, `#2`, … and the answer is one JSON object keyed by them, each value a CSV) when the host's native question group holds every option, or returns the interaction plan `numbered-multi` — render the whole list, never a shortlist or pages. An optional role (`min = 0`, e.g. critic) carries a `추가 안 함` row. A fixed single role (`min = max = 1`, e.g. report-writer) is a single pick `role-model:<role>:1`, and a role capped at one model (`max = 1`, e.g. critic) is a single pick on its `role-models:<role>` step; both split the same way when they exceed the native option limit — the tabs are checkbox questions, the answer is the same keyed JSON object, and the wizard rejects a screen whose tabs together name more than one value. current-session lead is this session and is listed on the confirmation summary, not as a wizard step. The wizard does not fork on defaults-vs-customize, does not show a provider roster multi-pick, and does not offer a separate implementer-provider pick. Dynamic verifiers are not chosen at launch. `--workers` is compatibility-only, not a launch picker. Repeated `--role-count` / `--role-model` tokens on `renderArgv` are intentional,
|
|
209
|
-
- **resume-clarification (in-session equivalent)** — there is no separate mode or flag matching the shell's `okstra.sh --resume-clarification`; two steps of the standard flow carry out its substance. (1) `reuse_previous` (yes/no to reuse the previous run's settings — in `requirements-discovery` / `error-analysis` / `implementation-planning`, only when prior run-inputs exist): YES prefills role-count·role-model·directive·related-tasks at once. (2) `clarification_pick`:
|
|
209
|
+
- **resume-clarification (in-session equivalent)** — there is no separate mode or flag matching the shell's `okstra.sh --resume-clarification`; two steps of the standard flow carry out its substance. (1) `reuse_previous` (yes/no to reuse the previous run's settings — in `requirements-discovery` / `error-analysis` / `implementation-planning` / `project-analysis` / `feature-analysis` / `change-impact-analysis`, only when prior run-inputs exist): YES prefills role-count·role-model·directive·related-tasks at once (and, for the analysis types, the target and evidence inputs). (2) `clarification_pick`: a `revision-requested` analysis report for the selected analysis type is recommended first; otherwise the **task-type's own** previous `final-report` is auto-recommended as the carry-in input (for `technical-verification`, the `implementation-option-selection` report), falling back to the newest by mtime across all phases when absent — except for `implementation-planning` and `technical-verification`, which get no cross-phase fallback. The approved plan is never recommended here. The same run's `user-responses/` sidecar (answers the user filled in) is attached alongside. The chosen path is passed to prepare as `--clarification-response` — the user makes the sidecar via the report's `Export user response`, places it in `runs/<task-type>/user-responses/`, and re-runs the same phase,
|
|
210
210
|
- **re-verification scope (`reverify_scope_pick`, `implementation-planning` clarification re-runs only)** — asked right before `confirm` when the re-run is narrowable **or** an answered `C-NNN` traces to no stage. When every answered id traces to a stage: 3 options — `auto` (recommended — leave it to the lead's `okstra incremental-scope` decision) / `full` (re-verify every stage) / Enter directly (a stage-number CSV, validated against the prior report's Stage Map). When an id is unlinked, `auto` is omitted and the user names stages or picks `full`; that unlinked id does not freeze the run at full. The answer goes out as `--reverify-scope` and reaches the lead prompt as the `REVERIFY_SCOPE_MODE` / `REVERIFY_SCOPE_STAGES` tokens; it shapes that CLI's inputs rather than replacing the decision. The confirmation block's `reverify-scope` line names unlinked ids as needing stage numbers, not as a forced full re-run,
|
|
211
211
|
- `release-handoff` PR template override + persist scope,
|
|
212
212
|
- final `Proceed / Edit` confirmation; on `Edit` the wizard asks which step to rewind to and clears every later answer.
|
|
@@ -271,7 +271,7 @@ Before invoking it, follow the active host relay's execution-permission guidance
|
|
|
271
271
|
|
|
272
272
|
Analysis sidetracks therefore forward wizard-owned tokens such as `--analysis-target "<value>"` and `--evidence-inputs "<value>"` when they are present. These are examples of the verbatim token rule, not a separate hard-coded argument list.
|
|
273
273
|
|
|
274
|
-
Step 3's empty-answer and escaping rules apply verbatim: every flag in `renderArgv` whose following value is the empty string MUST still be passed explicitly (e.g. `--workers ""`, `--directive ""`) —
|
|
274
|
+
Step 3's empty-answer and escaping rules apply verbatim: every flag in `renderArgv` whose following value is the empty string MUST still be passed explicitly (e.g. `--workers ""`, `--directive ""`) — the wizard's intent is always "flag present with empty value", even where prepare's default happens to be the same empty value.
|
|
275
275
|
|
|
276
276
|
`renderArgv` already contains exactly one `--lead-runtime <host-runtime>` pair. Do not add or replace it. Do not enumerate a fixed provider list in this skill because the wizard and role model pool own the ordered tokens.
|
|
277
277
|
|
|
@@ -299,9 +299,9 @@ Do not continue from the rendered prompt if this command fails. This record
|
|
|
299
299
|
associates the current-session lead with a verified invocation specification;
|
|
300
300
|
it does not claim that the host exposed or attested the delivered prompt bytes.
|
|
301
301
|
|
|
302
|
-
The python function underneath
|
|
302
|
+
The python function underneath allocates the run sequence number and writes `run-context-*.json` under the per-task lock (`~/.okstra/.locks/<task-key>.lock`), then writes `run-inputs-*.json` + all manifests + discovery files outside that lock, and registers the run in `~/.okstra/recent.jsonl` with status `prepared` under the central `~/.okstra/.lock` (a registration failure is reported on stderr and does not fail prepare).
|
|
303
303
|
|
|
304
|
-
**
|
|
304
|
+
**Not enforced:** `tests-js/wizard.test.mjs` pins the argv the wizard produces (`orderedRenderArgv` preserves the Python role selection bytes and repeated role order), not the argv you pass. Prepare's parser defaults most flags to `""` (e.g. `--directive`), so a dropped empty value is indistinguishable from its default and nothing rejects it — passing every token verbatim is on you.
|
|
305
305
|
|
|
306
306
|
You can delete the literal state-file path after this point — its job is done. Invoke `command rm` with the literal path (e.g. `command rm /var/folders/.../okstra-wizard.AbCd.json`), not a shell variable. `command` is what keeps a `rm='rm -i'` alias from turning this into a confirmation prompt nobody is there to answer.
|
|
307
307
|
|
|
@@ -462,9 +462,28 @@ The three branches that end or pause the queue — "Next stage not yet ready", "
|
|
|
462
462
|
|
|
463
463
|
Do not read the wizard state file directly. `okstra wizard outcome` exposes any release-handoff PR template write as `outcome.persistActions[]`; execute those actions before `render-bundle`.
|
|
464
464
|
|
|
465
|
+
## Comparison material for a direction choice
|
|
466
|
+
|
|
467
|
+
When the user has to choose an implementation direction — a finished `implementation-option-selection` run with routing `pending-direction-selection`, or the planning wizard's `selected_direction_pick` step — and asks for material comparing the directions, build it from the report record, not from memory or a hand read of the JSON:
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
~/.okstra/bin/okstra option-comparison --report <final-report-implementation-option-selection-NNN.data.json>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
At `selected_direction_pick` the report path is the option value. The command prints JSON; every number in the reply comes from it. Use the recorded `weightedScore` as printed; do not recompute it. Write the reply in the user's language, in this order:
|
|
474
|
+
|
|
475
|
+
1. **Lead-in** — one or two sentences on what the directions share and the axes they split on, drawn from `narrative.comparisonOverview` and each option's `coreMechanism`.
|
|
476
|
+
2. **Score table** — a Markdown table: one row per `criteria[]` entry in order, a weight column, one column per option (`<id> <short name>`), and a last row with each option's `weightedScore`. Write each criterion as its identifier with a translation in the user's language, e.g. `requirement-fit(요구사항 부합)`.
|
|
477
|
+
3. **Coverage and blockers** — one line per option, or one line when they agree: `coverage.verdict`, the `coverage.requirementIds` it covers, and the `safetyBlockers` and `unresolvedFeasibilityFacts` counts.
|
|
478
|
+
4. **Feasibility votes** — a Markdown table: one row per option, one column per `workers[]` entry, each cell that worker's `votes[<worker>].verdict`.
|
|
479
|
+
5. **Per direction** — one paragraph per option, recommended first and marked as recommended, with its `weightedScore`: what it does (`coreMechanism`), the criteria that carry its score (its high scores on heavy weights), and its main cost, taken from its low `scoreRationales` and the `counterevidence` of its votes. Name a worker who voted `not-feasible` or `uncertain` and give that worker's `rationale`.
|
|
480
|
+
6. **Remaining steps** — restate `nextStep`: where the direction is chosen (the HTML report's direction-selection Export saved under `user-responses/`) and how planning then picks it up.
|
|
481
|
+
|
|
482
|
+
The layout is guidance for the reply. Nothing checks the reply text; the command guarantees only the numbers.
|
|
483
|
+
|
|
465
484
|
## Concurrency
|
|
466
485
|
|
|
467
|
-
- `prepare_task_bundle`
|
|
486
|
+
- `prepare_task_bundle` takes the per-task lock `~/.okstra/.locks/<task-key>.lock` only while it allocates the run sequence number and writes the run-context file; concurrent invocations on the same task wait for that step and get distinct sequence numbers, and the rest of prepare is not serialized by it. Different tasks proceed in parallel.
|
|
468
487
|
- Each wizard run owns its own state file (one per `okstra wizard new-state-file`); two parallel skill invocations do not collide.
|
|
469
488
|
- The skill must NOT call `okstra.sh` (or any other bash entrypoint) that would re-implement the orchestration. The wizard + `render-bundle` is the single authority.
|
|
470
489
|
|
|
@@ -491,6 +510,6 @@ Follow the rendered launch prompt's "Progress, remaining work, and recommendatio
|
|
|
491
510
|
## Output Rules
|
|
492
511
|
|
|
493
512
|
- Echo each captured answer (`result.echo`) on one short line so the user sees what was registered.
|
|
494
|
-
- Name every file you show the user as a markdown link — `[<
|
|
513
|
+
- Name every file you show the user as a markdown link — `[<short label>](<absolute path>)`, with the absolute path inside the parentheses and a short label naming what the file is. A relative destination does not open from an external program. That is the only form the host renders as clickable; a path in backticks is text the user has to copy out. The `report-finalize` result's `reportPaths.markdown` carries the run's report, report record, and team state already in that form. Commands stay in backticks — a link is for a file, not for something to run.
|
|
495
514
|
- Never invent identity; if a `text` prompt returns an empty answer where the wizard rejects it, the user must retry.
|
|
496
515
|
- After Step 6, begin the lead workflow without re-summarizing the skill itself. For a single run, finish after Step 6 and any same-run recovery, unless the user has already authorized continuing the task through further phases. In an unattended chain where `orchestration.chainStages` has 2+ elements, repeat Step 6 per stage until Step 7's queue is empty (or it stops at a "not ready" / exception gate), then finish. When `report-finalize` returns `recovery.mode: same-run`, continue the authorized corrections in this run and execute `recovery.resumeCommand` before closeout; preserve approvals and model choices without reopening the wizard. The command and owner issues are supplied by `report_finalize._finalize_recovery`. When the lead (or this skill, after the lead returns) reports a successfully finalized run over, close with the user's next action — one command they can run now. A prohibition is not a next action. Take the pointer from the `report-finalize` result's top-level `nextRecommendedPhase` (`phase`, `status`, `rationale`; also on stderr as `next phase status:` / `next phase:` / `next phase rationale:`) — do not re-derive it from the report, and treat a `nextRecommendedPhaseError` as "pointer unreadable", said in one line before the `validate-run` branch. The same result also carries `nextCommand` — `{command, note}`, the table below already applied to this run. When `command` is non-empty it is the close; when it is empty the `note` says what to do with the `rationale` instead. After `implementation-planning`, open `blocks: approval` rows → `/okstra-user-response`. A recorded `accept-risk` / `select` / `answer` is not an open blocker. No open approval blocker → `/okstra-run` → `implementation` or `--approve` (do not start another planning run; do not say `/okstra-inspect`). For every other task type, quote the pointer's `rationale` in every branch — that sentence is the report's own reason and it is what the user asked to be analysed. Pointer `status: ready` → `/okstra-run` for that phase; `status: terminal` → say the task is finished, name any follow-up tasks this run registered, and do not say `/okstra-inspect`; `status: blocked` → issue the command the `rationale` calls for (`/okstra-user-response` for the `C-NNN` ids, `/okstra-run` for the phase it names); `validate-run` failed with `recovery.mode: phase-reentry` → name the cause and use `nextCommand` for the recorded earlier phase; otherwise `/okstra-inspect status`.
|