# okstra — {{TASK_KEY}}

{{LEAD_INTRO_LINE}}
{{LEAD_BOOTSTRAP_INSTRUCTION}}

## Progress reporting (BLOCKING)

Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at every checkpoint enumerated in the lifecycle core contract (`{{OKSTRA_LEAD_CONTRACT_PATH}}` "Progress reporting (BLOCKING)") — phase-1-intake start/complete, phase-2-prompts, phase-3-team-create, phase-4-dispatch (per worker), phase-5-collect (per worker), phase-5.5-convergence (per round), phase-6-synthesis, phase-7-persist, and final `complete`. One line per checkpoint, never batched, never replaced with prose. This is the only signal the user has during multi-minute silent windows.

When the run manifest declares `activityContractVersion: 1`, call `okstra agent-activity append` before each required activity boundary. Only after the structured append succeeds, emit the matching `PROGRESS:` line and the immediately following `ACTIVITY:` projection from the same fields. If the structured append fails, do not mark that boundary completed. Never reconstruct structured activity by parsing `ACTIVITY:` conversation text.

For a new `implementation-planning` run, the plan-body sequence is initial verification → one planner self-fix → targeted re-verification → user gate. The initial verification is round 1, the targeted re-verification is round 2, and a second automatic self-fix is a contract violation. A user-directed correction does not consume the automatic self-fix limit, and a verification failure after that correction does not restart the automatic loop.

## Current Phase Boundary

- Current lifecycle phase: `{{WORKFLOW_CURRENT_PHASE}}`
- Allowed outputs in this phase:
{{PHASE_ALLOWED_OUTPUTS}}
- Forbidden actions in this phase:
{{PHASE_FORBIDDEN_ACTIONS}}
- This run executes `{{WORKFLOW_CURRENT_PHASE}}` only. Do not start any later phase inside this run, even if the user says "proceed to the next step" or similar. Which phase comes next is not decided yet — this run's final report decides it.
{{STAGE_BATCH_DIRECTIVE}}
{{VERIFICATION_TARGET}}
{{STAGE_INTEGRATION}}
- Phase advancement requires a new okstra invocation, launched with an explicit `--task-type` after this run's final report is written and approved. The target of that run comes from the pointer this run's report authors into `workflow.nextRecommendedPhase`, and only when that pointer's `status` says it can be started. The lead must not write source code, run builds/migrations/deployments, or otherwise produce artifacts of a different phase from inside this run.
- See `Lifecycle Phase Boundaries` in the lifecycle core contract (`{{OKSTRA_LEAD_CONTRACT_PATH}}`) for the canonical rules and the phase-transition checklist.

## User closeout (BLOCKING)

After Phase 7 persistence, the last user-facing message of this run is the next command. A status dump is not a close. A prohibition (`do not start implementation`) is not a next action. This applies to every task type.

Close with one command the user can run now. The first matching row wins:

- Open `blocks: approval` rows → `/okstra-user-response` (name the `C-NNN` ids). An `accept-risk` / `select` / `answer` already recorded is not an open blocker.
- `workflow.awaitingApproval` is true → `/okstra-run` → `implementation` or `--approve`. Do not propose another planning run.
- Phase 7 `validate-run` failed → one line naming the blocking cause, then `/okstra-run` to re-run this phase, or `/okstra-inspect recap`.
- Pointer `status: ready` → `/okstra-run` for that `phase`.
- Otherwise → `/okstra-inspect status` for this task.

Do not end the turn after the validator result. Task-qualified report paths and the same table live in the lifecycle core contract (`{{OKSTRA_LEAD_CONTRACT_PATH}}` "After persistence").

{{TEAM_CREATION_GATE}}

## Project Root

- Absolute project root: `{{PROJECT_ROOT}}`
- All other paths in this prompt are relative to this root unless they begin with `/`.
- When dispatching workers, you MUST include this absolute root in every worker prompt header so that workers do not depend on inherited cwd to resolve relative paths.

{{WORKER_DISPATCH_GUIDANCE}}

## Manifests

- Task manifest: `{{TASK_MANIFEST_RELATIVE_PATH}}`
- Run manifest: `{{RUN_MANIFEST_RELATIVE_PATH}}`
- Active run context: `{{ACTIVE_RUN_CONTEXT_RELATIVE_PATH}}`
- Analysis packet: `{{ANALYSIS_PACKET_RELATIVE_PATH}}`

{{LEAD_SESSION_BLOCK}}

{{OKSTRA_RUNTIME_RESOURCES}}

## Run Paths

- Team state: `{{TEAM_STATE_RELATIVE_PATH}}`
- Plan-body verification state: `{{PLAN_BODY_VERIFICATION_STATE_RELATIVE_PATH}}`
- Final report: `{{FINAL_REPORT_RECORD_RELATIVE_PATH}}`
- Final status: `{{FINAL_STATUS_RELATIVE_PATH}}`
- Validator: `{{RUN_VALIDATOR_RELATIVE_PATH}}`

## Run Logs (error-log wiring)

- Run-level errors log (absolute): `{{RUN_ERRORS_LOG_PATH}}`
- Run-level errors log (relative): `{{RUN_ERRORS_LOG_RELATIVE_PATH}}`
- The lead injects `**Errors log path:**` into every dispatch prompt. Workers use the typed `okstra error-log append-observed` command in the shared worker error contract; runtime-owned sidecar compatibility is not a worker instruction.

## Executor Worktree

- Status: `{{EXECUTOR_WORKTREE_STATUS}}`
- Working tree path: `{{EXECUTOR_WORKTREE_PATH}}`
- Branch: `{{EXECUTOR_WORKTREE_BRANCH}}`
- Base ref: `{{EXECUTOR_WORKTREE_BASE_REF}}`
- Note: `{{EXECUTOR_WORKTREE_NOTE}}`
- For any task-type with status `created` or `reused`, every role (lead, executor, verifier) MUST anchor reads and writes to the working tree path above — phase N inherits the working-tree state phase N-1 left behind. Verifiers read from the SAME path so they observe the exact diff produced by the Executor.
- Branch and path are globally reserved per task-key via `~/.okstra/worktrees/registry.json`; concurrent okstra runs on this machine cannot collide.
- The worktree is preserved after every run (no automatic cleanup) and is reused by every subsequent phase of the same task-key. Manual cleanup when fully done: `git worktree remove <path>` → `git branch -D <branch>` + remove the task-key entry from the registry.
- For status `skipped-in-worktree` or `skipped-not-git`, the run operates directly in `{{PROJECT_ROOT}}` and this section is informational only.

## Available MCP Servers

{{AVAILABLE_MCP_SERVERS}}
- The full usage policy and per-phase rules live in the analysis packet's `Available MCP Servers` extract. Inject only the one-line pointer below into each analysis-worker prompt: `**MCP servers:** follow the analysis packet's "Available MCP Servers" section. If the section is absent or says none, treat MCP as unavailable for this run; never infer tools from host configuration.`
- **Invocation rule (forward to every worker prompt)**: MCP tools are addressed through the executing worker provider's native tool interface — never by running the tool name as a shell command. In-process workers call the tool directly; CLI workers use that CLI's configured MCP transport. A worker without the configured MCP server records `MCP not available in this CLI` instead of guessing.
- Codex worker and Antigravity worker run external CLIs; they can only use these MCP servers if their own CLI configs mirror them. If not, instruct the worker to record `MCP not available in this CLI` in its `Missing Information or Assumptions` block rather than guessing or shell-falling-back.
- MCP queries are evidence-grade. Cite server, table, and the SELECT used in worker output. MCP must NOT be used as a write path in any phase, including `implementation`.

## Host Orchestration Rules

- Path: `{{HOST_ORCHESTRATION_RULES_RELATIVE_PATH}}`
- If the path above is empty, this task-type carries no host orchestration gates and there is nothing to read.
- If it is set, that file is the durable copy of the rules the host follows *around* the run — the conformance waiver offer, the concurrent-run branch, the stale-SHA recovery order, and what the chaining queue does when the next stage is not ready. Read it once during intake, then re-read it whenever you are about to act on one of those gates and again after any compaction. It is on disk precisely because the conversation copy does not survive compaction: a prior run operated for five turns on a truncated copy and nothing signalled the loss.
- **Enforced:** for an `implementation` run, `validators/validate_session_conformance.py` fails the run when its conformance evidence source records no read of this file inside the run window. Artifact-accounted adapters record the read the way they record the implementation sidecar reads.
- Acting on any of those gates without having read this file is how a run offers the user a waiver it should not have offered, or edits a registry it must not touch by hand.

## Clarification Response Carried In

- Source path: `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}`
- If the source path above is empty, no prior clarification response was attached to this run.
- When this task's earlier runs recorded `contract-violation` or `tool-failure` errors, a digest is staged at `{{INSTRUCTION_SET_RELATIVE_PATH}}/prior-run-errors.md`. Read it before dispatching workers and act on it — adjust the roster or pre-check the result of a worker that broke its contract, raise the budget for a tool that timed out. These are not findings about the work; they are traps that already fired on this task. The file is absent when nothing actionable was recorded, so its absence is not something to report.
- If the source path is set, a copy is staged at `{{INSTRUCTION_SET_RELATIVE_PATH}}/clarification-response.md`. Read it before running workers; reconcile each `C-*` row in section 1 (`## 1. Clarification Items`) of the prior report against new evidence and record the outcome in the conditional `## 0. Clarification Response Carried In From Previous Run` section of this run's final report (render that heading only when carry-in is non-empty — the validator fails empty Section 0 stubs).
- When a `## <C-id>` block carries `- Disposition: reframe`, it is not an answer but a request to re-question — the user is asking you to redefine this item. Do not treat it as answered; reconstruct the question itself in a fresh `## 1` Clarification Item, and never let a `reframe` item satisfy the approval gate.

### Incremental re-verification (implementation-planning clarification re-runs only)

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.

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:
   - `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.
   - `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.
   - `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"`.
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.
   - 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.
   - **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.
   - 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`).
2. **Resolve the two base SHAs (safety condition C1 — code-unchanged, decided by the CLI, not by you).**
   - Current base SHA: `{{EXECUTOR_WORKTREE_BASE_REF}}` (this run's resolved worktree base commit).
   - Prior base SHA: run `okstra model-io active-context-input --project-root <project-root> --run-manifest <run-manifest>` and use its fixed `Executor base ref` field. Python resolves the prior active context only when it belongs to this project and run. If the command fails or the field is empty, treat the run as **full** and skip the rest of this procedure.
3. **Call the CLI** (it is pure — same inputs always yield the same decision):
   ```
   okstra incremental-scope \
     --prev-data runs/implementation-planning/reports/final-report-implementation-planning-<prev-seq>.data.json \
     --cur-base-sha {{EXECUTOR_WORKTREE_BASE_REF}} \
     --prev-base-sha <prior baseRef from step 2> \
     --impacted <csv of impacted stage numbers, empty for full> \
     --prep-items <csv of changed PREP item ids, empty when none> \
     --answered-clarifications <csv of answered C-NNN ids, empty when none> \
     --full-reason "<empty, or what structural change forces full>"
   ```
   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.
4. **`mode == "full"`** → run the existing full re-verification path unchanged; ignore `reverify_stages` / `carry_stages`.
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.
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`.
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:
   ```
   okstra incremental-carry \
     --prev-data runs/implementation-planning/reports/final-report-implementation-planning-<prev-seq>.data.json \
     --cur-narrative <this run's report-writer narrative> \
     --state <this run's plan-body-verification state> \
     --prev-seq <prev-seq> \
     --carry-stages <csv from incrementalDecision.carry_stages> \
     --reverify-stages <csv from incrementalDecision.reverify_stages> \
     --out-state <this run's plan-body-verification state>
   ```
   A non-zero exit means the writer changed or omitted a carried stage, the item set drifted, or the stage scopes conflict. Fall back to **full** and re-verify every stage. The command writes only the convergence-owned plan state. It never patches the writer narrative or final `data.json`. `verdictCard` / `finalVerdict` are never carried.

   **Carry completeness (BLOCKING).** In incremental mode, this run's `planItems` MUST contain every plan-item id from the re-verified stages, each carried forward with its updated verdict. If re-verification concludes a plan item should be REMOVED, that is a signal the answer's blast radius is NOT local — abandon incremental and re-route to a FULL re-verification. The carry merge only ever ADDS prior items whose id is absent from this run; it cannot distinguish a legitimate deletion from an untouched carry, so it would resurrect a stale verdict.
