okstra 0.183.2 → 0.185.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 +2 -2
- package/dist/cli-registry.mjs +9 -0
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/chat/chat.d.mts +1 -0
- package/dist/commands/chat/chat.mjs +385 -0
- package/dist/commands/chat/chat.mjs.map +1 -0
- package/dist/lib/skill-catalog.mjs +1 -0
- package/dist/lib/skill-catalog.mjs.map +1 -1
- package/docs/architecture.md +10 -8
- package/docs/cli.md +9 -5
- package/docs/for-ai/README.md +4 -2
- package/docs/for-ai/skills/okstra-chat.md +28 -0
- package/docs/for-ai/skills/okstra-inspect.md +1 -1
- package/docs/for-ai/skills/okstra-run.md +2 -2
- package/docs/for-ai/skills/okstra-user-response.md +10 -8
- package/docs/project-structure-overview.md +6 -5
- package/docs/task-process/README.md +2 -2
- package/docs/task-process/common-flow.md +2 -3
- package/docs/task-process/error-analysis.md +3 -4
- package/docs/task-process/final-verification.md +2 -3
- package/docs/task-process/implementation-planning.md +3 -4
- package/docs/task-process/implementation.md +2 -3
- package/docs/task-process/release-handoff.md +3 -4
- package/docs/task-process/requirements-discovery.md +3 -4
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/prompts/launch.template.md +8 -7
- package/runtime/prompts/lead/okstra-lead-contract.md +7 -6
- package/runtime/prompts/lead/plan-body-verification.md +27 -19
- package/runtime/prompts/lead/report-writer.md +4 -4
- package/runtime/prompts/profiles/_clarification-recommendation.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +1 -0
- package/runtime/prompts/profiles/_implementation-verifier.md +1 -1
- package/runtime/prompts/profiles/implementation-planning.md +11 -12
- package/runtime/prompts/wizard/prompts.ko.json +9 -10
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +2 -2
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +1 -1
- package/runtime/python/okstra_ctl/conformance.py +37 -1
- package/runtime/python/okstra_ctl/incremental_scope.py +84 -39
- package/runtime/python/okstra_ctl/next_phase.py +67 -4
- package/runtime/python/okstra_ctl/plan_items.py +410 -1
- package/runtime/python/okstra_ctl/plan_items_cli.py +346 -31
- package/runtime/python/okstra_ctl/render.py +4 -0
- package/runtime/python/okstra_ctl/user_response.py +147 -37
- package/runtime/python/okstra_ctl/wizard.py +52 -73
- package/runtime/schemas/final-report-v2.0.schema.json +12 -0
- package/runtime/schemas/final-report-v3.0.schema.json +12 -0
- package/runtime/skills/okstra-chat/SKILL.md +104 -0
- package/runtime/skills/okstra-inspect/facets/status.md +6 -5
- package/runtime/skills/okstra-run/SKILL.md +4 -4
- package/runtime/skills/okstra-user-response/SKILL.md +50 -16
- package/runtime/validators/validate-run.py +254 -81
- package/runtime/validators/validate_session_conformance.py +24 -5
package/docs/cli.md
CHANGED
|
@@ -292,7 +292,7 @@ Pins how much of an `implementation-planning` clarification re-run is verified a
|
|
|
292
292
|
- `full` — re-verify every stage. The lead still records the decision, passing `--full-reason "user requested full re-verification"`.
|
|
293
293
|
- a stage-number list such as `2,3` — the named stages enter the lead's `--impacted` set, unioned with whatever it resolves itself. The CLI's dependency closure and cutoff still apply on top, so a wide enough pin correctly resolves to full.
|
|
294
294
|
- Requires `--clarification-response`, and only `--task-type implementation-planning` accepts a non-empty value. Without a carried report there is no prior Stage Map to narrow against.
|
|
295
|
-
- The wizard asks for this
|
|
295
|
+
- The wizard asks for this when the re-run is narrowable **or** an answered `C-NNN` traces to no stage. An unlinked id does not freeze the run at full: the picker then offers stage numbers (recommended) or full, and omits `auto`. Direct stage input is validated against the prior report's Stage Map, so a number that plan never had is refused at the prompt. Empty input is auto only when every answered id already traces to a stage.
|
|
296
296
|
- The value reaches the lead as the `REVERIFY_SCOPE_MODE` / `REVERIFY_SCOPE_STAGES` tokens the "Clarification Response Carried In" section of the lead prompt reads. It narrows or widens the inputs to `okstra incremental-scope`; it does not bypass that decision.
|
|
297
297
|
|
|
298
298
|
### `--resume-clarification`
|
|
@@ -701,6 +701,7 @@ Disables the Phase 6 plan-body verification round for the `implementation-planni
|
|
|
701
701
|
|
|
702
702
|
- **Enabled (default)**: Immediately after the report-writer worker drafts its narrative in Phase 6, the lead extracts 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.
|
|
703
703
|
- **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.
|
|
704
|
+
- **Advisory auto-path (not this flag)**: when `designPreparation.mode` is `no-design-inputs` and the Stage Map has exactly one row, `okstra plan-items prepare` sets `convergence.planBodyVerification.gating=false`. Extraction and one verification round still run; the self-fix loop and a sweep batch do not. Two-or-more stages, a PREP item, or non-empty design-preparation items keep `gating=true`.
|
|
704
705
|
- 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.
|
|
705
706
|
- 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`.
|
|
706
707
|
|
|
@@ -815,13 +816,16 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
815
816
|
| `okstra plan-items extract (--narrative <report-narrative.md>\|--data <historical-data.json>) --output <items.json>` | Deterministically extract the complete implementation-planning `P-*` queue. Contract v3 reads the report-writer narrative before publication; `--data` is the historical v2 reader. |
|
|
816
817
|
| `okstra plan-items validate (--narrative <report-narrative.md>\|--data <historical-data.json>) --items <items.json>` | Require the persisted `P-*` queue to match a fresh deterministic extraction exactly. |
|
|
817
818
|
| `okstra plan-items derivations --data <data.json> --response <user-response sidecar> [--clarification C-NNN]` | List the plan statements an answered clarification may have falsified. Extracts the symbols, paths, and ids the answer names (backticked spans plus `R-001` / `DEV-10174`-style ids) and reports every string in the plan body that mentions one, as a JSON pointer plus excerpt. Advisory: it says where a decision's subject is mentioned, never which mentions are now wrong — the supersession rule (`prompts/profiles/_common-contract.md`) requires the author to enumerate before editing, and this supplies the enumeration |
|
|
818
|
-
| `okstra plan-items <prepare\|prompt\|validate-prepared> --run-manifest <path> …` | Bind the implementation-planning verification queue to the run manifest. `prepare` extracts the exact queue from `--narrative
|
|
819
|
+
| `okstra plan-items <prepare\|prompt\|validate-prepared> --run-manifest <path> …` | Bind the implementation-planning verification queue to the run manifest. `prepare` extracts the exact queue from `--narrative` and, when `designPreparation.mode` is `no-design-inputs` and the Stage Map has one row, flips `convergence.planBodyVerification.gating` to `false` (stdout `Gating`). `prompt` emits its fixed lossless view; `validate-prepared` proves the prepared queue still matches the narrative. Python resolves the convergence-owned state path, so model callers never choose it. |
|
|
819
820
|
| `okstra plan-items seed --narrative <report-narrative.md> --state <plan-body-verification.json>` | Create the convergence-owned `planBodyVerification.planItems[]` rows every verdict lands in, from the same deterministic extraction `extract` uses. The historical v2 form is `--data <data.json>`. Idempotent by id: an existing row keeps its verdicts and carried fields. Reports `seeded` / `existing` counts. |
|
|
820
821
|
| `okstra plan-items apply-verdicts --state <plan-body-verification.json> --result <worker-id>=<result.md>… --round <N>` | Read each worker's Markdown verdict directly, validate every current `P-*` id, reject duplicate worker submissions, and overwrite that round's stored verdicts. The historical `--verdicts <file>` form remains automation compatibility only. |
|
|
821
|
-
| `okstra plan-items complete-round --state <plan-body-verification.json> --run-manifest <current-run-manifest.json> --round <N> [--self-fix-note <item-id>=<markdown-file>]… [--self-fix-group <cause-file>=<item-id>[,<item-id>...]]… [--self-fix-stop-reason <all-resolved\|no-progress\|max-rounds-reached>]` | After `plan-verify` succeeds, atomically derive and record the round's per-item votes, gate result, participant counts from the actual assigned roster, immutable completion time, convergence history, and optional self-fix notes/groups read from Markdown files. Models do not write the state JSON. |
|
|
822
|
+
| `okstra plan-items complete-round --state <plan-body-verification.json> --run-manifest <current-run-manifest.json> --round <N> [--self-fix-note <item-id>=<markdown-file>]… [--self-fix-group <cause-file>=<item-id>[,<item-id>...]]… [--self-fix-stop-reason <all-resolved\|no-progress\|max-rounds-reached>]` | After `plan-verify` succeeds, atomically derive and record the round's per-item votes, gate result, participant counts from the actual assigned roster, immutable completion time, convergence history, and optional self-fix notes/groups read from Markdown files. Models do not write the state JSON. Stdout also carries `nextDispatch`. |
|
|
823
|
+
| `okstra plan-items next-dispatch --state <plan-body-verification.json> [--run-manifest <path>]` | After `apply-verdicts`, decide whether this round opens a worker batch. `kind: none` — missing-dependency `UNVERIFIABLE` only, no new batch. `kind: worker-correction` — re-prompt only those workers; peers stay idle. `kind: queue-reverify` — unsettled ties, those item ids only. A missing path is never environment-unverifiable. |
|
|
824
|
+
| `okstra plan-items correction-prompt --state <plan-body-verification.json> --run-manifest <path> --worker <id>` | Emit the planning-time environment-gap paragraph, then the assigned queue. The environment exception is first. Exits 2 unless `next-dispatch` named that worker as a blanket-UNVERIFIABLE correction target. |
|
|
822
825
|
| `okstra error-log append-observed --out <errors.jsonl> --task-key <key> --phase <phase> --agent <assigned-worker-id> --agent-role worker --model <model> --error-type tool-failure --command-file <markdown-file> --command-kind <kind> --message-file <markdown-file> [--cause <cause> --evidence-file <kind=file>]…` | Worker-facing typed error recording surface. Python validates and serializes the JSONL record; a worker supplies scalar identity fields plus Markdown files for free-form command, message, and probe content, never a JSON sidecar or JSON argument. `sandbox-denied` requires both `targetProbe` and `controlProbe` evidence files. |
|
|
823
826
|
| `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | Manage persistent settings such as `pr-template-path` with atomic JSON writes |
|
|
824
827
|
| `okstra memory <add\|list\|search\|show\|archive>` | Manage global conversation memory in `~/.okstra/memory-book`, a user-home store separate from project `.okstra/` and the CLI basis of the `save this in okstra` natural-language skill |
|
|
828
|
+
| `okstra chat <rooms\|create\|join\|members\|send\|unread\|inbox\|log\|ack>` | Global rooms under `~/.okstra/chat`. Join takes an explicit `--name`. Send requires `--to` (`all` or a member). Unread is the inbox after the read cursor; `inbox` keeps arrivals after ack. CLI basis of the `okstra-chat` skill. |
|
|
825
829
|
| `okstra model-io active-context-input --project-root <dir> --run-manifest <path>` | Resolve the prior implementation-planning active context only through the current project and run authority, then emit fixed fields such as the executor base ref. Caller-supplied active-context paths are not accepted. |
|
|
826
830
|
| `okstra report-translate <source\|write\|check-data> --run-manifest <path> …` | Resolve the report data and translation sidecar from the run manifest. `source` emits a source digest with the fixed translation queue; `write` requires that digest and rejects a stale report; `check-data` verifies the derived sidecar. Models never choose the data or sidecar path. |
|
|
827
831
|
| `okstra convergence prepare-groups --run-manifest <path> --input <grouping.md>` | Parse fixed grouping Markdown, validate distinct per-worker evidence and group semantics against the run authority, then publish the schema-valid groups artifact at the run-owned path. |
|
|
@@ -833,13 +837,13 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
833
837
|
| `okstra worker-audit-check --run-dir <runs/<task-type>/> --task-type <type> --seq <nnn> [--worker <id>]` | Apply the Phase 7 worker audit-sidecar rules mid-run, while the worker session is still alive. For each of this run's `worker-results/<worker>-<task-type>-<seq>.md` it checks that the file carries no `## 0. Reading Confirmation` heading, that the matching audit sidecar exists, and — for prompts carrying the required-v1 evidence-ledger marker — that every backticked `path:line` citation has an Evidence read row in that sidecar. `--worker` scopes it to the role that just returned. Emits `{ok, failures[]}` and exits 2 when `failures[]` is non-empty. The rules come from the `okstra_ctl.worker_audit_ledger` SSOT shared with `validate-run.py`, so an early pass and the Phase 7 pass cannot disagree. Run it right after collecting a result: the same failure at Phase 7 leaves only a retroactive edit, which breaks the audit chain, or a failed run |
|
|
834
838
|
| `okstra log-report [--project-root <dir>] [--cwd <dir>] [--top <N>] [--json]` | Read-only inventory of wrapper transcript `.log` files and their sibling prompt `.md` files. Each ranked entry preserves `path` / `sizeBytes` for compatibility and also reports `transcriptPath`, `transcriptBytes`, `promptPath`, `promptBytes`, and `transcriptToPromptRatio`; totals distinguish prompt bytes from transcript bytes and count paired files. Ranking remains transcript-size descending |
|
|
835
839
|
| `okstra recap <assemble\|record\|note> <task-root\|task-key> …` | Backend for the okstra-inspect `recap` facet. `assemble` is read-only and prints a JSON summary of phase transitions across a task's runs. `record --kind <summary\|qa> --mode <artifact\|code> --answer <text> [--question <text>] [--citation <path:line> …]` appends one line to `<task-root>/recap/recap-log.jsonl` and never mutates other artifacts. `note --kind <verification-evidence\|decision-draft\|analysis-note> --slug <topic> --purpose <text> --scope-note <text> (--body <markdown>\|--body-file <path>)` writes an agent-authored note to `<task-root>/notes/` and prints its path plus the `--clarification-response` argument for feeding it into a later run |
|
|
836
|
-
| `okstra user-response <list-view\|show-view\|begin\|answer\|plan-decision\|legacy-report-authoring\|finalize> …` | Backend for the `/okstra-user-response` skill. `list-view` and `show-view --report <md\|data.json> --project-root <dir>` are fixed-text model views; `show-view` validates that the report belongs to the explicit project root. The legacy `list` and `show` JSON reads retain their automation-compatible fields. `begin --report <md\|data.json> --task-key <key>` returns an opaque transaction id. A predefined clarification choice uses `answer --transaction <id> --clarification-id <C-NNN> --kind <kind> --option-number <N>`; Python resolves the answer, disposition, reach, and scope effects from the validated report. Direct input instead uses `--disposition <answer\|reframe> --value-file <md> [--rationale-file <md>]`. Every value, rationale, and reason file must be a regular file under `<PROJECT_ROOT>/.okstra/tmp/user-response/`; external paths and symbolic links are rejected. `plan-decision` accepts `approved`, `revision-requested`, or `rejected`, validates any `--implementation-option` against the report candidates, and requires `--reason-file` for the latter two statuses. `legacy-report-authoring` is restricted to report contract 2.0. `finalize` validates the complete existing sidecar before a lossless merge, uses compare-and-swap under a run-local lock, and atomically publishes only the user-owned sidecar; exit 0 ok / 1 error. |
|
|
840
|
+
| `okstra user-response <list-view\|show-view\|begin\|answer\|plan-decision\|legacy-report-authoring\|finalize> …` | Backend for the `/okstra-user-response` skill. `list-view` and `show-view --report <md\|data.json> --project-root <dir>` are fixed-text model views; `show-view` validates that the report belongs to the explicit project root and prints each open row's why-asked line, linked plan items, and cited `path:line` artifacts so the skill can read them before asking. The legacy `list` and `show` JSON reads retain their automation-compatible fields. `begin --report <md\|data.json> --task-key <key>` returns an opaque transaction id. A predefined clarification choice uses `answer --transaction <id> --clarification-id <C-NNN> --kind <kind> --option-number <N>`; Python resolves the answer, disposition, reach, and scope effects from the validated report. Direct input instead uses `--disposition <answer\|reframe> --value-file <md> [--rationale-file <md>]`. Every value, rationale, and reason file must be a regular file under `<PROJECT_ROOT>/.okstra/tmp/user-response/`; external paths and symbolic links are rejected. `plan-decision` accepts `approved`, `revision-requested`, or `rejected`, validates any `--implementation-option` against the report candidates, and requires `--reason-file` for the latter two statuses. `legacy-report-authoring` is restricted to report contract 2.0. `finalize` validates the complete existing sidecar before a lossless merge, uses compare-and-swap under a run-local lock, and atomically publishes only the user-owned sidecar; exit 0 ok / 1 error. |
|
|
837
841
|
| `okstra pr <template\|branches\|gen> … [--json]` | Backend for the okstra-pr-gen skill. Git-only—no project registration required. `template list\|show <name\|default>\|add --name <name> (--content <text>\|--file <path>)\|path` manages PR body templates under `~/.okstra/template/pr/` (bundled fallback `src/commands/pr/default.md`); `branches` recommends a base branch; `gen --base <ref> [--template <name\|default>]` emits fixed `Base`, `Current branch`, `Template name`, `Commits`, `Diff stat`, and `Template` sections by default. `--json` preserves the machine bundle for automation. |
|
|
838
842
|
| `okstra migrate [--apply] [--cwd <dir>] [--quiet]` | One-time migration of the project artifact root from `.project-docs/okstra/` to `.okstra/`. It is a dry run by default; `--apply` performs the move with `git mv` in a Git worktree, removes an empty `.project-docs/`, and synchronizes the `<PROJECT>/CLAUDE.md` import line, `.gitignore`, the project's rows in `~/.okstra/{recent,active}.jsonl`, and `~/.okstra/worktrees/registry.json`. It exits 1 if `.okstra/` already exists or the legacy directory is absent. Scheduled for removal by the end of v0.x |
|
|
839
843
|
| `okstra task-list [--project-root <path>]` | Combine `list_project_tasks` and `read_latest_task` into JSON containing the task catalog and latest task |
|
|
840
844
|
| `okstra task-show <task-key> [--project-root <path>]` | Summarize workflow, phase, status, and artifacts from the Task Read-Side Snapshot |
|
|
841
845
|
| `okstra stage-map <task-key> [--cwd <dir>\|--project <dir>]` | Dump the task's implementation-planning Stage Map as JSON: `{ ok, taskKey, taskRoot, state, sourcePlanPath, stages:[{stage_number,title,depends_on,step_count}], doneStages:[int] }`. `state` is `ready` for one resolved source and `missing` when no Stage Map exists; corrupt or conflicting sources return structured non-zero errors instead of silently selecting another report. `doneStages` is read from the implementation-planning stage consumer state (with carry recovery). This is the read-side source `/okstra-schedule-gen [task-group]` uses to derive selectable unfinished stages and their completed dependency closure |
|
|
842
|
-
| `okstra incremental-scope <args…>` | Decide re-verify vs carry-forward scope for an `implementation-planning` clarification re-run. Thin shim into `scripts/okstra_ctl/incremental_scope.py` (deterministic pure function): it reads the dependency graph from the prior run `data.json`'s `implementationPlanning.stageMap` and returns `mode:"incremental"` only when the base-ref SHA is unchanged and the affected stages' `downstream_stage_closure` covers at most half of all stages;
|
|
846
|
+
| `okstra incremental-scope <args…>` | Decide re-verify vs carry-forward scope for an `implementation-planning` clarification re-run. Thin shim into `scripts/okstra_ctl/incremental_scope.py` (deterministic pure function): it reads the dependency graph from the prior run `data.json`'s `implementationPlanning.stageMap` and returns `mode:"incremental"` only when the base-ref SHA is unchanged and the affected stages' `downstream_stage_closure` covers at most half of all stages; `--full-reason` (selected option / Stage Map / approach) still forces `mode:"full"`. An answered `C-NNN` that traces to no stage returns `mode:"unresolved"` rather than full — pass `--impacted` with the stage numbers or `--full-reason`. `--preview --prev-data <path> --answered-clarifications <csv>` runs the link half alone — no base SHA, no side effects — and prints `{wouldForceFull, unlinkedIds, reason}`; unlinked ids set `wouldForceFull: false` and fill `unlinkedIds` |
|
|
843
847
|
| `okstra incremental-carry <args…>` | Merge carried-forward plan-item verdicts into an incremental re-run. Contract v3 takes `--prev-data`, `--cur-narrative`, and the convergence-owned `--state`; it verifies carried stage rows and writes only `--out-state`, tagging copied verdicts with `carriedForwardFromSeq`. The historical v2 `--cur-data --out` form remains readable. Ownership, scope, item, or schema drift raises `CarryError` and forces a full fallback. |
|
|
844
848
|
| `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 |
|
|
845
849
|
| `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 |
|
package/docs/for-ai/README.md
CHANGED
|
@@ -25,6 +25,7 @@ This directory is a compressed manual for an AI to quickly select and precisely
|
|
|
25
25
|
| Project-wide recent run coverage, tokens, known cost, CPU, and wall-clock usage by task type | `okstra-usage` | [`skills/okstra-usage.md`](skills/okstra-usage.md) |
|
|
26
26
|
| Generate a client-facing work schedule for a whole task-group | `okstra-schedule-gen` | [`skills/okstra-schedule-gen.md`](skills/okstra-schedule-gen.md) |
|
|
27
27
|
| Store or search conversations/decisions/preferences/requirements in the global Memory Book | `okstra-memory` | [`skills/okstra-memory.md`](skills/okstra-memory.md) |
|
|
28
|
+
| Create or join a global room and send or read addressed messages across host sessions | `okstra-chat` | [`skills/okstra-chat.md`](skills/okstra-chat.md) |
|
|
28
29
|
| Manage the implementation-task worktree-based docker compose user-test environment | `okstra-container-build` | [`skills/okstra-container-build.md`](skills/okstra-container-build.md) |
|
|
29
30
|
| Answer the unresolved clarification questions an okstra run left behind in-session and record the approval gate | `okstra-user-response` | [`skills/okstra-user-response.md`](skills/okstra-user-response.md) |
|
|
30
31
|
| Register a PR body template or generate a PR description from a branch diff (global, git repository) | `okstra-pr-gen` | [`skills/okstra-pr-gen.md`](skills/okstra-pr-gen.md) |
|
|
@@ -35,7 +36,7 @@ This directory is a compressed manual for an AI to quickly select and precisely
|
|
|
35
36
|
1. Run commands as separate Bash calls whenever the source skill requires it. In particular, do not wrap `okstra preflight --runtime claude-code`, `okstra wizard ...`, or `okstra container ...` calls in `&&`, `||`, `$(...)`, a leading variable assignment, `eval`, or `export`.
|
|
36
37
|
2. An `okstra <subcmd>` call bootstraps its own Python path. Unless a skill states otherwise, do not build `okstra paths --shell` or `export PYTHONPATH=...`.
|
|
37
38
|
3. Most skills except `okstra-setup` do not use an `npx` fallback. If the runtime is missing, tell the user to run `/okstra-setup` and stop. But if it fails with `unknown command: <cmd>`, the `okstra` binary on PATH is older than the skill — point the user to `npm i -g okstra@latest` rather than `/okstra-setup`, and stop.
|
|
38
|
-
4. Project artifacts go under `<PROJECT_ROOT>/.okstra/` by default. The
|
|
39
|
+
4. Project artifacts go under `<PROJECT_ROOT>/.okstra/` by default. The exceptions are `okstra-memory` (`~/.okstra/memory-book/`) and `okstra-chat` (`~/.okstra/chat/`).
|
|
39
40
|
5. `runtime/` is build output. When fixing a source skill or template, edit the source under `skills/`, `templates/`, `validators/`, `scripts/`, `src/` and apply it via a build.
|
|
40
41
|
6. Do not guess the contents of a tracker, URL, file, report, log, zip, template, or validator. Use only what you have confirmed by reading or running with a tool.
|
|
41
42
|
7. Read-side skills also produce some artifacts. `okstra-inspect errors` produces an error report Markdown and `okstra-inspect error-zip` produces an anonymized zip. Even in these cases, keep the purpose-specific fixed CLI fields as the source of truth.
|
|
@@ -49,13 +50,14 @@ This directory is a compressed manual for an AI to quickly select and precisely
|
|
|
49
50
|
|
|
50
51
|
## Public Skill List
|
|
51
52
|
|
|
52
|
-
The public skills listed in this AI manual are the following
|
|
53
|
+
The public skills listed in this AI manual are the following 14:
|
|
53
54
|
|
|
54
55
|
- `okstra-setup`
|
|
55
56
|
- `okstra-brief-gen`
|
|
56
57
|
- `okstra-run`
|
|
57
58
|
- `okstra-manager`
|
|
58
59
|
- `okstra-memory`
|
|
60
|
+
- `okstra-chat`
|
|
59
61
|
- `okstra-inspect`
|
|
60
62
|
- `okstra-rollup`
|
|
61
63
|
- `okstra-usage`
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# okstra-chat AI Manual
|
|
2
|
+
|
|
3
|
+
## Source
|
|
4
|
+
|
|
5
|
+
- Skill source: [`skills/okstra-chat/SKILL.md`](../../../skills/okstra-chat/SKILL.md)
|
|
6
|
+
- CLI: [`src/commands/chat/chat.mts`](../../../src/commands/chat/chat.mts)
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Global rooms under the okstra home so host sessions from different providers can send and read messages. Not a project `.okstra/` artifact.
|
|
11
|
+
|
|
12
|
+
## CLI
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
okstra chat rooms
|
|
16
|
+
okstra chat create --room <name>
|
|
17
|
+
okstra chat join --room <name> --name <display>
|
|
18
|
+
okstra chat members --room <name>
|
|
19
|
+
okstra chat send --room <name> --as <display> --to <all|name> --body <text>
|
|
20
|
+
okstra chat unread --room <name> --as <display>
|
|
21
|
+
okstra chat inbox --room <name> --as <display>
|
|
22
|
+
okstra chat log --room <name> --as <display>
|
|
23
|
+
okstra chat ack --room <name> --as <display> --through <id>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Display names are typed. The CLI does not generate them.
|
|
27
|
+
|
|
28
|
+
Read the fixed text rows. Do not parse JSON.
|
|
@@ -87,7 +87,7 @@ Keep the table narrow.
|
|
|
87
87
|
- workStatus
|
|
88
88
|
- Next
|
|
89
89
|
|
|
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.
|
|
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. When `awaitingApproval` is true, the next human action is to approve the plan (`okstra-run` → `implementation`, or `--approve`); do not re-run `implementation-planning`. When the pointer is `blocked` after planning, send the user to `okstra-user-response` on the named `C-NNN` ids first.
|
|
91
91
|
|
|
92
92
|
### Specific task
|
|
93
93
|
|
|
@@ -213,7 +213,7 @@ Read the scope and path from the persist action of `okstra wizard outcome`, not
|
|
|
213
213
|
|
|
214
214
|
## Okstra lead takeover
|
|
215
215
|
|
|
216
|
-
After render-bundle, read `<INSTRUCTION_SET_PATH>/lead-execution-prompt.md` verbatim and proceed from Phase 1 in that prompt's order.
|
|
216
|
+
After render-bundle, read `<INSTRUCTION_SET_PATH>/lead-execution-prompt.md` verbatim and proceed from Phase 1 in that prompt's order. Before any in-run approval or clarification question, follow the lead contract "User confirmation before an approval blocker": read cited plan items, worker findings, and files, then ask in the user's language with each option's outcome.
|
|
217
217
|
|
|
218
218
|
Inform the user on one line.
|
|
219
219
|
|
|
@@ -221,7 +221,7 @@ Inform the user on one line.
|
|
|
221
221
|
Took over as Okstra lead (`<host-runtime>`) for `<taskKey>` (`<task-type>`). Run dir: `<RUN_DIR_RELATIVE_PATH>`. Beginning Phase 1 (context loading).
|
|
222
222
|
```
|
|
223
223
|
|
|
224
|
-
For a single-element chain, the end of Step 6 is the end of the run. Step 7 below applies only when the `chain-stages` CSV has 2 or more elements.
|
|
224
|
+
For a single-element chain, the end of Step 6 is the end of the run. Step 7 below applies only when the `chain-stages` CSV has 2 or more elements. After an `implementation-planning` run, if `workflow.awaitingApproval` is true, tell the user to approve the plan; do not start another planning run. If the pointer is `blocked`, send the user to `okstra-user-response` first.
|
|
225
225
|
|
|
226
226
|
## implementation unattended chaining (chain-stages)
|
|
227
227
|
|
|
@@ -15,7 +15,7 @@ The model-facing reads are fixed text. Do not use the automation-compatible JSON
|
|
|
15
15
|
| Command | Purpose |
|
|
16
16
|
|---|---|
|
|
17
17
|
| `okstra user-response list-view --home <home> --project <projectId> --limit 3` | List tasks that still need clarification answers or a plan decision. |
|
|
18
|
-
| `okstra user-response show-view --report <reportPath> --project-root <projectRoot>` | Show open questions, choices, impact, approval context, plan candidates, and current state after validating project ownership. |
|
|
18
|
+
| `okstra user-response show-view --report <reportPath> --project-root <projectRoot>` | Show open questions, choices, impact, why asked, linked plan items, cited artifacts, approval context, plan candidates, and current state after validating project ownership. |
|
|
19
19
|
| `okstra user-response begin --report <reportPath> --task-key <taskKey>` | Open a typed transaction and return an opaque id. |
|
|
20
20
|
| `okstra user-response answer ...` | Add one validated answer to the draft. |
|
|
21
21
|
| `okstra user-response plan-decision ...` | Record an explicit plan decision. |
|
|
@@ -26,14 +26,16 @@ The legacy `list` and `show` JSON commands remain for automation compatibility.
|
|
|
26
26
|
|
|
27
27
|
## Flow
|
|
28
28
|
|
|
29
|
-
1. Run `okstra preflight --runtime
|
|
30
|
-
2.
|
|
31
|
-
3.
|
|
32
|
-
4.
|
|
33
|
-
5.
|
|
34
|
-
6.
|
|
29
|
+
1. Run `okstra preflight --runtime <host-runtime>` for the current harness. On `Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. On `Okstra preflight: ready`, carry `Project root`, `Project ID`, `Runtime`, and `Relay contract`, then run `okstra paths --field home`.
|
|
30
|
+
2. Read the relay `Wizard interaction relay` JSON. When `native-single` is available and the option count fits `nativeLimits`, call `interactions.native-single.function` (`AskUserQuestion` / `ask_user_question` / `request_user_input` from that field). Do not print a numbered list in chat while the native tool is available. Otherwise render a numbered Markdown list. Do not substitute one host function name for another.
|
|
31
|
+
3. Select a task from `list-view` through that host picker.
|
|
32
|
+
4. Read only `show-view --report <reportPath> --project-root <projectRoot>` for report facts. The view also prints `Why asked`, `Linked plan items`, and `Cited artifacts`.
|
|
33
|
+
5. Read every cited `path:line` under the project root and every linked plan-item definition before asking. Do not search beyond that list. Investigation explains; it never changes `options[]`.
|
|
34
|
+
6. Ask one open clarification at a time in the user's language through the host picker. The question body is why, what is already decided, the fork, and what stays blocked. Do not lead with `Kind`, `Blocks`, `Expected form`, or `C-NNN`. Keep the row id in parentheses at the end.
|
|
35
|
+
7. Echo the complete response and confirm through the host picker (`Record as shown` / `Change an answer`). Do not ask them to type `confirmed`.
|
|
36
|
+
8. Begin the transaction, add answers and decisions, then finalize it.
|
|
35
37
|
|
|
36
|
-
Each `options[]` row displays `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`. Contract 3.0 additionally displays `reach`, `scopeEffects`, and row-level `approvalContext`.
|
|
38
|
+
Each `options[]` row displays `{role, answer, rationale, scopeImpact, addedWork, directionChange, disposition}`. Contract 3.0 additionally displays `reach`, `scopeEffects`, and row-level `approvalContext`. Option descriptions use this order: If you pick this (`addedWork`). What it reverses (`directionChange`). Scope (`reach` or `scopeImpact`). Why it is on the board (`rationale`). If the view says `not stated in the report`, repeat that text and never invent a value. A quote from a cited file may follow those axes; it does not replace them.
|
|
37
39
|
|
|
38
40
|
When the user selects a predefined option, pass only the fixed view's one-based option number. Python resolves that option's `disposition`, answer, reach, and scope effects from the validated report:
|
|
39
41
|
|
|
@@ -137,7 +137,7 @@ Runtime/install asset changes follow this checklist:
|
|
|
137
137
|
- `runtime/python/*` → `~/.okstra/lib/python/`
|
|
138
138
|
- `runtime/bin/*` → `~/.okstra/bin/`
|
|
139
139
|
- `runtime/templates/*` → `~/.okstra/templates/`
|
|
140
|
-
- `runtime/skills/<name>` (the
|
|
140
|
+
- `runtime/skills/<name>` (the fourteen user-facing skills only) → `~/.agents/skills` always, plus `~/.claude/skills` when `~/.claude` exists
|
|
141
141
|
- `runtime/prompts/*` → `~/.okstra/prompts/` (lead contracts under `prompts/lead/`, coding-preflight pack under `prompts/coding-preflight/`)
|
|
142
142
|
- the native Claude execution adapters in `runtime/agents/workers/` → `~/.claude/agents/` when `~/.claude` exists; retired provider transport-agent files are removed only when the prior install manifest owned them
|
|
143
143
|
- install manifests → `~/.okstra/installed-skills.json` (target-aware), `~/.okstra/installed-agents.json`
|
|
@@ -249,7 +249,7 @@ Important modules:
|
|
|
249
249
|
| `stage_ledger.py` | assembles the Stage Ledger handed to plan authoring — "what is already built" from the carry sidecar's plan, "which stage numbers are used" from the latest plan (ADR-0015 append-only, judged on the latest plan's `max`); it only joins `stage_targets` (status/lifecycle) and `stage_map` (source-of-stage) and serialises, owning no verdict. Carries `sourcePlan`/`latestPlan` and surfaces `planDivergence`; when the ledger cannot be read it emits the reason in plain text under the same heading instead of omitting the block |
|
|
250
250
|
| `design_surfaces.py` | deterministic detection of an `implementation-planning` stage's design surface — matches the stage's file-path tokens/suffixes/patterns and action wording via `SurfaceRule` to derive which design input the stage needs among domain contract, DB/table schema, external interface, transaction/consistency, transformation mapping, lifecycle, rollout/observability, and manual user test, plus its evidence (`TriggerEvidence`). An unmappable structure raises `DesignSurfaceError` |
|
|
251
251
|
| `design_prep.py` | fingerprint / materialize / resolve backend for design-preparation requests (CLI: `okstra design-prep <list\|show\|write>`) — computes an assessment fingerprint from the approved planning snapshot's `ASSESSMENT_FIELDS`, idempotently writes an Okstra-owned request under `design-prep-requests/`, and resolves the highest-revision append-only user response under `design-prep-inputs/` whose fingerprint matches as the effective response. Keeps the three authorities (report snapshot / Okstra request / user input) separate and never modifies the report or existing revisions. Sidecar I/O is protected by a directory-fd anchor + flock |
|
|
252
|
-
| `incremental_scope.py` | incremental re-verification decision for an `implementation-planning` clarification re-run (deterministic pure function) — reads the dependency graph from the previous run data.json's `implementationPlanning.stageMap` and returns `mode="incremental"` only when the base-ref SHA is unchanged and the affected stages' `downstream_stage_closure` is at most half of all stages. CLI: `okstra incremental-scope` |
|
|
252
|
+
| `incremental_scope.py` | incremental re-verification decision for an `implementation-planning` clarification re-run (deterministic pure function) — reads the dependency graph from the previous run data.json's `implementationPlanning.stageMap` and returns `mode="incremental"` only when the base-ref SHA is unchanged and the affected stages' `downstream_stage_closure` is at most half of all stages; an unlinked `C-NNN` is `mode="unresolved"` (needs `--impacted`), not full. CLI: `okstra incremental-scope` |
|
|
253
253
|
| `incremental_carry.py` | carry merge for an incremental re-run — verifies unchanged carried stage rows and merges their previous plan-item verdicts into the convergence-owned v3 plan state with a `carriedForwardFromSeq` tag. The historical v2 data.json form remains readable. Ownership, scope, or schema drift exits non-zero with `CarryError`. CLI: `okstra incremental-carry` |
|
|
254
254
|
| `build_tools.py` | allowlist SSOT for deciding whether a plan's command cell invokes the project build toolchain (`npm`/`pytest`/`cargo`/`gradle`/… behind transparent leaders like `sudo`/`env`). The planning worktree has no dependencies installed, so `validators/validate-run.py` uses this to warn (advisory) when a toolchain stage declares no install precondition. Intentionally an allowlist, not a denylist, so unknown tokens go undetected rather than firing on `grep`/`sed` in every plan |
|
|
255
255
|
| `stage_citations.py` | shared grammar SSOT for reading the Stage Map stage numbers a prose cell cites (`Stages 1, 2, and 3`, ranges, etc.). One definition serves two readers that must not drift — the coverage check in `validators/validate-run.py` proving every stage traces to a requirement, and `incremental_scope.py`'s back-trace resolving which stages an answered clarification touches |
|
|
@@ -318,7 +318,7 @@ Important modules:
|
|
|
318
318
|
| `codex_dispatch.py` | Compatibility adapter delegating `okstra codex-dispatch` to the provider-neutral `worker_dispatch` path |
|
|
319
319
|
| `analysis_packet.py` | assembles the compact analysis-worker input packet for a task run from worker-owned profile sections; report/lead procedure stays outside the packet |
|
|
320
320
|
| `analysis_inputs.py` | shared input boundary for `project-analysis`, `feature-analysis`, and `change-impact-analysis` — validates evidence-report identity and review status, enforces the type-to-type relation allowlist, computes `exact`/`stale` freshness, and resolves free-text or `PF-NNN` feature targets for both wizard and prepare paths |
|
|
321
|
-
| `user_response.py` | parses clarification/approval responses and the analysis-review sidecar; `parse_analysis_review` validates accepted, revision-requested, and rejected decisions plus their affected IDs and reason |
|
|
321
|
+
| `user_response.py` | parses clarification/approval responses and the analysis-review sidecar; `parse_analysis_review` validates accepted, revision-requested, and rejected decisions plus their affected IDs and reason; `format_show_view` prints why-asked, linked plan items, and cited artifacts for the in-session picker |
|
|
322
322
|
| `context_cost.py` | read-side context-cost estimator for a prepared okstra task bundle (the `okstra context-cost` backend) |
|
|
323
323
|
| `schema_excerpt.py` | generates a task-type-scoped excerpt of the final-report schema — a schema reduction to inject into the worker/lead prompt |
|
|
324
324
|
| `work_categories.py` | requirements-discovery work-category (domain) **SSOT** (`is_valid_category`) — the work-category allowlist is defined only here |
|
|
@@ -436,7 +436,7 @@ Optional (v1.0 backward-compatible) top-level keys:
|
|
|
436
436
|
|
|
437
437
|
### 4.10 `skills/`
|
|
438
438
|
|
|
439
|
-
|
|
439
|
+
14 user-facing skills (the only skills `okstra install` copies). The list SSOT is `USER_SKILL_NAMES` in `src/lib/skill-catalog.mts`; the Claude plugin manifest and the installer both derive from it.
|
|
440
440
|
|
|
441
441
|
Boilerplate shared by several skills (bash invocation rule, outdated-CLI preflight, python bootstrap note) is kept canonical in `skills/_fragments/*.md` and expanded in place inside each `SKILL.md` between `<!-- BEGIN FRAGMENT: <name> -->` / `<!-- END FRAGMENT: <name> -->` markers by `tools/sync-skill-fragments.mjs` (`--check` fails on drift). Sources stay fully expanded, so `runtime/` and installed copies remain self-contained; the guards are `tests-js/skill-fragments.test.mjs` and `tests/contract/test_prompt_fragment_ownership.py`.
|
|
442
442
|
|
|
@@ -445,6 +445,7 @@ Boilerplate shared by several skills (bash invocation rule, outdated-CLI preflig
|
|
|
445
445
|
| `okstra-brief-gen` | yes | Produce task brief from ticket/doc/link/conversation |
|
|
446
446
|
| `okstra-run` | yes | Start/resume an okstra task in the current registered host session |
|
|
447
447
|
| `okstra-memory` | yes | Store/search/archive global conversation memory under `~/.okstra/memory-book` |
|
|
448
|
+
| `okstra-chat` | yes | Global rooms under `~/.okstra/chat` so host sessions from different providers can send and read addressed messages |
|
|
448
449
|
| `okstra-inspect` | yes | Unified read-side — sub-commands `status` (lifecycle + workStatus), `history` (past runs / re-run / resume), `report` (find final-report), `time` (elapsed-time breakdown), `logs` (wrapper log inventory + cleanup), `cost` (task bundle context/read cost), `errors` (error-log aggregation), `error-zip` (anonymized cross-project error bundle), `run-audit` (progress-invariant audit over run artifacts), `recap` (cross-run phase recap). `SKILL.md` is a thin core (preflight + dispatch table + shared rules) and each sub-command body lives in `skills/okstra-inspect/facets/<sub-command>.md`, lazily read only after dispatch resolves; the 1:1 match between dispatch rows and facet files is enforced by `tests/contract/test_okstra_inspect_facets.py` |
|
|
449
450
|
| `okstra-rollup` | yes | Cross-task roll-up — aggregate runs/time/errors across a task-group (or whole project) and synthesize a digest from the report files |
|
|
450
451
|
| `okstra-usage` | yes | Read-only project usage snapshot — aggregate recent run coverage, tokens, known cost, CPU, and wall-clock time by task type (default: 30 days) |
|
|
@@ -453,7 +454,7 @@ Boilerplate shared by several skills (bash invocation rule, outdated-CLI preflig
|
|
|
453
454
|
| `okstra-pr-gen` | yes | Register PR body templates under `~/.okstra/template/pr/` and generate a PR description from a branch diff (drives `okstra pr template` / `branches` / `gen`). **Global skill** — needs a Git repo, not `<PROJECT_ROOT>/.okstra/project.json` |
|
|
454
455
|
| `okstra-manager` | yes | Coordinate cross-project okstra tasks through manager-owned plans, assignments, sync snapshots, status, and child launch context packets |
|
|
455
456
|
| `okstra-setup` | yes | Install/check runtime and register project |
|
|
456
|
-
| `okstra-user-response` | yes | Submit answers to a run's open clarification items through the installed response helper without hand-editing artifacts |
|
|
457
|
+
| `okstra-user-response` | yes | Submit answers to a run's open clarification items through the installed response helper without hand-editing artifacts. The skill reads cited context from `show-view` before asking, uses the host native selection UI, and each option names the outcome of picking it |
|
|
457
458
|
| `okstra-code-review` | yes | Census-based code review of a diff — one okstra `implementation` stage, or any branch — against this project's coding-preflight rules. The result file goes under the task bundle (`code-reviews/stage-<NN>.md`) in stage mode and under `.project-docs/code-reviews/<branch>/` in branch mode; `okstra code-review target` resolves both |
|
|
458
459
|
|
|
459
460
|
> The former internal skills — `context-loader`, `team-contract`, `convergence`, `report-writer`, `coding-preflight` — and the lead contract are no longer skills. They ship as runtime resources under `prompts/lead/*` and `prompts/coding-preflight/*` (installed to `~/.okstra/prompts/`); see §4.11.
|
|
@@ -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
|
-
Launch selection is role slots and model refs, not a provider roster. The wizard
|
|
37
|
+
Launch selection is role slots and model refs, not a provider roster. The wizard asks role counts (`min..max`, default **recommended**), then `--role-model <role>=<provider>/<model>` per slot. current-session lead is this session and is listed on the confirmation summary. 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
|
|
|
@@ -76,7 +76,7 @@ The last column is the `workflow.nextRecommendedPhase` pointer Phase 7 leaves be
|
|
|
76
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
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
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
|
|
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 approvable `plan-ready` (`awaitingApproval` until the user flips `approved`); `blocked` when the gate is blocking or a `Blocks=approval` row is open; `ready` at `implementation-option-selection` on `direction-invalidated` |
|
|
80
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
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
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` |
|
|
@@ -151,9 +151,8 @@ flowchart TD
|
|
|
151
151
|
T[task-type selected] --> W{active worktree in registry?}
|
|
152
152
|
W -->|yes| Reuse[reuse existing worktree<br/>base-ref prompt skipped]
|
|
153
153
|
W -->|no| Base[ask base-ref<br/>validate with git rev-parse]
|
|
154
|
-
Base -->
|
|
155
|
-
Reuse -->
|
|
156
|
-
L --> C[role-count min..max<br/>omit uses recommended]
|
|
154
|
+
Base --> C[role-count min..max<br/>omit uses recommended]
|
|
155
|
+
Reuse --> C
|
|
157
156
|
C --> M[role-model provider/model per slot]
|
|
158
157
|
M --> O[directive / related / clarification]
|
|
159
158
|
O --> Special{release-handoff?}
|
|
@@ -20,10 +20,9 @@ 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| RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
24
24
|
Worktree -->|no| BaseRef[base-ref pick/text<br/>main recommended]
|
|
25
|
-
BaseRef -->
|
|
26
|
-
Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
25
|
+
BaseRef --> RoleCount
|
|
27
26
|
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
28
27
|
RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
|
|
29
28
|
RoleAdd --> Extras[directive, related tasks, clarification]
|
|
@@ -31,7 +30,7 @@ flowchart TD
|
|
|
31
30
|
Confirm --> Render[render-bundle --render-only]
|
|
32
31
|
```
|
|
33
32
|
|
|
34
|
-
Launch selection uses role slots and model refs only:
|
|
33
|
+
Launch selection uses role slots and model refs only: current-session lead is this session (listed on the confirmation summary), 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.
|
|
35
34
|
|
|
36
35
|
## 3. prepare_task_bundle handling
|
|
37
36
|
|
|
@@ -24,8 +24,7 @@ flowchart TD
|
|
|
24
24
|
Type --> PlanPick[approved plan pick]
|
|
25
25
|
PlanPick --> Approved[approval marker confirm]
|
|
26
26
|
Approved --> Stage[stage pick<br/>whole-task or stage number]
|
|
27
|
-
Stage -->
|
|
28
|
-
Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
27
|
+
Stage --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
29
28
|
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
30
29
|
RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
|
|
31
30
|
RoleAdd --> Extras[directive, related tasks, clarification]
|
|
@@ -33,7 +32,7 @@ flowchart TD
|
|
|
33
32
|
Confirm --> Render[render-bundle]
|
|
34
33
|
```
|
|
35
34
|
|
|
36
|
-
Launch selection uses role slots and model refs only:
|
|
35
|
+
Launch selection uses role slots and model refs only: current-session lead is this session (listed on the confirmation summary), 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.
|
|
37
36
|
|
|
38
37
|
This phase does not ask for `base-ref` directly. The wizard selects whole-task or a single stage from the approved plan's Stage Map, and prepare resolves `VERIFICATION_TARGET` from the registry / `consumers.jsonl` / git state.
|
|
39
38
|
|
|
@@ -27,10 +27,9 @@ flowchart TD
|
|
|
27
27
|
Input -->|rerun| Prior[prior planning report via clarification-response]
|
|
28
28
|
Direction --> Worktree{active task worktree?}
|
|
29
29
|
Prior --> Worktree
|
|
30
|
-
Worktree -->|yes|
|
|
30
|
+
Worktree -->|yes| RoleCount[role-count min..max<br/>omit uses recommended]
|
|
31
31
|
Worktree -->|no| BaseRef[base-ref pick/text]
|
|
32
|
-
BaseRef -->
|
|
33
|
-
Leader --> RoleCount[role-count min..max<br/>omit uses recommended]
|
|
32
|
+
BaseRef --> RoleCount
|
|
34
33
|
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
35
34
|
RoleModel --> Extras[directive, related tasks, clarification]
|
|
36
35
|
Extras --> Confirm
|
|
@@ -63,7 +62,7 @@ sequenceDiagram
|
|
|
63
62
|
|
|
64
63
|
Prepare rejects a new plan without a selected-direction report. Comparison mode requires a valid `DIRECTION SELECTION` sidecar, while preselected-validation mode uses the confirmed upstream direction without one. The normalized snapshot binds the source report, source-data digest, option ID, direction body, requirements, and invariants.
|
|
65
64
|
|
|
66
|
-
Prepare does not name the next phase. It carries the inherited `workflow.nextRecommendedPhase` forward and lowers a `ready` pointer to `pending`, because this run has not finished and a `ready` pointer would read as an invitation to start the following phase. The pointer becomes `ready` at `implementation`
|
|
65
|
+
Prepare does not name the next phase. It carries the inherited `workflow.nextRecommendedPhase` forward and lowers a `ready` pointer to `pending`, because this run has not finished and a `ready` pointer would read as an invitation to start the following phase. The pointer becomes `ready` at `implementation` when Phase 7 projects an approvable `plan-ready` outcome; `workflow.awaitingApproval` is then true until the user flips `frontmatter.approved`. A blocking plan-body gate or an open `Blocks=approval` row projects `blocked` instead, so inspect and the wizard ask the user to answer those rows rather than start implementation or loop planning.
|
|
67
66
|
|
|
68
67
|
## 4. lead execution flow
|
|
69
68
|
|
|
@@ -31,8 +31,7 @@ flowchart TD
|
|
|
31
31
|
Approved -->|no| Retry[re-prompt same step]
|
|
32
32
|
Approved -->|yes| Stage[stage multi-pick<br/>ready/active markers]
|
|
33
33
|
Stage --> Chain[render-args<br/>stage + chain-stages]
|
|
34
|
-
Chain -->
|
|
35
|
-
Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
34
|
+
Chain --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
36
35
|
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
37
36
|
RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
|
|
38
37
|
RoleAdd --> Extras[directive, related tasks, clarification]
|
|
@@ -40,7 +39,7 @@ flowchart TD
|
|
|
40
39
|
Confirm --> Render[render-bundle]
|
|
41
40
|
```
|
|
42
41
|
|
|
43
|
-
Launch selection uses role slots and model refs only:
|
|
42
|
+
Launch selection uses role slots and model refs only: current-session lead is this session (listed on the confirmation summary), 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 defaults-vs-customize fork. `executor` is only a compatibility alias for `implementer` in model refs; implementer slots are chosen through role-count / role-model. Dynamic verifiers are not chosen at launch. `--workers` is a CLI compatibility input only, not a launch picker. `stage_pick` is a multi-pick that shows done/in-progress/ready/waiting status. The selected stage set goes through dependency closure and topological sort into a `chain-stages` CSV, and each actual run executes only one of those stages.
|
|
44
43
|
|
|
45
44
|
The current okstra-run wizard path does not expose `--approve` that directly flips the approval checkbox. The plan file must already have a recognized approval marker.
|
|
46
45
|
|
|
@@ -27,10 +27,9 @@ flowchart TD
|
|
|
27
27
|
Type --> Plan[approved plan auto/pick]
|
|
28
28
|
Plan --> Scope[handoff stage pick<br/>whole-task or eligible stages]
|
|
29
29
|
Scope --> Worktree{active task worktree?}
|
|
30
|
-
Worktree -->|yes|
|
|
30
|
+
Worktree -->|yes| RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
31
31
|
Worktree -->|no| BaseRef[base-ref pick/text]
|
|
32
|
-
BaseRef -->
|
|
33
|
-
Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
32
|
+
BaseRef --> RoleCount
|
|
34
33
|
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
35
34
|
RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
|
|
36
35
|
RoleAdd --> Extras[directive, related tasks, clarification]
|
|
@@ -40,7 +39,7 @@ flowchart TD
|
|
|
40
39
|
Confirm --> Render[render-bundle]
|
|
41
40
|
```
|
|
42
41
|
|
|
43
|
-
`release-handoff` has no analysis-worker dispatch. Launch selection still shows
|
|
42
|
+
`release-handoff` has no analysis-worker dispatch. Launch selection still shows any applicable role-count / role-model steps; current-session lead is this session and is listed on the confirmation summary. There is no provider roster multi-pick and no `Use defaults / Customize` fork. Dynamic verifiers are not chosen at launch. `--workers` is not a launch picker, and the runtime forces the worker list to empty. The wizard outcome's `renderArgs` includes `pr-template-path` only for release-handoff. Scope selection finishes before prepare, and the project/global save runs before `render-bundle` via the `config.set pr-template-path` action of `outcome.persistActions[]`. whole-task requires an accepted whole-task verification report, and for stage-group only the stages that were marked `verified` by an accepted single-stage verification in the Stage Lifecycle Snapshot but not yet covered by a `pr` become candidates.
|
|
44
43
|
|
|
45
44
|
Note that this phase is also a target of task worktree provisioning. The normal flow reuses the implementation/final-verification result of the same task-key. Starting a new task may create a new branch, and it is likely to be blocked at the entry gate's "implementation commit exists" condition.
|
|
46
45
|
|
|
@@ -31,10 +31,9 @@ flowchart TD
|
|
|
31
31
|
Keep -->|keep| Base
|
|
32
32
|
Keep -->|change/no brief| Brief
|
|
33
33
|
Type --> Base{active task worktree?}
|
|
34
|
-
Base -->|yes|
|
|
34
|
+
Base -->|yes| RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
35
35
|
Base -->|no| BaseRef[base-ref pick/text]
|
|
36
|
-
BaseRef -->
|
|
37
|
-
Leader --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
|
|
36
|
+
BaseRef --> RoleCount
|
|
38
37
|
RoleCount --> RoleModel[role-model provider/model per slot]
|
|
39
38
|
RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
|
|
40
39
|
RoleAdd --> Extras[directive, related tasks, clarification]
|
|
@@ -42,7 +41,7 @@ flowchart TD
|
|
|
42
41
|
Confirm --> Render[render-bundle]
|
|
43
42
|
```
|
|
44
43
|
|
|
45
|
-
Launch selection uses role slots and model refs only:
|
|
44
|
+
Launch selection uses role slots and model refs only: current-session lead is this session (listed on the confirmation summary), 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.
|
|
46
45
|
|
|
47
46
|
## 3. prepare_task_bundle handling
|
|
48
47
|
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -98,15 +98,15 @@ For a new `implementation-planning` run, the plan-body sequence is initial verif
|
|
|
98
98
|
|
|
99
99
|
### Incremental re-verification (implementation-planning clarification re-runs only)
|
|
100
100
|
|
|
101
|
-
The **default is full re-verification**.
|
|
101
|
+
The **default is full re-verification**. Narrow this re-run to the impacted stages only when the deterministic `okstra incremental-scope` CLI returns `mode == "incremental"`. When the wizard pin is `auto` and the CLI returns `mode == "incremental"`, do not upgrade to full — the CLI already applied the base-ref check, the dependency closure, and the cutoff. This procedure fires ONLY when this run's task-type is `implementation-planning` AND a prior final report exists for this task-key (its data.json at `runs/implementation-planning/reports/final-report-implementation-planning-<prev-seq>.data.json`, where `<prev-seq>` is the most recent prior implementation-planning run's seq). For every other task-type, ignore this block and re-verify normally. This branches on the CLI's `mode` output only — it does NOT re-implement the safety logic in the prompt.
|
|
102
102
|
|
|
103
|
-
0. **Honour the scope the user already pinned (not a judgement — an instruction).** The wizard asks for a re-verification scope whenever this re-run is narrowable, and the answer arrives as two tokens: mode `{{REVERIFY_SCOPE_MODE}}`, stages `{{REVERIFY_SCOPE_STAGES}}`. Apply it before you form your own view:
|
|
104
|
-
- `auto` — the user left the decision to this procedure. Run steps 1–
|
|
103
|
+
0. **Honour the scope the user already pinned (not a judgement — an instruction).** The wizard asks for a re-verification scope whenever this re-run is narrowable or an answered id traces to no stage, and the answer arrives as two tokens: mode `{{REVERIFY_SCOPE_MODE}}`, stages `{{REVERIFY_SCOPE_STAGES}}`. Apply it before you form your own view:
|
|
104
|
+
- `auto` — the user left the decision to this procedure. Run steps 1–7 exactly as written; nothing is pinned. If the CLI returns `mode == "incremental"`, keep it; do not upgrade to full.
|
|
105
105
|
- `full` — the user asked for full re-verification. Still call the CLI once (the record is the audit trail), passing `--full-reason "user requested full re-verification"` and every other CSV empty. Do not argue the user out of it with a narrower `--impacted`: the answer already weighed the cost.
|
|
106
106
|
- `stages` — the user named the stages that must be re-verified. Put **every** number in `{{REVERIFY_SCOPE_STAGES}}` into `--impacted`, unioned with any stage you resolve yourself. Never drop one because your own back-trace did not reach it — the user is telling you about a blast radius the prior report failed to record, which is exactly what the back-trace cannot see. The CLI still applies the dependency closure and the cutoff on top, so a wide enough pin correctly ends in `mode == "full"`.
|
|
107
107
|
1. **List the answered clarifications (a fact, not a judgement).** Collect the `C-NNN` ids you reconciled as answered in §1, and the IDs of any PREP items changed by the carried response. Pass the ids through `--answered-clarifications`; the CLI resolves which Stage Map stages each one touches by reading the prior run's own links — the `P-*` plan item that carried that `clarificationId`, and the requirement-coverage row blocked on `C-NNN` in either its `status` or its `approvalDisposition` (a `documented-deviation` row records the block in the latter). Do NOT map answers to stage numbers yourself.
|
|
108
|
-
- An id that traces to no stage in the prior report
|
|
109
|
-
- **Structural change is your call, and you declare it.** When an answer overturns the selected Option, restructures the stages, or changes the recommended approach, pass `--full-reason "<what changes and how>"`. It forces `mode == "full"` regardless of every other input — the back-trace resolves stages, it cannot judge whether the plan's shape survived. Do NOT express this by leaving the CSVs empty
|
|
108
|
+
- An id that traces to no stage in the prior report does **not** force `mode == "full"` for the whole re-run. The CLI returns `mode == "unresolved"` and names the ids. Ask the user for the stage numbers those answers affect, then call the CLI again with those numbers in `--impacted`. Do not drop the unlinked id from `--answered-clarifications`. Do not treat `unresolved` as full, and do not silently narrow to the ids that did trace. An approval blocker in this shape should have failed the prior report's back-trace; naming stages is the remaining outlet.
|
|
109
|
+
- **Structural change is your call, and you declare it.** When an answer overturns the selected Option, restructures the stages, or changes the recommended approach, pass `--full-reason "<what changes and how>"`. It forces `mode == "full"` regardless of every other input — the back-trace resolves stages, it cannot judge whether the plan's shape survived. Do NOT express this by leaving the CSVs empty. `--impacted` remains available for stage numbers you resolved yourself. `--full-reason` is the only structural path that still forces full.
|
|
110
110
|
- Pass ONLY stage numbers that appear in that Stage Map when you do use `--impacted`. Never invent or guess a stage number — a number absent from the graph must never enter `--impacted` (it would leak into `reverify_stages`).
|
|
111
111
|
2. **Resolve the two base SHAs (safety condition C1 — code-unchanged, decided by the CLI, not by you).**
|
|
112
112
|
- Current base SHA: `{{EXECUTOR_WORKTREE_BASE_REF}}` (this run's resolved worktree base commit).
|
|
@@ -124,8 +124,9 @@ The **default is full re-verification**. Only narrow this re-run to the impacted
|
|
|
124
124
|
```
|
|
125
125
|
The CLI reads the plan's dependency graph from the prior `implementationPlanning.stageMap`, which is authoritative for the impacted stage numbers. The CLI prints JSON `{mode, reverify_stages, carry_stages, reason}`. Instruct the report writer to record this decision in its narrative as `implementationPlanning.incrementalDecision`, using camel-case array keys `reverifyStages` and `carryStages`. Final report assembly preserves that writer-owned decision.
|
|
126
126
|
4. **`mode == "full"`** → run the existing full re-verification path unchanged; ignore `reverify_stages` / `carry_stages`.
|
|
127
|
-
5. **`mode == "incremental"`** → scope every worker dispatch prompt to `reverify_stages` only (the downstream closure of the impacted stages). Do NOT re-analyze `carry_stages` — their prior plan-item verdicts are carried forward verbatim (see `prompts/profiles/implementation-planning.md` "Cross-verification mode" and `prompts/lead/convergence.md` "Convergence scope").
|
|
128
|
-
6.
|
|
127
|
+
5. **`mode == "incremental"`** → scope every worker dispatch prompt to `reverify_stages` only (the downstream closure of the impacted stages). Do NOT re-analyze `carry_stages` — their prior plan-item verdicts are carried forward verbatim (see `prompts/profiles/implementation-planning.md` "Cross-verification mode" and `prompts/lead/convergence.md` "Convergence scope"). When the pin in step 0 was `auto`, this is the decision — do not upgrade it to full.
|
|
128
|
+
6. **`mode == "unresolved"`** → ask the user for stage numbers; re-enter step 3 with those numbers in `--impacted`. Do not fall back to full. Do not record `unresolved` as `incrementalDecision`. Then continue from the new `mode`.
|
|
129
|
+
7. **Merge carried-forward verdicts.** In `incremental` mode, the report writer includes every `carry_stages` stage row unchanged in its narrative. After `okstra plan-items seed --narrative ... --state ...`, the lead runs:
|
|
129
130
|
```
|
|
130
131
|
okstra incremental-carry \
|
|
131
132
|
--prev-data runs/implementation-planning/reports/final-report-implementation-planning-<prev-seq>.data.json \
|