# okstra-run AI Manual

## Source

- Skill source: [`skills/okstra-run/SKILL.md`](../../../skills/okstra-run/SKILL.md)
- wizard CLI wrapper: [`src/commands/execute/wizard.mjs`](../../../src/commands/execute/wizard.mjs)
- wizard state machine: [`scripts/okstra_ctl/wizard.py`](../../../scripts/okstra_ctl/wizard.py)
- render-bundle CLI: [`src/commands/execute/render-bundle.mjs`](../../../src/commands/execute/render-bundle.mjs)
- prepare entrypoint: [`scripts/okstra_ctl/run.py`](../../../scripts/okstra_ctl/run.py)

## Purpose

`okstra-run` starts an okstra task run inside the current supported agent host. Input collection is owned entirely by the `okstra wizard` state machine; the skill relays the wizard prompts to the user and then prepares the task bundle via `okstra render-bundle`. Once the bundle is ready, the current Claude Code, Codex, or Antigravity session takes over as the host-native Okstra lead.

Single authority:

- Question order, branching, validation: `scripts/okstra_ctl/wizard.py`
- task bundle materialization: `prepare_task_bundle()`
- Skill document: thin prompt-relay loop

## When to Use

Use it when:

- The user wants to start an okstra task in the current session.
- The user wants to continue the next phase of an existing task.
- "okstra run", "okstra start", "start okstra in this session", "run the next phase", etc.

Do not use it when:

- The user only wants status: `okstra-inspect status`
- The user wants past runs or a resume command: `okstra-inspect history`
- The user explicitly named a new terminal / new claude process: point them to inspect history/resume

## Preflight

Resolve `<host-runtime>` from the executing harness: Claude Code → `claude-code`, Codex → `codex`, Antigravity CLI → `antigravity`, and another adapter host → `external`. This is a host capability, not a `PATH` inference or worker-provider choice. The lead provider is derived from this value and cannot be selected independently. Then make one Bash call:

```bash
okstra preflight --runtime <host-runtime>
```

On `Okstra preflight: failed`, show `Reason`, `Recovery`, `Runtime readiness`,
and every repeated `Readiness check` line, then stop. On
`Okstra preflight: ready`, require `Runtime readiness: ready`, carry the fixed
`Project root` line, and read the `Relay contract` path. Do not create an
`export PYTHONPATH`.

## Bash invocation rule

Every okstra call begins with the literal token `okstra`. Read the `--state-file`, `--answer`, path, model, and worker values from the prior JSON/tool output and paste them as literal strings.

Avoid:

- `$STATE_FILE`, `$ANSWER`
- `$(...)`
- `VAR=... okstra ...`
- `eval`, `export`
- `okstra ... && okstra ...`

Do not drop the flag even for an empty answer.

```bash
okstra wizard step --state-file /tmp/okstra-wizard/state.json --answer ""
```

## wizard initialization

Create the state file:

```bash
okstra wizard new-state-file
```

Carry the printed absolute path verbatim.

wizard init:

```bash
okstra wizard init --state-file /tmp/okstra-wizard/state.json --project-root /abs/project --project-id project-id --host-runtime <host-runtime>
```

The result is `{ok, next}` JSON. The first step is `task_pick`.

## Interpreting the wizard JSON

Pick the UI according to `next.kind`.

| kind | Handling |
|---|---|
| `pick`, `multi: false` | Render every `options[]` verbatim as a selectable choice. Submit the chosen option's `value` |
| `pick`, `multi: true` | Submit all chosen values as a comma-separated string. An empty selection still submits `--answer ""` |
| `pick_group` | Render the wizard's `questions[]` as a single multi-question UI. Build a JSON object of per-step values and submit it in one shot |
| `text` | Show a plain text label without a picker, then submit the user's next message verbatim |
| `done` | Input collection finished. Move to render-args |
| `aborted` | Delete the state file and stop. Do not call render-args/render-bundle |

`progress.label` is a string the wizard composed. Append it verbatim after the UI prompt; do not compute it yourself.

## wizard loop

1. Render the prompt.
2. Submit the user's answer as a literal `--answer`.
3. `ok: true`: show `result.echo` to the user on one line and advance to the next step.
4. `ok: false`: show `result.error` verbatim and retry the same step via `result.current`.
5. `current: null`: a terminal error where the prompt cannot be reconstructed. Show the error and stop.

Important: never trim, hide, or restructure the wizard-provided options into a "recommended + Enter directly" form. The wizard's `options[]` is the complete choice set.

## brief candidate ordering

The brief selection for entry phases (`requirements-discovery`, `error-analysis`, `improvement-discovery`) is handled by the wizard.

- task-group candidates are shown newest-first by combining recent task-catalog use with the recent brief creation/modification times under `.okstra/briefs/<group>/`.
- brief file candidates are chosen from within the selected group's `.okstra/briefs/<task-group>/**/*.md`.
- The brief-file sort key is `max(file created/modified time, task-catalog updatedAt of the task that used this brief)`.
- direct input is always last.

## confirm step

When `next.step == "confirm"`, first fetch the confirmation summary.

```bash
okstra wizard confirmation --state-file /tmp/okstra-wizard/state.json
```

Show `text` to the user, then render the Proceed/Edit/Abort picker. `Edit` rewinds the wizard to an earlier step.

## outcome and render-bundle

When `next.kind == "done"`:

```bash
okstra wizard outcome --state-file /tmp/okstra-wizard/state.json
```

Run `outcome.persistActions[]` first, then pass each key of the `outcome.renderArgs` object exactly once as an `okstra render-bundle` flag. Pass empty string values explicitly too, and add `--lead-runtime <host-runtime>` from preflight. Do not enumerate provider-specific keys in this manual; the wizard and provider registry own the emitted arguments. Exception: the `chain-stages` key is not a render-bundle flag — it drives the Step 7 unattended-chaining loop, so do not pass it as a flag (`run.py` accepts only `--stage`/`--stages`).

```bash
okstra render-bundle \
  --lead-runtime <host-runtime> \
  --<first-renderArgs-key> "<first-renderArgs-value>" \
  --<each-remaining-renderArgs-key> "<corresponding-value>"
```

Parse the following labeled lines from stdout.

- `okstra task root:`
- `okstra instruction-set:`
- optionally `okstra concurrent-run stages:`

render-bundle calls `prepare_task_bundle()` in render-only mode to prepare the manifests, run context, instruction set, and discovery files, and registers the run as `prepared` in `~/.okstra/recent.jsonl`.

## conformance waiver

Classify the entry before offering a waiver. If `requires` contains `db`,
`http`, or `external`, do not offer a waiver: Okstra still attempts the command,
but any non-PASS or unavailable outcome is an external advisory with a
user-owned rerun method. If `requires=[]`, fail closed as a declaration or
contract defect and do not offer a waiver. Offer the waiver only when
`requires=[io]` and that blocking local conformance command is genuinely
impossible to run in the environment. A waiver requires user approval and a
verbatim reason. Neither the AI lead nor a worker creates a self-exemption.
The resulting blocking/advisory policy is enforced by
`scripts/okstra_ctl/conformance.py::decide_conformance_gate` and
`validators/validate-run.py::_validate_conformance`; the picker restriction is
defined by `prompts/host-orchestration/implementation.md` Step 5.1 (the
`okstra-run` skill body carries a generated copy).

When chosen, add it to `render-bundle` only.

```bash
--qa-waiver "<stageKey>:<reason>"
```

Omit the flag entirely when there is no value.

## concurrent-run branch

If `render-bundle` stdout carries `okstra concurrent-run stages:`, the no-team background gate is already reflected in the prompt.

Give the user three options.

1. Proceed as no-team background.
2. Wait — hold the dispatch, preserve the stage worktree·run context. After the occupying run finishes, print the resume command (`okstra-inspect` history → resume) so the user can resume the same stage.
3. Enter directly.

This picker is authored by the skill, so it is separate from the wizard-option-abbreviation ban.

## stale git SHA recovery

When a `PrepareError` such as `Recorded stage SHAs no longer match the git history` appears, do not fix the registry/consumers by hand.

1. Run the `okstra git-reconcile ... --check --text` printed in the error message verbatim.
2. For each confirm item, ask the user for the current branch tip, a different ref, or abort.
3. Run `okstra git-reconcile ... --apply --stage <N> --use-ref <ref>` with the chosen ref.
4. Retry the failed render-bundle with the same arguments.

If the anchor is unresolvable, run `--reset-anchor <ref>` after user confirmation.

## PR template persistence

In release-handoff, when `outcome.persistActions[]` returns a `config.set` / `pr-template-path` action, save the config before render-bundle.

```bash
# action.scope == "project"
okstra config set pr-template-path "<path>" --scope project
# action.scope == "global"
okstra config set pr-template-path "<path>" --scope global
```

Read the scope and path from the persist action of `okstra wizard outcome`, not from the wizard state file. Do not read the raw state file directly.

## Okstra lead takeover

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.

Inform the user on one line.

```text
Took over as Okstra lead (`<host-runtime>`) for `<taskKey>` (`<task-type>`). Run dir: `<RUN_DIR_RELATIVE_PATH>`. Beginning Phase 1 (context loading).
```

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. When the run is over, close with the user's next action — one command they can run now. A prohibition is not a next action. After `implementation-planning`: open approval blockers → `/okstra-user-response`; a recorded `accept-risk` / `select` / `answer` is not an open blocker; awaiting approval → `/okstra-run` → `implementation` or `--approve` (do not start another planning run); `validate-run` failed → one-line cause then `/okstra-run` or `/okstra-inspect recap`; pointer `ready` → `/okstra-run` for that phase.

## implementation unattended chaining (chain-stages)

When `task-type == implementation` and the render-args `chain-stages` CSV has 2 or more elements, the current session acts as the orchestrator and runs the stages as an unattended chain in dependency order. Queue = the topologically-sorted stage list from splitting `chain-stages` on `,`. For each stage `N` in the queue, in order:

1. Re-call render-bundle with the same arguments but `--stage N` (the base commit is auto-computed by prepare from the predecessor's done `head_commit` — do not pass it by hand). The `io`-only conformance waiver·concurrent-run·git-reconcile gates apply identically to each stage's render-bundle.
2. As in Step 6, become the host-native Okstra lead and run that stage's Phase 1–7 inline. Phase 6's lead persistence appends that stage's `status:"done"` row to `runs/<plan-task-key>/consumers.jsonl`.
3. After confirming the `done` row was written, move to the next stage. Clean up context (leftover panes·finished teammates) at each stage boundary. A `status:"failed"` row in place of `done` means the stage ended `FAIL` — stop the queue per the FAIL branch below.
4. One-line report at each stage start/finish: `stage N/<total> start` / `stage N done → next K`.

Once the whole queue is consumed, end the chain and report completion.

- **Next stage not yet ready — normal termination:** When a stage in the queue is occupied by another implementation run as started/reserved and render-bundle is rejected with `--stage N already in progress or reserved by another run` (StageTargetError), this is not an exception — **terminate the chain normally** and report the remaining queue (e.g. `remaining queue: stage 4, 5 — resume with okstra-run after occupancy is released`).
- **Stage ended FAIL — stop the queue and report:** When a stage's synthesised verdict is `FAIL`, Phase 6 writes no carry sidecar and appends a `status:"failed"` row instead of `done`. **Stop the queue there** and report the failed stage, its report path, and the remaining queue. Do not continue to the next stage even when it is dependency-independent — later work must not be stacked on a confirmed regression. The `failed` row frees the occupancy, so `--stage <N>` re-enters that stage on its preserved worktree and branch.
- **Exception gate during chaining:** If render-bundle raises a concurrent-run conflict or git stale-SHA reconciliation, **stop the chain at that stage** and present the gate to the user per the Step 5 procedure. Once the user resolves it, resume the remaining queue in place. Data corruption·concurrent-occupancy conflicts are confirmed by a human — this is the safety boundary of unattended chaining.

## Forbidden patterns

- Changing the question order the wizard emitted.
- Hiding wizard options or keeping only the recommendations.
- Turning a `text` prompt into a picker.
- Dropping the `--answer` flag on an empty answer.
- Bypassing the wizard/render-bundle path by calling `okstra.sh`.
- Calling render-args on a state the user aborted before render-bundle.
- Starting phase work arbitrarily before reading the Okstra lead prompt.
