okstra 0.175.1 → 0.176.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/docs/architecture/storage-model.md +2 -2
- package/docs/architecture.md +22 -19
- package/docs/cli.md +18 -14
- package/docs/for-ai/skills/okstra-inspect.md +2 -3
- package/docs/for-ai/skills/okstra-rollup.md +1 -0
- package/docs/project-structure-overview.md +57 -56
- package/docs/task-process/README.md +11 -9
- package/docs/task-process/common-flow.md +13 -16
- package/docs/task-process/error-analysis.md +9 -10
- package/docs/task-process/final-verification.md +7 -7
- package/docs/task-process/implementation-planning.md +9 -9
- package/docs/task-process/implementation.md +6 -6
- package/docs/task-process/release-handoff.md +8 -7
- package/docs/task-process/requirements-discovery.md +8 -8
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/lib/okstra/interactive.sh +12 -6
- package/runtime/bin/lib/okstra/usage.sh +3 -2
- package/runtime/bin/okstra-spawn-followups.py +4 -2
- package/runtime/prompts/launch.template.md +2 -2
- package/runtime/prompts/lead/context-loader.md +1 -2
- package/runtime/prompts/lead/okstra-lead-contract.md +3 -4
- package/runtime/prompts/lead/report-writer.md +15 -1
- package/runtime/prompts/lead/team-contract.md +16 -12
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +0 -3
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -7
- package/runtime/prompts/profiles/change-impact-analysis.md +9 -5
- package/runtime/prompts/profiles/error-analysis.md +14 -8
- package/runtime/prompts/profiles/feature-analysis.md +9 -5
- package/runtime/prompts/profiles/final-verification.md +10 -7
- package/runtime/prompts/profiles/implementation-option-selection.md +9 -5
- package/runtime/prompts/profiles/implementation-planning.md +13 -7
- package/runtime/prompts/profiles/implementation.md +9 -5
- package/runtime/prompts/profiles/improvement-discovery.md +10 -6
- package/runtime/prompts/profiles/project-analysis.md +9 -5
- package/runtime/prompts/profiles/requirements-discovery.md +15 -9
- package/runtime/prompts/wizard/prompts.ko.json +18 -1
- package/runtime/python/okstra_ctl/adapters/runtime/__init__.py +1 -0
- package/runtime/python/okstra_ctl/adapters/runtime/assembly.py +27 -0
- package/runtime/python/okstra_ctl/adapters/runtime/cli_wrapper.py +49 -0
- package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +74 -0
- package/runtime/python/okstra_ctl/application/open_worker.py +29 -0
- package/runtime/python/okstra_ctl/assignment_resolver.py +27 -27
- package/runtime/python/okstra_ctl/dispatch_core.py +120 -100
- package/runtime/python/okstra_ctl/domain/host.py +3 -1
- package/runtime/python/okstra_ctl/domain/wizard/interaction.py +5 -0
- package/runtime/python/okstra_ctl/domain/worker_runtime.py +44 -0
- package/runtime/python/okstra_ctl/implementation_outcome.py +21 -5
- package/runtime/python/okstra_ctl/legacy_model_selection.py +115 -27
- package/runtime/python/okstra_ctl/manager_sync.py +4 -1
- package/runtime/python/okstra_ctl/next_phase.py +236 -0
- package/runtime/python/okstra_ctl/ports/worker_runtime.py +26 -0
- package/runtime/python/okstra_ctl/recap.py +4 -1
- package/runtime/python/okstra_ctl/render.py +46 -47
- package/runtime/python/okstra_ctl/role_requirements.py +28 -35
- package/runtime/python/okstra_ctl/rollup.py +4 -1
- package/runtime/python/okstra_ctl/run.py +8 -5
- package/runtime/python/okstra_ctl/stage_fix_carry.py +17 -1
- package/runtime/python/okstra_ctl/team.py +14 -18
- package/runtime/python/okstra_ctl/wizard.py +248 -56
- package/runtime/python/okstra_ctl/worker_prompt_body.py +18 -2
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +40 -9
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +16 -1
- package/runtime/python/okstra_ctl/workflow.py +18 -32
- package/runtime/python/okstra_ctl/worktree.py +3 -3
- package/runtime/python/okstra_ctl/worktree_registry.py +5 -4
- package/runtime/python/okstra_project/state.py +54 -6
- package/runtime/schemas/final-report-v2.0.schema.json +43 -5
- package/runtime/skills/okstra-inspect/facets/recap.md +2 -0
- package/runtime/skills/okstra-inspect/facets/report.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +15 -13
- package/runtime/skills/okstra-rollup/SKILL.md +1 -0
- package/runtime/skills/okstra-run/SKILL.md +5 -5
- package/runtime/templates/implementation-worker-preamble.md +3 -18
- package/runtime/templates/project-docs/task-index.template.md +0 -1
- package/runtime/templates/reports/html/macros/forms.html +5 -4
- package/runtime/templates/reports/html/tasks/final-verification.template.html +1 -1
- package/runtime/templates/reports/html/tasks/implementation.template.html +1 -1
- package/runtime/templates/worker-prompt-preamble.md +3 -36
- package/runtime/validators/validate-run.py +57 -99
|
@@ -253,9 +253,9 @@ Examples of key fields:
|
|
|
253
253
|
- `workflow.currentPhaseState`
|
|
254
254
|
- `workflow.phaseStates`
|
|
255
255
|
- `workflow.lastCompletedPhase`
|
|
256
|
-
- `workflow.nextRecommendedPhase`
|
|
256
|
+
- `workflow.nextRecommendedPhase` *(object `{phase, status, rationale}`; `status` is `ready` / `pending` / `blocked` / `terminal`. The lead writes `phase` only under `ready` — an authoring rule, not a constraint the struct enforces: `prepare` lowers a `ready` pointer to `pending` and keeps its `phase`, so a stored non-`ready` pointer that still names a phase is a normal manifest state. Read `status` to decide whether anything can be launched.)*
|
|
257
|
+
- `workflow.nextRecommendedPhaseCorrection` *(present only when Phase 7 validation replaced the authored pointer — `{authored, applied}`)*
|
|
257
258
|
- `workflow.awaitingApproval`
|
|
258
|
-
- `workflow.routingStatus`
|
|
259
259
|
- `workflow.lastSafeCheckpoint`
|
|
260
260
|
- `phaseOutcome` *(artifact-derived semantic phase outcome; for example, when the implementation carry proves that all stages passed, the implementation phase outcome may be recorded as completed even if run contract validation failures remain)*
|
|
261
261
|
- `inputs`
|
package/docs/architecture.md
CHANGED
|
@@ -429,25 +429,27 @@ Selection rules:
|
|
|
429
429
|
|
|
430
430
|
- With `--task-type <name>`, `prompts/profiles/<name>.md` is rendered as the task bundle's `instruction-set/analysis-profile.md`.
|
|
431
431
|
- The single selector in the external interface is `task-type`.
|
|
432
|
-
- The selected task type is reflected unchanged in `taskType
|
|
432
|
+
- The selected task type is reflected unchanged in `taskType` and `workflow.currentPhase` in task-manifest.json. It is not written into `workflow.nextRecommendedPhase`: prepare only lowers an inherited `ready` pointer to `pending`, and the pointer's next value comes from the report this run produces.
|
|
433
433
|
- It is also used as the run-directory path segment (`runs/<task-type>/...`).
|
|
434
434
|
|
|
435
435
|
### Standard task types
|
|
436
436
|
|
|
437
437
|
Each task type enforces phase-specific allowed and forbidden actions. A run creates only the artifacts for its own task type and does not advance to the next phase. The next phase always begins with a new `okstra.sh` execution.
|
|
438
438
|
|
|
439
|
-
|
|
439
|
+
The fourth column is the `workflow.nextRecommendedPhase` pointer Phase 7 leaves behind. The pointer is an object `{phase, status, rationale}`; `status` is `ready`, `pending`, `blocked`, or `terminal`, and `phase` names a phase only under `ready`. Phase 7 does not decide the route — it projects the pointer from the report's own routing field (`scripts/okstra_ctl/next_phase.py::project`), named per row below. The authoring rule for the field is stated once, in the Phase 6 checklist of [`prompts/lead/report-writer.md`](../prompts/lead/report-writer.md); this table describes the outcome, not the rule.
|
|
440
|
+
|
|
441
|
+
| task type | Purpose | Core artifacts | Next-phase pointer after Phase 7 | Code changes allowed? |
|
|
440
442
|
|---|---|---|---|---|
|
|
441
|
-
| `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
|
|
442
|
-
| `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 |
|
|
443
|
-
| `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`
|
|
444
|
-
| `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`
|
|
445
|
-
| `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) |
|
|
446
|
-
| `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`) | `
|
|
447
|
-
| `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 | `
|
|
448
|
-
| `project-analysis` | Map the current project structure and feature index | components, dependencies, entry points, data stores, external systems, feature index | `pending
|
|
449
|
-
| `feature-analysis` | Trace one confirmed existing feature | flows, domain rules, state changes, external interactions, test coverage | `pending
|
|
450
|
-
| `change-impact-analysis` | Map the impact of one proposed change | preserved behavior, impact items, dependency blast radius, test and operational impact | `pending
|
|
443
|
+
| `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 | from `requirementsDiscovery.routing.nextTaskType`: `ready` at `error-analysis` or `implementation-option-selection`; `pending` when the run settles on neither | No |
|
|
444
|
+
| `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 | from `errorAnalysis.routing.nextTaskType`: `ready` at `implementation-option-selection` after a credible cause, or at `error-analysis` for continued investigation | No |
|
|
445
|
+
| `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 | from the `implementationOptionSelection.routing` string enum: `ready` at `implementation-planning` once a direction is confirmed, `pending` on `pending-direction-selection`, `blocked` on `blocked` | No (strictly read-only; source edits, builds, tests, migrations, and deploys are prohibited) |
|
|
446
|
+
| `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 | from `implementationPlanning.outcome`: `ready` at `implementation` on `plan-ready` (the plan still needs its separate approval before that run starts), `ready` at `implementation-option-selection` on `direction-invalidated` | No |
|
|
447
|
+
| `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 | from `implementation.routingRecommendation.target`: `ready` at that phase — `final-verification` on a clean stage, otherwise `error-analysis`, `implementation-planning`, or `implementation` | Yes (limited to the approved plan's file list; `git push`/publish/deploy/real migration prohibited) |
|
|
448
|
+
| `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`) | from `finalVerification.routingRecommendation.target`: `ready` at that value — `release-handoff` only on an `accepted` verdict, otherwise the phase owning the defect (cause, selected direction, or detailed plan). `release-handoff(stage-group)` is a scope qualifier on the same phase, so it projects to `release-handoff`. `done` becomes `terminal` | No (read-only tests only) |
|
|
449
|
+
| `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 | always `terminal` — the lifecycle ends here and this report has no routing field Phase 7 projects from | 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. |
|
|
450
|
+
| `project-analysis` | Map the current project structure and feature index | components, dependencies, entry points, data stores, external systems, feature index | always `pending` with no phase — a sidetrack settles no route | No (strictly read-only; tests are also prohibited) |
|
|
451
|
+
| `feature-analysis` | Trace one confirmed existing feature | flows, domain rules, state changes, external interactions, test coverage | always `pending` with no phase — a sidetrack settles no route | No (strictly read-only; tests are also prohibited) |
|
|
452
|
+
| `change-impact-analysis` | Map the impact of one proposed change | preserved behavior, impact items, dependency blast radius, test and operational impact | always `pending` with no phase — a sidetrack settles no route | No (strictly read-only; tests are also prohibited) |
|
|
451
453
|
|
|
452
454
|
Common constraints:
|
|
453
455
|
|
|
@@ -752,7 +754,7 @@ The report writer records the decision unchanged in `implementationPlanning.incr
|
|
|
752
754
|
scripts/okstra.sh --task-type implementation-planning --workers claude,codex --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
753
755
|
```
|
|
754
756
|
|
|
755
|
-
Abbreviated form for a later phase (if the manifest's `workflow.nextRecommendedPhase` is `implementation-planning`, `--task-type` may also be omitted):
|
|
757
|
+
Abbreviated form for a later phase (if the manifest's `workflow.nextRecommendedPhase` is `{"phase": "implementation-planning", "status": "ready", ...}`, `--task-type` may also be omitted):
|
|
756
758
|
|
|
757
759
|
```bash
|
|
758
760
|
scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --workers claude,codex
|
|
@@ -806,9 +808,9 @@ Checking the following fields first makes it easy to determine the current posit
|
|
|
806
808
|
- `workflow.currentPhaseState`
|
|
807
809
|
- `workflow.phaseStates`
|
|
808
810
|
- `workflow.lastCompletedPhase`
|
|
809
|
-
- `workflow.nextRecommendedPhase`
|
|
811
|
+
- `workflow.nextRecommendedPhase` *(object `{phase, status, rationale}`; `status` is `ready` / `pending` / `blocked` / `terminal`. The lead writes `phase` only under `ready` — an authoring rule, not a constraint the struct enforces: `prepare` lowers a `ready` pointer to `pending` and keeps its `phase`, so a non-`ready` pointer that still names a phase is a normal manifest state. Read `status` to decide whether anything can be launched.)*
|
|
812
|
+
- `workflow.nextRecommendedPhaseCorrection` *(present only when Phase 7 validation replaced the authored pointer — `{authored, applied}`, where `authored` is the pointer the lead wrote)*
|
|
810
813
|
- `workflow.awaitingApproval`
|
|
811
|
-
- `workflow.routingStatus`
|
|
812
814
|
- `workflow.lastSafeCheckpoint`
|
|
813
815
|
- `phaseOutcome`
|
|
814
816
|
|
|
@@ -826,8 +828,9 @@ Resume decision rules:
|
|
|
826
828
|
|
|
827
829
|
- Resume the current run: if `latestResumeCommandPath` exists, use that path first.
|
|
828
830
|
- Restart the current phase: run again with the same `task-key` and current `task-type`.
|
|
829
|
-
- Start the next phase: if `workflow.nextRecommendedPhase` is
|
|
830
|
-
- Additional material required: if `
|
|
831
|
+
- Start the next phase: if `workflow.nextRecommendedPhase.status` is `ready`, prepare the next `okstra.sh` run with its `phase`.
|
|
832
|
+
- Additional material required: if that `status` is `pending` or `blocked`, the pointer carries no phase. Read its `rationale`, augment the brief, and rerun the phase that left the pointer unsettled.
|
|
833
|
+
- Nothing left to run: `status` `terminal` means the lifecycle ended at this phase.
|
|
831
834
|
|
|
832
835
|
## Final report structure
|
|
833
836
|
|
|
@@ -925,7 +928,7 @@ Tokens used in each run are collected from lead/worker session transcripts and w
|
|
|
925
928
|
- CLI execution evidence and token attribution are independent. A wrapper `.status.json` proves `not-started`, `started`, `exited`, `timeout`, or `failed` and supplies the worker's collection window; only a matching transcript with a final token snapshot proves attributable usage. If a wrapper exited successfully but no attributable transcript exists, the worker remains `source: "unavailable"` with `cliExecutionStatus: "exited"` and a reason instead of becoming zero usage or being described as never invoked.
|
|
926
929
|
- Records billable-equivalent token math and USD cost estimates. It applies Anthropic billing ratios (`cache_creation_5m=1.25x`, `cache_creation_1h=2.0x`, `cache_read=0.1x`, `output=5x`). When the transcript provides separate `usage.cache_creation.ephemeral_5m_input_tokens` / `ephemeral_1h_input_tokens` values, they are counted separately.
|
|
927
930
|
- Pricing is centrally managed in `scripts/okstra_token_usage/pricing.py`. Update it when model prices change. Model IDs that fail price matching are exposed to the user in `usageSummary.unmatchedModels`, preventing silent-zero incidents.
|
|
928
|
-
- Project-wide historical usage is exposed through the read-only `okstra usage-report` command (`src/commands/inspect/usage-report.
|
|
931
|
+
- Project-wide historical usage is exposed through the read-only `okstra usage-report` command (`src/commands/inspect/usage-report.mts` → `scripts/okstra_ctl/usage_report.py`) and the `okstra-usage` skill. It defaults to the whole current project's last 30 days and returns run coverage, raw and billable-equivalent tokens, known USD cost, CPU-sum milliseconds, and wall-clock milliseconds grouped by task type. Runs without usable Phase 7 usage are excluded from resource totals and reported through unavailable reason counts rather than treated as zero usage; unmatched model names remain visible when their tokens and time are included but their cost is not. Use `okstra-inspect` for one task's elapsed/context detail and `okstra-rollup` for task-group or project status/report digests.
|
|
929
932
|
- **Incremental scan cache (P6)**: To avoid rescanning session jsonl files, a per-file byte cursor and the extracted usage events before windowing are stored in `$OKSTRA_HOME/cache/token-usage/<transcript-dir>/<sessionId>.json` (`scripts/okstra_token_usage/cursor.py`). The run window (since/until) is reevaluated over events on every invocation, so even if a rerun narrows the window, the total matches a full scan. The cache is derived data; identifier mismatch, truncation, or corruption automatically falls back to a full rescan, and `okstra-token-usage.py --no-cache` forces a bypass.
|
|
930
933
|
- **Phase timeline (P0 instrumentation)**: The collector extracts `PROGRESS: phase-*` checkpoint lines (see "Progress reporting" in prompts/lead/okstra-lead-contract.md) from the lead session jsonl scoped to the run window, and records them in team-state as a `phaseTimeline` block (`{source, phases: [{phase, firstAt, lastAt, markerCount, wallMsToNext}]}`) (`scripts/okstra_token_usage/collect.py :: phase_timeline`). This provides measurement points for per-phase wall-clock time within the run and is consumed by the "Per-run phase breakdown" in the `okstra-inspect` time facet. Runs without markers explicitly report that measurement is unavailable with `phases: []`.
|
|
931
934
|
|
|
@@ -942,7 +945,7 @@ Each validator blocks the phase with a `contract-violated` exit code when a cont
|
|
|
942
945
|
|
|
943
946
|
**Blocking failures vs advisories.** `validate-run.py` splits its findings into `validation.failures` and `validation.advisories` (both written to the run manifest and team state, and printed on stdout; advisories also go to stderr one per line). Only `failures` decide `validation.status`, so a run can pass while carrying advisories. The dividing line is whether a remedy still exists at Phase 7: a defect in the report is fixable by re-authoring and re-rendering, while a defect in what an *already-ended session* wrote down is not — the worker that would restate its citation and the lead pane that would emit its PROGRESS line are both gone, so the only remaining move is to void the phase, which blocks the next one without establishing that any conclusion in the report is wrong. Two surfaces are advisory today: the worker citation ledger (`okstra_ctl.worker_audit_ledger.worker_results_audit_findings` — a `path:line` citation with no matching Evidence read row; a missing or unreadable sidecar stays blocking) and the PROGRESS narration lines (`validators/validate_session_conformance.py` `SessionConformanceResult.advisories`; the user-confirmation cross-check stays blocking because it verifies a claim the report makes). **Enforced:** `tests/contract/test_worker_audit_check.py::test_an_unmatched_citation_is_advisory_and_a_missing_sidecar_is_not` and `tests/contract/test_validate_session_conformance.py::test_missing_checkpoints_are_advisory_not_blocking`.
|
|
944
947
|
|
|
945
|
-
`contractValidation.status=failed` means the run artifact contract failed; it does not necessarily mean the implementation itself is incomplete. An implementation run derives `phaseOutcome.implementation` from `runs/implementation/carry/stage-<N>.json`, `runs/implementation-planning/consumers.jsonl`, and the approved Stage Map together. If every Stage Map stage has pass-grade carry evidence, it can retain the contract failure as audit information while
|
|
948
|
+
`contractValidation.status=failed` means the run artifact contract failed; it does not necessarily mean the implementation itself is incomplete. An implementation run derives `phaseOutcome.implementation` from `runs/implementation/carry/stage-<N>.json`, `runs/implementation-planning/consumers.jsonl`, and the approved Stage Map together. If every Stage Map stage has pass-grade carry evidence, it can retain the contract failure as audit information while raising `workflow.nextRecommendedPhase.status` to `ready`. It does not choose the phase: the reconciler's fact is that every stage finished, and the destination was already settled by the last stage's report routing, so it leaves `phase` untouched and raises the status only when `phase` is non-empty.
|
|
946
949
|
|
|
947
950
|
## Practical notes
|
|
948
951
|
|
package/docs/cli.md
CHANGED
|
@@ -153,7 +153,7 @@ The lifecycle task types run in this order:
|
|
|
153
153
|
- 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.
|
|
154
154
|
- 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.
|
|
155
155
|
- Validator: `validators/validate_improvement_report.py` enforces the 11-part contract for an `improvement-discovery` final report.
|
|
156
|
-
- Because an `improvement-discovery` run is not in `PHASE_SEQUENCE`, the `--task-key` short form
|
|
156
|
+
- Because an `improvement-discovery` run is not in `PHASE_SEQUENCE`, its report has no routing field to project from, so the run leaves `workflow.nextRecommendedPhase` `pending` with no phase. The `--task-key` short form therefore cannot fill `--task-type` after one.
|
|
157
157
|
|
|
158
158
|
#### Analysis sidetrack task types
|
|
159
159
|
|
|
@@ -165,7 +165,7 @@ The three read-only analysis types are independent sidetracks outside `PHASE_SEQ
|
|
|
165
165
|
| `feature-analysis` | Trace one existing feature through flows, domain rules, state changes, external interactions, and test coverage. |
|
|
166
166
|
| `change-impact-analysis` | Map the blast radius of a proposed change across preserved behavior, dependencies, tests, and operations. |
|
|
167
167
|
|
|
168
|
-
Each one starts from a brief and produces a report only. The target project is strictly read-only: no edits, tests, builds, migrations, or deployments. A run ends
|
|
168
|
+
Each one starts from a brief and produces a report only. The target project is strictly read-only: no edits, tests, builds, migrations, or deployments. A run ends with `workflow.nextRecommendedPhase` `pending` and carrying no phase; it does not advance the normal phase sequence.
|
|
169
169
|
|
|
170
170
|
### `--analysis-target`
|
|
171
171
|
|
|
@@ -234,10 +234,10 @@ A short form that supplies `--project-id`, `--task-group`, and `--task-id` toget
|
|
|
234
234
|
- Behavior:
|
|
235
235
|
- Splits the value into the three IDs and populates `PROJECT_ID`, `TASK_GROUP`, and `TASK_ID`.
|
|
236
236
|
- If the same values are also provided explicitly, they are accepted only when they match; a conflict exits immediately with an error.
|
|
237
|
-
- If the task has a `task-manifest.json`, a missing `--task-brief` is filled from the manifest's `taskBriefPath`, and a missing `--task-type` is filled from `workflow.nextRecommendedPhase`.
|
|
237
|
+
- If the task has a `task-manifest.json`, a missing `--task-brief` is filled from the manifest's `taskBriefPath`, and a missing `--task-type` is filled from `workflow.nextRecommendedPhase.phase` — but only while that pointer's `status` is `ready`.
|
|
238
238
|
- Without a manifest, as on initial entry, the normal missing-argument validation remains in effect and full arguments are required.
|
|
239
239
|
- Explicit arguments always take precedence over manifest values.
|
|
240
|
-
-
|
|
240
|
+
- Under any other `status` — `pending`, `blocked`, or `terminal` — the pointer names no runnable phase and `--task-type` is not filled automatically. Supply `--task-type` explicitly or supplement the brief, then rerun the command.
|
|
241
241
|
|
|
242
242
|
Examples:
|
|
243
243
|
|
|
@@ -411,9 +411,11 @@ scripts/okstra.sh --task-type implementation-planning ... \
|
|
|
411
411
|
|
|
412
412
|
### `--workers`
|
|
413
413
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
When supplied,
|
|
414
|
+
Compatibility input only. Prefer `--role-count` and `--role-model` for launch selection.
|
|
415
|
+
|
|
416
|
+
When supplied, the CSV of provider names converts into role slots and model refs for the profile's initial cross-verification role (for example analysers or planners). It is not a provider roster picker and is not the selection unit on the wizard start screen.
|
|
417
|
+
|
|
418
|
+
If the same role is also named by `--role-model` (or other canonical role flags), the converted providers must match the model-ref provider prefixes in order and slot count. Matching values keep the canonical role models and drop the legacy constraint. Different values fail before any worktree or state file is created.
|
|
417
419
|
|
|
418
420
|
Example:
|
|
419
421
|
|
|
@@ -449,7 +451,7 @@ worker roster contains Claude, Codex, or Antigravity.
|
|
|
449
451
|
|
|
450
452
|
### Runtime auto-detection (`auto`)
|
|
451
453
|
|
|
452
|
-
`okstra run` defaults to `auto`. `src/lib/host-registry-client.
|
|
454
|
+
`okstra run` defaults to `auto`. `src/lib/host-registry-client.mts` asks the Python host registry to resolve explicit IDs and aliases, the `OKSTRA_RUNTIME_HOST` environment declaration, Claude Code skill handoff, or the external tmux claim. It fails fast when no adapter claims the session. Installed CLI presence alone never selects a host.
|
|
453
455
|
|
|
454
456
|
- Inside a registered host, the installed `okstra-run` skill uses `current-session`, declares the live semantic function list, and reuses the session you are already in.
|
|
455
457
|
- From a terminal, `okstra run <host-id-or-alias>` uses `spawn-process` and starts the selected host CLI. The leading word is an alias for `--lead-runtime`.
|
|
@@ -476,15 +478,17 @@ The Codex worker (`--workers codex`, `--codex-model`) and Codex lead runtime are
|
|
|
476
478
|
|
|
477
479
|
### `--role-count`
|
|
478
480
|
|
|
479
|
-
Sets
|
|
481
|
+
Sets how many slots open for one static role: `--role-count <role>=<N>`. Repeat the flag for each role. `N` must fall in that role's profile range `min..max`. Omit the flag to use the profile **recommended** count (not a separate roster default). Roles with `min == max` are fixed quantity and reject this flag. Dynamic roles and roles absent from the profile also reject it. `lead` is a compatibility alias for `leader`. New records write `leader`.
|
|
480
482
|
|
|
481
|
-
|
|
483
|
+
Each confirmed count becomes `RoleInstance` ordinals. `ModelPool` then assigns one model ref per ordinal. A pinned model is kept only when the host can bind it exactly. Roles with `min = 0` do not open slots by default; optional add steps or an explicit count above zero open them.
|
|
482
484
|
|
|
483
485
|
### `--role-model`
|
|
484
486
|
|
|
485
|
-
Pins one model reference onto a role
|
|
487
|
+
Pins one model reference onto a role slot, in ordinal order: `--role-model <role>=<modelRef>`. Repeat the flag to fill later ordinals. `modelRef` is `<provider>/<model>`, for example `claude/opus-5` or `codex/gpt-5.6-sol`.
|
|
488
|
+
|
|
489
|
+
A known selectable model may be assigned to any canonical role. The same role must not receive the same model ref twice; duplicate refs in one role panel fail before any worktree or state file is created. Same provider with different models is allowed. Fewer models than the confirmed count are filled from the model-default chain. Extra models do not raise the count; set `--role-count <role>=<N>` first. Unknown roles and unknown model refs fail before side effects.
|
|
486
490
|
|
|
487
|
-
|
|
491
|
+
Legacy `--lead-model`, `--claude-model`, `--codex-model`, `--antigravity-model`, `--worker-model`, `--report-writer-model`, `--executor`, and `--workers` remain compatibility inputs. They convert to role-model selections. A new flag and a legacy flag that name different models (or, for `--workers`, different provider prefixes) for the same role fail.
|
|
488
492
|
|
|
489
493
|
`okstra model list [--role <role>] [--host <host>] [--json]` prints the catalog without an inference call. `okstra model default set|unset <role> ... --scope project|global` writes `modelDefaults` to `.okstra/project.json` or `~/.okstra/config.json`.
|
|
490
494
|
|
|
@@ -780,7 +784,7 @@ chmod +x ~/.local/bin/okstra-ctl
|
|
|
780
784
|
|
|
781
785
|
### `okstra` Node CLI — introspection subcommands
|
|
782
786
|
|
|
783
|
-
The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and introspection commands used by skills and agents. It goes through the Node wrapper instead of invoking the Python runtime directly, so `src/lib/python-helper.
|
|
787
|
+
The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and introspection commands used by skills and agents. It goes through the Node wrapper instead of invoking the Python runtime directly, so `src/lib/python-helper.mts` wires `PYTHONPATH`.
|
|
784
788
|
|
|
785
789
|
| Command | Purpose |
|
|
786
790
|
|---|---|
|
|
@@ -854,7 +858,7 @@ The convergence state lifecycle is `groups v1.0 → work v1.0 → final v1.3`; r
|
|
|
854
858
|
|
|
855
859
|
`okstra convergence` and `okstra plan-items` are internal admin CLI families used by the lead protocol. Each is an internal admin CLI, not a user-facing skill, and their presence does not add a public skill. The former `okstra-convergence` skill remains obsolete; the installed `prompts/lead/convergence.md` and `prompts/lead/plan-body-verification.md` contracts tell the lead when to invoke these operations.
|
|
856
860
|
|
|
857
|
-
> Every subcommand is wired to `PYTHONPATH` and `~/.okstra/lib/python` by the Python helper (`src/lib/python-helper.
|
|
861
|
+
> Every subcommand is wired to `PYTHONPATH` and `~/.okstra/lib/python` by the Python helper (`src/lib/python-helper.mts`) spawned by `bin/okstra`. When invoking `python3 -m okstra_ctl.*` directly, you must configure `PYTHONPATH` yourself.
|
|
858
862
|
|
|
859
863
|
#### `okstra design-prep`
|
|
860
864
|
|
|
@@ -87,7 +87,7 @@ Keep the table narrow.
|
|
|
87
87
|
- workStatus
|
|
88
88
|
- Next
|
|
89
89
|
|
|
90
|
-
If `awaitingApproval
|
|
90
|
+
`nextRecommendedPhase` is an object `{phase, status, rationale}`. The Next cell is its `phase`, or `--` when that is empty. If `awaitingApproval`, or `nextRecommendedPhase.status` is anything but `ready`, add a marker to the Next cell and explain it.
|
|
91
91
|
|
|
92
92
|
### Specific task
|
|
93
93
|
|
|
@@ -98,9 +98,8 @@ Information to show:
|
|
|
98
98
|
- work category
|
|
99
99
|
- current phase/state
|
|
100
100
|
- last completed phase
|
|
101
|
-
- next
|
|
101
|
+
- next-phase pointer: `phase` (or `--`), its `status`, its `rationale`
|
|
102
102
|
- awaiting approval
|
|
103
|
-
- routing status
|
|
104
103
|
- task status, latest run status
|
|
105
104
|
- latest report, resume command
|
|
106
105
|
- workStatus, note
|
|
@@ -62,6 +62,7 @@ Top level:
|
|
|
62
62
|
|
|
63
63
|
- `taskGroup` — the scope (`null` = whole project), `taskCount` — number of tasks.
|
|
64
64
|
- `tasks[]` — per task: `taskKey, taskGroup, taskId, taskType, workCategory, workStatus, currentPhase, currentPhaseState, nextRecommendedPhase, latestRunStatus, updatedAt, reportPath, runCount, cpuSumMs, wallClockMs, errorCount`.
|
|
65
|
+
- `nextRecommendedPhase` is an object `{phase, status, rationale}`, not a string. Print `phase`, or `--` when it is empty. Never interpolate the object itself.
|
|
65
66
|
- `totals` — `runs, cpuSumMs, wallClockMs, errors`, plus `byWorkStatus` / `byWorkCategory` / `byCurrentPhase` / `byTaskType` (each a `{value: count}` map).
|
|
66
67
|
|
|
67
68
|
Numeric meanings (must observe):
|
|
@@ -160,58 +160,58 @@ Runtime/install asset changes follow this checklist:
|
|
|
160
160
|
|
|
161
161
|
| Command | Module | Role |
|
|
162
162
|
|---|---|---|
|
|
163
|
-
| `paths` | `src/commands/lifecycle/paths.
|
|
164
|
-
| `install`, `ensure-installed` | `src/commands/lifecycle/install.
|
|
165
|
-
| `uninstall` | `src/commands/lifecycle/uninstall.
|
|
166
|
-
| `doctor` | `src/commands/lifecycle/doctor.
|
|
167
|
-
| `setup` | `src/commands/lifecycle/setup.
|
|
168
|
-
| `check-project` | `src/commands/lifecycle/check-project.
|
|
169
|
-
| `preflight` | `src/commands/lifecycle/preflight.
|
|
170
|
-
| `config` | `src/commands/lifecycle/config.
|
|
171
|
-
| `migrate` | `src/commands/lifecycle/migrate.
|
|
172
|
-
| `git-reconcile` | `src/commands/execute/git-reconcile.
|
|
173
|
-
| `handoff` | `src/commands/execute/handoff.
|
|
174
|
-
| `integrate-stages` | `src/commands/execute/integrate-stages.
|
|
175
|
-
| `task-list`, `task-show` | `src/commands/inspect/task-list.
|
|
176
|
-
| `resolve-task-key` | `src/commands/inspect/resolve-task-key.
|
|
177
|
-
| `set-work-status` | `src/commands/inspect/set-work-status.
|
|
178
|
-
| `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.
|
|
179
|
-
| `run-audit` | `src/commands/inspect/run-audit.
|
|
180
|
-
| `worker-liveness` | `src/commands/inspect/worker-liveness.
|
|
181
|
-
| `worker-audit-check` | `src/commands/execute/worker-audit-check.
|
|
182
|
-
| `context-cost` | `src/commands/inspect/context-cost.
|
|
183
|
-
| `worktree-lookup` | `src/commands/execute/worktree-lookup.
|
|
184
|
-
| `worktree-status` | `src/commands/execute/worktree-status.
|
|
185
|
-
| `plan-validate` | `src/commands/execute/plan-validate.
|
|
186
|
-
| `render-bundle` | `src/commands/execute/render-bundle.
|
|
187
|
-
| `profile` | `src/commands/inspect/profile-show.
|
|
188
|
-
| `run` | `src/commands/execute/run.
|
|
189
|
-
| `codex-run`, `codex-dispatch` | `src/commands/execute/codex-*.
|
|
190
|
-
| `agent-prompt`, `worker-dispatch` | `src/commands/execute/{agent-prompt,worker-dispatch}.
|
|
191
|
-
| `team` | `src/commands/execute/team.
|
|
192
|
-
| `convergence` | `src/commands/execute/convergence.
|
|
193
|
-
| `plan-items` | `src/commands/execute/plan-items.
|
|
194
|
-
| `agent-activity` | `src/commands/report/agent-activity.
|
|
195
|
-
| `report-finalize` | `src/commands/report/finalize.
|
|
196
|
-
| `render-views` | `src/commands/report/render-views.
|
|
197
|
-
| `render-final-report`, `inject-report-index` | `src/commands/report/*.
|
|
198
|
-
| `wizard` | `src/commands/execute/wizard.
|
|
199
|
-
| `token-usage` | `src/commands/execute/token-usage.
|
|
200
|
-
| `spawn-followups`, `error-log` | `src/commands/execute/*.
|
|
201
|
-
| `memory` | `src/commands/memory/memory.
|
|
202
|
-
| `pr` | `src/commands/pr/pr.
|
|
203
|
-
| `recap` | `src/commands/inspect/recap.
|
|
204
|
-
| `stage-map` | `src/commands/inspect/stage-map.
|
|
205
|
-
| `design-prep` | `src/commands/inspect/design-prep.
|
|
206
|
-
| `rollup` | `src/commands/inspect/rollup.
|
|
207
|
-
| `usage-report` | `src/commands/inspect/usage-report.
|
|
208
|
-
| `container` | `src/commands/inspect/container.
|
|
209
|
-
| `code-review` | `src/commands/inspect/code-review.
|
|
210
|
-
| `manager` | `src/commands/manager.
|
|
211
|
-
|
|
212
|
-
`src/lib/python-helper.
|
|
213
|
-
|
|
214
|
-
`src/lib/helper-scripts.
|
|
163
|
+
| `paths` | `src/commands/lifecycle/paths.mts` | Resolve package/runtime/home paths (library at `src/lib/paths.mts`) |
|
|
164
|
+
| `install`, `ensure-installed` | `src/commands/lifecycle/install.mts` | Install or refresh runtime, skills, agents, templates |
|
|
165
|
+
| `uninstall` | `src/commands/lifecycle/uninstall.mts` | Remove managed runtime/skills/agents, optionally purge data |
|
|
166
|
+
| `doctor` | `src/commands/lifecycle/doctor.mts` | Diagnose runtime and Python imports |
|
|
167
|
+
| `setup` | `src/commands/lifecycle/setup.mts` | Create/update `<PROJECT_ROOT>/.okstra/project.json` |
|
|
168
|
+
| `check-project` | `src/commands/lifecycle/check-project.mts` | Verify project registration |
|
|
169
|
+
| `preflight` | `src/commands/lifecycle/preflight.mts` | One-call skill preflight: ensure-installed + check-project + host-specific runtime readiness (single JSON) |
|
|
170
|
+
| `config` | `src/commands/lifecycle/config.mts` | Read/write project/global settings such as PR template path |
|
|
171
|
+
| `migrate` | `src/commands/lifecycle/migrate.mts` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
|
|
172
|
+
| `git-reconcile` | `src/commands/execute/git-reconcile.mts` | Reconcile stale stage SHAs after external git history changes |
|
|
173
|
+
| `handoff` | `src/commands/execute/handoff.mts` | Stage-group release-handoff eligibility / assemble / record helpers |
|
|
174
|
+
| `integrate-stages` | `src/commands/execute/integrate-stages.mts` | Merge verified stages into the task worktree and clean stage worktrees |
|
|
175
|
+
| `task-list`, `task-show` | `src/commands/inspect/task-list.mts`, `src/commands/inspect/task-show.mts` | Task/run introspection for skills; `task-show` consumes the Python task read-side snapshot |
|
|
176
|
+
| `resolve-task-key` | `src/commands/inspect/resolve-task-key.mts` | Resolve a bare task-id to candidate task-keys from the project catalog |
|
|
177
|
+
| `set-work-status` | `src/commands/inspect/set-work-status.mts` | Set a task's user-managed `workStatus` in task-manifest.json (Python: `okstra_ctl.set_work_status`) |
|
|
178
|
+
| `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.mts` | Read-side task runtime, wrapper log, and error aggregation helpers |
|
|
179
|
+
| `run-audit` | `src/commands/inspect/run-audit.mts` | Anomaly detection — checks run artifacts against progress invariants and reports invariant violations, read-only (Python: `okstra_ctl.run_audit`) |
|
|
180
|
+
| `worker-liveness` | `src/commands/inspect/worker-liveness.mts` | Report whether pending workers are still alive, so the lead's poll ends a stalled wait early instead of paying the deadline (Python: `okstra_ctl.worker_liveness`) |
|
|
181
|
+
| `worker-audit-check` | `src/commands/execute/worker-audit-check.mts` | Apply the Phase 7 worker audit-sidecar rules while the worker session is still alive, so it can fix its own citations (Python: `okstra_ctl.worker_audit_check`, rules in `okstra_ctl.worker_audit_ledger`) |
|
|
182
|
+
| `context-cost` | `src/commands/inspect/context-cost.mts` | Estimate task bundle file/read context cost |
|
|
183
|
+
| `worktree-lookup` | `src/commands/execute/worktree-lookup.mts` | Look up a task-key's registered worktree |
|
|
184
|
+
| `worktree-status` | `src/commands/execute/worktree-status.mts` | Clean-worktree check over source paths only, excluding okstra's provisioned entries and nested stage worktrees (Python: `okstra_ctl.worktree.dirty_entries_excluding_okstra`) |
|
|
185
|
+
| `plan-validate` | `src/commands/execute/plan-validate.mts` | Check approved-plan approval marker |
|
|
186
|
+
| `render-bundle` | `src/commands/execute/render-bundle.mts` | Preview `prepare_task_bundle(render_only=True)` |
|
|
187
|
+
| `profile` | `src/commands/inspect/profile-show.mts` | Print a phase profile with `{{INCLUDE:}}` expanded and its lazy-read sidecars appended transitively, so one grep answers whether a task-type covers a rule — a top-level grep alone returns false negatives (Python: `okstra_ctl.profile_show`). Read-only, unlike `render-bundle` |
|
|
188
|
+
| `run` | `src/commands/execute/run.mts` | Host-aware execution front door (`auto` → Claude/Codex/Antigravity/external path selection) |
|
|
189
|
+
| `codex-run`, `codex-dispatch` | `src/commands/execute/codex-*.mts` | Codex lead dry-run bundle preparation; `codex-dispatch` is the compatibility alias for provider-neutral worker dispatch |
|
|
190
|
+
| `agent-prompt`, `worker-dispatch` | `src/commands/execute/{agent-prompt,worker-dispatch}.mts` | Materialize/verify invocation prompts, record host-native specification/result links, and launch verified CLI assignments through the provider-neutral dispatcher |
|
|
191
|
+
| `team` | `src/commands/execute/team.mts` | External lead tmux-pane worker dispatch / await / teardown |
|
|
192
|
+
| `convergence` | `src/commands/execute/convergence.mts` | Internal admin CLI for the deterministic Phase 5.5 convergence engine (`seed`/`plan-round`/`apply-round`/`apply-critic-gaps`/`finalize`/`validate`/`example`; Python: `okstra_ctl.convergence`) |
|
|
193
|
+
| `plan-items` | `src/commands/execute/plan-items.mts` | Internal admin CLI for deterministic plan-body item extraction and exact-match validation (`extract`/`validate`; Python: `okstra_ctl.plan_items_cli`) |
|
|
194
|
+
| `agent-activity` | `src/commands/report/agent-activity.mts` | Thin Node shim for `okstra_ctl.agent_activity`; `append` records one run-bound activity and `project` writes the validated event projection into final-report data |
|
|
195
|
+
| `report-finalize` | `src/commands/report/finalize.mts` | Run the whole Phase 7 post-report sequence in contractual order (Python: `okstra_ctl.report_finalize`) — the single reference point shared with the Codex lead adapter |
|
|
196
|
+
| `render-views` | `src/commands/report/render-views.mts` | Render schema v2 data with its task-specific human template, or use the quick-report compatibility view |
|
|
197
|
+
| `render-final-report`, `inject-report-index` | `src/commands/report/*.mts` | Render version-selected AI handoff Markdown from data.json; v1 index injection remains compatibility-only |
|
|
198
|
+
| `wizard` | `src/commands/execute/wizard.mts` | Drive the `okstra-run` interactive state machine, including the final outcome envelope |
|
|
199
|
+
| `token-usage` | `src/commands/execute/token-usage.mts` | Wrap installed Python token usage CLI |
|
|
200
|
+
| `spawn-followups`, `error-log` | `src/commands/execute/*.mts` | Follow-up task bundle creation and run error-log append helpers |
|
|
201
|
+
| `memory` | `src/commands/memory/memory.mts` | Store/find global conversation memory under `~/.okstra/memory-book` |
|
|
202
|
+
| `pr` | `src/commands/pr/pr.mts` | `okstra pr <template\|branches\|gen>` — PR body template store under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`), base-branch recommendation, and the `gen` JSON bundle (template + `<base>..HEAD` commits + `<base>...HEAD` diffstat) backing the okstra-pr-gen skill. Git-only; no project registration required |
|
|
203
|
+
| `recap` | `src/commands/inspect/recap.mts` | `okstra recap <assemble\|record\|note>` Node wrapper backing the okstra-inspect `recap` facet — `assemble` is a read-only phase-transition summary, `record` appends one line to `recap/recap-log.jsonl`, and `note` writes an agent-authored note under `notes/` and prints the `--clarification-response` argument for a follow-up run |
|
|
204
|
+
| `stage-map` | `src/commands/inspect/stage-map.mts` | `okstra stage-map <task-key>` — exposes a task's implementation-planning Stage Map as JSON (`stages[].{stage_number,title,depends_on,step_count}` + consumer-state-based `doneStages[]`). If there is no Stage Map, `stages: []`. The read-side basis from which `okstra-schedule-gen` derives stage units and dependency closure |
|
|
205
|
+
| `design-prep` | `src/commands/inspect/design-prep.mts` | `okstra design-prep <list\|show\|write>` thin shim into `scripts/okstra_ctl/design_prep.py` — queries (`list`/`show`) the design items that implementation-planning pre-authored with AI, and records the user-confirmed responses as an append-only sidecar under `design-prep-inputs/` (`write`, `--confirmed` required). It never modifies the report snapshot |
|
|
206
|
+
| `rollup` | `src/commands/inspect/rollup.mts` | `okstra rollup` thin shim into `scripts/okstra_ctl/rollup.py` — read-only cross-task roll-up backing the okstra-rollup skill |
|
|
207
|
+
| `usage-report` | `src/commands/inspect/usage-report.mts` | `okstra usage-report` thin shim into `scripts/okstra_ctl/usage_report.py` — read-only project usage snapshot backing the okstra-usage skill |
|
|
208
|
+
| `container` | `src/commands/inspect/container.mts` | `bin okstra container` thin shim into `scripts/okstra_ctl/container.py` for the okstra-container-build skill |
|
|
209
|
+
| `code-review` | `src/commands/inspect/code-review.mts` | `okstra code-review target` thin shim into `scripts/okstra_ctl/code_review_target.py` — resolves what one implementation stage's or one branch's review reads (worktree, branch, base/head commits) and where its result file goes, for the okstra-code-review skill. Read-only; creates no directory or file |
|
|
210
|
+
| `manager` | `src/commands/manager.mts` | Thin shim into `scripts/okstra_ctl/manager_cli.py` for cross-project manager state and child launch packets |
|
|
211
|
+
|
|
212
|
+
`src/lib/python-helper.mts` centralizes Node → Python execution so command modules do not duplicate subprocess wiring.
|
|
213
|
+
|
|
214
|
+
`src/lib/helper-scripts.mts` is the SSOT list of the Python helper scripts that `okstra <cmd>` subcommands front through `runInstalledScript()`. `okstra preflight` asserts every one of them resolves under `~/.okstra/bin` using the same resolver the dispatch path uses, so a stale install fails at the cheap environment gate instead of at the blocking lead step that calls it mid-run. A contract test keeps the list in step with the `scriptName:` literals in `src/commands/**`.
|
|
215
215
|
|
|
216
216
|
### 4.2 `scripts/` — Runtime source
|
|
217
217
|
|
|
@@ -258,11 +258,12 @@ Important modules:
|
|
|
258
258
|
| `run_context.py` | Per-task mutex, run context and run-input persistence; `consumers_mutex` helper for atomic `consumers.jsonl` writes |
|
|
259
259
|
| `path_hints.py` | Compact path-hint persistence + legacy context hydration — stores `run-context` / `active-run-context` in the schemaVersion `2.0` `identity` + `pathHints` compact schema, and hydrates the legacy flat path keys (`RUN_MANIFEST_RELATIVE_PATH`, `TEAM_STATE_PATH`, etc.) in memory the moment the host-side reader reads them |
|
|
260
260
|
| `consumers.py` | Append-only `consumers.jsonl` writer + reader — records which `implementation` runs consumed which `implementation-planning` stage |
|
|
261
|
-
| `implementation_outcome.py` | Artifact-derived reconstruction of the implementation phase outcome — reads `runs/implementation/carry/stage-<N>.json` + `consumers.jsonl` + the approved Stage Map to derive `phaseOutcome.implementation`, and when every stage has pass-grade carry evidence it
|
|
261
|
+
| `implementation_outcome.py` | Artifact-derived reconstruction of the implementation phase outcome — reads `runs/implementation/carry/stage-<N>.json` + `consumers.jsonl` + the approved Stage Map to derive `phaseOutcome.implementation`, and when every stage has pass-grade carry evidence it raises `workflow.nextRecommendedPhase.status` to `ready` (keeping the `contract-violated` audit information). It never picks the phase — `phase` is left as the last stage's report routing settled it, and the status is raised only while `phase` is non-empty |
|
|
262
262
|
| `paths.py` | Path/sequence computation for task/run artifacts (including recap directory/log paths) |
|
|
263
263
|
| `recap.py` | deterministic backend for the okstra-inspect `recap` facet — `assemble` builds the cross-run phase transitions from the timeline, `record` append-only writes a summary/Q&A to `<task-root>/recap/recap-log.jsonl` (other task artifacts unchanged) |
|
|
264
264
|
| `render.py` | task manifest, run manifest, timeline, task index, discovery, team-state, prompt/template render |
|
|
265
|
-
| `workflow.py` | Phase sequence, allowed outputs, forbidden actions
|
|
265
|
+
| `workflow.py` | Phase sequence (`PHASE_SEQUENCE`), per-phase allowed outputs, forbidden actions. It does not decide the next phase — that is `next_phase.py` |
|
|
266
|
+
| `next_phase.py` | `workflow.nextRecommendedPhase` SSOT — the pointer's shape (`make` / `is_pointer` over `{phase, status, rationale}`, `status` ∈ `ready`/`pending`/`blocked`/`terminal`), the promotion of a legacy string pointer (`promote`), the projection of one report's routing field into a pointer (`project`), and the `ready`-only read the shell and wizard autofill share (`autofill_task_type`). There is no static phase table and no sequence walk: the next phase comes from what the report authored, and nothing else may compute one |
|
|
266
267
|
| `workers.py`, `models.py` | Worker roster; `models.py` is the model catalog SSOT (`ModelSpec` per alias + `ROLE_DEFAULTS`) — add-a-model single reference point from which picker options, codex pricing, and role defaults all derive |
|
|
267
268
|
| `worktree.py`, `worktree_registry.py` | One worktree per task-key, branch registry, sync dirs/files/snapshots |
|
|
268
269
|
| `project_meta.py`, `resolver.py`, `path_resolve.py` | Project/task/run resolution |
|
|
@@ -634,7 +635,7 @@ Project-local `<PROJECT_ROOT>/.claude/settings.local.json` is provisioned as a s
|
|
|
634
635
|
| `final-verification` | Read-only acceptance verification | `release-handoff` if accepted |
|
|
635
636
|
| `release-handoff` | User-selected commit/PR handoff | done or follow-up |
|
|
636
637
|
|
|
637
|
-
The independent analysis sidetracks do not appear in this phase sequence. `project-analysis` maps the current project, `feature-analysis` traces one existing feature, and `change-impact-analysis` maps a proposed change's impact. Each
|
|
638
|
+
The independent analysis sidetracks do not appear in this phase sequence. `project-analysis` maps the current project, `feature-analysis` traces one existing feature, and `change-impact-analysis` maps a proposed change's impact. Each leaves the next-phase pointer `pending` with no phase, and remains read-only, including no test or build execution.
|
|
638
639
|
|
|
639
640
|
### 7.5 Report and follow-up
|
|
640
641
|
|
|
@@ -683,4 +684,4 @@ Clarifications now live in the unified `## 1. Clarification Items` table. Deprec
|
|
|
683
684
|
|
|
684
685
|
---
|
|
685
686
|
|
|
686
|
-
*Updated: 2026-
|
|
687
|
+
*Updated: 2026-08-18 · Source of truth checked against `package.json`, `bin/okstra`, `src/cli-registry.mts`, `src/lib/skill-catalog.mts`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
|
|
@@ -34,7 +34,7 @@ flowchart TD
|
|
|
34
34
|
|
|
35
35
|
`okstra-run` does not call `scripts/okstra.sh`. Instead it goes through `okstra wizard` and `okstra render-bundle` and converges on the same single Python entrypoint, `prepare_task_bundle()`.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Launch selection is role slots and model refs, not a provider roster. The wizard shows the leader session read-only, then role counts (`min..max`, default **recommended**), then `--role-model <role>=<provider>/<model>` per slot. Roles with `min = 0` stay closed unless the user adds them. There is no provider multi-pick and no `Use defaults / Customize` fork for worker selection. `--workers` is compatibility-only. `lead` is a compatibility alias for `leader`. `executor` is a compatibility alias for `implementer`. New records write `leader` and `implementer`.
|
|
38
38
|
|
|
39
39
|
## 3. task-type documents
|
|
40
40
|
|
|
@@ -69,12 +69,14 @@ The wizard asks role count before role models. `--role-count <role>=<N>` and `--
|
|
|
69
69
|
|
|
70
70
|
## 5. Quick comparison table
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
The last column is the `workflow.nextRecommendedPhase` pointer Phase 7 leaves behind — an object `{phase, status, rationale}`, projected from the report's own routing field. There is no static default: a run that settles no route ends `pending` with no phase. The authoring rule is stated once, in the Phase 6 checklist of [`prompts/lead/report-writer.md`](../../prompts/lead/report-writer.md).
|
|
73
|
+
|
|
74
|
+
| task-type | wizard special question | runtime prepare gate | lead/worker mode | next-phase pointer |
|
|
73
75
|
|---|---|---|---|---|
|
|
74
|
-
| `requirements-discovery` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 1 round default | `
|
|
75
|
-
| `error-analysis` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 2 rounds default | `implementation-option-selection` |
|
|
76
|
-
| `implementation-option-selection` | comparison or preselected-validation context | stable brief IDs and at least three analysers | read-only candidate validation, exact coverage, separate direction confirmation | `implementation-planning` or `blocked` |
|
|
77
|
-
| `implementation-planning` | selected-direction report for a new plan | selection report/sidecar/digest or same-task planning rerun | one-direction realization + Phase 6 plan-body verification | `implementation`
|
|
78
|
-
| `implementation` | approved plan, stage multi-pick, executor | approved marker, Stage Lifecycle Snapshot, stage-key reservation, QA command deny-list | one run = one stage; executor writes in isolated stage worktree, verifiers read-only | `final-verification` |
|
|
79
|
-
| `final-verification` | approved plan, stage pick (whole-task or single-stage) | `VERIFICATION_TARGET` resolved; whole-task auto integration/teardown or single-stage worktree reuse | whole-task may integrate stages first; analyser verification itself is read-only | `
|
|
80
|
-
| `release-handoff` | handoff scope (stage-group or whole-task), PR template override/scope | Stage Lifecycle Snapshot eligibility, generated `release-handoff-input.md`, empty worker roster | single-lead; whole-task PR or stage-group collector branch/PR | `
|
|
76
|
+
| `requirements-discovery` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 1 round default | `ready` at `error-analysis` or `implementation-option-selection`; `pending` when neither is settled |
|
|
77
|
+
| `error-analysis` | common questions only | profile/brief/base-ref exist | multi-worker analysis, convergence 2 rounds default | `ready` at `implementation-option-selection`, or at `error-analysis` while the investigation continues |
|
|
78
|
+
| `implementation-option-selection` | comparison or preselected-validation context | stable brief IDs and at least three analysers | read-only candidate validation, exact coverage, separate direction confirmation | `ready` at `implementation-planning`, `pending` on `pending-direction-selection`, or `blocked` |
|
|
79
|
+
| `implementation-planning` | selected-direction report for a new plan | selection report/sidecar/digest or same-task planning rerun | one-direction realization + Phase 6 plan-body verification | `ready` at `implementation` on `plan-ready` (the plan still needs its separate approval), or at `implementation-option-selection` on `direction-invalidated` |
|
|
80
|
+
| `implementation` | approved plan, stage multi-pick, executor | approved marker, Stage Lifecycle Snapshot, stage-key reservation, QA command deny-list | one run = one stage; executor writes in isolated stage worktree, verifiers read-only | `ready` at the stage report's `routingRecommendation.target` — `final-verification` on a clean stage |
|
|
81
|
+
| `final-verification` | approved plan, stage pick (whole-task or single-stage) | `VERIFICATION_TARGET` resolved; whole-task auto integration/teardown or single-stage worktree reuse | whole-task may integrate stages first; analyser verification itself is read-only | `ready` at `release-handoff` on an `accepted` verdict, otherwise at the phase owning the defect; `terminal` on `done` |
|
|
82
|
+
| `release-handoff` | handoff scope (stage-group or whole-task), PR template override/scope | Stage Lifecycle Snapshot eligibility, generated `release-handoff-input.md`, empty worker roster | single-lead; whole-task PR or stage-group collector branch/PR | always `terminal` |
|
|
@@ -56,18 +56,17 @@ stateDiagram-v2
|
|
|
56
56
|
TaskType --> BaseRef: no active worktree
|
|
57
57
|
TaskType --> ImplementationExtras: implementation only
|
|
58
58
|
BaseRef --> ImplementationExtras: implementation only
|
|
59
|
-
BaseRef -->
|
|
60
|
-
ImplementationExtras -->
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
ModelAndOptionalInputs --> Confirm
|
|
59
|
+
BaseRef --> LeaderSession: non-implementation
|
|
60
|
+
ImplementationExtras --> LeaderSession
|
|
61
|
+
LeaderSession --> RoleSlots: role-count then role-model
|
|
62
|
+
RoleSlots --> OptionalInputs: directive / related / clarification
|
|
63
|
+
OptionalInputs --> Confirm
|
|
65
64
|
Confirm --> EditTarget: Edit
|
|
66
65
|
EditTarget --> TaskType: rewind selected step
|
|
67
66
|
Confirm --> Done: Proceed
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
A new task receives its brief first. If the brief frontmatter has `task-group:` and `brief-id:`, the wizard shows the task group/id as recommended picks. An existing task shows the manifest's `workflow.nextRecommendedPhase` as the recommended task-type, and
|
|
69
|
+
A new task receives its brief first. If the brief frontmatter has `task-group:` and `brief-id:`, the wizard shows the task group/id as recommended picks. An existing task shows the manifest's `workflow.nextRecommendedPhase.phase` as the recommended task-type, but only while that pointer's `status` is `ready`. Under any other status the recommended slot stays empty and the list falls back to rerunning `workflow.currentPhase` plus the full task-type choices. If an existing brief path exists it asks whether to keep or change it.
|
|
71
70
|
|
|
72
71
|
## 4. render-bundle and prepare_task_bundle
|
|
73
72
|
|
|
@@ -152,20 +151,18 @@ flowchart TD
|
|
|
152
151
|
T[task-type selected] --> W{active worktree in registry?}
|
|
153
152
|
W -->|yes| Reuse[reuse existing worktree<br/>base-ref prompt skipped]
|
|
154
153
|
W -->|no| Base[ask base-ref<br/>validate with git rev-parse]
|
|
155
|
-
Base -->
|
|
156
|
-
Reuse -->
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
WO --> Confirm
|
|
162
|
-
M --> Special{release-handoff?}
|
|
154
|
+
Base --> L[leader session read-only]
|
|
155
|
+
Reuse --> L
|
|
156
|
+
L --> C[role-count min..max<br/>omit uses recommended]
|
|
157
|
+
C --> M[role-model provider/model per slot]
|
|
158
|
+
M --> O[directive / related / clarification]
|
|
159
|
+
O --> Special{release-handoff?}
|
|
163
160
|
Special -->|yes| PR[PR template override/scope]
|
|
164
161
|
Special -->|no| Confirm
|
|
165
162
|
PR --> Confirm
|
|
166
163
|
```
|
|
167
164
|
|
|
168
|
-
The
|
|
165
|
+
Launch selection is role slots and model refs. The wizard does not show a provider roster multi-pick and does not fork on `Use defaults / Customize` for workers. Omitting `--role-count` keeps each static role at its profile **recommended** count within `min..max`. Duplicate model refs in the same role are rejected. `--workers` remains a CLI compatibility input only.
|
|
169
166
|
|
|
170
167
|
Worktree rules differ per phase. From `requirements-discovery` through `implementation-planning`, the task-key worktree is reused. `implementation` uses the task-key worktree as an anchor but does the actual execution isolated one stage at a time in a stage-key (`stage-<N>`) worktree and the `runs/implementation/stage-<N>/` deliverables. `final-verification --stage N` reuses that implementation stage worktree as a read target, and whole-task mode auto-integrates the stage commits into the task-key worktree and then builds the verification target. The Stage Lifecycle Snapshot is a read-side view that does not change this storage structure.
|
|
171
168
|
|
|
@@ -20,19 +20,18 @@ flowchart TD
|
|
|
20
20
|
Start[/okstra-run/] --> Common[common task identity flow]
|
|
21
21
|
Common --> Type[task-type = error-analysis]
|
|
22
22
|
Type --> Worktree{active worktree exists?}
|
|
23
|
-
Worktree -->|yes|
|
|
23
|
+
Worktree -->|yes| Leader[leader session read-only]
|
|
24
24
|
Worktree -->|no| BaseRef[base-ref pick/text<br/>main recommended]
|
|
25
|
-
BaseRef -->
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
X --> Confirm
|
|
25
|
+
BaseRef --> Leader
|
|
26
|
+
Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
27
|
+
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
28
|
+
RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
|
|
29
|
+
RoleAdd --> Extras[directive, related tasks, clarification]
|
|
30
|
+
Extras --> Confirm
|
|
32
31
|
Confirm --> Render[render-bundle --render-only]
|
|
33
32
|
```
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
Launch selection uses role slots and model refs only: leader is the current session (read-only), then each static role's count in `min..max` (default **recommended**; the count step is skipped when `min == max`), then one `provider/model` per slot. Roles with `min = 0` stay closed unless the user opens them with role-add (default skip). Duplicate model refs in the same role are rejected. There is no provider roster multi-pick and no `Use defaults / Customize` fork. Dynamic verifiers are not chosen at launch. `--workers` is a CLI compatibility input only, not a launch picker.
|
|
36
35
|
|
|
37
36
|
## 3. prepare_task_bundle handling
|
|
38
37
|
|
|
@@ -57,7 +56,7 @@ sequenceDiagram
|
|
|
57
56
|
|
|
58
57
|
For canonical briefs, preflight runs before worker resolution, worktree provisioning, or report creation. A brief whose `reporter-confirmations` status is `pending` stops at this point; legacy briefs keep the compatibility path.
|
|
59
58
|
|
|
60
|
-
The final report records its next phase in `errorAnalysis.routing.nextTaskType`.
|
|
59
|
+
The final report records its next phase in `errorAnalysis.routing.nextTaskType`. A credible cause uses `implementation-option-selection`; continued investigation uses `error-analysis`. When report validation passes, Phase 7 projects `workflow.nextRecommendedPhase` from that one field (`scripts/okstra_ctl/next_phase.py::project`) — a `ready` pointer naming it. A report that leaves the field empty leaves the pointer `pending`; there is no static fallback that supplies a phase the report did not author.
|
|
61
60
|
|
|
62
61
|
## 4. lead execution flow
|
|
63
62
|
|