# final-verification process

## Index

- [1. Purpose](#1-purpose)
- [2. okstra-run wizard flow](#2-okstra-run-wizard-flow)
- [3. entry gate](#3-entry-gate)
- [4. Verification execution flow](#4-verification-execution-flow)
- [5. Verdict and routing](#5-verdict-and-routing)
- [6. Deliverables](#6-deliverables)
- [7. Forbidden actions](#7-forbidden-actions)
- [8. Verified code](#8-verified-code)

## 1. Purpose

`final-verification` determines whether the committed diff produced by `implementation` can be finally accepted. Without performing any source edit or follow-up fix, it confirms that the implementation report matches the actual checkout, then records acceptance blockers, residual risk, and a release recommendation.

## 2. okstra-run wizard flow

```mermaid
flowchart TD
    Start[/okstra-run/] --> Common[common task identity flow]
    Common --> Type[task-type = final-verification]
    Type --> PlanPick[approved plan pick]
    PlanPick --> Approved[approval marker confirm]
    Approved --> Stage[stage pick<br/>whole-task or stage number]
    Stage --> RoleCount[role-count min..max<br/>omit uses recommended; skip if min==max]
    RoleCount --> RoleModel[role-model provider/model per slot]
    RoleModel --> RoleAdd[min=0 roles via role-add only<br/>default skip]
    RoleAdd --> Extras[directive, related tasks, clarification]
    Extras --> Confirm[confirmation]
    Confirm --> Render[render-bundle]
```

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.

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.

## 3. entry gate

```mermaid
sequenceDiagram
    participant P as prepare_task_bundle
    participant C as consumers.jsonl
    participant Reg as worktree registry
    participant Git as verification worktree
    participant Lead as Okstra lead

    P->>C: backfill carry and read done rows
    P->>Reg: resolve task or stage worktree
    alt whole-task
        P->>Git: merge done stage commits into task worktree
        P->>Git: keep stage worktrees (teardown runs after the verdict)
    else single-stage
        P->>Git: reuse selected stage worktree
    end
    P->>Git: resolve base/head/diff stat
    P-->>Lead: inject VERIFICATION_TARGET
    Lead->>Lead: verify against injected target only
```

prepare fixes the verification target before worker dispatch. If any of the following fails, the lead prompt does not start and it stops with `PrepareError`.

- The approved plan's Stage Map cannot be read.
- It is whole-task but not every stage in the Stage Map is `done`.
- A merge conflict occurs during whole-task auto-integration.
- It is single-stage but the selected stage's implementation stage worktree is missing or dirty.
- The verification worktree is in a dirty state outside `.okstra/`.

Once started, the lead treats `VERIFICATION_TARGET` as authoritative. It does not re-pick worktree/base/head/stage/source report from the brief.

## 4. Verification execution flow

```mermaid
flowchart TD
    Gate[entry gate passed] --> Target[injected VERIFICATION_TARGET]
    Target --> Lead[Okstra lead confirms target snapshot]
    Lead --> CW[Claude verifier<br/>read-only]
    Lead --> XW[Codex verifier<br/>read-only]
    Lead --> GW{Antigravity opt-in?}
    GW -->|yes| Antigravity[Antigravity verifier<br/>read-only]
    GW -->|no| Collect
    CW --> Collect[collect independent findings]
    XW --> Collect
    Antigravity --> Collect
    Collect --> Conv[convergence<br/>default max rounds = 2]
    Conv --> Writer[report-writer final synthesis]
    Writer --> SelfReview[lead self-review<br/>verdict, blockers, coverage, no-mutation]
    SelfReview --> Persist[final report + manifests]
```

The validation command is never guessed automatically. When independent re-verification is needed, there are only two tiers of command source.

```mermaid
flowchart LR
    Need[needs validation command] --> Tier1{task brief / approved plan<br/>validation set?}
    Tier1 -->|yes| Deny[Deny-list self-check]
    Tier1 -->|no| Tier2{project.json<br/>qaCommands?}
    Tier2 -->|yes| Deny
    Tier2 -->|no| Missing[record<br/>qa-command not configured]
    Deny -->|clean| Run[execute read-only command]
    Deny -->|denied token| Reject[record rejected command<br/>do not execute]
```

The runtime validates the `project.json` `qaCommands` deny-list at the prepare stage for both `implementation` and `final-verification` (`okstra_ctl.run.validate_project_qa_commands`), so a Tier 2 declaration carrying a mutating token stops the run before it starts. Tier 1 comes from the brief or the approved plan and is not covered by that gate — the lead self-checks those commands right before execution.

## 5. Verdict and routing

```mermaid
flowchart TD
    Verdict{Verdict Token}
    Verdict -->|accepted| Release[route to release-handoff or done]
    Verdict -->|conditional-accept| Conditions[conditions listed exhaustively]
    Conditions --> Followup[route by cause, direction, or detailed-plan defect]
    Verdict -->|blocked| Blockers[acceptance blockers with evidence]
    Blockers --> Followup
```

`## 7. Final Verdict` must contain exactly one `Verdict Token` field, and its value is one of the following three.

- `accepted`: a state that becomes a candidate for plain `release-handoff` when whole-task, or `release-handoff(stage-group)` when single-stage
- `conditional-accept`: all conditions must be stated explicitly, and when a condition is a gate it blocks the next phase
- `blocked`: a state that has acceptance blockers and cannot proceed to release-handoff

Vague phrasings such as "looks good" or "mostly ready" are not allowed.

## 6. Deliverables

```mermaid
flowchart TD
    Snapshot[base/head SHA<br/>status + diff stat] --> Report[final-verification final report]
    Source[Source Implementation Report<br/>path + quoted commit/diff] --> Report
    Coverage[requirement coverage<br/>artifact per requirement] --> Report
    Added[added-surface audit<br/>each addition → requirement] --> Report
    Blockers[acceptance blockers] --> Report
    Risks[residual risks] --> Report
    Commands[read-only command log] --> Report
    Report --> Route[routing recommendation]
```

The final report requires at least the following.

- originating implementation final-report path
- verification scope (`whole-task` or `single-stage`) and the injected `VERIFICATION_TARGET`
- inspected worktree path
- implementation base ref and run start head SHA
- quoted commit list / diff summary
- `Verdict Token`
- blocker table or `No acceptance blockers found.`
- residual risk and escalation trigger
- coverage artifact per requirement
- added-surface audit — one row per identifier / module / configuration entry the diff added, with its callers and the requirement it serves
- read-only command log and exit code
- next safe phase recommendation

## 7. Forbidden actions

```mermaid
flowchart TD
    FV[final-verification] --> Runtime[prepare-owned whole-task integration<br/>or single-stage target resolution]
    FV --> Allowed[lead read-only inspect/test/validate]
    FV -. forbidden .-> Edit[source edit or config edit]
    FV -. forbidden .-> Fix[in-run bug fix]
    FV -. forbidden .-> Mutate[lead-owned mutating command]
    FV -. forbidden .-> Expand[scope expansion]
    FV -. forbidden .-> Hide[hide verifier dissent]
```

The stage merge of whole-task mode is a runtime-owned integration step that prepare performs; the matching teardown is a runtime-owned step too, but it runs after the verdict (Phase 7 `teardown-stages`) and only when the verdict clears the work for release. After that, lead verification is read-only. Source edit, follow-up fix, and scope expansion are all forbidden. When a defect is found, it is not fixed within the current run. Cause defects route to `error-analysis`, selected-direction defects route to `implementation-option-selection`, and detailed-plan defects route to `implementation-planning`.

## 8. Verified code

- [`prompts/profiles/final-verification.md`](../../prompts/profiles/final-verification.md)
- [`templates/reports/final-verification-input.template.md`](../../templates/reports/final-verification-input.template.md)
- [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py)
- [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
- [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py)
- [`scripts/okstra_ctl/render.py`](../../scripts/okstra_ctl/render.py)
- [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md)
