# okstra-run common flow

## Index

- [1. One-line summary](#1-one-line-summary)
- [2. Where the two entrypoints meet](#2-where-the-two-entrypoints-meet)
- [3. wizard input collection flow](#3-wizard-input-collection-flow)
- [4. render-bundle and prepare_task_bundle](#4-render-bundle-and-prepare_task_bundle)
- [5. Okstra lead phase 1-7](#5-okstra-lead-phase-1-7)
- [6. artifact layout](#6-artifact-layout)
- [7. Common branching rules](#7-common-branching-rules)
- [8. Inconsistencies to watch for](#8-inconsistencies-to-watch-for)

## 1. One-line summary

`okstra-run` is not a "skill that decides questions on its own" but a thin loop that relays the `okstra wizard` JSON state machine to the user. Once input collection finishes, it calls `okstra render-bundle`, and that command builds the task bundle through `python3 -m okstra_ctl.run --render-only`. After that, the current Claude Code, Codex, or Antigravity session switches over to the host-native `Okstra lead`.

## 2. Where the two entrypoints meet

```mermaid
flowchart LR
    subgraph InSession["supported host session"]
        A[okstra-run skill] --> B[okstra wizard]
        B --> C[okstra render-bundle<br/>forces --render-only]
    end

    subgraph Terminal["terminal path"]
        D[scripts/okstra.sh] --> E[CLI parse / prompt / confirm]
    end

    C --> P[prepare_task_bundle()]
    E --> P
    P --> G[task bundle artifacts]
    G --> H{launch mode}
    H -->|render-only| I[current host reads lead prompt]
    H -->|non-render-only| J[exec claude --session-id ...]
```

The common principle is that `prepare_task_bundle()` is the single authority for task bundle creation. Neither the wizard nor the shell wrapper duplicates the path computation, manifest creation, or worktree creation logic.

## 3. wizard input collection flow

```mermaid
stateDiagram-v2
    [*] --> VerifyRuntime: okstra ensure-installed / paths / check-project
    VerifyRuntime --> NewState: okstra wizard new-state-file
    NewState --> TaskPick: wizard init
    TaskPick --> BriefPath: brand-new task
    TaskPick --> TaskType: existing task
    BriefPath --> TaskGroup: new task, brief accepted
    TaskGroup --> TaskId
    TaskId --> TaskType
    TaskType --> BriefKeep: existing task with existing brief
    BriefKeep --> BriefPath: change
    BriefKeep --> BaseRef: keep
    TaskType --> BaseRef: no active worktree
    TaskType --> ImplementationExtras: implementation only
    BaseRef --> ImplementationExtras: implementation only
    BaseRef --> LeaderSession: non-implementation
    ImplementationExtras --> LeaderSession
    LeaderSession --> RoleSlots: role-count then role-model
    RoleSlots --> OptionalInputs: directive / related / clarification
    OptionalInputs --> Confirm
    Confirm --> EditTarget: Edit
    EditTarget --> TaskType: rewind selected step
    Confirm --> Done: Proceed
```

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.

## 4. render-bundle and prepare_task_bundle

```mermaid
sequenceDiagram
    participant Skill as okstra-run skill
    participant Node as okstra CLI
    participant Py as okstra_ctl.run
    participant FS as .okstra
    participant Home as ~/.okstra

    Skill->>Node: okstra wizard outcome
    Node-->>Skill: { renderArgs: ..., persistActions: ... }
    opt persistActions present
        Skill->>Node: okstra config set ...
    end
    Skill->>Node: okstra render-bundle --... --render-only
    Node->>Py: python3 -m okstra_ctl.run --render-only --...
    Py->>Py: validate profile, brief, task-type gates
    Py->>Home: reserve/reuse task worktree registry
    Py->>FS: write run-context and instruction-set
    Py->>FS: write task/run manifests, team-state, timeline, discovery
    Py->>Home: record_start status=prepared
    Py-->>Node: task root, instruction-set, rendered lead prompt
    Node-->>Skill: stdout
    Skill->>FS: read lead-execution-prompt.md
```

The Node shim for `render-bundle` is [`src/commands/execute/render-bundle.mjs`](../../src/commands/execute/render-bundle.mjs). This shim attaches the `--workspace-root`, `--render-only`, and runtime resolution arguments directly. As a result, on the okstra-run path the initial run status starts at `prepared` and the task status starts at `ready-for-lead`.

## 5. Okstra lead phase 1-7

```mermaid
flowchart TD
    P1[Phase 1<br/>task bundle intake] --> P2[Phase 2<br/>worker prompt preparation]
    P2 --> P3[Phase 3<br/>resolve persisted runners]
    P3 -->|native session| P4[Phase 4<br/>host-native dispatch]
    P3 -->|CLI wrapper| P5[Phase 4<br/>provider CLI dispatch]
    P4 --> C[Phase 5.5<br/>convergence]
    P5 --> C
    C --> P6[Phase 6<br/>report-writer synthesis]
    P6 --> PV{implementation-planning?}
    PV -->|yes| PBV[Plan-body verification]
    PV -->|no| P7[Phase 7<br/>persist + validate]
    PBV --> P7
    P7 --> Done[final report + manifests updated]
```

The roles of the analysis workers and the report-writer are separated. `report-writer` is not a Phase 4/5 analysis worker but the Phase 6 final report author. Note, however, that `release-handoff` is a single-lead phase, so it deliberately does not follow this phase graph.

## 6. artifact layout

```mermaid
flowchart TD
    Root["<PROJECT_ROOT>/.okstra/tasks/<group>/<task>/"] --> IS[instruction-set/]
    Root --> Runs[runs/<task-type>/]
    Root --> Hist[history/timeline.json]
    IS --> Profile[analysis-profile.md]
    IS --> Brief[task-brief.md]
    IS --> Lead[lead-execution-prompt.md]
    Runs --> Man[manifests/run-manifest-*.json]
    Runs --> Prompts[prompts/*-worker-prompt-*.md]
    Runs --> Results[worker-results/*.md]
    Runs --> Reports[reports/final-report-*.md<br/>reports/*.data.json<br/>reports/final-report-*.html]
    Runs --> State[state/*.json]
    Runs --> Status[status/final-status-*.json]
    Runs --> ImplStage[implementation/stage-N/...]
    Runs --> FvStage[final-verification/stage-N/...]
    Runs --> Carry[implementation/carry/stage-N.json]
    Runs --> Consumers[implementation-planning/consumers.jsonl]
    Root --> Handoff[release-handoff-input.md]
```

`implementation` and single-stage `final-verification` isolate their run deliverables under `stage-<N>/`. The `implementation` carry sidecar and `consumers.jsonl` are cross-stage coordination ledgers, so they remain at the phase root. The runtime reads this ledger and the registry reservations as a Stage Lifecycle Snapshot to compute stage selection and handoff eligibility. `release-handoff` does not receive a brief; prepare generates `release-handoff-input.md`.

`runtime/` is build output, so when you fix this flow you edit the sources `scripts/`, `skills/`, `agents/`, `prompts/`, `templates/`, `validators/` and refresh with `npm run build`.

## 7. Common branching rules

```mermaid
flowchart TD
    T[task-type selected] --> W{active worktree in registry?}
    W -->|yes| Reuse[reuse existing worktree<br/>base-ref prompt skipped]
    W -->|no| Base[ask base-ref<br/>validate with git rev-parse]
    Base --> C[role-count min..max<br/>omit uses recommended]
    Reuse --> C
    C --> M[role-model provider/model per slot]
    M --> O[directive / related / clarification]
    O --> Special{release-handoff?}
    Special -->|yes| PR[PR template override/scope]
    Special -->|no| Confirm
    PR --> Confirm
```

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.

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.

## 8. Inconsistencies to watch for

- The `okstra-run` wizard path passes only if the implementation approved plan already has an approval marker. `scripts/okstra.sh` has `--approve`, which can flip the checkbox with a CLI ack, but the current wizard `render_args()` has no `approve` flag.
- `release-handoff` has no brief. Prepare cites the accepted final-verification report to build `release-handoff-input.md`, and the wizard's `handoff_stage_pick` or the CLI `--stages` fixes the whole-task/stage-group scope.
- `release-handoff` is also a target for task worktree provisioning. A healthy handoff is safest when it reuses the implementation/final-verification results of the same task-key. Starting a new task creates a new worktree, which may be blocked at the profile's "an implementation commit must exist" entry gate.
- `release-handoff` has no `Required workers:` block in its profile. The runtime also forces the worker roster to be empty.
- No task-type starts the next lifecycle phase within a single run. "Proceed to the next step" is interpreted only as wrapping up the current phase's output.
