okstra 0.160.0 → 0.162.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/docs/architecture.md +1 -0
- package/docs/cli.md +17 -3
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/okstra.sh +46 -13
- package/runtime/prompts/launch.template.md +4 -0
- package/runtime/prompts/lead/adapters/cmux.md +67 -0
- package/runtime/prompts/profiles/implementation-planning.md +1 -1
- package/runtime/prompts/wizard/prompts.ko.json +27 -0
- package/runtime/python/okstra_ctl/cmux.py +595 -0
- package/runtime/python/okstra_ctl/codex_dispatch.py +1 -13
- package/runtime/python/okstra_ctl/dispatch_core.py +101 -16
- package/runtime/python/okstra_ctl/dispatch_state.py +16 -0
- package/runtime/python/okstra_ctl/incremental_scope.py +37 -0
- package/runtime/python/okstra_ctl/lead_runtime.py +30 -2
- package/runtime/python/okstra_ctl/models.py +87 -0
- package/runtime/python/okstra_ctl/render.py +7 -2
- package/runtime/python/okstra_ctl/run.py +99 -7
- package/runtime/python/okstra_ctl/team.py +50 -11
- package/runtime/python/okstra_ctl/wizard.py +171 -18
- package/runtime/skills/okstra-run/SKILL.md +1 -0
- package/runtime/validators/validate-workflow.sh +6 -0
- package/runtime/validators/validate_session_conformance.py +37 -3
- package/src/commands/execute/run.mjs +117 -30
package/docs/architecture.md
CHANGED
|
@@ -147,6 +147,7 @@ Runtime entry points are consolidated in Python packages. Bash and skills only c
|
|
|
147
147
|
|
|
148
148
|
- [`prompts/lead/okstra-lead-contract.md`](../prompts/lead/okstra-lead-contract.md) is the runtime-neutral lifecycle core: phase boundaries, artifacts, convergence, report ownership, and persistence semantics.
|
|
149
149
|
- `prompts/lead/adapters/claude-code.md`, `prompts/lead/adapters/codex.md`, `prompts/lead/adapters/antigravity.md`, and `prompts/lead/adapters/external.md` map the same semantic operations to one selected host runtime. The generated launch prompt exposes the core path plus exactly one adapter path.
|
|
150
|
+
- `prompts/lead/adapters/cmux.md` is selected by environment rather than by runtime: when the run manifest's `terminalBackend` is `cmux-pane`, every lead runtime resolves to it and dispatches through `okstra team`, because okstra owns the worker panes on that path instead of the host. It overrides only the adapter and the dispatch mode; the lead's agent, role, and session accounting still come from its own runtime.
|
|
150
151
|
- Runtime metadata and role assignments are persisted separately, but the lead provider is derived from the host: Claude Code maps to Claude, Codex maps to Codex, and Antigravity CLI maps to Antigravity. New runs persist `hostRuntime`, `leadAssignment`, and `workerAssignments[]`; each assignment records its provider, model, execution value, and resolved `native-session` or `cli-wrapper` runner. `lead-execution-prompt.md` is canonical, while `claude-execution-prompt.md` is a byte-identical compatibility alias for historical consumers.
|
|
151
152
|
- Provider registry and front-door separation are implemented: the active Claude Code, Codex, or Antigravity host owns the native lead session, while non-host providers run through their registered CLI wrappers.
|
|
152
153
|
- [`skills/okstra-setup/SKILL.md`](../skills/okstra-setup/SKILL.md) — **first-run bootstrap**. Runs `okstra install` and creates `project.json`.
|
package/docs/cli.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- [Optional arguments and options](#optional-arguments-and-options)
|
|
20
20
|
- [`--task-key`](#--task-key)
|
|
21
21
|
- [`--clarification-response`](#--clarification-response)
|
|
22
|
+
- [`--reverify-scope`](#--reverify-scope)
|
|
22
23
|
- [`--resume-clarification`](#--resume-clarification)
|
|
23
24
|
- [`--project-root`](#--project-root)
|
|
24
25
|
- [`--analysis-target`](#--analysis-target)
|
|
@@ -249,6 +250,18 @@ scripts/okstra.sh \
|
|
|
249
250
|
--clarification-response .okstra/tasks/tasks/8852/runs/2026-04-29/error-analysis/reports/final-report-2026-04-29_10-15-30.md
|
|
250
251
|
```
|
|
251
252
|
|
|
253
|
+
### `--reverify-scope`
|
|
254
|
+
|
|
255
|
+
Pins how much of an `implementation-planning` clarification re-run is verified again. Like `--analysis-target` and `--evidence-inputs`, this is an internal `node bin/okstra render-bundle` input collected by the `/okstra-run` wizard — `scripts/okstra.sh` does not accept it.
|
|
256
|
+
|
|
257
|
+
- Accepted values — exactly three forms; anything else is rejected rather than read as a default:
|
|
258
|
+
- `auto` (or empty, the default) — leave the call to the lead's deterministic `okstra incremental-scope` decision.
|
|
259
|
+
- `full` — re-verify every stage. The lead still records the decision, passing `--full-reason "user requested full re-verification"`.
|
|
260
|
+
- 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.
|
|
261
|
+
- 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.
|
|
262
|
+
- The wizard asks for this **only when the re-run is narrowable** — that is, when every answered `C-NNN` traces back to a stage in the prior report. When one does not, full is already fixed and the confirmation block's `reverify-scope` line names the unlinked id instead of offering a choice that cannot change the outcome. Direct stage input is validated against the prior report's Stage Map, so a number that plan never had is refused at the prompt.
|
|
263
|
+
- 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.
|
|
264
|
+
|
|
252
265
|
### `--resume-clarification`
|
|
253
266
|
|
|
254
267
|
Immediately edits the final report from the previous `requirements-discovery` or `error-analysis` run and automatically reruns the same phase. You do not need to manage the `--clarification-response` path manually.
|
|
@@ -394,9 +407,10 @@ worker roster contains Claude, Codex, or Antigravity.
|
|
|
394
407
|
|
|
395
408
|
`okstra run` defaults to `auto`. `auto` resolves to one of `claude-code`, `codex`, `antigravity`, or `external` based on the host through `src/lib/runtime-resolver.mjs`. Precedence: explicit runtime > the `OKSTRA_RUNTIME_HOST` environment variable > Claude Code skill handoff > external when tmux is available > fail fast otherwise. The safe fallback never silently selects a runtime different from the user's intent, and the presence of the `agy` binary alone never selects the Antigravity host.
|
|
396
409
|
|
|
397
|
-
- Inside
|
|
398
|
-
-
|
|
399
|
-
-
|
|
410
|
+
- Inside a supported host, the installed `okstra-run` skill is the front door and reuses the session you are already in.
|
|
411
|
+
- From a terminal, `okstra run <lead>` starts that lead itself: `okstra run` (Claude Code), `okstra run codex`, `okstra run antigravity`. The leading word is an alias for `--lead-runtime`.
|
|
412
|
+
- `okstra run external` does not start a lead — it orchestrates an all-CLI run through `okstra team`.
|
|
413
|
+
- Starting a lead whose CLI sandboxes itself prints what is given up and waits for a `y`; `--yes` answers it. Today only Codex asks, because a sandboxed lead can reach neither cmux nor the worker CLIs' own configuration.
|
|
400
414
|
- In a generic terminal with tmux, `okstra run` orchestrates `render-bundle --lead-runtime external` -> `okstra team dispatch` -> `okstra team await`.
|
|
401
415
|
|
|
402
416
|
`doctor` and `render-bundle` also default to `auto`, but a plain terminal without a host signal must specify a host. `okstra install` and `ensure-installed` are exceptions. Installation places the shared runtime and skill targets based on agent homes rather than the runtime host, so it records the `auto` request and unresolved state in the manifest and continues even without a host signal. Skill copy targets depend on the presence of agent homes and the default Agent target policy, not runtime resolution. `~/.agents/skills/` is always created, and Claude skills/agents are installed when `~/.claude` exists. The host-aware `okstra-run` skill passes the current harness runtime explicitly; Claude-only maintenance skills continue to pass `--runtime claude-code` where that host is part of their contract.
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
package/runtime/bin/okstra.sh
CHANGED
|
@@ -153,24 +153,60 @@ fi
|
|
|
153
153
|
# Display summary lines to user (everything except the machine-readable line).
|
|
154
154
|
printf '%s\n' "$PREPARE_OUTPUT" | grep -v '^__OKSTRA_LAUNCH__ '
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
fi
|
|
160
|
-
|
|
161
|
-
# Parse launch JSON and exec claude.
|
|
156
|
+
# Parse launch metadata. Everything provider-specific — which executable, which
|
|
157
|
+
# flags, whether a sandbox must be waived — is decided by the model catalog and
|
|
158
|
+
# arrives already assembled, so this wrapper stays a thin adapter.
|
|
162
159
|
LAUNCH_JSON="$(printf '%s\n' "$PREPARE_OUTPUT" | sed -n 's/^__OKSTRA_LAUNCH__ //p' | tail -n1)"
|
|
163
160
|
if [[ -z "$LAUNCH_JSON" ]]; then
|
|
164
161
|
printf 'okstra: prepare_task_bundle did not emit launch metadata\n' >&2
|
|
165
162
|
exit 1
|
|
166
163
|
fi
|
|
167
164
|
|
|
168
|
-
|
|
169
|
-
read -r CLAUDE_SESSION_ID LEAD_MODEL_EXECUTION_VALUE PROJECT_ROOT_FROM_PY PROMPT_FILE < <(
|
|
165
|
+
read -r LEAD_EXECUTABLE PROJECT_ROOT_FROM_PY < <(
|
|
170
166
|
okstra_py - "$LAUNCH_JSON" <<'PY'
|
|
171
167
|
import json, sys
|
|
172
168
|
d = json.loads(sys.argv[1])
|
|
173
|
-
print(d["
|
|
169
|
+
print(d["leadExecutable"], d["projectRoot"])
|
|
170
|
+
PY
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if ! command -v "$LEAD_EXECUTABLE" >/dev/null 2>&1; then
|
|
174
|
+
printf '%s command not found\n' "$LEAD_EXECUTABLE" >&2
|
|
175
|
+
exit 1
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Starting some leads means lowering a protection that CLI applies to itself.
|
|
179
|
+
# okstra never waives it silently: the note says what is given up, and nothing
|
|
180
|
+
# starts without an explicit yes.
|
|
181
|
+
SANDBOX_NOTE="$(
|
|
182
|
+
okstra_py - "$LAUNCH_JSON" <<'PY'
|
|
183
|
+
import json, sys
|
|
184
|
+
print(json.loads(sys.argv[1])["sandboxWaiverNote"])
|
|
185
|
+
PY
|
|
186
|
+
)"
|
|
187
|
+
if [[ -n "$SANDBOX_NOTE" ]]; then
|
|
188
|
+
printf '\n%s\n' "$SANDBOX_NOTE" >&2
|
|
189
|
+
if [[ "$ASSUME_YES" == "true" ]]; then
|
|
190
|
+
printf 'Proceeding without the sandbox (--yes).\n\n' >&2
|
|
191
|
+
else
|
|
192
|
+
printf 'Start %s without its sandbox? [y/N] ' "$LEAD_EXECUTABLE" >&2
|
|
193
|
+
read -r SANDBOX_ANSWER < /dev/tty || SANDBOX_ANSWER=""
|
|
194
|
+
if [[ "$SANDBOX_ANSWER" != "y" && "$SANDBOX_ANSWER" != "Y" ]]; then
|
|
195
|
+
printf 'okstra: cancelled. The task bundle is prepared; rerun to resume it.\n' >&2
|
|
196
|
+
exit 1
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# NUL-separated so a prompt carrying newlines or quotes survives the handoff.
|
|
202
|
+
LAUNCH_ARGV=()
|
|
203
|
+
while IFS= read -r -d '' LAUNCH_ARG; do
|
|
204
|
+
LAUNCH_ARGV+=("$LAUNCH_ARG")
|
|
205
|
+
done < <(
|
|
206
|
+
okstra_py - "$LAUNCH_JSON" <<'PY'
|
|
207
|
+
import json, sys
|
|
208
|
+
for arg in json.loads(sys.argv[1])["launchArgv"]:
|
|
209
|
+
sys.stdout.write(arg + "\0")
|
|
174
210
|
PY
|
|
175
211
|
)
|
|
176
212
|
|
|
@@ -178,8 +214,5 @@ PY
|
|
|
178
214
|
# provisions <PROJECT_ROOT>/.claude/settings.local.json as a symlink to
|
|
179
215
|
# ~/.okstra/templates/settings.local.json, which Claude Code auto-loads
|
|
180
216
|
# whenever it runs inside that project — no CLI flag required.
|
|
181
|
-
PROMPT="$(cat "$PROMPT_FILE")"
|
|
182
217
|
cd "$PROJECT_ROOT_FROM_PY"
|
|
183
|
-
|
|
184
|
-
CLAUDE_COMMAND+=("$PROMPT")
|
|
185
|
-
exec "${CLAUDE_COMMAND[@]}"
|
|
218
|
+
exec "${LAUNCH_ARGV[@]}"
|
|
@@ -100,6 +100,10 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
|
|
|
100
100
|
|
|
101
101
|
The **default is full re-verification**. Only narrow this re-run to the impacted stages when the deterministic `okstra incremental-scope` CLI returns `mode == "incremental"`; on any doubt, stay full. 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–6 exactly as written; nothing is pinned.
|
|
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
|
+
- `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"`.
|
|
103
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.
|
|
104
108
|
- An id that traces to no stage in the prior report makes the CLI return `mode == "full"` for the whole re-run. That is the intended outcome: an answer whose blast radius the prior report never recorded must not narrow anything.
|
|
105
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: that produces the same `no impacted stages resolved` reason as a re-run that simply failed to map anything, and the two become indistinguishable in the record. `--impacted` remains available for stage numbers you resolved yourself.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# cmux Lead Runtime Adapter
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
This adapter maps the neutral Okstra lead operations to a cmux session, where Okstra owns the worker panes regardless of which model is leading. Read it only when the rendered launch prompt selects it; the run manifest's `terminalBackend` is `cmux-pane` for exactly those runs.
|
|
6
|
+
|
|
7
|
+
It replaces the per-runtime adapter, not the lead contract. Your own runtime still decides how you read files, ask the user, and record your session — this file only decides how workers are started, awaited, and reclaimed.
|
|
8
|
+
|
|
9
|
+
## Capability declaration
|
|
10
|
+
|
|
11
|
+
| Field | Value |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `runtime` | environment-selected — any lead runtime resolves to this adapter under cmux |
|
|
14
|
+
| `leadRoleLabel` | `Okstra lead` |
|
|
15
|
+
| `userPromptMode` | `host-text` |
|
|
16
|
+
| `workerDispatchBackend` | `cmux-pane` |
|
|
17
|
+
| `initialPromptDeliveryMode` | `lazy-path-reference` |
|
|
18
|
+
| `sessionAccounting` | unchanged — keep your own runtime's accounting |
|
|
19
|
+
| `resumeMode` | `artifact-checkpoint` |
|
|
20
|
+
| `teardownMode` | `pane-teardown` |
|
|
21
|
+
| `leadEventSource` | `lead-events-jsonl` |
|
|
22
|
+
|
|
23
|
+
## Semantic operation mapping
|
|
24
|
+
|
|
25
|
+
| Operation | Mapping |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `read_artifacts` | Read the manifest-provided paths through the current host's file or shell interface. |
|
|
28
|
+
| `write_artifact` | Write only core-authorized `.okstra/` artifacts and preserve their schemas. |
|
|
29
|
+
| `prompt_user` | Ask through the host text/question interface and require an explicit approval or clarification response. |
|
|
30
|
+
| `dispatch_worker` | Run `okstra team dispatch --project-root <root> --run-manifest <path>`; use `--dry-run` first when the core requires a dispatch preview. |
|
|
31
|
+
| `await_workers` | Run `okstra team await --project-root <root> --run-manifest <path>` through the host's asynchronous shell facility. |
|
|
32
|
+
| `redispatch_worker` | Create the core-specified fresh jobs file and dispatch it with a new `dispatchKind`; never reuse a live worker conversation. |
|
|
33
|
+
| `shutdown_workers` | Run `okstra team teardown --project-root <root> --run-manifest <path>` only after the user-approved cleanup gate. |
|
|
34
|
+
| `record_lead_event` | Append the required structured event to the manifest-provided `leadEventsPath`; emit the matching user-facing `PROGRESS:` line. |
|
|
35
|
+
| `collect_usage` | Collect artifact/CLI-log-backed usage through the existing Okstra token-usage path; never substitute another runtime's session log. |
|
|
36
|
+
|
|
37
|
+
## Pane placement is not yours to compute
|
|
38
|
+
|
|
39
|
+
Okstra creates, sizes, labels, and closes every worker pane. Do not issue terminal-multiplexer commands of any kind — not to place a worker, not to resize the lead, not to reclaim a finished round. Pane geometry depends on the display, and a lead that recomputes it per run gets it wrong differently on every host.
|
|
40
|
+
|
|
41
|
+
Concretely: you never choose a split direction, a pane width, a surface id, or a title. `okstra team dispatch` does all of it and records what it created.
|
|
42
|
+
|
|
43
|
+
## Watching a worker is not the same as judging it
|
|
44
|
+
|
|
45
|
+
Workers run beside you, so you can read their screens. That is a diagnostic channel and nothing more.
|
|
46
|
+
|
|
47
|
+
- A worker is finished when its dispatch record reaches a terminal status and its required Result Paths exist. Nothing you see on a screen changes that verdict.
|
|
48
|
+
- Never parse a pane's contents into a result. Terminal output is a rendered grid — wrapped to the pane's width, with history truncated — so a path or a number read off it may be silently incomplete.
|
|
49
|
+
- Never send input to a running worker. Workers are one-shot sessions whose prompt is already delivered; retries and re-verification always create a fresh session, and interrupting a live worker contaminates exactly the context that rule protects.
|
|
50
|
+
|
|
51
|
+
Use the screen to tell "still working" from "stuck", and to see at a glance which worker failed. Use the artifacts for everything else.
|
|
52
|
+
|
|
53
|
+
## cmux dispatch details
|
|
54
|
+
|
|
55
|
+
- For convergence reverify, consume the persisted round plan exactly. This adapter may map and transport each returned batch, but it cannot change batch membership and does not classify findings or branch on task type, provider, or model identity.
|
|
56
|
+
- Do not invoke Claude Code team tools or `okstra codex-dispatch`. Under cmux every lead dispatches through `okstra team`, including a Claude Code lead.
|
|
57
|
+
- Worker completion is valid only from `workerDispatches[]`, terminal status sidecars, and required Result Paths. Pane creation alone is not completion.
|
|
58
|
+
- Reverify uses a fresh jobs file at `runs/<task-type>/state/reverify-jobs-r<N>-<task-type>-<seq>.json`, sets `dispatchKind: "reverify-r<N>"`, and dispatches with `okstra team dispatch --project-root <root> --run-manifest <path> --dispatch-kind reverify-r<N> --jobs-file <jobs-file>`.
|
|
59
|
+
- Report-writer uses a fresh one-job jobs file with `dispatchKind: "report-writer"` and the same schema, then dispatches through `okstra team dispatch --project-root <root> --run-manifest <path> --jobs-file <jobs-file>`.
|
|
60
|
+
- Every reverify or report-writer jobs file carries `workerId`, `provider`, `role`, `modelExecutionValue`, `promptPath`, `resultPath`, `workerResultPath`, and `completionPaths`. For reverify, set `role` to `worker-reverify-r<N>` for the pane title. The report-writer completion paths include both data.json and the worker-results audit file.
|
|
61
|
+
- After either dispatch, run `okstra team await --project-root <root> --run-manifest <path>` before evaluating terminal status or completion paths.
|
|
62
|
+
|
|
63
|
+
## Completion, cleanup, and resume
|
|
64
|
+
|
|
65
|
+
- Await through `okstra team await`; raw Result Path polling is forbidden for this backend.
|
|
66
|
+
- Reclaim each round's panes at the round boundary through `okstra team teardown`, before the next round's dispatch. Finished workers leave their panes behind on purpose — the screen survives the process so you can still read a failure — so an unreclaimed round keeps shrinking the space the next one gets.
|
|
67
|
+
- Resume from run artifacts and lead-events checkpoints. After usage collection, persistence, and the core user-approval gate, run `okstra team teardown --project-root <root> --run-manifest <path>` and tear down only Okstra-owned panes recorded for the run.
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
- Phase 5.5 finding convergence runs in **adversarial mode** for this phase (`convergence.adversarial=true`). Verifiers actively try to refute each worker finding (requirement gap / risk / option) by re-inspecting its cited evidence; the burden of proof sits on the claim. See `prompts/lead/convergence.md` §"Adversarial Verification Mode".
|
|
64
64
|
- §5.5.9 plan-body verification runs with an **adversarial posture** (`prompts/lead/plan-body-verification.md` §"Adversarial plan-body posture"): verifiers open and confirm every cited path / command and put the burden of proof on the plan. The gate threshold is majority-based for kinds `b`/`c`/`e`, but a single `DISAGREE` blocks on its own for the concrete, safety-critical kind `a` (path/symbol mismatch) — and `f` on `P-Req-*` items. `P-Var-*` items are excepted from the kind-`a` exception: a variation-point defect takes a majority. Rollback ordering (`d`) is advisory and never blocks the gate — a rollback is executed by a human, not by okstra's workers or verifiers. A majority also needs ≥2 participating votes, so a lone dissent whose peer returned a non-result does not block on a majority-gated kind (see that contract's §"Adversarial plan-body posture").
|
|
65
65
|
- **Incremental re-verification scope (clarification re-runs):** when the lead's `okstra incremental-scope` decision is `mode == "incremental"` (procedure in `prompts/launch.template.md` §"Clarification Response Carried In"), workers re-analyze ONLY the stages listed in `reverify_stages` (the downstream closure of the impacted stages). Workers MUST NOT re-open, re-score, or re-judge any stage in `carry_stages` — those stages' prior plan-item verdicts are carried forward verbatim, and a worker never overwrites a carried verdict with its own judgement. When the decision is `mode == "full"` (the default), every stage is re-analyzed as usual.
|
|
66
|
-
- **Single incremental-scope decision:** the lead calls `okstra incremental-scope` exactly once for the re-run, passing the answered `C-NNN` ids through `--answered-clarifications`, changed design-preparation IDs through `--prep-items`, and any lead-resolved stage numbers through `--impacted`; the CLI unions all three before applying the existing dependency closure and cutoff. The clarification ids are resolved to stages by the CLI from the prior report's own `planItems[].clarificationId` and `blocked C-NNN` coverage links — the lead does not map answers to stage numbers. An answer that changes the selected option, Stage Map, or recommended approach is not a local impact: pass every CSV empty so the same call returns `mode == "full"`. A clarification id that traces to no stage, unknown PREP IDs, or invalid `stageRefs` also return an explicit full decision instead of being guessed.
|
|
66
|
+
- **Single incremental-scope decision:** the lead calls `okstra incremental-scope` exactly once for the re-run, passing the answered `C-NNN` ids through `--answered-clarifications`, changed design-preparation IDs through `--prep-items`, and any lead-resolved stage numbers through `--impacted`; the CLI unions all three before applying the existing dependency closure and cutoff. The clarification ids are resolved to stages by the CLI from the prior report's own `planItems[].clarificationId` and `blocked C-NNN` coverage links — the lead does not map answers to stage numbers. An answer that changes the selected option, Stage Map, or recommended approach is not a local impact: pass every CSV empty so the same call returns `mode == "full"`. A clarification id that traces to no stage, unknown PREP IDs, or invalid `stageRefs` also return an explicit full decision instead of being guessed. When the user pinned a scope at the wizard (`REVERIFY_SCOPE_MODE` / `REVERIFY_SCOPE_STAGES` in `prompts/launch.template.md` §"Clarification Response Carried In" step 0), that pin is an input to this same single call — `full` supplies the `--full-reason`, and pinned stage numbers join `--impacted` — never a second call or a bypass of the CLI's closure and cutoff.
|
|
67
67
|
- **Stage-aware carry:** for an incremental decision, pass its `carry_stages` and `reverify_stages` CSVs unchanged to `okstra incremental-carry`. The helper carries the prior whole stage rows and their owned PREP / `P-Prep-*` artifacts; overlap, cross-scope ownership, scope leaks, or canonical conflicts return `CarryError`. On that error, discard the partial merge and run full re-verification.
|
|
68
68
|
{{INCLUDE:_coverage-critic.md}}
|
|
69
69
|
- Non-goals:
|
|
@@ -398,6 +398,31 @@
|
|
|
398
398
|
"latest_report": "clarification: {value} (재사용)"
|
|
399
399
|
}
|
|
400
400
|
},
|
|
401
|
+
"reverify_scope_pick": {
|
|
402
|
+
"label": "재검증 범위를 어떻게 할까요? (답변한 항목이 모두 직전 리포트의 stage 에 연결돼 있어 범위를 좁힐 수 있는 상태입니다 — 최종 확정은 run 시점 base-ref 비교)",
|
|
403
|
+
"echo_template": "reverify-scope: {value}",
|
|
404
|
+
"options": {
|
|
405
|
+
"auto": "관련 stage 만 (추천) — 답변이 닿는 stage 와 그 하위만 다시 검증하고 나머지는 직전 판정을 그대로 이월",
|
|
406
|
+
"full": "전체 재검증 — stage 전부를 처음부터 다시 교차검증 (시간은 더 들지만 계획 형태가 바뀌었을 때 안전)",
|
|
407
|
+
"__free_input__": "직접 입력 — 다시 볼 stage 번호를 지정"
|
|
408
|
+
},
|
|
409
|
+
"echo_suffixes": {
|
|
410
|
+
"auto": "reverify-scope: auto (좁힐 수 있으면 좁힘)",
|
|
411
|
+
"full": "reverify-scope: full (전체 재검증)"
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
"reverify_scope_stages": {
|
|
415
|
+
"label": "다시 볼 stage 번호를 쉼표로 입력하세요 (예: 2,3 — 직전 리포트 Stage Map 에 있는 번호만 유효. 지정한 stage 의 하위 stage 까지 함께 재검증됩니다. 빈 줄이면 자동 판정)",
|
|
416
|
+
"echo_template": "reverify-scope: stage {value}",
|
|
417
|
+
"echo_suffixes": {
|
|
418
|
+
"auto": "reverify-scope: auto (좁힐 수 있으면 좁힘)"
|
|
419
|
+
},
|
|
420
|
+
"errors": {
|
|
421
|
+
"not_a_number": "stage 번호는 정수여야 합니다: {token}",
|
|
422
|
+
"unknown_stage": "직전 리포트의 Stage Map 에 없는 stage 입니다: {stages} (Stage Map 의 번호: {known})",
|
|
423
|
+
"no_stage_map": "직전 리포트에서 Stage Map 을 읽을 수 없어 stage 번호를 검증할 수 없습니다: {reason}"
|
|
424
|
+
}
|
|
425
|
+
},
|
|
401
426
|
"pr_template_pick": {
|
|
402
427
|
"label": "PR 본문 템플릿 경로를 직접 지정할까요?",
|
|
403
428
|
"echo_template": "pr-template(pick): {value}",
|
|
@@ -567,6 +592,8 @@
|
|
|
567
592
|
"reverify_scope_incremental": " reverify-scope: incremental 가능 — 답변된 항목이 모두 직전 리포트의 stage 에 연결됨 (최종 확정은 run 시점 base-ref 비교)",
|
|
568
593
|
"reverify_scope_unlinked": " reverify-scope: full 예상 — {ids} 이(가) 직전 리포트의 어느 stage 에도 연결되지 않아 범위를 좁힐 수 없음",
|
|
569
594
|
"reverify_scope_full": " reverify-scope: full 예상 — {reason}",
|
|
595
|
+
"reverify_scope_user_full": " reverify-scope: full (사용자 지정 — 전체 재검증)",
|
|
596
|
+
"reverify_scope_user_stages": " reverify-scope: stage {stages} 재검증 지정 (사용자 지정 — 하위 stage 포함, 나머지는 직전 판정 이월)",
|
|
570
597
|
"stage_whole_task": "전체 task",
|
|
571
598
|
"handoff_scope_whole_task": "전체 task (whole-task 검증 기반)",
|
|
572
599
|
"handoff_scope_stage_group": "stage-group ({stages})"
|