okstra 0.172.0 → 0.174.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 +24 -3
- package/docs/architecture.md +21 -35
- package/docs/cli.md +39 -7
- package/docs/container.md +1 -1
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/performance-improvement-plan-v2.md +6 -5
- package/docs/project-structure-overview.md +33 -25
- package/docs/task-process/README.md +6 -4
- 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 +24 -16
- package/docs/task-process/requirements-discovery.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +1 -1
- 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 +2 -1
- package/runtime/bin/lib/okstra/usage.sh +3 -0
- package/runtime/bin/okstra-provider-exec.py +29 -12
- package/runtime/bin/okstra-trace-cleanup.sh +58 -129
- 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/lead/adapters/cmux.md +2 -0
- 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 +7 -6
- package/runtime/prompts/lead/plan-body-verification.md +23 -6
- package/runtime/prompts/lead/report-writer.md +33 -11
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +2 -0
- package/runtime/prompts/profiles/_implementation-verifier.md +2 -2
- package/runtime/prompts/profiles/error-analysis.md +4 -4
- 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 +61 -46
- package/runtime/prompts/profiles/implementation.md +4 -2
- package/runtime/prompts/profiles/improvement-discovery.md +1 -1
- package/runtime/prompts/profiles/release-handoff.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/dispatch/__init__.py +1 -6
- package/runtime/python/okstra_ctl/adapters/hosts/external/relay.md +4 -4
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +5 -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/conformance.py +68 -0
- package/runtime/python/okstra_ctl/dispatch_core.py +89 -39
- package/runtime/python/okstra_ctl/dispatch_state.py +142 -14
- package/runtime/python/okstra_ctl/doctor.py +2 -2
- package/runtime/python/okstra_ctl/domain/worker_exec.py +5 -0
- package/runtime/python/okstra_ctl/exact_coverage.py +128 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +5 -4
- 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/pane_reclaim.py +13 -22
- package/runtime/python/okstra_ctl/plan_items.py +51 -3
- package/runtime/python/okstra_ctl/render.py +1 -0
- package/runtime/python/okstra_ctl/render_final_report.py +16 -19
- package/runtime/python/okstra_ctl/report_contract.py +45 -14
- package/runtime/python/okstra_ctl/report_finalize.py +68 -9
- 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 +25 -10
- package/runtime/python/okstra_ctl/report_views.py +148 -12
- package/runtime/python/okstra_ctl/run.py +393 -4
- package/runtime/python/okstra_ctl/schema_excerpt.py +1 -1
- package/runtime/python/okstra_ctl/scope_provenance.py +16 -10
- package/runtime/python/okstra_ctl/session.py +69 -12
- package/runtime/python/okstra_ctl/team.py +51 -25
- package/runtime/python/okstra_ctl/tmux.py +19 -149
- 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_prompt_policy.py +2 -0
- package/runtime/python/okstra_ctl/worker_request.py +2 -0
- package/runtime/python/okstra_ctl/workflow.py +29 -7
- package/runtime/python/okstra_ctl/worktree.py +69 -3
- package/runtime/python/okstra_token_usage/cli.py +1 -1
- package/runtime/python/okstra_token_usage/collect.py +66 -6
- package/runtime/schemas/final-report-v2.0.schema.json +1428 -137
- package/runtime/skills/okstra-setup/references/project-config.md +11 -0
- package/runtime/templates/reports/final-report-v2.template.md +4 -0
- package/runtime/templates/reports/final-verification-input.template.md +1 -1
- package/runtime/templates/reports/html/base.template.html +3 -2
- package/runtime/templates/reports/html/i18n/en.json +21 -1
- package/runtime/templates/reports/html/i18n/ko.json +21 -1
- package/runtime/templates/reports/html/macros/forms.html +21 -2
- package/runtime/templates/reports/html/tasks/implementation-option-selection.template.html +49 -0
- package/runtime/templates/reports/html/tasks/implementation-planning.template.html +36 -2
- package/runtime/templates/reports/i18n/en.json +13 -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 +111 -4
- package/runtime/templates/reports/settings.template.json +0 -24
- package/runtime/templates/reports/task-brief.template.md +9 -3
- package/runtime/templates/reports/user-response.template.md +25 -4
- package/runtime/templates/worker-prompt-preamble.md +8 -0
- package/runtime/validators/lib/fixtures.sh +49 -17
- package/runtime/validators/validate-implementation-plan-stages.py +169 -4
- package/runtime/validators/validate-report-views.py +2 -2
- package/runtime/validators/validate-run.py +149 -498
- package/runtime/validators/validate_improvement_report.py +5 -1
- package/runtime/validators/validate_session_conformance.py +1 -1
- package/src/cli-registry.mjs +8 -1
- package/src/commands/execute/codex-run.mjs +1 -0
- package/src/commands/execute/render-bundle.mjs +1 -0
- package/src/commands/execute/team.mjs +3 -3
- package/src/commands/execute/worktree-status.mjs +109 -0
- package/src/commands/lifecycle/install.mjs +0 -2
- package/src/commands/report/finalize.mjs +13 -6
- package/runtime/bin/okstra-subagent-reclaim.sh +0 -26
- package/runtime/schemas/final-report-v1.0.schema.json +0 -6366
- package/runtime/templates/reports/final-report.template.md +0 -1258
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>/`
|
|
@@ -59,7 +60,7 @@ The representative files below are all relative to the resolved run directory (`
|
|
|
59
60
|
|
|
60
61
|
After the host-native lead takes over, the lead and its assigned workers add the following result files to the current run.
|
|
61
62
|
- `sessions/claude-resume-<task-type>-<seq>.sh`
|
|
62
|
-
- `reports/final-report-<task-type>-<seq>.data.json` *(schema v2 source of truth for both audiences
|
|
63
|
+
- `reports/final-report-<task-type>-<seq>.data.json` *(schema v2 source of truth for both audiences)*
|
|
63
64
|
- `reports/final-report-<task-type>-<seq>.md`
|
|
64
65
|
- `reports/final-report-<task-type>-<seq>.html` *(Phase 7 deterministic post-processing: task-specific, self-contained HTML for human reviewers, with inline CSS/JS)*
|
|
65
66
|
- `design-prep-requests/design-prep-request-<seq>-PREP-<NNN>.md` *(implementation-planning only: deterministic AI-prepared request for a `provisional` or `blocked` design item)*
|
|
@@ -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 |
|
|
@@ -79,7 +90,7 @@ Design-preparation storage has three separate authorities:
|
|
|
79
90
|
| `design-prep-inputs/design-prep-input-<seq>-PREP-<NNN>-r<revision>-<uuid>.md` | user or wizard | Append-only and written only after semantic confirmation. Existing revisions are never edited or reserved before confirmation. |
|
|
80
91
|
|
|
81
92
|
The resolver selects the highest unique revision whose assessment fingerprint still matches the approved snapshot. Duplicate revision numbers and stale fingerprints are skipped with warnings rather than granted authority. A markerless legacy plan has no sidecars to migrate: it proceeds with the `legacy-unassessed` warning. This compatibility path does not rewrite its report.
|
|
82
|
-
The final result files are not created by saving worker stdout. The report writer writes `final-report-<task-type>-<seq>.data.json`; Phase 7 derives the Markdown and HTML siblings deterministically.
|
|
93
|
+
The final result files are not created by saving worker stdout. The report writer writes `final-report-<task-type>-<seq>.data.json`; Phase 7 derives the Markdown and HTML siblings deterministically. Bundles use `schemas/final-report-v2.0.schema.json` and `templates/reports/final-report-v2.template.md`: AI handoff Markdown and task-specific human HTML are rendered independently from the same data.json. Rendering never modifies the source data or a pre-existing Markdown input.
|
|
83
94
|
For the standalone Claude launcher, `sessions/claude-resume-<task-type>-<seq>.sh` remains an interruption-recovery compatibility helper. In-host Codex runs use host task continuity plus the generic `leadSession` manifest identity.
|
|
84
95
|
|
|
85
96
|
The resolved run directory collects execution history. It divides its contents into type-specific subdirectories such as `manifests/`, `state/`, `prompts/`, `reports/`, `status/`, `sessions/`, and `worker-results/`, then distinguishes each run-level artifact and result file with a `-<task-type>-<seq>` suffix (a three-digit, zero-padded per-category counter, such as `001` or `002`).
|
|
@@ -87,7 +98,17 @@ Worker prompt history is retained not under `/tmp`, but always as a canonical ar
|
|
|
87
98
|
|
|
88
99
|
`state/team-state-<task-type>-<seq>.json` stores invocation-aware dispatch
|
|
89
100
|
records. Code-owned worker launches record the invocation fields directly in
|
|
90
|
-
`workerDispatches[]
|
|
101
|
+
`workerDispatches[]`, including the `sessionId` the dispatch minted for that
|
|
102
|
+
attempt. That id is the only handle on a worker that runs as its own CLI
|
|
103
|
+
process, because such a session tags its transcript with neither an agent nor a
|
|
104
|
+
team name; it is empty for providers whose CLI takes no session-id argument. A
|
|
105
|
+
row is keyed by its dispatch ID rather than appended blindly: a row repeating a
|
|
106
|
+
`dispatchId` already present replaces that row in place, so one dispatch ID is
|
|
107
|
+
recorded at most once and a re-sent dispatch cannot make the run read as a
|
|
108
|
+
duplicate. Rows carrying no dispatch ID have no key to collapse on and still
|
|
109
|
+
stack. Nothing prunes the array and no row is ever dropped, so a replaced row
|
|
110
|
+
takes its `paneId` out of the ledger with it and the pane-reclaim gate no longer
|
|
111
|
+
offers that pane. Host-native calls use `agentDispatches[]`, and
|
|
91
112
|
`agentResultLinks[]` associates an accepted result path with exactly one
|
|
92
113
|
dispatch ID. The inverse is also exclusive: one dispatch ID cannot authorize
|
|
93
114
|
multiple accepted paths. State mutation uses a run-state lock and unique
|
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,8 +134,8 @@ 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` —
|
|
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.
|
|
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
|
+
- `templates/project-docs/task-index.template.md` · `templates/reports/final-report-v2.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
|
|
|
141
141
|
### Support assets (not referenced at runtime)
|
|
@@ -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
|
|
|
@@ -394,7 +394,7 @@ On the first run, it writes the four fields `projectId`, `projectRoot`, `created
|
|
|
394
394
|
|
|
395
395
|
`architecture.style` (optional, one of `hexagonal` / `layered` / `none`, default `none`) declares the project's architecture. It is read by [`scripts/okstra_project/resolver.py`](../scripts/okstra_project/resolver.py) `resolve_architecture`, which falls back to `none` on an absent field, an unrecognized value, or an unreadable `project.json`. It is the switch for the second of two enforcement layers.
|
|
396
396
|
|
|
397
|
-
**Layer 1 — always on, style-agnostic.** Independent of any declaration, every `implementation-planning` plan emits `variationPointAnalysis`: whether the same behavior is served by two or more implementations, and for each such point the interface it is extracted behind (`extractionDecision`) plus the Stage Map stage that builds it. `hasMultipleImplementations: false` is a claim rather than an omission, so it requires a written `noVariationRationale` and an empty `points` array. The recommended option carries `testSeams` — one row per boundary a test injects at and replaces — and each point becomes a `P-Var-<N>` item judged in the plan-body verification gate (§5.5.9), which DISAGREEs when an extraction branches on resource identity instead of extracting the interface the next implementation plugs into (the open/closed shape). **Enforced:** `schemas/final-report-
|
|
397
|
+
**Layer 1 — always on, style-agnostic.** Independent of any declaration, every `implementation-planning` plan emits `variationPointAnalysis`: whether the same behavior is served by two or more implementations, and for each such point the interface it is extracted behind (`extractionDecision`) plus the Stage Map stage that builds it. `hasMultipleImplementations: false` is a claim rather than an omission, so it requires a written `noVariationRationale` and an empty `points` array. The recommended option carries `testSeams` — one row per boundary a test injects at and replaces — and each point becomes a `P-Var-<N>` item judged in the plan-body verification gate (§5.5.9), which DISAGREEs when an extraction branches on resource identity instead of extracting the interface the next implementation plugs into (the open/closed shape). **Enforced:** `schemas/final-report-v2.0.schema.json` `$defs.VariationPointAnalysis` pins the shape, [`validators/validate-run.py`](../validators/validate-run.py) `_validate_variation_point_analysis` rejects a rationale-less or points-carrying `false`, a point-less `true`, and an `extract: true` decision with an empty `interfaceKind` or `coveredBy`, and `okstra_ctl.plan_items` emits the `P-Var-*` items.
|
|
398
398
|
|
|
399
399
|
**Layer 2 — only when a style is declared.** A declared style promotes the placement rules from advisory to binding at three sites. `hexagonal`: extraction itself is not made mandatory, but when a point *is* extracted the interface has to be a port — an `extractionDecision` carrying `extract: true` with any `interfaceKind` other than `"port"` is a validator failure in the same `_validate_variation_point_analysis`, while `extract: false` remains a legal decision the style does not reject; the executor loads `prompts/coding-preflight/architectures/hexagonal.md` even when none of the router's Stage 3 layout signals matched, so the declaration, not the directory shape, decides; and the verifier promotes an added or modified service dependency injecting a concrete adapter instead of a port from an advisory recommendation to a blocking finding → verdict `FAIL` ([`prompts/profiles/_coding-conventions-preflight.md`](../prompts/profiles/_coding-conventions-preflight.md), [`_implementation-verifier.md`](../prompts/profiles/_implementation-verifier.md)). `layered` has no pack resource; its binding invariant is dependency direction — an upper layer may import a lower one, never the reverse — and it is worker judgement, because no machine check reads layer names.
|
|
400
400
|
|
|
@@ -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
|
|
@@ -832,21 +834,6 @@ New task bundles use `schemas/final-report-v2.0.schema.json` as the final-report
|
|
|
832
834
|
- Each task template names the sections a reading agent should meet first and closes with a `md_rest()` sweep, so a field added to the schema reaches the Markdown without a template edit. **Enforced:** `tests/contract/test_ai_markdown_rendering.py`.
|
|
833
835
|
- `templates/reports/html/tasks/<task-type>.template.html` produces the task-specific human-facing HTML. It leads with a plain-language decision summary and presents the selected task's findings, diagrams, tables, evidence, and actions. Worker execution and convergence detail stays in a visually subordinate audit section.
|
|
834
836
|
|
|
835
|
-
The legacy schema v1 contract remains supported by `schemas/final-report-v1.0.schema.json` and `templates/reports/final-report.template.md`. Its Markdown structure is:
|
|
836
|
-
|
|
837
|
-
- `## Verdict Card` — **mandatory top section**. Five rows: Final Conclusion / Verdict Token / Direction / Approval Required? / Next Step. The Verdict Token / Direction / Next Step cells must byte-match the authoritative cells in body §2 (execution status) and §6 (next steps).
|
|
838
|
-
- (Optional) `## Reader Summary` — a five-row table rendered immediately below the Verdict Card only when data.json has `readerSummary`: decision (`decision`) / action required from a human (`humanActionRequired`) / blocking items (`blockingItems`) / safe-to-skip items (`safeToSkip`) / recommended command (`recommendedCommand`). When present, all five fields are required (schema `required`), and it contains only a summary rather than repeating raw evidence tables. Older data.json files without it continue to render unchanged.
|
|
839
|
-
- `## Background and Rationale` — **mandatory for every task type** (data.json `rationale`). Reviewer-oriented prose that answers four questions in order: Why are we doing this (`motivation`)? / Why is it a problem (`problem`)? / What work is therefore needed (`approach`)? / Why is this a reasonable choice (`justification`)? It is prose, not a table. Every field must contain either an evidence reference such as `path:line`, a report ID (`C-001`), or `§5.4`, or an explicit insufficiency marker (`insufficient evidence`). `_validate_rationale_evidence` in `validators/validate-run.py` fails any field that has neither.
|
|
840
|
-
- (Optional) `## 0. Clarification Response Carried In From Previous Run` — rendered only when a response was carried in from the previous run. The heading itself is omitted for an empty carry-in.
|
|
841
|
-
- (Optional) `### 0.1 Incremental Re-Verification Scope` — rendered only when data.json contains `implementationPlanning.incrementalDecision`. When `mode == "incremental"`, the `Re-verified stages` and `Carried-forward stages` rows are mandatory, and `validators/validate-run.py` blocks their absence as `contract-violated`. Carried plan items record the run in which they were verified with a `carriedForwardFromSeq` tag.
|
|
842
|
-
- `## 1. Problem or Verification Target Summary` — preserves the `Source items (worker:item)` column in both the §6.1 Consensus and §6.2 Differences tables for cross-worker traceability.
|
|
843
|
-
- `## 2. Agent Execution Status`
|
|
844
|
-
- `## 3. Cross-Verification Results` — §2.1 Primary Evidence contains the `Source items (worker:item)` and `Source (path:line / log)` columns.
|
|
845
|
-
- `## 4. Final Assessment` — emits §5.5.9 Plan Body Verification for `implementation-planning` grouped by plan item: the item's `subject` (a one-line description of what was verified) becomes the heading, followed by a per-worker `Worker / Verdict / Breakage kind / Note` table. It also renders three legends: gate values, verdict tokens, and breakage kinds (a–f).
|
|
846
|
-
- `## 1. Clarification Items` — a single consolidated eight-column table. The former §6.1 / §6.2 / §5.5.8 / §5.5.9 Open Questions are deprecated, and the validator fails if they appear.
|
|
847
|
-
- `## 6. Recommended Next Steps`
|
|
848
|
-
- `## Token Usage Summary` — the validator blocks publication if sentinel (`pending` / `N/A` / `--` / `?` / empty cell) or zero (`0` / `$0.00`) values are frozen into the report. Only the `Codex/Antigravity CLI Add-on` row may use `$0.00` to mean "CLI not used."
|
|
849
|
-
|
|
850
837
|
The `## 0. Reading Confirmation` block from worker output is written to the sidecar at the resolved `<run-dir>/worker-results/<worker>-audit-<task-type>-<seq>.md`, not included in the report body (enforced by the validator).
|
|
851
838
|
|
|
852
839
|
If there are no substantive differences, state that fact rather than manufacturing a contrast.
|
|
@@ -868,7 +855,7 @@ An approval row classifies its cause as `user-decision`, `noncritical-dissent`,
|
|
|
868
855
|
|
|
869
856
|
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`.
|
|
870
857
|
|
|
871
|
-
- `reports/final-report-<task-type>-<seq>.html` — always generated for schema v2 with one of
|
|
858
|
+
- `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.
|
|
872
859
|
- **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.
|
|
873
860
|
- **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.
|
|
874
861
|
- **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.
|
|
@@ -910,9 +897,8 @@ Errors that occur while provider workers, the report writer, or the Okstra lead
|
|
|
910
897
|
- The `.log` is an execution transcript containing wrapper/CLI output, not the original prompt. `okstra log-report` pairs it with the sibling persisted `.md` prompt and reports `transcriptBytes`, `promptBytes`, and their ratio separately. The compatibility fields `path`, `sizeBytes`, and `totalBytes` continue to mean transcript data, so existing consumers and transcript-size ordering remain stable.
|
|
911
898
|
- **Run-wide cap on the progress copy in the log** (`_LOG_PROGRESS_LINE_CAP` in `scripts/okstra_ctl/worker_runner.py`): workers read their required inputs end-to-end per the Worker Preamble's *Reading rules*, so a single report read can dump 170KB+ into the log and observed sidecars reach 8MB. The runner archives the first 5000 progress lines of the run and replaces the rest with a `[okstra log-cap] N progress line(s) elided` marker, emitted every 500 elided lines so a reader tailing the log can see the run is still producing. The cap is run-wide rather than per-block because a block boundary is a provider's own vocabulary and the shared runner has none; the cost is that a very long run keeps its opening rather than a sample throughout, which the elision notices make visible. **Only the log copy is capped** — never the screen, and never the result stream, because a truncated tool echo costs detail while a truncated answer costs the whole post-mortem.
|
|
912
899
|
- **Progress lands in the worker's own pane, not in a sibling tail pane.** The presentation is passed to the entrypoint as `--presentation live|quiet`; `live` is claimed only by a backend that opened a pane, and the default is `quiet`. Under `live` the runner renders each event into one readable row on the caller's own streams (`→ Bash: …` for a tool call, ` ← ok (N bytes)` for its result, `!! PERMISSION DENIED — <tool>: <reason>` for a refusal); thinking events are dropped. Under `quiet` progress is withheld and only the worker's closing text is printed, which is what a `cli-wrapper` dispatch on a machine with no pane surface needs. `scripts/okstra_ctl/domain/worker_stream.py` owns all three projections (`format_live`, `format_log`, `final_text`) as pure functions over *normalised* events — `Text`, `ToolCall`, `ToolResult`, `Denial`, `Result`. Providers do not share a wire format and this layer may not name one, so each adapter supplies the function that turns its own events into those, declared on `ExecCommand.normalise` beside the stream format it belongs to. Adding a provider whose stream is shaped differently is that one function; a provider that declares `stream-json` without one is failed by `tests/contract/test_provider_execution_contract.py`, which runs the schema each provider claims through its own normaliser and requires rows out.
|
|
913
|
-
-
|
|
914
|
-
- **
|
|
915
|
-
- **Automatic cleanup on phase transitions, including worker-agent panes**: `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` closes tagged worker-compute panes plus the worker-agent panes occupied by dispatched subagents. These harness-owned panes cannot be tagged, so the script identifies them within the lead's window (`tmux list-panes -t <lead-pane>`, no `-s`) through a title allowlist: `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`. Implementation role titles such as `claude-executor` / `codex-verifier`, and FleetView teammate prefixes `✳ ` / `⠂ `, are also treated as okstra panes. Every entry matches as a substring (`*agy-executor*`), which is how a former `agy-executor-tail` trace pane was caught even though the allowlist never named trace panes; no such pane is created now. Split-pane teammates always land in the lead's window, so window scope still catches all of this run's worker panes while leaving a second okstra lead running in another window of the same tmux session out of range. Window scoping and exclusion of the lead's own pane are determined by `<RUN_DIR>/state/lead-pane.id`; the lead pane is never killed even if its title matches. At every worker round boundary — after collecting that round's results and token usage, immediately before the next dispatch and before the `PROGRESS: phase-5.5-convergence` / `phase-6-synthesis` marker — the lead calls this script with `--run-dir` to reclaim the prior round's completed panes without prompting. `--keep <substr>` (repeatable) excludes panes whose title contains the substring, which is how an in-flight `report-writer-worker` survives the boundary. The lead first runs the same command with `--list` to count the panes it is about to reclaim and reports that count as `PROGRESS: phase-batch-cleanup panes=<n>`.
|
|
900
|
+
- **No okstra pane carries a tag any more, and the tag scan is gone with them.** Two writers disappeared at different times. The wrappers stopped splitting a `tail -F` sibling, so **nothing spawns a trace pane** and `@okstra_trace_run` / `@okstra_status` lost their writer — the operator watches the worker pane itself instead. Then the `tmux-pane` dispatch backend was removed, so `tmux.tag_pane` and `@okstra_worker_run` went with it: a worker now gets a cmux surface or a cli-wrapper subprocess, neither of which is a tmux pane okstra owns. `okstra-trace-cleanup.sh` therefore no longer scans tags at all, and the two modes that existed only for that scan were removed — `--reclaim-completed` (with the `okstra-subagent-reclaim.sh` entry that drove it from `SubagentStop` / `TaskCompleted`) and `--reap` (with its `SessionEnd` entry). Those hooks are gone from `templates/reports/settings.template.json`; `SessionEnd` now carries only `okstra-team-reconcile.sh --session-end`.
|
|
901
|
+
- **What cleanup still does — worker-agent panes**: `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` closes the worker-agent panes occupied by dispatched subagents. These harness-owned panes cannot be tagged, so the script identifies them within the lead's window (`tmux list-panes -t <lead-pane>`, no `-s`) through a title allowlist: `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`. Implementation role titles such as `claude-executor` / `codex-verifier`, and FleetView teammate prefixes `✳ ` / `⠂ `, are also treated as okstra panes. Every entry matches as a substring (`*agy-executor*`), which is how a former `agy-executor-tail` trace pane was caught even though the allowlist never named trace panes; no such pane is created now. Split-pane teammates always land in the lead's window, so window scope still catches all of this run's worker panes while leaving a second okstra lead running in another window of the same tmux session out of range. Window scoping and exclusion of the lead's own pane are determined by `<RUN_DIR>/state/lead-pane.id`; the lead pane is never killed even if its title matches. At every worker round boundary — after collecting that round's results and token usage, immediately before the next dispatch and before the `PROGRESS: phase-5.5-convergence` / `phase-6-synthesis` marker — the lead calls this script with `--run-dir` to reclaim the prior round's completed panes without prompting. `--keep <substr>` (repeatable) excludes panes whose title contains the substring, which is how an in-flight `report-writer-worker` survives the boundary. The lead first runs the same command with `--list` to count the panes it is about to reclaim and reports that count as `PROGRESS: phase-batch-cleanup panes=<n>`.
|
|
916
902
|
- **Cleanup survives compaction and precedes user gates**: A `SessionStart` hook with matcher `compact` (`okstra-compact-reminder.sh`, seeded in `settings.template.json`) fires after every `/compact` or auto-compaction. It reads `cwd` from the hook's stdin JSON, finds any in-progress okstra run for that project via `active.jsonl` (`pane_reclaim.active_run_dirs_for_project`), and, if one exists, prints a factual reminder naming the run dir and how completed panes/tasks are reclaimed — restoring the boundary/gate cleanup obligation that a compaction summary can otherwise drop. The hook never kills panes itself: a teammate pane is untagged and title-only, so a hook cannot tell an in-flight worker from a finished one; the actual `kill-pane` stays with the lead, which knows completion state. Separately, the lead runs the same completed-pane reclaim immediately before any user approval/clarification/decision gate (`PROGRESS: phase-gate-cleanup panes=<n>`), so a gate is never shown with finished worker panes still open. At every cleanup point the pane-kill (`trace-cleanup`) and the task-stop (`TaskStop`) are paired — a `TaskStop` alone idles the roster task but leaves the pane open.
|
|
917
903
|
- **User confirmation at phase end**: At the final step of the run, the lead calls `okstra-trace-cleanup.sh --list --run-dir <RUN_DIR>` to show remaining okstra panes (worker-agent + trace), then asks once whether to "close all and clean up teammates / keep them." It follows the response (see *Phase wrap-up* in `prompts/profiles/_common-contract.md`). If approved, the lead cleans the panes. For a split-pane run, it then uses `okstra-team-reconcile.sh` to mark dead-pane members inactive and sends each completed teammate a `SendMessage` shutdown_request (`TeamDelete` was removed in v2.1.178; the implicit team disappears with the session). The lead does not gate this pane step by interpreting `lead-pane.id`; it **always** invokes the script, which safely returns an empty pane list and no-ops outside tmux. The teammate step is determined by the existence of an on-disk team configuration whose `leadSessionId` matches (`~/.claude/teams/session-*/config.json`), not by `teamCreate.status`. `--list` does not kill panes and prints only `<pane_id>\t<pane_title>`, so the user can see exactly what would be closed.
|
|
918
904
|
- Disk accumulation is handled by the `okstra-inspect logs` flow, which offers a read-only inventory and suggests cleanup commands for the user to copy and paste.
|
|
@@ -986,7 +972,7 @@ Each validator blocks the phase with a `contract-violated` exit code when a cont
|
|
|
986
972
|
|
|
987
973
|
- `README.md`
|
|
988
974
|
- `templates/reports/task-brief.template.md`
|
|
989
|
-
- `templates/reports/final-report.template.md`
|
|
975
|
+
- `templates/reports/final-report-v2.template.md`
|
|
990
976
|
- `prompts/lead/okstra-lead-contract.md`
|
|
991
977
|
- `scripts/okstra-error-log.py`
|
|
992
978
|
- `scripts/okstra-token-usage.py`
|
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`.
|
|
@@ -778,6 +809,7 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
778
809
|
| `okstra code-review target --task-key <k> --stage <N> [--project-root <dir>] [--cwd <dir>] [--json]` / `okstra code-review target --branch <name> [--base <ref>] [--date <YYYY-MM-DD>] [--project-root <dir>] [--cwd <dir>] [--json]` | Resolve what a code review reads and where its result file goes. Output is always JSON, so `--json` only makes that explicit. `--project-root` and `--cwd` are shared pre-dispatch arguments and apply to both modes; `--cwd` is only consulted when `--project-root` is absent. Both modes return `{ ok, projectRoot, mode, worktreePath, branch, baseCommit, headCommit, reviewPath, round }`; stage mode additionally returns `taskKey`, `taskRoot`, and `stage`. Stage mode takes the diff base from the `base_ref` recorded on that stage's worktree-registry row when it was provisioned — not from a rule re-applied at review time — and names the result `.okstra/tasks/<task-group>/<task-id>/code-reviews/stage-<NN>.md`, where a re-review of the same stage becomes `-r2`, `-r3`, … (the `round` field). Only a legacy row provisioned before `base_ref` was recorded falls back to re-deriving the base through `stage_targets`, and a failure there is reported as `stage_base_unresolved`. `worktreePath` comes back empty whenever the stage worktree is not usable as a live checkout — the registry row is no longer `active` (whole-task final-verification released it), the row never carried a path, or the recorded directory is gone — and the review then reads the `branch` ref instead. Branch mode uses `--base` when given, otherwise the merge-base with the default branch (`refs/remotes/origin/HEAD`, else `main`/`master`), and names the result `.project-docs/code-reviews/<branch>/<YYYY-MM-DD>-<NN>.md`, where `<NN>` (the `round` field) is the next sequence number for that date — the highest already on disk plus one. Read-only: it resolves paths and creates no directory and no file, so the review directory does not exist until the caller writes the report. Backend for the okstra-code-review skill |
|
|
779
810
|
| `okstra set-work-status <token> <todo\|in-progress\|blocked\|done> [--note <text>] [--task-group <g>] [--project-root <dir>]` | Update user-managed `workStatus` in task-manifest.json, along with `workStatusUpdatedAt` and, when `--note` is supplied, `workStatusNote`. `<token>` is a full task key or bare task ID. It uses the manifest renderer's serialization rules and returns `stage:"ambiguous"` plus `matches[]` when ambiguous |
|
|
780
811
|
| `okstra worktree-lookup <task-key>` | Return the `worktree_registry.lookup` result: reserved path, branch, base ref, and current status |
|
|
812
|
+
| `okstra worktree-status [--path <dir>] [--check-clean]` | Answer "is this worktree clean?" over source paths only, excluding what okstra provisioned there — `.okstra`, the configured sync entries (`.project-docs`, `.claude`, …), and any nested stage worktree. A bare `git status --porcelain` in a task worktree is never empty for that reason, so a plan step asserting a clean tree with one fails on okstra's scaffolding instead of on the stage's own work; this is the same gate `handoff` and stage integration use. Output is JSON `{ ok, path, clean, entries, excluded }` where `entries` holds the `git status --short` rows that made it dirty. Exit code is 0 regardless unless `--check-clean` is given, which exits 1 on a dirty tree so it can stand as a shell assertion (`okstra worktree-status --check-clean && git tag -f stage-<N>-exit`). A path outside a git work tree exits 2 rather than reporting a clean tree |
|
|
781
813
|
| `okstra plan-validate <plan-path>` | Run `_validate_approved_plan` and report frontmatter `approved` recognition plus unresolved Blocks=approval rows |
|
|
782
814
|
| `okstra render-bundle <args…> [--stage <auto\|N>] [--stages <csv>]` | Thin shim over `prepare_task_bundle(render_only=True)` with the same signature as `python3 -m okstra_ctl.run --render-only`. `--stage` is for `implementation` and `final-verification`: for implementation, `auto` (default) selects the earliest incomplete stage with satisfied dependencies, while `<N>` forces a stage; for final-verification, `<N>` verifies one stage with artifacts under `runs/final-verification/stage-<N>/` and a `-fv-s<N>` team suffix, while an empty value performs whole-task verification with the flat layout. The separate `--stages <csv>` channel is for `release-handoff`: stage-group mode bundles the listed stage numbers into one PR, while an empty value selects whole-task mode. Preparation enforces eligibility—`done` + accepted `verified` + not yet `pr`—and automatically creates an input document that cites verification reports |
|
|
783
815
|
| `okstra profile show <task-type> [--resolved]` | Print a phase profile. `--resolved` expands its `{{INCLUDE:}}` targets and appends the lazy-read sidecars named in the profile body — transitively, because sidecars name sidecars of their own (`_implementation-executor.md` points at the coding-conventions preflight, the diff-review sweep, and the completion self-check). That matters because a profile is assembled from three places, so grepping only the top-level file returns false negatives: `grep clarification prompts/profiles/implementation.md` finds nothing while the assembled profile has many hits. One grep over this output answers whether a task-type covers a rule. The sidecar list is read from the profile body, never hard-coded, so a newly added sidecar is picked up without a code change. Read-only: it writes no manifest and registers no run, which is what separates it from `render-bundle` — `render-bundle` answers the same question but records a run in `recent.jsonl`, so it cannot be used to look something up. Exits 2 for an unknown task-type |
|
|
@@ -788,7 +820,7 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
788
820
|
| `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
821
|
| `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. |
|
|
790
822
|
| `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. |
|
|
791
|
-
| `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,
|
|
823
|
+
| `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, except `token-usage`: its input is the lead session log, so a failure there defers rather than deleting the html, follow-ups and validation that come after it — the run still reports `ok: false`, and names that step unless a later one also fails, in which case the later failure is the reason. Whenever a step exits non-zero the command prints the `--only` flags that resume the sequence from the earliest failing step; after a deferral that tail is what re-renders the html the deferred step invalidated. 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. |
|
|
792
824
|
| `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 |
|
|
793
825
|
| `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 |
|
|
794
826
|
| `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 |
|
|
@@ -844,4 +876,4 @@ For every dispatch, whichever provider runs it, okstra creates a `runs/<task-typ
|
|
|
844
876
|
|
|
845
877
|
**Progress appears in the worker's own pane.** Earlier versions split a sibling `tail -F` trace pane next to each worker; they no longer do, and no trace pane is created at all. Instead the presentation is passed to the entrypoint as `--presentation live|quiet`, and only a backend that opened a pane asks for `live` — the default, and what a `cli-wrapper` subagent dispatch passes, is `quiet`. Under `live` each event becomes one readable row on the worker's own streams — `→ Bash: npm run check`, then ` ← ok (2481 bytes)`, and `!! PERMISSION DENIED — <tool>: <reason>` for a refusal. Under `quiet` progress is withheld and only the worker's closing text is printed, which is what a dispatch on a machine with no pane surface needs. The `.log` sidecar records the progress either way, so withholding it from the screen loses nothing.
|
|
846
878
|
|
|
847
|
-
|
|
879
|
+
Every pane tag this script once scanned has lost its writer, so the tag scan is gone along with the two modes that existed only to drive it. `@okstra_trace_run` / `@okstra_status` went inert when the wrappers stopped splitting a trace pane, which retired `--reclaim-completed` and the `okstra-subagent-reclaim.sh` hook behind it; `@okstra_worker_run` went with the `tmux-pane` dispatch backend, which retired `--reap` and its `SessionEnd` hook. What okstra still has to close are the teammate panes the **harness** splits for dispatched worker agents — panes okstra never created and cannot tag. The lead calls `okstra-trace-cleanup.sh --run-dir <RUN_DIR>`, which finds them by a title allowlist within the lead-window scope (`tmux list-panes -t <lead-pane>`, no `-s`, so a second lead in another window of the same session is out of range), while excluding the lead's own pane. Worker-agent titles include `claude-worker`, `codex-worker`, `antigravity-worker`, `report-writer-worker`, implementation role titles, and FleetView teammate prefixes `✳ ` / `⠂ `. The lead runs `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` at every worker round boundary — after collecting that round's results and before the next dispatch, not once per phase — to reclaim the completed panes. `--keep <substr>` (repeatable) excludes panes whose title contains the substring, which is how an in-flight report writer is preserved (`--keep report-writer-worker`), and `--list` prints the same set without killing so the lead can count what it is about to reclaim. The lead also runs the same reclaim immediately before any user approval/clarification/decision gate (`PROGRESS: phase-gate-cleanup panes=<n>`), and an `okstra-compact-reminder.sh` `SessionStart` hook (matcher `compact`) re-injects this obligation after a `/compact`.
|
package/docs/container.md
CHANGED
|
@@ -75,7 +75,7 @@ One watcher per container runs in the detached session.
|
|
|
75
75
|
1. **Lightweight scan** — Fetch incremental logs with `docker compose logs --since` and match only regular expressions (`ERROR`/`FATAL`/`Exception`/`Traceback`/abnormal exit codes, and so on). If there are no matches, proceed to the next interval without an LLM call → zero token cost during healthy periods.
|
|
76
76
|
2. **Deep analysis** — Only when a pattern is detected, the watcher AI analyzes the relevant log window and appends its findings to `findings.md`. Identical error signatures are debounced (meaningful numbers such as HTTP statuses and exit codes are preserved, while only noise such as timestamps and pids is normalized). The watcher **only detects and reports**; it does not modify code or configuration.
|
|
77
77
|
|
|
78
|
-
Watcher/tail panes carry only the dedicated `@okstra_container_run` tag
|
|
78
|
+
Watcher/tail panes carry only the dedicated `@okstra_container_run` tag and survive a Claude session ending — no session-end hook reclaims panes any more. Stop them with `stop-watcher` or `down`.
|
|
79
79
|
|
|
80
80
|
## Labels and artifacts
|
|
81
81
|
|