okstra 0.171.0 → 0.173.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 +8 -6
- package/docs/architecture/storage-model.md +11 -0
- package/docs/architecture.md +29 -14
- package/docs/cli.md +40 -7
- package/docs/for-ai/skills/okstra-user-response.md +2 -2
- package/docs/performance-improvement-plan-v2.md +6 -5
- package/docs/project-structure-overview.md +24 -14
- package/docs/task-process/README.md +5 -3
- package/docs/task-process/error-analysis.md +2 -2
- package/docs/task-process/final-verification.md +2 -2
- package/docs/task-process/implementation-option-selection.md +70 -0
- package/docs/task-process/implementation-planning.md +23 -15
- package/docs/task-process/requirements-discovery.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +30 -6
- package/runtime/bin/lib/okstra/cli.sh +5 -1
- package/runtime/bin/lib/okstra/globals.sh +1 -0
- package/runtime/bin/lib/okstra/usage.sh +3 -0
- package/runtime/bin/okstra.sh +2 -0
- package/runtime/prompts/duties/direction-selection-worker.md +44 -0
- package/runtime/prompts/duties/planning-worker.md +12 -4
- package/runtime/prompts/launch.template.md +4 -0
- package/runtime/prompts/lead/adapters/cmux.md +1 -1
- package/runtime/prompts/lead/context-loader.md +1 -1
- package/runtime/prompts/lead/convergence.md +5 -5
- package/runtime/prompts/lead/okstra-lead-contract.md +42 -17
- package/runtime/prompts/lead/plan-body-verification.md +42 -14
- package/runtime/prompts/lead/report-writer.md +38 -15
- package/runtime/prompts/lead/team-contract.md +2 -0
- package/runtime/prompts/profiles/_clarification-recommendation.md +3 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -2
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/error-analysis.md +3 -3
- package/runtime/prompts/profiles/final-verification.md +3 -3
- package/runtime/prompts/profiles/forbidden-actions.json +7 -0
- package/runtime/prompts/profiles/implementation-option-selection.md +35 -0
- package/runtime/prompts/profiles/implementation-planning.md +56 -37
- package/runtime/prompts/profiles/implementation.md +2 -1
- package/runtime/prompts/profiles/improvement-discovery.md +1 -1
- package/runtime/prompts/profiles/requirements-discovery.md +3 -3
- package/runtime/prompts/wizard/prompts.ko.json +9 -1
- package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/external/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +1 -1
- package/runtime/python/okstra_ctl/agent_activity.py +306 -0
- package/runtime/python/okstra_ctl/agent_invocation.py +1 -0
- package/runtime/python/okstra_ctl/analysis_packet.py +6 -0
- package/runtime/python/okstra_ctl/clarification_items.py +37 -20
- package/runtime/python/okstra_ctl/exact_coverage.py +128 -0
- package/runtime/python/okstra_ctl/fix_cycles.py +3 -1
- package/runtime/python/okstra_ctl/implementation_direction.py +836 -0
- package/runtime/python/okstra_ctl/implementation_options.py +479 -0
- package/runtime/python/okstra_ctl/lead_events.py +47 -4
- package/runtime/python/okstra_ctl/plan_items.py +51 -3
- package/runtime/python/okstra_ctl/render.py +12 -3
- package/runtime/python/okstra_ctl/render_final_report.py +1 -0
- package/runtime/python/okstra_ctl/report_contract.py +45 -13
- package/runtime/python/okstra_ctl/report_finalize.py +51 -14
- package/runtime/python/okstra_ctl/report_html/common.py +5 -3
- package/runtime/python/okstra_ctl/report_html/render.py +4 -2
- package/runtime/python/okstra_ctl/report_html/router.py +4 -0
- package/runtime/python/okstra_ctl/report_html/view_models/implementation_option_selection.py +32 -0
- package/runtime/python/okstra_ctl/report_html/view_models/implementation_planning.py +42 -11
- package/runtime/python/okstra_ctl/report_translation.py +14 -0
- package/runtime/python/okstra_ctl/report_views.py +148 -12
- package/runtime/python/okstra_ctl/run.py +350 -2
- package/runtime/python/okstra_ctl/scope_provenance.py +15 -9
- package/runtime/python/okstra_ctl/user_response.py +75 -0
- package/runtime/python/okstra_ctl/wizard.py +144 -0
- package/runtime/python/okstra_ctl/worker_audit_ledger.py +150 -0
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +2 -0
- package/runtime/python/okstra_ctl/workflow.py +29 -7
- package/runtime/schemas/final-report-v2.0.schema.json +1623 -143
- package/runtime/skills/okstra-user-response/SKILL.md +2 -2
- package/runtime/templates/reports/final-report-v2.template.md +12 -0
- package/runtime/templates/reports/final-verification-input.template.md +1 -1
- package/runtime/templates/reports/html/assets/base.css +7 -0
- package/runtime/templates/reports/html/base.template.html +3 -2
- package/runtime/templates/reports/html/i18n/en.json +27 -2
- package/runtime/templates/reports/html/i18n/ko.json +27 -2
- package/runtime/templates/reports/html/macros/forms.html +42 -4
- package/runtime/templates/reports/html/tasks/implementation-option-selection.template.html +49 -0
- package/runtime/templates/reports/html/tasks/implementation-planning.template.html +61 -2
- package/runtime/templates/reports/i18n/en.json +17 -0
- package/runtime/templates/reports/implementation-input.template.md +4 -2
- package/runtime/templates/reports/implementation-planning-input.template.md +18 -4
- package/runtime/templates/reports/improvement-discovery-input.template.md +1 -1
- package/runtime/templates/reports/md/tasks/implementation-option-selection.template.md +13 -0
- package/runtime/templates/reports/md/tasks/implementation-planning.template.md +17 -0
- package/runtime/templates/reports/report.js +137 -21
- package/runtime/templates/reports/task-brief.template.md +9 -3
- package/runtime/templates/reports/user-response.template.md +28 -5
- package/runtime/templates/worker-prompt-preamble.md +16 -0
- package/runtime/validators/validate-implementation-plan-stages.py +106 -1
- package/runtime/validators/validate-report-views.py +2 -2
- package/runtime/validators/validate-run.py +1124 -54
- package/runtime/validators/validate_improvement_report.py +5 -1
- package/runtime/validators/validate_session_conformance.py +523 -35
- package/src/cli-registry.mjs +7 -0
- package/src/commands/execute/codex-run.mjs +1 -0
- package/src/commands/execute/render-bundle.mjs +1 -0
- package/src/commands/report/agent-activity.mjs +21 -0
package/README.md
CHANGED
|
@@ -206,7 +206,7 @@ To start a task outside a Claude Code session:
|
|
|
206
206
|
--project-id <id> \
|
|
207
207
|
--task-group <group> \
|
|
208
208
|
--task-id <id> \
|
|
209
|
-
--task-type <requirements-discovery|improvement-discovery|project-analysis|change-impact-analysis|error-analysis|implementation-planning|implementation|final-verification|release-handoff> \
|
|
209
|
+
--task-type <requirements-discovery|improvement-discovery|project-analysis|change-impact-analysis|error-analysis|implementation-option-selection|implementation-planning|implementation|final-verification|release-handoff> \
|
|
210
210
|
--base-ref <branch|tag|sha> \
|
|
211
211
|
--task-brief ./brief.md
|
|
212
212
|
```
|
|
@@ -215,27 +215,29 @@ To start a task outside a Claude Code session:
|
|
|
215
215
|
|
|
216
216
|
This starts a new `claude` process in the lead role. For the complete argument list, see `okstra.sh --help` or [`docs/cli.md`](docs/cli.md).
|
|
217
217
|
|
|
218
|
-
Notable flags
|
|
218
|
+
Notable workflow flags:
|
|
219
219
|
|
|
220
220
|
- `--executor claude|codex|antigravity` — selects the provider that may mutate files for `--task-type implementation`. The other two providers are dispatched as strict read-only verifiers in the same run ([`docs/cli.md`](docs/cli.md#--executor)).
|
|
221
221
|
- `--work-category bugfix|feature|refactor|ops|improvement` — directly classifies work when the lifecycle skips the `requirements-discovery` phase.
|
|
222
222
|
- `--approve` — with `--approved-plan`, toggles the plan's YAML frontmatter `approved` field from `false` to `true`, replacing the removed `--ack-approved` alias and the former `[ ] Approved` checkbox marker.
|
|
223
|
+
- `--selected-direction <selection-final-report.md>` — starts a new `implementation-planning` run from a validated `implementation-option-selection` report. Existing planning reruns continue through `--clarification-response`.
|
|
223
224
|
|
|
224
225
|
Major workflow changes added to `main` after 0.8.0:
|
|
225
226
|
|
|
226
|
-
- **Automatic isolated worktrees for every task type** — During preparation, `okstra-ctl` runs `git worktree add ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>` once per task key to create an isolated working tree and a `<work-category-namespace>/<task-id-segment>` branch (for example, `feature/dev-9436` or `fix/dev-7311`). The user chooses the base ref with `--base-ref`, using the same choices as the release-handoff PR base picker: `main`, `dev`, `staging`, `preprod`, `prod`, or a custom value. It is required in the first phase; the okstra-run skill collects it through `AskUserQuestion`, while non-interactive callers must pass `--base-ref` explicitly. Later **non-`implementation`** phases for the same task key (`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`) reuse the same path and branch. `implementation` runs are **stage-isolated**: each run executes one stage in its own `.../<task>/stage-<N>/` worktree on a `<work-category-namespace>/<task>-s<N>` branch, so independent stages with `depends-on (none)` can run concurrently without sharing a tree. The registry reserves both task keys and **stage keys** with flock. Provisioning is skipped when the caller is already in another worktree or project_root is not a Git repository; stage isolation degrades to a flat path in those cases. Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` plus release/removal of the registry entry. Details: [`docs/architecture.md`](docs/architecture.md), in the *Task type* section, and [`docs/cli.md#--executor`](docs/cli.md#--executor).
|
|
227
|
+
- **Automatic isolated worktrees for every task type** — During preparation, `okstra-ctl` runs `git worktree add ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>` once per task key to create an isolated working tree and a `<work-category-namespace>/<task-id-segment>` branch (for example, `feature/dev-9436` or `fix/dev-7311`). The user chooses the base ref with `--base-ref`, using the same choices as the release-handoff PR base picker: `main`, `dev`, `staging`, `preprod`, `prod`, or a custom value. It is required in the first phase; the okstra-run skill collects it through `AskUserQuestion`, while non-interactive callers must pass `--base-ref` explicitly. Later **non-`implementation`** phases for the same task key (`requirements-discovery` → `error-analysis` → `implementation-option-selection` → `implementation-planning` → `final-verification` → `release-handoff`) reuse the same path and branch. `implementation` runs are **stage-isolated**: each run executes one stage in its own `.../<task>/stage-<N>/` worktree on a `<work-category-namespace>/<task>-s<N>` branch, so independent stages with `depends-on (none)` can run concurrently without sharing a tree. The registry reserves both task keys and **stage keys** with flock. Provisioning is skipped when the caller is already in another worktree or project_root is not a Git repository; stage isolation degrades to a flat path in those cases. Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` plus release/removal of the registry entry. Details: [`docs/architecture.md`](docs/architecture.md), in the *Task type* section, and [`docs/cli.md#--executor`](docs/cli.md#--executor).
|
|
227
228
|
- **`release-handoff` lifecycle phase** — runs immediately after `final-verification` returns `verdict=accepted`. The current Okstra lead drafts the candidate messages and PR body inline, then uses the selected host adapter's user-prompt operation for the delivery choices. Only the Git/GitHub CLI commands selected through those menus are run. Force pushes, direct pushes to the base branch, hook bypasses (`--no-verify`), and release publication (`gh release`, `npm publish`, and similar commands) are prohibited. This phase does not edit source code. Profile: [`prompts/profiles/release-handoff.md`](prompts/profiles/release-handoff.md).
|
|
228
229
|
- **Configurable PR body template** (release-handoff) — PR bodies are populated from a Markdown template selected in this order: one-time override (`--pr-template-path` or the okstra-run Step 6 prompt) → `prTemplatePath` in `<project_root>/.okstra/project.json` → `prTemplatePath` in `~/.okstra/config.json` → the installed default at `~/.okstra/templates/pr/pr-body.template.md`. Register a template with `okstra config set pr-template-path <path> [--scope project|global]`; project scope accepts a path relative to the project root, while global scope requires an absolute path or a path beginning with `~/`. `okstra config get pr-template-path --scope all` prints every scoped value and the effective winner. The default template contains `## Summary`, `## Changes`, `## Test plan`, and `## Linked issues`, plus HTML comment guidance that the lead removes immediately before PR creation.
|
|
229
230
|
- **Profile worker-roster validation** — `--workers <csv>` and the okstra-run Step 6 worker prompt accept only the worker IDs declared in the selected profile's `Required workers:` block. Requesting a worker absent from the profile—for example, `codex` or `antigravity` for `release-handoff`—fails with a clear error, and the interactive prompt shows only workers accepted by that profile.
|
|
230
231
|
- **Host-aware lead adapters** — `okstra-run` resolves the current harness through the same dynamic host registry used by the terminal front door. Claude Code, Codex, Antigravity, Grok, and Kimi keep their matching provider assignment native; `external` remains the explicit all-CLI host. Host and provider are separate axes, and every non-native worker assignment runs through the deterministic `okstra worker-dispatch` process boundary. `leadAssignment` and every `workerAssignments[]` row record provider, model, and `runner`. `okstra codex-dispatch` remains a compatibility alias for the provider-neutral dispatcher.
|
|
231
232
|
- **Per-invocation duty contracts** — every Okstra-owned LLM call composes three independently managed inputs: a persisted model assignment, a functional duty contract from `prompts/duties/`, and call-specific task instructions. The final prompt and adjacent metadata carry exactly five SHA-256 digests (catalog, assignment, duty, instruction, prompt). Code-owned process launches fail before execution when verification fails; host-native calls record a verified-specification link without claiming that Okstra observed the bytes delivered by the host. Standalone code-review and schedule-verification calls use the same contract under `.okstra/agent-invocations/`.
|
|
233
|
+
- **Implementation direction selection before detailed planning** — `implementation-option-selection` is a read-only lifecycle phase between error analysis and planning. Comparison mode evaluates the merged raw candidates and displays at most three ranked directions. Every displayed direction has `coveragePercent == 100`, `scopePrecisionPercent == 100`, no unmapped commitment, and no contradicted requirement. The user confirms one direction in a separate `DIRECTION SELECTION` response before a new planning run starts with `--selected-direction`. `implementation-planning` then expands that one direction into files, stages, validation, and rollback, and the resulting plan still requires its own approval. A preselected direction is validated without generating alternatives. Existing approved plans without `planningContract: selected-direction` keep the legacy `--implementation-option` execution path.
|
|
232
234
|
- **Multi-stage `implementation-planning` / `implementation`** — `implementation-planning` always produces a Stage Map and N stage sections. Each stage has no more than six steps, and stages with `depends-on (none)` can be implemented concurrently in separate `implementation` runs. Each `implementation` invocation runs a single stage, selected with `--stage <auto|N>`, and creates an evidence sidecar at `carry/stage-<N>.json` for automatic carry-in to the next stage. The `implementation-planning` run directory accumulates `consumers.jsonl` reverse links that record which run consumed each stage.
|
|
233
235
|
- **AI-prepared design preparation (implementation-planning → implementation)** — `implementation-planning` detects which stages need design input (domain contract, DB/table schema, external interface, transaction/consistency, transformation mapping, lifecycle, rollout/observability, manual user test) and has the AI draft a concrete proposal first, instead of handing the user an empty design document. Each item is assessed as `ready`, `provisional`, `blocked`, or `not-applicable`; a simple task may declare `no-design-inputs`. Phase 7 materializes an Okstra-owned request under `design-prep-requests/`, and `okstra design-prep <list|show|write>` or the okstra-run wizard records the confirmed answer as an **append-only** revision under `design-prep-inputs/`—neither path ever edits the approved planning snapshot. Before creating its worktree, `implementation` resolves only the items its selected stage cites in `stageRefs`: safe `provisional` assumptions are injected into the executor prompt so work proceeds, while an unsafe open decision makes only that stage wait or replan. A markerless legacy plan continues with a `legacy-unassessed` warning. Storage authorities: [`docs/architecture/storage-model.md`](docs/architecture/storage-model.md). CLI: [`docs/cli.md#okstra-design-prep`](docs/cli.md#okstra-design-prep).
|
|
234
|
-
- **Phase 6 plan-body verification (implementation-planning only)** — Immediately after the report-writer worker drafts the final report and before the user approval gate, the lead performs one post-verification round.
|
|
236
|
+
- **Phase 6 plan-body verification (implementation-planning only)** — Immediately after the report-writer worker drafts the final report and before the user approval gate, the lead performs one post-verification round. A selected-direction plan starts with `P-Dir-1`; a legacy candidate plan retains `P-Opt-*`. Both branches add `P-Step-*`, `P-Dep-*`, `P-Val-*`, and `P-Rb-*` items and ask every analyzer worker for an `AGREE`, `DISAGREE(a-e)`, or `SUPPLEMENT` verdict. The aggregate result is `passed`, `passed-with-dissent`, `blocked-by-disagreement`, or `aborted-non-result`. The frontmatter `approved` field is always published as `false`; a blocking result keeps it false and becomes a row in `## 1. Clarification Items`. For fast iteration, opt out with `--no-plan-verification`. Contract details: the "Plan-body verification mode" section of [`prompts/lead/convergence.md`](prompts/lead/convergence.md) and [`docs/cli.md#--no-plan-verification`](docs/cli.md#--no-plan-verification).
|
|
235
237
|
- **Brief as translation layer + Step 6.5 reporter batch confirmation** — `okstra-brief-gen` converts external input—an issue ticket, requirements document, or user message—verbatim and marks okstra-added content as labeled augmentation. Step 6.5 asks the user to confirm in one batch whether that conversion changed meaning and records the result in `Reporter Confirmations`. Every analysis profile requires this section before phase analysis begins; `validators/validate-brief.py` enforces the requirement.
|
|
236
238
|
- **Artifact-home rule (`.okstra/`)** — `<project>/.okstra/` is the only project artifact root owned by okstra. Anything outside this root is not okstra memory and may be read only when explicitly cited in Source Material or Reporter Confirmations. Writing outside the root requires the same explicit requested path. Internal equivalents are `glossary.md` for terminology and `decisions/<NNNN>-<slug>.md` for decision records, evaluated during `implementation-planning`.
|
|
237
|
-
- **Separate AI and human final-report views** — New runs write `final-report-<task-type>-<seq>.data.json` against `schemas/final-report-v2.0.schema.json`. Phase 7 independently derives compact AI handoff Markdown with `templates/reports/final-report-v2.template.md` and a task-specific, self-contained human HTML view from that same data. Each of the
|
|
238
|
-
- **`improvement-discovery` task type (sidetrack entry point)** — Within a codebase scope and priority-lens allowlist, multi-worker consensus produces N improvement candidates, with a default of eight and a hard cap of 12. This is a sidetrack entry point outside `PHASE_SEQUENCE`; the user selects candidates and starts each under a new task ID with `requirements-discovery`, `implementation-
|
|
239
|
+
- **Separate AI and human final-report views** — New runs write `final-report-<task-type>-<seq>.data.json` against `schemas/final-report-v2.0.schema.json`. Phase 7 independently derives compact AI handoff Markdown with `templates/reports/final-report-v2.template.md` and a task-specific, self-contained human HTML view from that same data. Each of the eleven task types owns a dedicated template under `templates/reports/html/tasks/`; the HTML emphasizes the task's decisions, findings, visualizations, evidence, and next actions instead of exposing worker discussion as the main narrative. CSS / JavaScript remain inline, print and no-JavaScript reading are supported, and `Export user response` writes the next-phase sidecar. Existing schema v1 data and quick Markdown reports retain the legacy conditional renderer.
|
|
240
|
+
- **`improvement-discovery` task type (sidetrack entry point)** — Within a codebase scope and priority-lens allowlist, multi-worker consensus produces N improvement candidates, with a default of eight and a hard cap of 12. This is a sidetrack entry point outside `PHASE_SEQUENCE`; the user selects candidates and starts each under a new task ID with `requirements-discovery`, `implementation-option-selection`, or `error-analysis`. Lens enum SSOT: [`scripts/okstra_ctl/improvement_lenses.py`](scripts/okstra_ctl/improvement_lenses.py). Output section: `## 5.9 Improvement Candidates` (11-column table). Validator: [`validators/validate_improvement_report.py`](validators/validate_improvement_report.py).
|
|
239
241
|
- **Read-only analysis task types (independent sidetracks)** — `project-analysis` maps the current project's components, dependencies, entry points, data stores, external systems, and feature index. `feature-analysis` traces one existing feature through flows, domain rules, state changes, integrations, and test coverage. `change-impact-analysis` maps the blast radius of a proposed change across preserved behavior, dependencies, tests, and operations. These are independent sidetracks outside `PHASE_SEQUENCE`, not lifecycle phases. No edits, tests, builds, migrations, or deployments are allowed against the target project. Start analysis runs through `/okstra-run`; its wizard owns target and evidence collection before calling the internal Node render command. The final report remains immutable: the HTML `Analysis Review` records accept, revision, or reject in a user-response sidecar. A revision request prioritizes a same-task, same-type full rerun; that rerun reanalyzes the whole confirmed scope and resolves every affected report ID instead of patching only the disputed rows. Input details: [`docs/cli.md`](docs/cli.md#analysis-sidetrack-task-types).
|
|
240
242
|
|
|
241
243
|
<a id="ops-commands"></a>
|
|
@@ -19,6 +19,7 @@ The task manifest, task index, instruction set, runs, and history are collected
|
|
|
19
19
|
- `verification-target.md` for final verification and optional `directive.txt`
|
|
20
20
|
- `host-orchestration-rules.md`, the staged copy of the host orchestration rules for this task type, when the run has one
|
|
21
21
|
- `clarification-response.md`, the user's carried-in clarification answers, when the run has any
|
|
22
|
+
- `selected-direction.json`, the validated implementation direction snapshot for a new `implementation-planning` run
|
|
22
23
|
- `final-report-schema.json`, `final-report-template.md`
|
|
23
24
|
- canonical `lead-execution-prompt.md` plus the `claude-execution-prompt.md` compatibility alias
|
|
24
25
|
- `runs/<task-type>/`
|
|
@@ -70,6 +71,16 @@ After the host-native lead takes over, the lead and its assigned workers add the
|
|
|
70
71
|
- `runs/implementation/carry/stage-<N>.json` *(implementation only: execution evidence sidecar. Stage-SHARED like `consumers.jsonl` — it lives flat under the task-type run dir, NOT under `stage-<N>/`, because the next stage's carry-in and `backfill_done_from_carry` glob it without knowing the producing run's layout)*
|
|
71
72
|
- `consumers.jsonl` *(implementation-planning only: backlinks to the impl-run that consumed each stage in this plan; append-only)*
|
|
72
73
|
|
|
74
|
+
#### Direction-selection handoff authorities
|
|
75
|
+
|
|
76
|
+
| Artifact | Content authority | Digest contract |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Option-selection data report | The immutable `data.json` records the validated candidates. | It does not store the handoff digest. |
|
|
79
|
+
| User-response sidecar | In comparison mode, the sidecar records the confirmed `IO-NNN` choice without changing the report. | `source-data-sha256` records the digest of the exact `data.json` bytes. Planning prepare recomputes SHA-256 over those bytes and rejects a mismatch. |
|
|
80
|
+
| Selected-direction snapshot | Planning prepare writes the normalized choice to `instruction-set/selected-direction.json`; the planning report cites it through `selectedDirectionRef`. | `sourceDataSha256` records the digest that planning prepare verified. |
|
|
81
|
+
|
|
82
|
+
Preselected-validation mode records its upstream confirmation in the option-selection report and needs no user-selection sidecar. Planning prepare still writes the selected-direction snapshot with the verified source-data digest.
|
|
83
|
+
|
|
73
84
|
Design-preparation storage has three separate authorities:
|
|
74
85
|
|
|
75
86
|
| Artifact | Owner | Mutation contract |
|
package/docs/architecture.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
Its core capabilities at a glance are:
|
|
14
14
|
|
|
15
15
|
- **Task identity**: Creates or reuses a task root using a stable task key based on `<project-id>/<task-group>/<task-id>`, and consistently updates the manifest, index, and timeline.
|
|
16
|
-
- **Profiles by task type**: Loads standard task-type profiles such as `requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`, `final-verification`, and `release-handoff` to render the instruction set.
|
|
16
|
+
- **Profiles by task type**: Loads standard task-type profiles such as `requirements-discovery`, `error-analysis`, `implementation-option-selection`, `implementation-planning`, `implementation`, `final-verification`, and `release-handoff` to render the instruction set.
|
|
17
17
|
- **Run lifecycle**: Non-stage runs use `runs/<task-type>/` as the run directory, while `implementation` and single-stage `final-verification` use `runs/<task-type>/stage-<N>/`. Manifests, prompts, state, reports, sessions, worker results, and logs accumulate beneath the resolved run directory, and the filename suffix `-<task-type>-<seq>` separates reruns of the same phase.
|
|
18
18
|
- **Single python authority**: All prepare wiring—resolving profiles/workers/models, computing paths, rendering, and central record_start—is concentrated in a single function, [`okstra_ctl.run.prepare_task_bundle()`](../scripts/okstra_ctl/run.py). `okstra.sh` and the `okstra-run` skill are thin callers of that same function and do not pass state through environment variables. Task identity, paths, and workflow state are recalculated from authoritative on-disk files every time.
|
|
19
19
|
- **Host-aware handoff**: Claude Code, Codex, Antigravity, Grok, and Kimi can keep their current native session as the lead. The standalone compatibility launcher still starts a new `claude` process by default, while the external adapter uses registered CLI wrappers. Every path consumes the same `prepare_task_bundle` outputs.
|
|
@@ -134,7 +134,7 @@ Runtime entry points are consolidated in Python packages. Bash and skills only c
|
|
|
134
134
|
### Runtime assets (templates + lead resources)
|
|
135
135
|
|
|
136
136
|
- `prompts/launch.template.md` — lead prompt template.
|
|
137
|
-
- `prompts/profiles/*.md` —
|
|
137
|
+
- `prompts/profiles/*.md` — eleven task-type profiles: the seven lifecycle profiles (`requirements-discovery`, `error-analysis`, `implementation-option-selection`, `implementation-planning`, `implementation`, `final-verification`, `release-handoff`) plus `improvement-discovery`, `project-analysis`, `feature-analysis`, and `change-impact-analysis` sidetracks.
|
|
138
138
|
- `templates/project-docs/task-index.template.md` · `templates/reports/final-report.template.md` · `templates/reports/final-report-v2.template.md` · `templates/reports/html/` · `templates/reports/settings.template.json` — runtime render inputs. The unversioned Markdown template is the schema v1 compatibility template; the v2 Markdown and task-specific HTML trees are separate audiences.
|
|
139
139
|
- `<PROJECT_ROOT>/.okstra/project.json` — project self-registration. Created/verified automatically on the first okstra.sh run; when `--project-root` is omitted, PROJECT_ROOT is resolved through ancestors / `git toplevel`.
|
|
140
140
|
|
|
@@ -317,7 +317,7 @@ The standard `okstra` workflow applies the following team contract consistently
|
|
|
317
317
|
|
|
318
318
|
`PromptPlan` is the generating SSOT for functional prompt audience, equality group, packet-only input, coding-preflight eligibility, required headers, and size limits. It resolves only from task type, worker ID, the manifest's executor worker ID, and dispatch kind; provider and model identity never assign scope. The resolved analyser order used for improvement primary-pass rotation is a separate roster operation and is not a `PromptPlan` input.
|
|
319
319
|
|
|
320
|
-
The same analysis-core rule applies to `requirements-discovery`, `error-analysis`, `implementation-planning`, `improvement-discovery`, and `final-verification`: every selected initial analyser receives the same normalized semantic body and independently covers the whole common scope. In `implementation`, the implementation executor is excluded from verifier equality; all selected implementation verifiers form their own equality group. If the roster contains one verifier, individual header rules still apply, while one verifier makes normalized equality a deliberate no-op. Report-writer and reverify prompts are excluded from analysis equality groups because they author or adjudicate existing findings instead of producing an initial independent analysis.
|
|
320
|
+
The same analysis-core rule applies to `requirements-discovery`, `error-analysis`, `implementation-option-selection`, `implementation-planning`, `improvement-discovery`, and `final-verification`: every selected initial analyser receives the same normalized semantic body and independently covers the whole common scope. In `implementation`, the implementation executor is excluded from verifier equality; all selected implementation verifiers form their own equality group. If the roster contains one verifier, individual header rules still apply, while one verifier makes normalized equality a deliberate no-op. Report-writer and reverify prompts are excluded from analysis equality groups because they author or adjudicate existing findings instead of producing an initial independent analysis.
|
|
321
321
|
|
|
322
322
|
The policy selects one audience preamble: analysis uses `templates/worker-prompt-preamble.md`; executor and verifier use `templates/implementation-worker-preamble.md`; report writing uses `templates/report-writer-prompt-preamble.md`. Every initial audience also reads the shared `templates/worker-error-contract.md`. Only implementation executor/verifier prompts receive `**Coding preflight pack:**`; a report writer never loads implementation coding instructions.
|
|
323
323
|
|
|
@@ -434,11 +434,12 @@ Each task type enforces phase-specific allowed and forbidden actions. A run crea
|
|
|
434
434
|
|
|
435
435
|
| task type | Purpose | Core artifacts | Next recommended phase | Code changes allowed? |
|
|
436
436
|
|---|---|---|---|---|
|
|
437
|
-
| `requirements-discovery` | Classify the request as bugfix, feature, refactor, ops, or improvement, then route it to a safe next phase | work category, routing decision, missing-input list, clarification requests | `pending-routing-decision`
|
|
438
|
-
| `error-analysis` | Analyze the symptoms, causes, and reproduction gaps of a reported error/incident based on evidence | symptom/trigger summary, root-cause hypotheses, reproduction gap, validation path | `implementation-
|
|
439
|
-
| `implementation-
|
|
437
|
+
| `requirements-discovery` | Classify the request as bugfix, feature, refactor, ops, or improvement, then route it to a safe next phase | work category, routing decision, missing-input list, clarification requests | `error-analysis`, `implementation-option-selection`, or `pending-routing-decision` | No |
|
|
438
|
+
| `error-analysis` | Analyze the symptoms, causes, and reproduction gaps of a reported error/incident based on evidence | symptom/trigger summary, root-cause hypotheses, reproduction gap, validation path | `implementation-option-selection` after a credible cause, or `error-analysis` for continued investigation | No |
|
|
439
|
+
| `implementation-option-selection` | Compare or validate implementation directions before detailed planning | up to three ranked directions, per-direction `coveragePercent` and `scopePrecisionPercent`, rejected-candidate audit, separate `DIRECTION SELECTION` response | `implementation-planning` after a valid direction is confirmed; otherwise `blocked` | No (strictly read-only; source edits, builds, tests, migrations, and deploys are prohibited) |
|
|
440
|
+
| `implementation-planning` | Expand one selected direction into an executable plan without changing its mechanism or architecture boundary | selected-direction snapshot/reference, direction realization, affected-file list, Stage Map, validation/rollback, exact plan coverage, YAML frontmatter `approved: false`, **§5.5.9 Plan Body Verification**. Existing plans without `planningContract: selected-direction` retain the legacy option-candidate and `implementation-option:` contract | `implementation` after separate plan approval, or `implementation-option-selection` when the direction is invalidated | No |
|
|
440
441
|
| `implementation` | Modify source code according to the approved `implementation-planning` final report. **One run executes exactly one stage** (selected with `--stage <auto\|N>`) | commit list, diff summary, out-of-plan edits block, validation/TDD evidence, rollback verification, verifier results (Antigravity/Codex/Claude), `carry/stage-<N>.json` evidence sidecar | `final-verification` | Yes (limited to the approved plan's file list; `git push`/publish/deploy/real migration prohibited) |
|
|
441
|
-
| `final-verification` | Check completed work for residual defects and regression risk, then make a release judgment | acceptance verdict, residual risk, follow-up routing (`error-analysis`/`implementation-planning`/`release-handoff`) | `pending-release-handoff`
|
|
442
|
+
| `final-verification` | Check completed work for residual defects and regression risk, then make a release judgment | acceptance verdict, residual risk, follow-up routing (`error-analysis`/`implementation-option-selection`/`implementation-planning`/`release-handoff`) | `pending-release-handoff` when accepted; otherwise route by whether the defect is in the cause, selected direction, or detailed plan | No (read-only tests only) |
|
|
442
443
|
| `release-handoff` | Deliver `accepted` changes as a commit, push, or PR according to the user's chosen method | user menu responses (H1 action / H2 PR base / H3 message handling), executed git/gh command log, commit SHA list, PR URL | `done-or-follow-up` | Yes—but execute **only the mutating commands selected by the user in the menu**. `git push --force*`, direct push to the base branch, `--no-verify`, `gh release`, and publish/deploy are prohibited. The source code itself must not be changed; package the existing `implementation` diff unchanged. |
|
|
443
444
|
| `project-analysis` | Map the current project structure and feature index | components, dependencies, entry points, data stores, external systems, feature index | `pending-routing-decision` | No (strictly read-only; tests are also prohibited) |
|
|
444
445
|
| `feature-analysis` | Trace one confirmed existing feature | flows, domain rules, state changes, external interactions, test coverage | `pending-routing-decision` | No (strictly read-only; tests are also prohibited) |
|
|
@@ -447,7 +448,7 @@ Each task type enforces phase-specific allowed and forbidden actions. A run crea
|
|
|
447
448
|
Common constraints:
|
|
448
449
|
|
|
449
450
|
- Every phase except `implementation` prohibits source-code edits, builds, migrations, deployments, and other state-mutating commands (`final-verification` allows read-only test commands only). `implementation` permits edits/commits only within the file list of the approved plan; `git push`, publish, deploy, real migration, and third-party write APIs remain prohibited.
|
|
450
|
-
- **Isolated worktree for pre-implementation non-implementation phases (BLOCKING)**: The first pre-implementation non-implementation phase prepare creates a task-key `git worktree` through `okstra-ctl`. Pre-implementation non-implementation phases reuse the task-key worktree: `requirements-discovery` → `error-analysis` → `implementation-planning` use the same worktree and branch for the same task key. `implementation` does not reuse this task-key worktree; implementation uses a dedicated stage-specific worktree and branch for every stage/run, as described in the next item. The task-key worktree lives at `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` (special characters such as `/` and `:` in segments are normalized to `-`), and the branch is named `<work-category-namespace>/<task-id-segment>` (for example, `feature/dev-9436` or `fix/dev-7311`). The namespace is derived from work_category (`feature`·`improvement`→`feature/`, `bugfix`→`fix/`, `refactor`→`refactor/`, `ops`→`ops/`, unspecified→`task/`). The work_category itself is resolved by `work_categories.resolve_work_category` as **explicit `--work-category` → the classification recorded in `task-manifest.json` → `feature`**, so the `task/` fallback is only reached when a task has no recorded classification at all; a run that omits the flag still inherits the namespace `requirements-discovery` classified. The base ref is the commit selected by the user's `--base-ref` during the first phase's prepare. `~/.okstra/worktrees/registry.json` (guarded by flock) globally manages task-key → path/branch mappings to prevent path and branch collisions during concurrent runs. Configured sync directories are linked from the main worktree as symlinks to provide filesystem continuity across task checkouts (the sync list can be overridden by `worktreeSyncDirs` in `project.json` or the `OKSTRA_WORKTREE_SYNC_DIRS` environment variable; an empty array disables syncing). This sync does not expand the okstra context/write boundary. Provisioning is skipped when the caller is already inside another worktree or project_root is not a Git repository, and the executor works directly from project_root. The worktree is not automatically deleted after a run; it is the authoritative artifact for later phases, PR authoring, and rollback verification. Manual cleanup: `git -C <main-worktree> worktree remove <path>` → `git -C <main-worktree> branch -D <branch>` + remove the registry entry. See the *Task worktree* block in `prompts/profiles/implementation.md` and the *Task worktree (BLOCKING for every task-type)* section in `prompts/lead/okstra-lead-contract.md` for details.
|
|
451
|
+
- **Isolated worktree for pre-implementation non-implementation phases (BLOCKING)**: The first pre-implementation non-implementation phase prepare creates a task-key `git worktree` through `okstra-ctl`. Pre-implementation non-implementation phases reuse the task-key worktree: `requirements-discovery` → `error-analysis` → `implementation-option-selection` → `implementation-planning` use the same worktree and branch for the same task key. `implementation` does not reuse this task-key worktree; implementation uses a dedicated stage-specific worktree and branch for every stage/run, as described in the next item. The task-key worktree lives at `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` (special characters such as `/` and `:` in segments are normalized to `-`), and the branch is named `<work-category-namespace>/<task-id-segment>` (for example, `feature/dev-9436` or `fix/dev-7311`). The namespace is derived from work_category (`feature`·`improvement`→`feature/`, `bugfix`→`fix/`, `refactor`→`refactor/`, `ops`→`ops/`, unspecified→`task/`). The work_category itself is resolved by `work_categories.resolve_work_category` as **explicit `--work-category` → the classification recorded in `task-manifest.json` → `feature`**, so the `task/` fallback is only reached when a task has no recorded classification at all; a run that omits the flag still inherits the namespace `requirements-discovery` classified. The base ref is the commit selected by the user's `--base-ref` during the first phase's prepare. `~/.okstra/worktrees/registry.json` (guarded by flock) globally manages task-key → path/branch mappings to prevent path and branch collisions during concurrent runs. Configured sync directories are linked from the main worktree as symlinks to provide filesystem continuity across task checkouts (the sync list can be overridden by `worktreeSyncDirs` in `project.json` or the `OKSTRA_WORKTREE_SYNC_DIRS` environment variable; an empty array disables syncing). This sync does not expand the okstra context/write boundary. Provisioning is skipped when the caller is already inside another worktree or project_root is not a Git repository, and the executor works directly from project_root. The worktree is not automatically deleted after a run; it is the authoritative artifact for later phases, PR authoring, and rollback verification. Manual cleanup: `git -C <main-worktree> worktree remove <path>` → `git -C <main-worktree> branch -D <branch>` + remove the registry entry. See the *Task worktree* block in `prompts/profiles/implementation.md` and the *Task worktree (BLOCKING for every task-type)* section in `prompts/lead/okstra-lead-contract.md` for details.
|
|
451
452
|
- **Isolated implementation-stage worktrees (concurrent parallelism)**: The task-key worktree above is the model for `requirements-discovery` through `implementation-planning`. `implementation` tasks use **stage isolation**: **one run = one stage**, and every run receives an isolated worktree at `.../<task-id-segment>/stage-<N>/` (branch `<work-category-namespace>/<task-id-segment>-s<N>`). The registry reserves task keys and **stage keys** (`<task-key>#stage-<N>`) together under flock. The Stage Lifecycle Snapshot reads `done`/`started` entries in `consumers.jsonl`, carry-sidecar backfills, and reserved registry stages together, and removes them from the ready set (occupancy SSOT = registry). Thus, if the user starts two `implementation` runs simultaneously, they proceed on different independent stages without collision. Base selection: independent = common anchor (HEAD fixed at entry to the first stage); single dependency = predecessor's done commit; multiple dependencies = task worktree HEAD only if every predecessor is an ancestor (`git merge-base --is-ancestor`; otherwise `PrepareError`). The cost-aware-design ready-set batch has been retired because each stage needs an isolated branch and reserving two stage keys on one branch creates a branch-uniqueness collision, so it offers no benefit: sequential work uses the next run after a stage is done, and concurrent work uses separate runs, at equivalent cost. Select a stage with `--stage <auto|N>` or the wizard's `stage_pick`. The wizard's `stage_pick` is a multiselect that labels each stage with its state (`mark_done`/`mark_active`/`mark_ready`/`mark_blocked`), topologically sorts the dependency closure of the selection with Kahn's algorithm (`stage_targets.order_stage_closure`), and exports it as the `chain-stages` CSV in render-args. The `okstra-run` SKILL consumes this queue and sequentially executes N single-stage runs in dependency order as an unattended chain, advancing only after checking the Phase 6 `done` row for each stage. This is an orchestration layer only; the **one run = one stage** isolation invariant of the wizard and prepare remains unchanged. Not only worktrees but also **run artifacts (reports, state, worker results, manifests) are isolated per stage under `runs/implementation/stage-<N>/`**, so reports and state from two concurrently running stages do not mix. In contrast, `consumers.jsonl` and the worktree registry remain at the task-type root (`runs/implementation/`) because they are shared coordination sources of truth across stages.
|
|
452
453
|
- **Isolation of single-stage final-verification run artifacts (concurrent parallelism)**: Single-stage `final-verification` (`--stage <N>`) also isolates run artifacts under `runs/final-verification/stage-<N>/`, like implementation, with independent sequences per stage, and appends `-fv-s<N>` to the team name. The `-fv-` delimiter prevents collisions with the same stage's implementation team (`-s<N>`) and with the default whole-task verification name. Thus, final-verification for multiple stages can run concurrently without mixing state, worker results, reports, or teams. It does not create a new worktree; it reuses the corresponding implementation stage worktree from the registry read-only and therefore does not reserve a registry stage key. The `-fv-s<N>` suffix on the `teamName` label is only for audit/display distinction. The actual team is the per-session implicit team (`session-<leadSid>`), so the pre-v2.1.178 hard failure caused by a `TeamCreate` name collision no longer occurs. Whole-task verification (empty stage value) retains the existing flat `runs/final-verification/` structure.
|
|
453
454
|
- **Final-verification target acquisition seam**: `stage_targets.acquire_final_verification_target()` accepts semantic task identity, the approved plan, the normalized Stage Map, and `stage: int | None`; it derives ledger, registry, worktree, Git, and integration facts behind one task-key `worktree_provision_mutex`. Single-stage acquisition is read-only and whole-task acquisition integrates and tears down completed stage worktrees. `run.py` remains the adapter that converts CLI values, builds render-context fields, computes the diff summary, and writes the target snapshot. The container keeps using the locked `resolve_and_integrate_whole_task()` interface; both interfaces share an internal unlocked implementation so the acquisition path never re-enters the non-reentrant task-key mutex.
|
|
@@ -461,11 +462,12 @@ Common constraints:
|
|
|
461
462
|
- After the user fills answers into the `## 1. Clarification Items` section of a final report produced by `requirements-discovery`, `error-analysis`, or `implementation-planning`, carry that file into the next run with `--clarification-response <previous-final-report.md>`.
|
|
462
463
|
- The carried-in file is copied to the current run's `instruction-set/clarification-response.md`; the lead updates each prior `Q*` row's `Status` (`resolved` / `obsolete`) in Section 0 before proceeding.
|
|
463
464
|
- To edit answers and rerun in one operation, use `--resume-clarification`. See the `### --resume-clarification` section for details.
|
|
465
|
+
- A comparison-mode `implementation-option-selection` report exports the confirmed direction in a separate `DIRECTION SELECTION` sidecar. A new planning run consumes the selection report through `--selected-direction`, validates the sidecar and source-data digest, and writes the normalized `instruction-set/selected-direction.json` snapshot. Preselected-validation mode uses its confirmed upstream direction and needs no selection sidecar.
|
|
464
466
|
- **Stage carry-in (`implementation` → next stage)**: Every `implementation` run writes a `runs/implementation/carry/stage-<N>.json` evidence sidecar (flat under the task-type run dir — stage-shared, like `consumers.jsonl`). The next stage automatically carries in this file. Reverse links identifying which `implementation` run consumed each stage accumulate in the shared coordination file `runs/implementation-planning/consumers.jsonl`.
|
|
465
467
|
|
|
466
468
|
### Fix cycle (post-release bug hotfix history)
|
|
467
469
|
|
|
468
|
-
If a bug is discovered in artifacts after a task has completed release-handoff, fix it by reentering the same task ID through an entry phase (`requirements-discovery` / `error-analysis` / `implementation-planning`). There is no dedicated hotfix task type, and the phase gates remain unchanged. This set of reentry runs is a **fix cycle**. Its source of truth is the append-only event rows (`opened` / `run` / `closed`) in `<task_root>/history/fix-cycles.jsonl`, owned exclusively by the module `scripts/okstra_ctl/fix_cycles.py`. The entry-phase list is defined only in `fix_cycles.FIX_CYCLE_ENTRY_PHASES` and is shared by the prepare gate and wizard detection predicate.
|
|
470
|
+
If a bug is discovered in artifacts after a task has completed release-handoff, fix it by reentering the same task ID through an entry phase (`requirements-discovery` / `error-analysis` / `implementation-option-selection` / `implementation-planning`). There is no dedicated hotfix task type, and the phase gates remain unchanged. This set of reentry runs is a **fix cycle**. Its source of truth is the append-only event rows (`opened` / `run` / `closed`) in `<task_root>/history/fix-cycles.jsonl`, owned exclusively by the module `scripts/okstra_ctl/fix_cycles.py`. The entry-phase list is defined only in `fix_cycles.FIX_CYCLE_ENTRY_PHASES` and is shared by the prepare gate and wizard detection predicate.
|
|
469
471
|
|
|
470
472
|
- **Entry**: The okstra-run wizard detects reentry into an entry phase for a completed task and confirms it at the `fix_cycle_confirm` step. The CLI uses `--fix-cycle <yes|no>` (when omitted, nothing is recorded). `--fix-cycle yes` opens a cycle only if both guards pass: task type is an entry phase, and the manifest's `workflow.lastCompletedPhase` is `release-handoff`; a violation raises `PrepareError`. A task may have only one open cycle at a time.
|
|
471
473
|
- **Attachment**: While a cycle is open, all runs for the same task attach to it as `run` rows even without a later `--fix-cycle` flag, and `fixCycleId` is recorded in run-manifest and timeline entries.
|
|
@@ -495,7 +497,7 @@ The stage-group interaction order is: **G1 select base → G2 confirm stages (se
|
|
|
495
497
|
[improvement-discovery]
|
|
496
498
|
↓ final-report (## 5.9 Improvement Candidates, N candidates)
|
|
497
499
|
↓ (user selects K candidates and writes a new brief for each)
|
|
498
|
-
[requirements-discovery | implementation-
|
|
500
|
+
[requirements-discovery | implementation-option-selection | error-analysis] (new task-id per selected candidate)
|
|
499
501
|
````
|
|
500
502
|
|
|
501
503
|
A sidetrack entry point that is not a formal member of `PHASE_SEQUENCE`. It supports codebase-discovery scenarios without breaking the one-way lifecycle. The lens allowlist and candidate cap are consolidated in the single source of truth `scripts/okstra_ctl/improvement_lenses.py`. `validators/validate_improvement_report.py` checks eleven contract items against the final report; one of them is the shape of the `## 5.9 Improvement Candidates` table, whose eleven columns run from `Cand ID` through `Evidence` (the two counts are independent and happen to coincide). Two bidirectional grilling points—an enhanced budget of 8 in `okstra-brief-gen` Step 4 and the lead's Phase 1.5 reflect-back budget of 12—align the user's and AI's understanding.
|
|
@@ -529,7 +531,7 @@ The complete specification for `okstra`'s three storage areas (stable task root
|
|
|
529
531
|
|
|
530
532
|
`okstra` is brief-first. The brief is the canonical source material that preserves external input and okstra augmentations. Any additional material workers need—reports, code snippets, logs, and so on—must be included inline or by path in the brief's `Evidence and Source Materials` section.
|
|
531
533
|
|
|
532
|
-
Briefs are accepted as direct input **only for entry phases**: users provide a brief path for `requirements-discovery`, `error-analysis`, `improvement-discovery`, `project-analysis`, `feature-analysis`, and `change-impact-analysis`. Downstream phases (implementation-planning / implementation / final-verification) automatically carry in the task manifest's `taskBriefPath
|
|
534
|
+
Briefs are accepted as direct input **only for entry phases**: users provide a brief path for `requirements-discovery`, `error-analysis`, `improvement-discovery`, `project-analysis`, `feature-analysis`, and `change-impact-analysis`. Downstream phases (`implementation-option-selection` / `implementation-planning` / `implementation` / `final-verification`) automatically carry in the task manifest's `taskBriefPath`; a new planning run additionally requires its selected-direction report. The okstra-run wizard does not ask for the brief again. If the brief is unregistered, a fallback picker recommends switching to an entry phase. `release-handoff` has no brief; prepare generates an input document that cites verification reports.
|
|
533
535
|
|
|
534
536
|
A brief is a **translation layer**: it converts external input—an issue-tracker ticket, requirements document, or user message—into an okstra-readable format while preserving the original verbatim and clearly distinguishing okstra additions as labelled augmentation. The output of the `okstra-brief-gen` skill is the source of truth. For each analysis phase, `prepare_task_bundle()` extracts the necessary frontmatter, task-specific brief sections, reference expectations, carried-in clarification, and directive into `instruction-set/analysis-packet.md`. This compact packet is the analysis workers' primary input; the original brief and profile/material files are fallback evidence opened only to verify evidence or fill omissions.
|
|
535
537
|
|
|
@@ -634,8 +636,8 @@ analysing phases therefore share four contracts rather than one: `discovery-work
|
|
|
634
636
|
(requirements-discovery, improvement-discovery — hand over candidates without
|
|
635
637
|
starting them), `diagnosis-worker` (error-analysis — fix the symptom, establish
|
|
636
638
|
reproduction, submit only falsifiable causes), `planning-worker`
|
|
637
|
-
(implementation-planning —
|
|
638
|
-
own plan), and `analysis-worker` for the observational phases (project-,
|
|
639
|
+
(implementation-planning — realize one selected direction, stage the work, and never approve its
|
|
640
|
+
own plan), `direction-selection-worker` (implementation-option-selection — compare or validate directions without writing a detailed plan), and `analysis-worker` for the observational phases (project-,
|
|
639
641
|
feature-, and change-impact-analysis), which describe an area without designing
|
|
640
642
|
for it. The map lives in [`scripts/okstra_ctl/worker_prompt_policy.py`](../scripts/okstra_ctl/worker_prompt_policy.py)
|
|
641
643
|
`ANALYSIS_DUTY_BY_TASK_TYPE`; an unmapped analysis task type takes the
|
|
@@ -852,13 +854,26 @@ The `## 0. Reading Confirmation` block from worker output is written to the side
|
|
|
852
854
|
If there are no substantive differences, state that fact rather than manufacturing a contrast.
|
|
853
855
|
Write the actual Markdown report body to the file instead of metadata about save failures or session limitations.
|
|
854
856
|
|
|
857
|
+
### Implementation-planning activity and approval contract
|
|
858
|
+
|
|
859
|
+
The manifest-provided `lead-events-*.jsonl` file is the canonical record for structured agent activity. Activity writers append `eventType: "activity"` rows to that file and receive monotonically increasing `A-NNN` identifiers from the shared append path.
|
|
860
|
+
|
|
861
|
+
`activityContractVersion: 1` is an interpretation version for new `implementation-planning` artifacts. A run without that field remains a historical run and does not require activity events or an `agentActivity[]` projection.
|
|
862
|
+
|
|
863
|
+
The shared `okstra report-finalize` entrypoint projects canonical activity before translation source checking. Its in-process `project-activity` step filters events by run identity, validates activity ID order, and replaces only `agentActivity[]` in the report data. A legacy manifest without activity contract v1 leaves data.json unchanged. For a non-English report, the lead runs the finalizer with `--only project-activity --only check-source` before translator dispatch, then runs the full finalizer after the translation sidecar exists. Conformance compares the resulting `agentActivity[]` IDs, order, and core fields with the canonical events for every lead host.
|
|
864
|
+
|
|
865
|
+
Approval blockers use `open`, `answered`, `resolved`, and `obsolete`. Both `open` and `answered` block approval because `answered` means that a user response exists but has not passed application and checking. A response sidecar hides an answered row from the next user-input prompt, but it does not change the approval status of an existing report.
|
|
866
|
+
|
|
867
|
+
An approval row classifies its cause as `user-decision`, `noncritical-dissent`, or `correctness-critical`. A `noncritical-dissent` row can become `passed-with-dissent` only after the user explicitly selects `accept-risk` and the report records the related activity evidence. A `correctness-critical` row cannot use `accept-risk`; it becomes resolved only after the plan is revised and the affected target passes re-verification.
|
|
868
|
+
|
|
855
869
|
## Final report views (HTML)
|
|
856
870
|
|
|
857
871
|
The Phase 7 `render-views` step accepts either a final-report data.json or its Markdown sibling. For schema v2, it locates and validates `final-report-<task-type>-<seq>.data.json`, selects the task type fail-closed, and renders HTML directly from the structured data. It does not parse the AI Markdown back into a human model. The lead reaches this step through `okstra report-finalize`, which owns the shared Phase 7 sequence in `scripts/okstra_ctl/report_finalize.py`.
|
|
858
872
|
|
|
859
|
-
- `reports/final-report-<task-type>-<seq>.html` — always generated for schema v2 with one of
|
|
873
|
+
- `reports/final-report-<task-type>-<seq>.html` — always generated for schema v2 with one of eleven dedicated task templates. It includes an accessible summary, task-specific prose, tables and inline SVG diagrams, evidence references, decisions, and next actions. CSS / JS are embedded inline with no external assets; print and no-JavaScript fallback content preserve the essential information.
|
|
860
874
|
- **Human summary**: `humanSummary` is the sole v2 top-level human summary contract. It is not copied into AI Markdown. Each task view decides how to present it together with the task deliverable instead of sharing a generic dashboard body.
|
|
861
875
|
- **Audit isolation**: worker execution, convergence, and token/cost material remain available for traceability but are subordinate to the user's findings and decisions. They never replace the task analysis narrative.
|
|
876
|
+
- **Implementation-planning activity**: activity-contract reports show each agent's task, summary, and outcome in the default view. Commands, exit codes, file-and-line evidence, and result paths remain inside expandable detail. Approval decision cards link to the relevant `id-A-NNN` activity anchors and preserve each option's disposition in the exported user response.
|
|
862
877
|
- **Schema v1 compatibility**: existing v1 data and quick Markdown reports keep the legacy conditional renderer, including `readerSummary`, reader modes, and the original Markdown-parsing path.
|
|
863
878
|
- **`C-*` select option order (schema v1)**: the legacy renderer parses `Expected form`, puts the `Recommended:` answer **first**, and relabels the `Alternatives:` items consecutively as `(a)`, `(b)`, and so on (the original character labels are not retained). Schema v2 parses nothing here — a `Kind=decision` row carries `options[]`, and the presentation order is the array order with the `role: recommended` entry first.
|
|
864
879
|
|
package/docs/cli.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- [Optional arguments and options](#optional-arguments-and-options)
|
|
20
20
|
- [`--task-key`](#--task-key)
|
|
21
21
|
- [`--clarification-response`](#--clarification-response)
|
|
22
|
+
- [`--selected-direction`](#--selected-direction)
|
|
22
23
|
- [`--reverify-scope`](#--reverify-scope)
|
|
23
24
|
- [`--resume-clarification`](#--resume-clarification)
|
|
24
25
|
- [`--project-root`](#--project-root)
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
Base command for initial entry with full arguments:
|
|
60
61
|
|
|
61
62
|
```bash
|
|
62
|
-
scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-runtime <host-id-or-alias>] [--lead-provider <provider>] [--lead-model <model>] [--worker-model provider=model,...] [--report-writer-provider <provider>] [--report-writer-model <model>] [--executor claude|codex|antigravity] [--critic off|claude|codex|antigravity|grok|kimi] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--base-ref <branch|tag|sha>] [--clarification-response <previous-final-report>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>] [--fix-cycle <yes|no>]
|
|
63
|
+
scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-runtime <host-id-or-alias>] [--lead-provider <provider>] [--lead-model <model>] [--worker-model provider=model,...] [--report-writer-provider <provider>] [--report-writer-model <model>] [--executor claude|codex|antigravity] [--critic off|claude|codex|antigravity|grok|kimi] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--base-ref <branch|tag|sha>] [--clarification-response <previous-final-report>] [--selected-direction <selection-final-report.md>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>] [--fix-cycle <yes|no>]
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
Analysis input ownership is narrower than the base shell command. The `/okstra-run` wizard collects `--analysis-target` and `--evidence-inputs` values and passes them internally to `node bin/okstra render-bundle`. `scripts/okstra.sh` does not accept either flag. Because `feature-analysis` requires a target, start that task type with the in-host skill; the two option sections below document the internal Node render inputs, not standalone shell options.
|
|
@@ -120,6 +121,18 @@ Examples:
|
|
|
120
121
|
The single input that determines the purpose of this run, profile selection, run-directory segment, and lifecycle phase routing.
|
|
121
122
|
For standard values and phase-specific responsibilities, see [Task type](#--task-type) above.
|
|
122
123
|
|
|
124
|
+
The lifecycle task types run in this order:
|
|
125
|
+
|
|
126
|
+
| task type | Responsibility | Normal handoff |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| `requirements-discovery` | Fix the requirement ledger and decide whether cause analysis is needed. | `error-analysis` or `implementation-option-selection` |
|
|
129
|
+
| `error-analysis` | Establish a credible cause and counter-evidence. | `implementation-option-selection` or continued `error-analysis` |
|
|
130
|
+
| `implementation-option-selection` | Compare or validate read-only directions and expose only exact-coverage candidates. | `implementation-planning` after direction confirmation |
|
|
131
|
+
| `implementation-planning` | Realize one selected direction as files, stages, validation, and rollback. | `implementation` after separate plan approval |
|
|
132
|
+
| `implementation` | Execute one approved stage. | `final-verification` |
|
|
133
|
+
| `final-verification` | Verify acceptance and classify any cause, direction, or plan defect. | `release-handoff`, `error-analysis`, `implementation-option-selection`, or `implementation-planning` |
|
|
134
|
+
| `release-handoff` | Perform only the user-selected delivery action. | done or follow-up |
|
|
135
|
+
|
|
123
136
|
#### `--task-type improvement-discovery`
|
|
124
137
|
|
|
125
138
|
`improvement-discovery` is a sidetrack entry point outside `PHASE_SEQUENCE`. It uses multi-worker consensus to find improvement candidates within the codebase scope and lens allowlist.
|
|
@@ -131,7 +144,7 @@ For standard values and phase-specific responsibilities, see [Task type](#--task
|
|
|
131
144
|
- `candidate-cap`: 1–12; default 8.
|
|
132
145
|
- Output: the `## 5.9 Improvement Candidates` table with 11 columns: Cand ID / Lens / Title / Scope / Severity / Effort / Consensus / Source workers / Recommended next-phase / Expected behavior after / Evidence.
|
|
133
146
|
- Verdict Token: `analysis-complete` / `analysis-partial` / `blocked` — the shared analysis enum, which is what `schemas/final-report-v2.0.schema.json` admits. Finding no candidates is not a verdict: the run stays `analysis-complete` and records an empty candidate set with a `no-candidate` row per lens. (`candidates-ready` / `no-candidates` appear only in a schema-v1 legacy report's `## 7. Final Verdict`.)
|
|
134
|
-
- Routing: there is no automatic spin-off. The user selects candidates and starts each under a new task ID with `requirements-discovery`, `implementation-
|
|
147
|
+
- Routing: there is no automatic spin-off. The user selects candidates and starts each under a new task ID with `requirements-discovery`, `implementation-option-selection`, or `error-analysis`.
|
|
135
148
|
- Workers: claude + codex + antigravity + report-writer are all required.
|
|
136
149
|
- Primary-pass assignment: selected analyser instances are enumerated in `requiredWorkerRoles` order, then the lead rotates the primary pass across the resolved priority lenses. Provider/model names do not affect the order, and every analyser still covers every resolved lens after its primary pass.
|
|
137
150
|
- Two bidirectional grilling points: an enhanced Step 4 in `okstra-brief-gen` with a budget of 8, and the lead's Phase 1.5 reflect-back with a budget of 12.
|
|
@@ -250,6 +263,22 @@ scripts/okstra.sh \
|
|
|
250
263
|
--clarification-response .okstra/tasks/tasks/8852/runs/2026-04-29/error-analysis/reports/final-report-2026-04-29_10-15-30.md
|
|
251
264
|
```
|
|
252
265
|
|
|
266
|
+
### `--selected-direction`
|
|
267
|
+
|
|
268
|
+
Starts a new `implementation-planning` run from a validated `implementation-option-selection` final report. The option-selection report may contain at most three displayed directions. Every displayed direction has exact requirement coverage and exact scope precision: both percentages are 100, with no unmapped commitment or contradicted requirement.
|
|
269
|
+
|
|
270
|
+
In `candidate-comparison` mode, the user first confirms one displayed direction in the report's `DIRECTION SELECTION` response. Prepare validates the report, its sibling data JSON, the response sidecar, the selected option ID, and the source-data digest before writing `instruction-set/selected-direction.json`. In `preselected-validation` mode, the validated upstream direction is used without generating or selecting an alternative.
|
|
271
|
+
|
|
272
|
+
The direction decision does not approve the detailed plan. Planning produces a separate `approved: false` report, and implementation still requires explicit plan approval. A new planning run without `--selected-direction` is rejected. A same-task planning rerun instead uses `--clarification-response` with its prior planning report.
|
|
273
|
+
|
|
274
|
+
Example:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
scripts/okstra.sh --task-type implementation-planning \
|
|
278
|
+
--selected-direction .okstra/tasks/tasks/8852/runs/implementation-option-selection/reports/final-report-implementation-option-selection-001.md \
|
|
279
|
+
--project-id jobs --task-group tasks --task-id 8852
|
|
280
|
+
```
|
|
281
|
+
|
|
253
282
|
### `--reverify-scope`
|
|
254
283
|
|
|
255
284
|
Pins how much of an `implementation-planning` clarification re-run is verified again. Like `--analysis-target` and `--evidence-inputs`, this is an internal `node bin/okstra render-bundle` input collected by the `/okstra-run` wizard — `scripts/okstra.sh` does not accept it.
|
|
@@ -373,7 +402,7 @@ scripts/okstra.sh --task-type implementation-planning ... \
|
|
|
373
402
|
|
|
374
403
|
### `--fix-cycle`
|
|
375
404
|
|
|
376
|
-
- `--fix-cycle <yes|no>` records whether re-entry into an entry phase (`requirements-discovery` / `error-analysis` / `implementation-planning`) after completion through release-handoff is a bug-fix cycle. When omitted, no cycle is recorded. The `fix_cycle_confirm` step in the okstra-run wizard accepts the same input.
|
|
405
|
+
- `--fix-cycle <yes|no>` records whether re-entry into an entry phase (`requirements-discovery` / `error-analysis` / `implementation-option-selection` / `implementation-planning`) after completion through release-handoff is a bug-fix cycle. When omitted, no cycle is recorded. The `fix_cycle_confirm` step in the okstra-run wizard accepts the same input.
|
|
377
406
|
- `yes` opens a new cycle only when both conditions hold: the task type is an entry phase, and the manifest's `workflow.lastCompletedPhase` is `release-handoff`. Preparation rejects the request if either condition is false. Once a cycle is open, later runs for the same task attach to it automatically without this flag.
|
|
378
407
|
|
|
379
408
|
### `--workers`
|
|
@@ -533,6 +562,8 @@ Selects the provider for the opt-in Phase 5.6 critic pass. The value is `off`, `
|
|
|
533
562
|
|
|
534
563
|
Accepts the path to a previous `implementation-planning` final report as input to `--task-type implementation`. The file's YAML frontmatter must contain an `approved` field whose value is `true`.
|
|
535
564
|
|
|
565
|
+
A selected-direction plan also must have `planningContract: selected-direction`, `outcome: plan-ready`, exact plan coverage, and a valid `selectedDirectionRef`. It does not accept `--implementation-option`. An already approved legacy plan without the discriminator keeps its candidate-selection behavior, including an explicit `--implementation-option` or fallback to the recommended option.
|
|
566
|
+
|
|
536
567
|
Approval format:
|
|
537
568
|
|
|
538
569
|
- Exactly one line inside the final report's leading `---` YAML fence: `approved: true` or `approved: false`.
|
|
@@ -550,7 +581,7 @@ Used with `--approved-plan` and `--task-type implementation`, this flag **treats
|
|
|
550
581
|
- If the file is already `approved: true`, leaves frontmatter unchanged and adds the audit line only if it has never been recorded.
|
|
551
582
|
- If the file has no YAML frontmatter or no `approved:` line, exits immediately with an error because the path may refer to the wrong plan file.
|
|
552
583
|
|
|
553
|
-
Using `--approve` outside `--task-type implementation` is meaningless and exits with an error. Use it in CI or scripts, or when approval and the next phase must happen in a single command. The former `--ack-approved` alias was removed in 0.8.0.
|
|
584
|
+
Using `--approve` outside `--task-type implementation` is meaningless and exits with an error. Selected-direction semantics are validated before this flag can mutate the plan. Use it in CI or scripts, or when approval and the next phase must happen in a single command. The former `--ack-approved` alias was removed in 0.8.0.
|
|
554
585
|
|
|
555
586
|
Example:
|
|
556
587
|
|
|
@@ -640,7 +671,7 @@ It does:
|
|
|
640
671
|
|
|
641
672
|
Disables the Phase 6 plan-body verification round for the `implementation-planning` task type. It is enabled by default and ignored for other task types.
|
|
642
673
|
|
|
643
|
-
- **Enabled (default)**: Immediately after the report-writer worker drafts the final report in Phase 6, the lead divides the synthesized plan
|
|
674
|
+
- **Enabled (default)**: Immediately after the report-writer worker drafts the final report in Phase 6, the lead divides the synthesized plan into `P-*` items and dispatches them for reverification to every analyzer worker: `claude`, `codex`, and opted-in `antigravity`. A selected-direction plan uses `P-Dir-1` plus its step, dependency, validation, rollback, requirement, preparation, and variation items. A legacy candidate plan retains `P-Opt-*`. Worker verdicts (`AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT`) are aggregated into one of four gate results: `passed`, `passed-with-dissent`, `blocked-by-disagreement`, or `aborted-non-result`. The approval control is available only for `passed` or `passed-with-dissent`. Items with majority DISAGREE become rows with `Blocks=approval` in `## 1. Clarification Items`. There is no automatic revision; the user answers and resumes the same phase.
|
|
644
675
|
- **Disabled (with `--no-plan-verification`)**: The entire Phase 6 substep is skipped and the Approval marker is always rendered at the top of the final report, matching legacy behavior. This is a fast-iteration opt-out and is not recommended for a handoff-ready plan.
|
|
645
676
|
- The flag records `false` in the manifest at `convergence.planBodyVerification.enabled`. The resume command must include the same flag to preserve behavior; `_canonical_argv` guarantees faithful emission on resume.
|
|
646
677
|
- For the detailed round protocol, verdict semantics, and state-file schema, see the "Plan-body verification mode (implementation-planning only)" section of `prompts/lead/convergence.md`.
|
|
@@ -767,7 +798,7 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
767
798
|
| `okstra worker-audit-check --run-dir <runs/<task-type>/> --task-type <type> --seq <nnn> [--worker <id>]` | Apply the Phase 7 worker audit-sidecar rules mid-run, while the worker session is still alive. For each of this run's `worker-results/<worker>-<task-type>-<seq>.md` it checks that the file carries no `## 0. Reading Confirmation` heading, that the matching audit sidecar exists, and — for prompts carrying the required-v1 evidence-ledger marker — that every backticked `path:line` citation has an Evidence read row in that sidecar. `--worker` scopes it to the role that just returned. Emits `{ok, failures[]}` and exits 2 when `failures[]` is non-empty. The rules come from the `okstra_ctl.worker_audit_ledger` SSOT shared with `validate-run.py`, so an early pass and the Phase 7 pass cannot disagree. Run it right after collecting a result: the same failure at Phase 7 leaves only a retroactive edit, which breaks the audit chain, or a failed run |
|
|
768
799
|
| `okstra log-report [--project-root <dir>] [--cwd <dir>] [--top <N>] [--json]` | Read-only inventory of wrapper transcript `.log` files and their sibling prompt `.md` files. Each ranked entry preserves `path` / `sizeBytes` for compatibility and also reports `transcriptPath`, `transcriptBytes`, `promptPath`, `promptBytes`, and `transcriptToPromptRatio`; totals distinguish prompt bytes from transcript bytes and count paired files. Ranking remains transcript-size descending |
|
|
769
800
|
| `okstra recap <assemble\|record\|note> <task-root\|task-key> …` | Backend for the okstra-inspect `recap` facet. `assemble` is read-only and prints a JSON summary of phase transitions across a task's runs. `record --kind <summary\|qa> --mode <artifact\|code> --answer <text> [--question <text>] [--citation <path:line> …]` appends one line to `<task-root>/recap/recap-log.jsonl` and never mutates other artifacts. `note --kind <verification-evidence\|decision-draft\|analysis-note> --slug <topic> --purpose <text> --scope-note <text> (--body <markdown>\|--body-file <path>)` writes an agent-authored note to `<task-root>/notes/` and prints its path plus the `--clarification-response` argument for feeding it into a later run |
|
|
770
|
-
| `okstra user-response <list\|show\|write> …` | Backend for the `/okstra-user-response` skill: answer a task's open clarification questions in-session and write the response sidecar. `list --home <dir> --project <id> [--limit <n>]` finds reports with open questions; `show --report <md>` reads one report's questions; `write --report <md> --answers <json> [--plan-decision <json>] [--task-key <key>]` writes the sidecar; the plan decision carries `status` (`approved` / `revision-requested` / `rejected`) and a `reason` that is mandatory for the latter two.
|
|
801
|
+
| `okstra user-response <list\|show\|write> …` | Backend for the `/okstra-user-response` skill: answer a task's open clarification questions in-session and write the response sidecar. `list --home <dir> --project <id> [--limit <n>]` finds reports with open questions; `show --report <md>` reads one report's questions; `write --report <md> --answers <json> [--plan-decision <json>] [--task-key <key>]` writes the sidecar; the plan decision carries `status` (`approved` / `revision-requested` / `rejected`) and a `reason` that is mandatory for the latter two. A selected structured option preserves its exact gate `disposition` (`select`, `accept-risk`, `request-revision`, or `reject`); direct free text uses `answer`, and a request to re-ask uses `reframe`. A `reframe` is carried into the next run as a re-scoped brief. JSON output; exit 0 ok / 1 error |
|
|
771
802
|
| `okstra pr <template\|branches\|gen> …` | Backend for the okstra-pr-gen skill. Git-only—no project registration required. `template list\|show <name\|default>\|add --name <name> (--content <text>\|--file <path>)\|path` manages PR body templates under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`); `branches` recommends a base branch; `gen --base <ref> [--template <name\|default>]` emits a JSON bundle of the template plus `<base>..HEAD` commits and `<base>...HEAD` diffstat |
|
|
772
803
|
| `okstra migrate [--apply] [--cwd <dir>] [--quiet]` | One-time migration of the project artifact root from `.project-docs/okstra/` to `.okstra/`. It is a dry run by default; `--apply` performs the move with `git mv` in a Git worktree, removes an empty `.project-docs/`, and synchronizes the `<PROJECT>/CLAUDE.md` import line, `.gitignore`, the project's rows in `~/.okstra/{recent,active}.jsonl`, and `~/.okstra/worktrees/registry.json`. It exits 1 if `.okstra/` already exists or the legacy directory is absent. Scheduled for removal by the end of v0.x |
|
|
773
804
|
| `okstra task-list [--project-root <path>]` | Combine `list_project_tasks` and `read_latest_task` into JSON containing the task catalog and latest task |
|
|
@@ -786,7 +817,9 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
786
817
|
| `okstra codex-dispatch --project-root <dir> --run-manifest <path> [--workers <csv>] [--dry-run]` | Compatibility alias for `okstra worker-dispatch`; it no longer selects a Codex-only transport-agent path. |
|
|
787
818
|
| `okstra agent-prompt materialize\|verify\|record-dispatch\|link-result\|materialize-result\|complete\|verify-completion` | Internal invocation-contract CLI. `materialize` composes model assignment, functional duty, and task instructions; `verify` rejects identity, path, snapshot, assignment, source, or digest drift. Run-backed calls resolve `assignmentRef` from the manifest, enforce `authorizedPaths`, and reject real-path or symbolic-link escape. `record-dispatch` records a verified host-native specification before dispatch and `link-result` binds the accepted result; one result path belongs to one dispatch, so a corrective round retires the first attempt with `reject-result --dispatch-id <first> --superseded-by <corrective> --reason <text>` before the new link is accepted — the rejected row stays in `agentResultLinks` carrying `supersededBy` and `rejectionReason` rather than being deleted. Standalone calls are identified by `(purpose, invocationId)` under `.okstra/agent-invocations/<purpose>/`; they publish a canonical result envelope and publish the completion marker last. Consumers use only the `returnedBody` from `verify-completion`. Metadata contains exactly `catalogDigest`, `assignmentDigest`, `dutyDigest`, `instructionDigest`, and `promptDigest`; JSON inputs use UTF-8, sorted keys, compact separators, and no non-finite values, while duty files use versioned sorted-name/byte framing. Instruction sources use `{kind: project\|runtime, path: <relative POSIX path>}` and never persist an installed absolute runtime path. A published prompt is immutable, so re-running `materialize` with an edited instruction file fails as `existing_invocation_conflict`; `--replace-undispatched` is the one exit, for a call that failed a pre-dispatch gate and therefore ran nowhere — it covers a differing prompt and a differing metadata alike, since the two are published together and describe one call. It republishes prompt and metadata together, and it is verified rather than trusted — a row in `agentDispatches` or `workerDispatches` naming this `invocationId` refuses the replacement and names the dispatch that used it. |
|
|
788
819
|
| `okstra team dispatch --project-root <dir> --run-manifest <path> [--workers <csv>] [--jobs-file <path>] [--dry-run]` / `okstra team await --project-root <dir> --run-manifest <path> [--json]` / `okstra team teardown --project-root <dir> --run-manifest <path> [--dry-run] [--json]` | Read a `leadRuntime=external` run manifest and dispatch, await, or tear down tmux-pane workers. Default dispatch excludes report writer; Phase 6 selects it explicitly, and mixed analysis/report jobs are rejected. If a tmux pane cannot be created, gracefully degrade to the CLI wrapper and record the fallback in `workerDispatches[].degradedFrom` |
|
|
789
|
-
| `okstra
|
|
820
|
+
| `okstra agent-activity append --project-root <dir> --run-manifest <path> --kind <kind> --agent <id> --summary <text> --outcome <outcome> [--plan-item-id <id>]… [--evidence-ref <ref>]… [--command-record <json>]… [--result-path <path>] [--audit-sidecar <path>]` | Append one structured activity to the run manifest's `leadEventsPath`. `kind` accepts `worker-dispatched`, `worker-completed`, `verification-round-completed`, `self-fix-applied`, `user-decision-required`, or `user-decision-evaluated`. `outcome` accepts `pending`, `completed`, `failed`, `blocked`, or `resolved`. Repeated `--command-record` values and `Evidence command` rows from `--audit-sidecar` must contain exactly `command`, `cwd`, `exitCode`, and `outputSummary`; malformed or potentially secret-bearing evidence stops the append. The command requires `activityContractVersion: 1` and returns the assigned `activityId` in JSON. |
|
|
821
|
+
| `okstra agent-activity project --project-root <dir> --run-manifest <path> --data <data.json>` | Project this run's canonical activity events into `agentActivity[]`. The command preserves event order, rejects duplicate or decreasing activity IDs, and replaces no other report field. A historical manifest without `activityContractVersion: 1` returns an empty projection and leaves data.json unchanged. Normal Phase 7 execution reaches this behavior through `report-finalize`; use the standalone command only for diagnostics. |
|
|
822
|
+
| `okstra report-finalize --project-root <dir> --run-manifest <path> --report <final-report.md>` | Run the whole Phase 7 post-report sequence in its contractual order: `project-activity` → `check-source` → `token-usage` → `render-views` → `spawn-followups` → `validate-run`. Stops at the first non-zero exit and names the failing step, then prints a per-step `[ok]` / `[FAIL]` / `[skip]` summary on stderr so the outcome is legible without parsing the JSON payload. `project-activity` is an in-process byte-preserving no-op for legacy manifests without activity contract v1. Every step is idempotent, so re-running after a fix is safe — but `--only <step>` (repeatable) reruns just the named steps in contractual order. For a non-English report, run `--only project-activity --only check-source` before translator dispatch, then run the full sequence after the translation sidecar exists. This is the same code path (`scripts/okstra_ctl/report_finalize.py`) every lead adapter runs after its report-writer completes. `--workspace-root` is owned by the Node wrapper. Prefer this over invoking the six steps individually. |
|
|
790
823
|
| `okstra render-views <final-report.data.json\|final-report.md>` | The Phase 7 `render-views` step, runnable on its own. Schema v2 data is rendered directly (contract: `schemas/final-report-v2.0.schema.json`) into an always-generated, task-specific human HTML sibling while `templates/reports/final-report-v2.template.md` independently owns the AI handoff Markdown. Passing the Markdown sibling locates the same v2 data.json. Schema v1 and quick reports keep the legacy conditional renderer. The Node wrapper calls `scripts/okstra-render-report-views.py`; `validators/validate-report-views.py` verifies source/schema/template digests, required human fields, form controls, external assets, diagram/table ID parity, and Response ID parity |
|
|
791
824
|
| `okstra design-prep <list\|show\|write>` | Review AI-prepared implementation design requests, inspect their effective confirmed response, or append a confirmed user/wizard response without editing the planning report |
|
|
792
825
|
| `okstra wizard <init\|step\|render-args\|confirmation\|outcome> --state-file <path>` | Interactive input state machine for okstra-run, implemented by `okstra_ctl.wizard`. Seed a state file with `init`, then repeatedly call `step --answer <val>` to receive the next `Prompt` JSON. `--answer` is **required**; use `--no-submit` to peek at the next prompt without submitting a response. A `pick` with more choices than the host picker can display keeps `kind: "pick"` but adds `presentation: "numbered-text"`; render every option as a numbered Markdown list and submit the user's 1-based number, exact value, or exact label. Invalid, out-of-range, and ambiguous answers re-prompt without dropping choices. `render-args` returns the final `render-bundle` argument map, and `confirmation` returns the user echo block. On a completed wizard, `outcome` returns `renderArgs`, `persistActions`, and `confirmationText` together; project/global release-handoff PR-template persistence appears as `persistActions[].command == "config.set"`. For an `implementation` task type, `stage_pick` follows `approved_plan_pick` and selects the stage before `executor_pick`. The brief step appears only for entry task types—requirements-discovery, error-analysis, improvement-discovery, project-analysis, feature-analysis, and change-impact-analysis. Analysis inputs use `feature_evidence_pick` / `feature_evidence`, `project_evidence_pick` / `project_evidence`, and `analysis_target_pick` / `analysis_target`; a revision-requested report prioritizes its same-task, same-type rerun. Downstream lifecycle phases automatically carry the manifest brief, with a three-option `brief_carry` fallback when none is registered; `release-handoff` has no brief and enters multi-select `handoff_stage_pick` for eligible stage groups or the whole task |
|
|
@@ -37,11 +37,11 @@ okstra preflight --runtime claude-code --json
|
|
|
37
37
|
## Flow
|
|
38
38
|
|
|
39
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}`; `resolvedRefs` carries the `definition` of internal tokens such as `RB-002`/`§4.7`. A schema-v1 report has nowhere to record impact, so those
|
|
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 internal tokens such as `RB-002`/`§4.7`. 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
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
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 `§`/`path:line` in `contextRefs[]`; **never invent it** — say the report is silent instead. Close with `Source: C-014 — "<raw statement>"`.
|
|
43
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
|
|
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
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
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
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.)
|
|
@@ -50,16 +50,17 @@ The current documentation and code contain two layers with similarly named phase
|
|
|
50
50
|
|
|
51
51
|
#### Task-type lifecycle
|
|
52
52
|
|
|
53
|
-
`PHASE_SEQUENCE` in `scripts/okstra_ctl/workflow.py` contains
|
|
53
|
+
`PHASE_SEQUENCE` in `scripts/okstra_ctl/workflow.py` contains the following task types in order.
|
|
54
54
|
|
|
55
55
|
| Order | task-type | Responsibility |
|
|
56
56
|
|---|---|---|
|
|
57
57
|
| 1 | `requirements-discovery` | Classify the work category, route safely to the next phase, and identify missing inputs |
|
|
58
58
|
| 2 | `error-analysis` | Analyze symptoms, root-cause hypotheses, reproduction gaps, and verification paths |
|
|
59
|
-
| 3 | `implementation-
|
|
60
|
-
| 4 | `implementation` |
|
|
61
|
-
| 5 | `
|
|
62
|
-
| 6 | `
|
|
59
|
+
| 3 | `implementation-option-selection` | Compare implementation directions, validate exact coverage, and record the user's selected direction |
|
|
60
|
+
| 4 | `implementation-planning` | Expand the `selected-direction` contract into execution order, validation, rollback, and a separate plan approval request |
|
|
61
|
+
| 5 | `implementation` | Execute the approved plan, commit, run verifier checks, and capture rollback evidence |
|
|
62
|
+
| 6 | `final-verification` | Verify acceptability and residual risk, and decide whether to enter release handoff |
|
|
63
|
+
| 7 | `release-handoff` | Perform the commit/push/PR handoff action selected by the user |
|
|
63
64
|
|
|
64
65
|
Each okstra invocation performs exactly one task type. Moving to the next task type requires a new invocation.
|
|
65
66
|
|