okstra 0.122.0 → 0.124.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/README.md +5 -2
- package/docs/architecture/storage-model.md +15 -1
- package/docs/architecture.md +45 -7
- package/docs/cli.md +47 -5
- package/docs/for-ai/README.md +42 -36
- package/docs/for-ai/skills/okstra-brief-gen.md +105 -105
- package/docs/for-ai/skills/okstra-container-build.md +61 -61
- package/docs/for-ai/skills/okstra-graphify.md +64 -0
- package/docs/for-ai/skills/okstra-inspect.md +86 -86
- package/docs/for-ai/skills/okstra-manager.md +32 -32
- package/docs/for-ai/skills/okstra-memory.md +49 -50
- package/docs/for-ai/skills/okstra-pr-gen.md +48 -0
- package/docs/for-ai/skills/okstra-rollup.md +58 -58
- package/docs/for-ai/skills/okstra-run.md +95 -95
- package/docs/for-ai/skills/okstra-schedule-gen.md +320 -0
- package/docs/for-ai/skills/okstra-setup.md +63 -64
- package/docs/for-ai/skills/okstra-user-response.md +48 -0
- package/docs/performance-improvement-plan-v2.md +4 -4
- package/docs/pr-template-usage.md +34 -34
- package/docs/project-structure-overview.md +92 -70
- package/docs/task-process/README.md +33 -33
- package/docs/task-process/common-flow.md +26 -26
- package/docs/task-process/error-analysis.md +20 -21
- package/docs/task-process/final-verification.md +41 -41
- package/docs/task-process/implementation-planning.md +52 -28
- package/docs/task-process/implementation.md +51 -32
- package/docs/task-process/release-handoff.md +46 -46
- package/docs/task-process/requirements-discovery.md +22 -23
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/antigravity-worker.md +4 -4
- package/runtime/agents/workers/claude-worker.md +2 -2
- package/runtime/agents/workers/codex-worker.md +4 -4
- package/runtime/agents/workers/report-writer-worker.md +4 -4
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/prompts/coding-preflight/frameworks/node-server.md +1 -1
- package/runtime/prompts/launch.template.md +6 -3
- package/runtime/prompts/lead/convergence.md +11 -21
- package/runtime/prompts/lead/okstra-lead-contract.md +16 -18
- package/runtime/prompts/lead/plan-body-verification.md +47 -18
- package/runtime/prompts/lead/report-writer.md +50 -45
- package/runtime/prompts/lead/team-contract.md +11 -122
- package/runtime/prompts/profiles/_common-contract.md +15 -22
- package/runtime/prompts/profiles/_implementation-deliverable.md +4 -2
- package/runtime/prompts/profiles/_implementation-executor.md +6 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
- package/runtime/prompts/profiles/error-analysis.md +2 -2
- package/runtime/prompts/profiles/final-verification.md +3 -1
- package/runtime/prompts/profiles/implementation-planning.md +24 -14
- package/runtime/prompts/profiles/implementation.md +1 -1
- package/runtime/prompts/profiles/improvement-discovery.md +1 -1
- package/runtime/prompts/profiles/release-handoff.md +3 -3
- package/runtime/prompts/profiles/requirements-discovery.md +18 -18
- package/runtime/prompts/wizard/prompts.ko.json +44 -0
- package/runtime/python/okstra_ctl/codex_dispatch.py +23 -1
- package/runtime/python/okstra_ctl/design_prep.py +1462 -0
- package/runtime/python/okstra_ctl/design_surfaces.py +243 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +33 -1
- package/runtime/python/okstra_ctl/implementation_stage.py +35 -0
- package/runtime/python/okstra_ctl/incremental_carry.py +294 -21
- package/runtime/python/okstra_ctl/incremental_scope.py +51 -5
- package/runtime/python/okstra_ctl/material.py +1 -1
- package/runtime/python/okstra_ctl/model_discovery.py +98 -0
- package/runtime/python/okstra_ctl/models.py +8 -3
- package/runtime/python/okstra_ctl/render.py +5 -0
- package/runtime/python/okstra_ctl/run.py +53 -5
- package/runtime/python/okstra_ctl/user_response.py +67 -2
- package/runtime/python/okstra_ctl/wizard.py +283 -3
- package/runtime/python/okstra_token_usage/report.py +11 -0
- package/runtime/schemas/final-report-v1.0.schema.json +336 -0
- package/runtime/skills/_fragments/bash-invocation-rule.md +1 -0
- package/runtime/skills/_fragments/preflight-outdated-cli.md +1 -0
- package/runtime/skills/_fragments/python-bootstrap-note.md +1 -0
- package/runtime/skills/okstra-brief-gen/SKILL.md +117 -122
- package/runtime/skills/okstra-container-build/SKILL.md +24 -14
- package/runtime/skills/okstra-graphify/SKILL.md +12 -4
- package/runtime/skills/okstra-inspect/SKILL.md +105 -99
- package/runtime/skills/okstra-manager/SKILL.md +1 -1
- package/runtime/skills/okstra-memory/SKILL.md +3 -3
- package/runtime/skills/okstra-rollup/SKILL.md +12 -6
- package/runtime/skills/okstra-run/SKILL.md +49 -88
- package/runtime/skills/{okstra-schedule → okstra-schedule-gen}/SKILL.md +38 -32
- package/runtime/skills/okstra-setup/SKILL.md +1 -1
- package/runtime/skills/okstra-setup/references/project-config.md +17 -16
- package/runtime/skills/okstra-usage/SKILL.md +5 -2
- package/runtime/skills/okstra-user-response/SKILL.md +23 -9
- package/runtime/templates/prd/brief.template.md +92 -92
- package/runtime/templates/reports/error-analysis-input.template.md +1 -1
- package/runtime/templates/reports/fan-out-unit.template.md +6 -6
- package/runtime/templates/reports/final-report.template.md +67 -0
- package/runtime/templates/reports/final-verification-input.template.md +6 -6
- package/runtime/templates/reports/i18n/en.json +31 -0
- package/runtime/templates/reports/i18n/ko.json +31 -0
- package/runtime/templates/reports/implementation-input.template.md +1 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
- package/runtime/templates/reports/improvement-discovery-input.template.md +1 -1
- package/runtime/templates/reports/quick-input.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +1 -1
- package/runtime/templates/reports/schedule.template.md +22 -22
- package/runtime/templates/reports/task-brief.template.md +3 -3
- package/runtime/templates/reports/user-response.template.md +20 -20
- package/runtime/templates/worker-prompt-preamble.md +111 -13
- package/runtime/validators/validate-run.py +426 -5
- package/runtime/validators/validate-schedule.py +5 -5
- package/src/cli-registry.mjs +7 -0
- package/src/commands/inspect/design-prep.mjs +23 -0
- package/src/lib/skill-catalog.mjs +2 -1
- package/docs/for-ai/skills/okstra-schedule.md +0 -320
|
@@ -75,7 +75,7 @@ For the report writer specifically, the `## Inputs` list always includes:
|
|
|
75
75
|
|
|
76
76
|
For the carry-in `clarification-response.md` (if present), walk every row of `## 1. Clarification Items` including rows whose `User input` cell is blank — a blank cell with `Status=open` is a signal you must surface in the conditional `## 0. Clarification Response Carried In From Previous Run` section (the template's `RENDER_IF` guard activates it when the carry-in path is non-empty). When no carry-in path was provided, OMIT the `## 0.` heading entirely — do NOT write an empty-state stub.
|
|
77
77
|
|
|
78
|
-
Write a Reading Confirmation block to your **audit sidecar** at `runs/<task-type>/worker-results/report-writer-worker-audit-<task-type>-<seq>.md
|
|
78
|
+
Write a Reading Confirmation block to your **audit sidecar** at `runs/<task-type>/worker-results/report-writer-worker-audit-<task-type>-<seq>.md`, per the worker preamble §"Reading rules" (canonical — the main final-report and worker-results files carry no Section 0 heading). If you cannot truthfully confirm a file end-to-end, record a `tool-failure` in the errors sidecar instead of fabricating the report.
|
|
79
79
|
|
|
80
80
|
## Authoring Contract
|
|
81
81
|
|
|
@@ -90,9 +90,9 @@ Rules (the schema enforces most of these — they are listed here so you know *w
|
|
|
90
90
|
- **Verdict Card consistency.** `verdictCard.verdictToken` / `.direction` / `.nextStep` MUST byte-match `finalVerdict.verdictToken` / `.direction` / `.nextStep` and `recommendedNextSteps[0].text`. The renderer pulls both from the same data structure — duplicating values across `verdictCard` and `finalVerdict` is intentional so the validator can diff them.
|
|
91
91
|
- **Reader Summary.** Populate `readerSummary` when the schema excerpt exposes it. It is the human-first entrypoint for both Markdown and HTML: one sentence for the decision, one for the human action required, one for blockers, one for audit sections safe to skip on first read, and one runnable recommended command. Do not duplicate raw evidence tables here.
|
|
92
92
|
- **§7 phase-continuation row (mandatory for non-terminal task-types).** When `header.taskType` is one of `requirements-discovery` / `implementation-planning` / `error-analysis` / `implementation` / `final-verification`, `followUpTasks` MUST contain at least one row whose `origin` is `phase-continuation`, `suggestedTaskType` equals the next phase (byte-identical to `finalVerdict.nextStep`'s referenced phase), `newTaskId` reuses the current task-id, `autoSpawn` is `"no"`, and `priority` is `"P0"`. For `release-handoff` runs, omit the phase-continuation row. Schema `allOf` clause enforces this via `contains`.
|
|
93
|
-
- **No deprecated sections.** The schema has no `4.5.8 User Approval Request` body field, no `4.5.9 Open Questions`, no `5.1
|
|
93
|
+
- **No deprecated sections.** The schema has no `4.5.8 User Approval Request` body field, no `4.5.9 Open Questions`, no `5.1 Additional Material Request`, no `5.2 User Confirmation Questions` — clarifications go under the unified `clarificationItems[]` array.
|
|
94
94
|
- **Optional Section 0.** Include `clarificationCarryIn` ONLY when the lead's prompt provides a non-empty carry-in path. Omit the key entirely otherwise (do NOT set it to `null` or an empty object).
|
|
95
|
-
- **Reading Confirmation**
|
|
95
|
+
- **Reading Confirmation** goes in the audit sidecar per the preamble §"Reading rules" — never in the data.json or the main worker-results file.
|
|
96
96
|
- Include all four convergence categories. The schema's `crossVerification.consensus` / `.differences` arrays carry full / partial / contested / worker-unique items; do not omit any.
|
|
97
97
|
- Convergence round history goes in `crossVerification.roundHistory.rounds[]` with `round2SkippedReason`. When convergence is disabled, set `crossVerification.roundHistory` to `{"disabled": true}`. Values come verbatim from `state/convergence-<task-type>-<seq>.json` — do not recompute.
|
|
98
98
|
- `verification-error` votes are their own verdict (`planItems[].verdicts[].verdict` enum); they are NOT folded into AGREE / DISAGREE counts.
|
|
@@ -105,7 +105,7 @@ Rules (the schema enforces most of these — they are listed here so you know *w
|
|
|
105
105
|
- For `implementation-planning`, also populate `implementationPlanning.decisionDrafts` (one row per decision meeting all three decision-record criteria; `[]` otherwise) and `implementationPlanning.skippedAdrCandidates` (evaluated-but-dropped adr-candidates; `[]` otherwise). The schema excerpt enumerates the row shape; the renderer emits §5.4 `### Decision Drafts`. When `decisionDrafts` is non-empty, the plan's stages MUST carry a stepwise step that creates `.okstra/decisions/<NNNN>-<slug>.md` (validate-run gates this).
|
|
106
106
|
- When the `Task Type` is `improvement-discovery`, populate `## 5.9 Improvement Candidates` with the 10-column schema enforced by `validators/validate_improvement_report.py`. Source the row IDs (`I-NNN`), lens whitelist, and Source workers patterns from `scripts/okstra_ctl/improvement_lenses.py` — do NOT introduce new lens names or worker prefixes. `improvement-discovery` is NOT in the data.json schema enum, so author its markdown directly (not via `okstra-render-final-report.py`). Immediately after writing the markdown, run (`Bash`): `okstra inject-report-index <markdown path> --report-language <en|ko>`. That adds the top-of-report Index plus `I-NNN` / `C-NNN` scroll anchors; the run validator fails the report when the Index anchor is absent.
|
|
107
107
|
|
|
108
|
-
Write the data.json (and the audit sidecar `.md`) with your `Write` tool — that is the canonical authoring path, and okstra ships no hook that blocks `.md` writes (its only settings hook is the `SessionEnd` trace-cleanup; the coding-preflight hook emits reminders but never blocks). A Bash heredoc is acceptable ONLY when a specific `Write` call is genuinely rejected by the host environment, and it MUST produce byte-identical content — do not reach for it pre-emptively. Then invoke the renderer (`Bash`): `okstra render-final-report <data.json path>`. Confirm both files exist and respond with a short status line prefixed by your model identity,
|
|
108
|
+
Write the data.json (and the audit sidecar `.md`) with your `Write` tool — that is the canonical authoring path, and okstra ships no hook that blocks `.md` writes (its only settings hook is the `SessionEnd` trace-cleanup; the coding-preflight hook emits reminders but never blocks). A Bash heredoc is acceptable ONLY when a specific `Write` call is genuinely rejected by the host environment, and it MUST produce byte-identical content — do not reach for it pre-emptively. Then invoke the renderer (`Bash`): `okstra render-final-report <data.json path>`. Confirm both files exist and respond with a short status line prefixed by your model identity, per the preamble §"Return message to the lead":
|
|
109
109
|
|
|
110
110
|
```
|
|
111
111
|
**Model:** Report writer worker, <modelExecutionValue>
|
|
@@ -29,7 +29,7 @@ optional arguments:
|
|
|
29
29
|
(1) ancestor of cwd that contains .okstra/project.json,
|
|
30
30
|
(2) \`git rev-parse --show-toplevel\` from cwd. Errors out if neither resolves.
|
|
31
31
|
--directive Free-form user-supplied directive carried into the run as a "## Directive" section
|
|
32
|
-
inside instruction-set/analysis-material.md. Lead, workers, and skills (e.g. okstra-schedule)
|
|
32
|
+
inside instruction-set/analysis-material.md. Lead, workers, and skills (e.g. okstra-schedule-gen)
|
|
33
33
|
may treat this as a hard hint that overrides default heuristics. Use to express intent
|
|
34
34
|
like "render a Gantt even with single XL task" or "emphasize rollout risk".
|
|
35
35
|
--fix-cycle <yes|no> When re-entering an entry phase (requirements-discovery / error-analysis /
|
|
@@ -90,7 +90,7 @@ options:
|
|
|
90
90
|
(Antigravity worker is optional; add \`antigravity\` explicitly, e.g. --workers claude,codex,antigravity,report-writer)
|
|
91
91
|
--lead-model Model for Claude lead. Default: OKSTRA_DEFAULT_LEAD_MODEL or opus
|
|
92
92
|
--claude-model Model for Claude worker. Default: OKSTRA_DEFAULT_CLAUDE_MODEL or opus
|
|
93
|
-
--codex-model Model for Codex worker. Default: OKSTRA_DEFAULT_CODEX_MODEL or gpt-5.6
|
|
93
|
+
--codex-model Model for Codex worker. Default: OKSTRA_DEFAULT_CODEX_MODEL or gpt-5.6-sol
|
|
94
94
|
--antigravity-model Model for Antigravity worker. Default: OKSTRA_DEFAULT_ANTIGRAVITY_MODEL or gemini-3.1-pro
|
|
95
95
|
--report-writer-model
|
|
96
96
|
Model for report writer worker. Default: OKSTRA_DEFAULT_REPORT_WRITER_MODEL or lead model default
|
|
@@ -124,7 +124,7 @@ model defaults:
|
|
|
124
124
|
Claude lead: OKSTRA_DEFAULT_LEAD_MODEL or opus
|
|
125
125
|
Report writer worker: OKSTRA_DEFAULT_REPORT_WRITER_MODEL or Claude lead default
|
|
126
126
|
Claude worker: OKSTRA_DEFAULT_CLAUDE_MODEL or opus
|
|
127
|
-
Codex worker: OKSTRA_DEFAULT_CODEX_MODEL or gpt-5.6
|
|
127
|
+
Codex worker: OKSTRA_DEFAULT_CODEX_MODEL or gpt-5.6-sol
|
|
128
128
|
Antigravity worker: OKSTRA_DEFAULT_ANTIGRAVITY_MODEL or gemini-3.1-pro
|
|
129
129
|
Implementation executor: OKSTRA_DEFAULT_EXECUTOR or claude (one of: claude | codex | antigravity)
|
|
130
130
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Node.js Conventions (server-side)
|
|
2
2
|
|
|
3
|
-
Load this **in addition to** [javascript-typescript.md](javascript-typescript.md). JS / TS rules still apply; this file adds the server-specific layer.
|
|
3
|
+
Load this **in addition to** [javascript-typescript.md](../languages/javascript-typescript.md). JS / TS rules still apply; this file adds the server-specific layer.
|
|
4
4
|
|
|
5
5
|
## Architecture
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
|
|
|
14
14
|
{{PHASE_ALLOWED_OUTPUTS}}
|
|
15
15
|
- Forbidden actions in this phase:
|
|
16
16
|
{{PHASE_FORBIDDEN_ACTIONS}}
|
|
17
|
-
- This run executes `{{WORKFLOW_CURRENT_PHASE}}` only. Do not start `{{WORKFLOW_NEXT_RECOMMENDED_PHASE}}` or any later phase inside this run, even if the user says "
|
|
17
|
+
- This run executes `{{WORKFLOW_CURRENT_PHASE}}` only. Do not start `{{WORKFLOW_NEXT_RECOMMENDED_PHASE}}` or any later phase inside this run, even if the user says "proceed to the next step" or similar.
|
|
18
18
|
{{STAGE_BATCH_DIRECTIVE}}
|
|
19
19
|
{{VERIFICATION_TARGET}}
|
|
20
20
|
{{STAGE_INTEGRATION}}
|
|
@@ -91,7 +91,7 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
|
|
|
91
91
|
|
|
92
92
|
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.
|
|
93
93
|
|
|
94
|
-
1. **Resolve the impacted stage set (safety condition C2 — your discretionary judgement).** For each answered `C-*` row you reconciled in §1, decide which **Stage Map stage numbers** (from the prior plan's `## 5.5 Stage Map`) the answer touches. Rules:
|
|
94
|
+
1. **Resolve the impacted stage set (safety condition C2 — your discretionary judgement).** For each answered `C-*` row you reconciled in §1, decide which **Stage Map stage numbers** (from the prior plan's `## 5.5 Stage Map`) the answer touches. Also collect the IDs of any PREP items changed by the carried response. Rules:
|
|
95
95
|
- Pass ONLY stage numbers that appear in that Stage Map. Never invent or guess a stage number — a number absent from the graph must never enter `--impacted` (it would leak into `reverify_stages`).
|
|
96
96
|
- If you cannot map a touched item to a real stage with confidence, leave the impacted set **EMPTY** — an empty set forces `mode == "full"`. Widening to full is always the safe choice; guessing is not.
|
|
97
97
|
- If any answer overturns the selected Option, restructures the stages, or changes the recommended approach (rather than a localized detail), also leave the impacted set **EMPTY**.
|
|
@@ -104,7 +104,8 @@ The **default is full re-verification**. Only narrow this re-run to the impacted
|
|
|
104
104
|
--prev-data runs/implementation-planning/reports/final-report-implementation-planning-<prev-seq>.data.json \
|
|
105
105
|
--cur-base-sha {{EXECUTOR_WORKTREE_BASE_REF}} \
|
|
106
106
|
--prev-base-sha <prior baseRef from step 2> \
|
|
107
|
-
--impacted <csv of impacted stage numbers, empty for full>
|
|
107
|
+
--impacted <csv of impacted stage numbers, empty for full> \
|
|
108
|
+
--prep-items <csv of changed PREP item ids, empty when none>
|
|
108
109
|
```
|
|
109
110
|
The CLI reads the plan's dependency graph from the top-level `## 5.5 Stage Map` (`implementationPlanning.stageMap`), which is authoritative for the impacted stage numbers — there is no per-option stage graph. The CLI prints JSON `{mode, reverify_stages, carry_stages, reason}`. Instruct the report-writer to record this JSON verbatim into this run's data.json as `implementationPlanning.incrementalDecision` (keys `mode`, `reverifyStages`, `carryStages`, `reason`) — the renderer turns it into the `### 0.1 Incremental Re-Verification Scope` audit block, and the validator fails an `incremental`-mode run whose Section 0 omits that block.
|
|
110
111
|
4. **`mode == "full"`** → run the existing full re-verification path unchanged; ignore `reverify_stages` / `carry_stages`.
|
|
@@ -115,6 +116,8 @@ The **default is full re-verification**. Only narrow this re-run to the impacted
|
|
|
115
116
|
--prev-data runs/implementation-planning/reports/final-report-implementation-planning-<prev-seq>.data.json \
|
|
116
117
|
--cur-data <this run's data.json> \
|
|
117
118
|
--prev-seq <prev-seq> \
|
|
119
|
+
--carry-stages <csv from incrementalDecision.carry_stages> \
|
|
120
|
+
--reverify-stages <csv from incrementalDecision.reverify_stages> \
|
|
118
121
|
--out <this run's data.json>
|
|
119
122
|
```
|
|
120
123
|
A non-zero exit (`CarryError` — schema drift between the two runs) means the carry is unsafe: fall back to **full** — discard the incremental result and re-verify every stage. Note: `verdictCard` / `finalVerdict` are NEVER carried — this run re-computes them from the re-verified plus carried plan items.
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
## Scope and Terminology (BLOCKING)
|
|
24
24
|
|
|
25
|
-
This contract governs **Phase 5.5 (Convergence loop)** — a *lead operating phase* inside a single okstra run, not a task-type lifecycle phase.
|
|
25
|
+
This contract governs **Phase 5.5 (Convergence loop)** — a *lead operating phase* inside a single okstra run, not a task-type lifecycle phase. It leaves the 6 task-type lifecycle phases (`requirements-discovery` → `error-analysis` → `implementation-planning` → `implementation` → `final-verification` → `release-handoff`, see [okstra-lead-contract](./okstra-lead-contract.md) "Lifecycle Phase Boundaries") unchanged; the lead operating phases (Phase 1 Intake → Phase 7 Persist, see [okstra-lead-contract](./okstra-lead-contract.md) "Quick Reference") drive a *single* task-type run.
|
|
26
26
|
|
|
27
27
|
**`contested` is a final classification only.** It is NEVER an intermediate queue label. The verification queue carries findings that are *unique to a single worker* (entered in Round 0) or *mixed/unresolved after a re-verification round* (carried forward). The `contested` label is assigned only when the **last executed round** completes and the queue is still non-empty.
|
|
28
28
|
|
|
@@ -30,9 +30,8 @@ When this contract says "queue" without qualifier, it means the *verification qu
|
|
|
30
30
|
|
|
31
31
|
## When to Use
|
|
32
32
|
|
|
33
|
-
- When okstra lead Phase 5.5 (convergence loop) begins
|
|
34
|
-
-
|
|
35
|
-
- When findings need to be systematically classified by consensus level
|
|
33
|
+
- When okstra lead Phase 5.5 (convergence loop) begins — immediately after all workers complete Phases 4 and 5
|
|
34
|
+
- When findings need systematic classification by consensus level
|
|
36
35
|
|
|
37
36
|
## Configuration
|
|
38
37
|
|
|
@@ -64,7 +63,7 @@ Configure this in the `convergence` block of `task-manifest.json`. If the block
|
|
|
64
63
|
|
|
65
64
|
Read the worker result files generated in Phase 4/5 and extract individual findings.
|
|
66
65
|
|
|
67
|
-
**Convergence scope.** Convergence operates on sections 1–5 of the worker output (the common core, see
|
|
66
|
+
**Convergence scope.** Convergence operates on sections 1–5 of the worker output (the common core, see the worker preamble §"Worker output sections"). Section 6 ("Specialization Lens") is additive worker-specific depth and MUST NOT be fed into the consensus grouping, the verification queue, or the round-N reverify prompts. Carry Section 6 forward into the final report verbatim through the report-writer worker — do not let it inflate `unique` counts or trigger spurious `verification-error` statuses.
|
|
68
67
|
|
|
69
68
|
**Incremental re-verification scope (implementation-planning clarification re-runs).** When the lead's `okstra incremental-scope` decision is `mode == "incremental"` (procedure in `prompts/launch.template.md` §"Clarification Response Carried In"), only findings the lead attributes to a stage in `reverify_stages` enter the verification queue. Findings and plan-item verdicts carried forward for `carry_stages` are NOT re-queued — they skip the re-verification rounds entirely and are merged verbatim into this run's data.json via `okstra incremental-carry`. When the decision is `mode == "full"` (the default), every finding enters the queue as usual.
|
|
70
69
|
|
|
@@ -73,7 +72,7 @@ Read the worker result files generated in Phase 4/5 and extract individual findi
|
|
|
73
72
|
- For bullet/numbered findings, parse `[TICKETID: <id>]` from the item title.
|
|
74
73
|
- Items with multiple tickets (e.g. `TICKET-123, TICKET-456`) expand to a set of ticket keys.
|
|
75
74
|
- Items tagged `unknown` keep the literal `unknown` as their ticket key.
|
|
76
|
-
2. For each finding, record the summary, evidence (file path, line number, basis), the worker
|
|
75
|
+
2. For each finding, record the summary, evidence (file path, line number, basis), the discovering worker, **the worker-internal item ID that worker assigned** (e.g. `F-001`, `1.1`, `F-3` — see `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT), and the parsed ticket set. Persist the item ID as `findings[].discoveredBy.<worker>.itemId` and each cross-worker confirmation as `findings[].sourceItems[]` (one entry per contributing `<worker>:<item-id>` pair). The final-report `## 6.1 Consensus` / `## 6.2 Differences` / `## 2.1 Primary Evidence` tables read this verbatim into their `Source items` columns; without it the synthesised `C-NNN` row loses its link back to the original worker wording.
|
|
77
76
|
3. The lead groups findings based on semantic similarity AND ticket-set equality:
|
|
78
77
|
- Same semantics + same ticket set across 2+ workers → immediately reach `full consensus`.
|
|
79
78
|
- Same semantics but disjoint ticket sets → keep as separate groups (do NOT over-merge across tickets).
|
|
@@ -180,23 +179,15 @@ The exit conditions and final-classification rules are defined by the §"Converg
|
|
|
180
179
|
|
|
181
180
|
### Lightweight (Default)
|
|
182
181
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
Advantages: Fast and cost-effective
|
|
186
|
-
Disadvantages: Accuracy decreases if evidence is insufficient
|
|
182
|
+
Decide solely on the findings and evidence other reviewers present; do not reanalyze the original code or data. Fast and cost-effective, but accuracy drops when evidence is insufficient.
|
|
187
183
|
|
|
188
184
|
### Full Re-analysis (opt-in)
|
|
189
185
|
|
|
190
|
-
Use
|
|
191
|
-
|
|
192
|
-
Advantages: High accuracy
|
|
193
|
-
Disadvantages: 2–3 times the cost, increased time
|
|
186
|
+
Use each finding as a guide but reanalyze the original code/data yourself. High accuracy at 2–3× the cost and time.
|
|
194
187
|
|
|
195
188
|
## Adversarial Verification Mode
|
|
196
189
|
|
|
197
|
-
Active only when `config.adversarial == true` (default for `requirements-discovery`, `error-analysis`, and `implementation-planning`; see §"Configuration")
|
|
198
|
-
|
|
199
|
-
In adversarial mode the verifier's job inverts: instead of confirming a peer's finding, the verifier **tries to break it**, and the burden of proof sits on the claim — a finding survives only if refutation attempts fail.
|
|
190
|
+
Active only when `config.adversarial == true` (default for `requirements-discovery`, `error-analysis`, and `implementation-planning`; see §"Configuration"); when `false`, every rule in this section is inert and the collaborative behaviour elsewhere in this contract applies unchanged. In adversarial mode the verifier's job inverts: instead of confirming a peer's finding, the verifier **tries to break it**, and the burden of proof sits on the claim — a finding survives only if refutation attempts fail.
|
|
200
191
|
|
|
201
192
|
### Scoped full-reanalysis
|
|
202
193
|
|
|
@@ -246,7 +237,7 @@ ELSE:
|
|
|
246
237
|
|
|
247
238
|
`contested` remains a **final classification only** (per §"Scope and Terminology"): a disputed finding is carried forward through intermediate rounds and labelled `contested` only at the last executed round. For `requirements-discovery` (`effectiveMaxRounds = 1`) the single round IS the last round, so a split-with-hard-refute finding is labelled `contested` in that one round. The final-classifier block of §"Convergence Algorithm" is unchanged; this section only changes how each round's verdicts resolve into queue actions.
|
|
248
239
|
|
|
249
|
-
Design intent: one `counter-evidence` refute
|
|
240
|
+
Design intent: one `counter-evidence` refute denies a claim consensus (it cannot rise above `contested` however many others AGREE); a lone `burden-not-met` doubt does not sink an otherwise-surviving claim — only a majority of them does. When every non-discoverer refutes (all_others_disagree) the finding is worker-unique regardless of refute basis — only the discoverer still holds it. A SUPPLEMENT/caveat with zero disagrees lands partial-consensus, not full-consensus, because a caveat means the claim does not pass cleanly (unlike the collaborative classifier, where SUPPLEMENT counts as full agreement).
|
|
250
241
|
|
|
251
242
|
## Re-verification Dispatch
|
|
252
243
|
|
|
@@ -256,7 +247,6 @@ For each analysis worker with a non-empty current round's `items_for_W` batch, b
|
|
|
256
247
|
|
|
257
248
|
Call `await_workers(handles)` through the same adapter and apply the shared terminal-status/completion-path contract before counting a vote. The selected adapter owns native invocation spelling and any jobs-file/CLI fields. This contract owns only the reverify payload and verdict semantics.
|
|
258
249
|
|
|
259
|
-
|
|
260
250
|
**Completion detection per round (BLOCKING).** A dispatch acknowledgement is NOT completion — detect each round's completion via the SSOT protocol in [team-contract](./team-contract.md) "Worker-completion detection", with the pending set reconstructed from that round's dispatched workers' Result Paths. Do NOT end the turn with a prose "waiting" statement.
|
|
261
251
|
|
|
262
252
|
### Required reverify-prompt anchor headers (BLOCKING)
|
|
@@ -277,7 +267,7 @@ Assigned worker prompt history path: <Project Root>/<Prompt History Path>
|
|
|
277
267
|
2. `team-state-<task-type>-<seq>.json` → `workers[].usage.cliModel` for that role (initial run's actual execution value)
|
|
278
268
|
3. The `**Model:**` line of the initial Phase 4 prompt for that role (read from its persisted prompt-history file)
|
|
279
269
|
|
|
280
|
-
If none of the three is available, **abort the reverify dispatch for that role** and record a `contract-violation` event via `okstra error-log append-observed`. Do NOT guess or fall back to a runtime default. The selected adapter receives the exact value through the assignment and owns how it reaches the worker runtime. The current Codex catalog default is `gpt-5.6`, but that reference value never replaces the manifest assignment.
|
|
270
|
+
If none of the three is available, **abort the reverify dispatch for that role** and record a `contract-violation` event via `okstra error-log append-observed`. Do NOT guess or fall back to a runtime default. The selected adapter receives the exact value through the assignment and owns how it reaches the worker runtime. The current Codex catalog default is `gpt-5.6-sol`, but that reference value never replaces the manifest assignment.
|
|
281
271
|
|
|
282
272
|
### Reverify prompt: required-reading suppression
|
|
283
273
|
|
|
@@ -475,7 +465,7 @@ Save it to `runs/<task-type>/state/convergence-<task-type>-<seq>.json`.
|
|
|
475
465
|
}
|
|
476
466
|
```
|
|
477
467
|
|
|
478
|
-
>
|
|
468
|
+
> Abbreviated example: `findings[]` shows only `F-001` though `finalClassificationCounts` totals 7 — a real artifact has one `findings[]` entry per finding. This is a clean one-round queue-drained run; a Round 2 run adds a second `roundHistory[]` entry of the same shape.
|
|
479
469
|
|
|
480
470
|
Schema rules:
|
|
481
471
|
|
|
@@ -34,7 +34,7 @@ This document is the operating contract and phase index. Detailed procedures liv
|
|
|
34
34
|
| [plan-body-verification](./plan-body-verification.md) | Phase 6 plan-body verification sub-step (implementation-planning only) — plan-item extraction, verdict semantics, gate resolution, state schema. Read only at that sub-step |
|
|
35
35
|
| [report-writer](./report-writer.md) | Phase 6 final-report authorship, dispatch template, resume-safe dispatch, shared-graph integrity check, Phase 7 token-usage collector |
|
|
36
36
|
|
|
37
|
-
Read-side inspection (`/okstra-inspect`) and scheduling (`/okstra-schedule`) are user-invoked skills, not lead support contracts — the lead does not consult them during a run.
|
|
37
|
+
Read-side inspection (`/okstra-inspect`) and scheduling (`/okstra-schedule-gen`) are user-invoked skills, not lead support contracts — the lead does not consult them during a run.
|
|
38
38
|
|
|
39
39
|
## Quick Reference
|
|
40
40
|
|
|
@@ -82,13 +82,13 @@ Phase-transition checklist (lead, end of run):
|
|
|
82
82
|
|
|
83
83
|
User-utterance interpretation rule:
|
|
84
84
|
|
|
85
|
-
- "
|
|
85
|
+
- "proceed to the next step" / "move on to the next step" / equivalent phrases are scoped to **the current phase only**. Interpret them as "produce the remaining outputs of the current phase," never as "start the next lifecycle phase."
|
|
86
86
|
- If the current phase's outputs are already complete and the user clearly wants to advance, reply with the phase-transition checklist above and the exact next-run command. Wait for explicit user confirmation before any action that belongs to the next phase.
|
|
87
87
|
- If `nextRecommendedPhase` is `implementation-planning`, the next run produces a **plan**, not code. The next run after that is `implementation`.
|
|
88
88
|
|
|
89
89
|
## Progress reporting (BLOCKING)
|
|
90
90
|
|
|
91
|
-
A single okstra run frequently spans 30–120 minutes
|
|
91
|
+
A single okstra run frequently spans 30–120 minutes with multi-minute silent windows while workers run; without progress signals the user cannot distinguish "still working" from "hung". Lead MUST emit a single short progress line at each checkpoint below — plain user-facing text in a separate brief message (not buried inside a tool call), one line per checkpoint, format: `PROGRESS: <phase-id> <verb-phrase>`. Emit the line raw — the literal `PROGRESS:` token must begin the line. Do NOT wrap it in inline-code backticks (`` `PROGRESS: ...` ``) or a ```` ``` ```` code fence; markdown wrapping is what the post-hoc conformance validator scrapes around, and raw emit keeps the signal unambiguous.
|
|
92
92
|
|
|
93
93
|
Required checkpoints:
|
|
94
94
|
|
|
@@ -101,15 +101,15 @@ Required checkpoints:
|
|
|
101
101
|
- `PROGRESS: phase-5-collect worker=<role> status=<terminal-status>` — once per worker, immediately after the result file is verified.
|
|
102
102
|
- `PROGRESS: phase-5.5-convergence round=<N> queue=<count>` — at the start of each convergence round (Phase 5.5).
|
|
103
103
|
- `PROGRESS: phase-5.6-critic provider=<provider> gaps=<n>` — after the critic result is collected (Phase 5.6, opt-in; the critic dispatch itself fires concurrently with the first 5.5 reverify round). Omitted when `convergence.critic.enabled == false`.
|
|
104
|
-
- `PROGRESS: phase-batch-cleanup panes=<n> teammates=<m>` —
|
|
104
|
+
- `PROGRESS: phase-batch-cleanup panes=<n> teammates=<m>` — immediately after cleaning up the previous batch's panes and completed teammates, at each batch boundary (① just before the first `phase-5.5-convergence` round ② just before the `phase-6-synthesis` report-writer dispatch). Expose only the counts and NEVER expose `%NNN`/lead-pane.id/raw worker handles. Just before the first batch (analysis-worker dispatch) there is nothing to clean up, so it is a no-op and the marker is omitted.
|
|
105
105
|
- `PROGRESS: phase-6-synthesis dispatching report-writer-worker` — at the start of Phase 6.
|
|
106
106
|
- `PROGRESS: phase-7-persist updating manifests` — at the start of Phase 7.
|
|
107
107
|
- `PROGRESS: phase-7-teardown shutting-down-workers` — only after usage collection and user approval, immediately before `shutdown_workers`; omitted when no cleanup resource exists or the user keeps it.
|
|
108
108
|
- `PROGRESS: complete final-report=<relative-path>` — final summary line, after all persistence.
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
Do NOT replace them with prose ("Now I'm starting Phase 2..."), do NOT skip a checkpoint because "the previous message already said that", and do NOT batch multiple checkpoints into one. Each line stands alone so the user (or any operator scraping stdout) can timestamp it externally.
|
|
111
111
|
|
|
112
|
-
`okstra-run` surfaces these lines to the user directly; other launch paths persist them in the selected adapter's declared conformance evidence/event source for post-hoc retrieval.
|
|
112
|
+
`okstra-run` surfaces these lines to the user directly; other launch paths persist them in the selected adapter's declared conformance evidence/event source for post-hoc retrieval.
|
|
113
113
|
|
|
114
114
|
**Enforcement:** the Phase 7 validator (`validators/validate-run.py` → `validate_session_conformance.py`) reads the selected adapter's declared conformance evidence/event source within the run window and fails the run as `contract-violated` when a required checkpoint is missing — including the per-worker `phase-4-dispatch` / `phase-5-collect` lines (which must name each worker's role) and the `phase-batch-cleanup` lines that MUST precede the first `phase-5.5-convergence` round and the `phase-6-synthesis` report-writer dispatch. `phase-7-teardown` and `complete` fire after validation and are not checked.
|
|
115
115
|
|
|
@@ -126,7 +126,7 @@ The table below documents those prep-time seed values **for reference only** —
|
|
|
126
126
|
| Lead role | opus | -- | runtime-specific role label; orchestration + convergence supervision + final-report review/approval |
|
|
127
127
|
| Report writer worker | opus | report-writer-worker | `agents/workers/report-writer-worker.md` |
|
|
128
128
|
| Claude worker | opus | claude-worker | `agents/workers/claude-worker.md` |
|
|
129
|
-
| Codex worker | gpt-5.6 | codex-worker | generated from `agents/workers/_cli-wrapper-template.md` + `codex-worker.params.json` |
|
|
129
|
+
| Codex worker | gpt-5.6-sol | codex-worker | generated from `agents/workers/_cli-wrapper-template.md` + `codex-worker.params.json` |
|
|
130
130
|
| Antigravity worker | auto | antigravity-worker | generated from `agents/workers/_cli-wrapper-template.md` + `antigravity-worker.params.json` |
|
|
131
131
|
|
|
132
132
|
All three analysis workers use dedicated agent definitions; Codex/Antigravity wrappers handle external CLI invocation internally; Claude worker runs as an in-process subagent with explicitly registered MCP tools so it does not fall back to `claude --mcp-cli` Bash invocations.
|
|
@@ -138,7 +138,7 @@ For `--task-type implementation` runs, the task bundle additionally pins one of
|
|
|
138
138
|
- `instruction-set/analysis-profile.md` — top "Executor binding" block (provider, displayName, workerAgent, model)
|
|
139
139
|
- `runs/implementation/manifests/run-manifest-*.json` — `teamContract.executor` object (same fields plus `appliesTo: "implementation"`)
|
|
140
140
|
|
|
141
|
-
Lead MUST dispatch Edit/Write-bearing work only through the `workerAgent` declared there. The other two providers still run as read-only verifiers in the same run; the executor's own provider is *also* dispatched separately as a verifier
|
|
141
|
+
Lead MUST dispatch Edit/Write-bearing work only through the `workerAgent` declared there. The other two providers still run as read-only verifiers in the same run; the executor's own provider is *also* dispatched separately as a verifier in a fresh CLI session, so the diff is reviewed context-isolated. Session isolation is the primary self-review safeguard — same-model executor and same-provider verifier is acceptable in distinct sessions. A different model variant (e.g. executor=opus / Claude verifier=sonnet) is recommended but not mandatory.
|
|
142
142
|
|
|
143
143
|
Executor is chosen at run-prep time via `--executor <claude|codex|antigravity>` (or `OKSTRA_DEFAULT_EXECUTOR`, fallback `claude`); the model used by the executor is taken from the corresponding worker model flag (`--claude-model` / `--codex-model` / `--antigravity-model`). For CLI-backed executors, the underlying file mutation happens inside the executor CLI's own auto-edit mode (e.g. `codex exec --sandbox workspace-write`), not through the lead runtime's `write_artifact` operation.
|
|
144
144
|
|
|
@@ -164,7 +164,7 @@ Executor is chosen at run-prep time via `--executor <claude|codex|antigravity>`
|
|
|
164
164
|
|
|
165
165
|
Treat cross verify input as a task bundle, not as a single file. If the user did not specify an explicit task key or task path, use `.okstra/discovery/latest-task.json` as the current-task convenience pointer. If task browsing, task-id disambiguation, or project-level task inventory is needed, inspect `.okstra/discovery/task-catalog.json` first.
|
|
166
166
|
|
|
167
|
-
After context-loader completes, read **only the compact intake files below** in a single parallel-Read message at the start of Phase 1. The other instruction-set files are loaded lazily at the phase that actually needs them — see "Lazy reading discipline" below. This split exists because re-absorbing the full instruction-set baseline at every phase entry
|
|
167
|
+
After context-loader completes, read **only the compact intake files below** in a single parallel-Read message at the start of Phase 1. The other instruction-set files are loaded lazily at the phase that actually needs them — see "Lazy reading discipline" below. This split exists because re-absorbing the full instruction-set baseline at every phase entry is the dominant source of lead-token bloat — most of it is files only one downstream phase uses.
|
|
168
168
|
|
|
169
169
|
**Mandatory at Phase 1 start (parallel Read, one message):**
|
|
170
170
|
|
|
@@ -184,11 +184,11 @@ After context-loader completes, read **only the compact intake files below** in
|
|
|
184
184
|
|
|
185
185
|
**Implementation profile lazy reading discipline (BLOCKING — applies only when `task_type == "implementation"`):**
|
|
186
186
|
|
|
187
|
-
The `implementation` profile's thin core (`prompts/profiles/implementation.md`) is intentionally minimal so the Phase 1 baseline stays small. Three sidecar files carry the bulk of the rules and MUST be read at the listed phase — do NOT pre-load them at Phase 1. The sidecar list and each one's `Read at` phase live in
|
|
187
|
+
The `implementation` profile's thin core (`prompts/profiles/implementation.md`) is intentionally minimal so the Phase 1 baseline stays small. Three sidecar files carry the bulk of the rules and MUST be read at the listed phase — do NOT pre-load them at Phase 1. The sidecar list and each one's `Read at` phase live in that profile's "Lazy section pointers" table, which arrives in the Phase 1 intake via `analysis-profile.md`, so it is already in context whenever this discipline applies.
|
|
188
188
|
|
|
189
|
-
**Entry guard (BLOCKING).** Before transitioning into Phase 5 or Phase 6 for an `implementation` run, lead MUST emit a single Read tool call for the sidecar(s) whose `Read at` (per that table) matches the entering phase. If lead enters the phase without that Read recorded in the selected adapter's conformance evidence/event source, phase
|
|
189
|
+
**Entry guard (BLOCKING).** Before transitioning into Phase 5 or Phase 6 for an `implementation` run, lead MUST emit a single Read tool call for the sidecar(s) whose `Read at` (per that table) matches the entering phase. If lead enters the phase without that Read recorded in the selected adapter's conformance evidence/event source, phase entry is refused — lead writes a `contract-violation` to the run-level errors log with `--message "implementation-sidecar-not-loaded"` and stops. Re-entry requires the sidecar Read first. **Enforcement:** the Phase 7 validator (`validate_session_conformance.py`) verifies post-hoc that all three sidecar Reads exist in the selected adapter's declared source within this run's window, and that they precede the `phase-6-synthesis` / `phase-7-persist` checkpoints respectively.
|
|
190
190
|
|
|
191
|
-
The guard is not satisfied by
|
|
191
|
+
The guard is not satisfied by memory from a prior run — each implementation run re-reads the sidecar fresh, since `okstra install` may have updated it between runs.
|
|
192
192
|
|
|
193
193
|
This pattern is implementation-only. Other profiles (`requirements-discovery`, `error-analysis`, `implementation-planning`, `final-verification`, `release-handoff`) load their whole profile body at Phase 1 as before — they are short enough not to benefit from a split.
|
|
194
194
|
|
|
@@ -229,7 +229,7 @@ The launch prompt's `## Run Logs (error-log wiring)` section gives Lead the reso
|
|
|
229
229
|
- `**Errors log path:** <absolute run-level errors log path from launch prompt>`
|
|
230
230
|
- `**Errors sidecar path:** <absolute per-worker sidecar path matching the dispatched worker>`
|
|
231
231
|
|
|
232
|
-
Workers are contractually required to extract these two lines and abort with `<WORKER>_ERRORS_PATH_MISSING` if either is absent (see each worker definition's "Path extraction (BLOCKING)" block). Omitting these headers reproduces the historical bug
|
|
232
|
+
Workers are contractually required to extract these two lines and abort with `<WORKER>_ERRORS_PATH_MISSING` if either is absent (see each worker definition's "Path extraction (BLOCKING)" block). Omitting these headers reproduces the historical bug where every run's `errors-<task-type>-<seq>.jsonl` stayed empty (workers had only template placeholders).
|
|
233
233
|
|
|
234
234
|
After each worker terminates, BEFORE classifying its terminal status, verify the canonical result file exists at the absolute path resolved from the `**Result Path:**` header. If it is absent — or the wrapper sub-agent returned `CODEX_RESULT_MISSING` / `ANTIGRAVITY_RESULT_MISSING` — re-dispatch the SAME worker once with the byte-identical prompt. Only after the second attempt also misses may the role be classified `error` with `--message "result-missing after 1 retry"`. Full rules: [team-contract](./team-contract.md) "Lead Redispatch Policy on Result-Missing".
|
|
235
235
|
|
|
@@ -283,7 +283,7 @@ Before constructing the dispatch prompt, the lead MUST:
|
|
|
283
283
|
`**Report Language:**` in the report-writer dispatch prompt, and ensure
|
|
284
284
|
the worker writes the same value into `data.json.meta.reportLanguage`.
|
|
285
285
|
|
|
286
|
-
|
|
286
|
+
The convergence output provides four finding categories:
|
|
287
287
|
|
|
288
288
|
1. Full Consensus
|
|
289
289
|
2. Partial Consensus
|
|
@@ -298,7 +298,7 @@ If only one worker result is usable: reduced-confidence synthesis. If evidence i
|
|
|
298
298
|
|
|
299
299
|
After the Report writer worker draft is reviewed (or after the lead-authored fallback completes), **if** `task_type == "implementation-planning"` **and** `task-manifest.json` `convergence.planBodyVerification.enabled == true` (default), the lead MUST run one additional verification round on the consolidated plan body before declaring Phase 6 complete and entering Phase 7.
|
|
300
300
|
|
|
301
|
-
This is a Phase 6 sub-step — it does NOT introduce a new top-level lifecycle phase
|
|
301
|
+
This is a Phase 6 sub-step — it does NOT introduce a new top-level lifecycle phase; the lead operating-phase model (Phase 1 Intake → Phase 7 Persist, labels in the "Quick Reference" table above as the single source of truth) is preserved. `okstra-inspect status` exposes it as a `planVerification` sub-field of the implementation-planning phase, not a separate lifecycle phase identifier.
|
|
302
302
|
|
|
303
303
|
**REQUIRED RESOURCE:** Read [plan-body-verification](./plan-body-verification.md) for the round protocol, plan-item ID scheme (`P-Opt-*` / `P-Step-*` / `P-Dep-*` / `P-Val-*` / `P-Rb-*`), verdict semantics (`AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT`), classification rules, gate-result resolution, and the state-file schema at `runs/<task-type>/state/plan-body-verification.json`.
|
|
304
304
|
|
|
@@ -320,8 +320,6 @@ Lead's responsibilities in this sub-step (in order):
|
|
|
320
320
|
|
|
321
321
|
If `convergence.planBodyVerification.enabled == false` (set by `--no-plan-verification` or by `okstra config set plan-verification off`), the entire sub-step is skipped and the top-of-report Approval marker is rendered unconditionally (legacy behaviour). This opt-out is intended for fast iteration only and is not recommended for handoff-ready plans.
|
|
322
322
|
|
|
323
|
-
The `okstra-inspect status` sub-command exposes the sub-step's state as a `planVerification` sub-field of the implementation-planning phase, not as a separate lifecycle phase identifier.
|
|
324
|
-
|
|
325
323
|
## Phase 7: Artifact persistence and validator handoff
|
|
326
324
|
|
|
327
325
|
The detailed persistence checklist and the BLOCKING token-usage collector invocation live in [report-writer](./report-writer.md). Persist the run yourself — do not assume okstra saves the final artifacts for you.
|
|
@@ -350,7 +348,7 @@ jq -s 'group_by(.errorType) | map({type: .[0].errorType, count: length})' <runDi
|
|
|
350
348
|
|
|
351
349
|
The errors log is informational. Its presence/absence does not affect the final verdict. Do not block report writing on it.
|
|
352
350
|
|
|
353
|
-
After persistence, reply briefly in the resolved Report Language with: completion status, final report path, team-state path, validator result, resume command path, any remaining blocker. **Lead this reply with the run's task identity** — state `<task-group>/<task-id>` (or the full `taskKey`) first, so the reader knows which task the reply is about. **Every run-artifact path in this reply MUST be task-qualified** — report the final report as `.okstra/tasks/<task-group>/<task-id>/runs/<task-type>/reports/final-report-<task-type>-<seq>.md`
|
|
351
|
+
After persistence, reply briefly in the resolved Report Language with: completion status, final report path, team-state path, validator result, resume command path, any remaining blocker. **Lead this reply with the run's task identity** — state `<task-group>/<task-id>` (or the full `taskKey`) first, so the reader knows which task the reply is about. **Every run-artifact path in this reply MUST be task-qualified** — report the final report as `.okstra/tasks/<task-group>/<task-id>/runs/<task-type>/reports/final-report-<task-type>-<seq>.md` rooted at the task bundle, NOT the bare `runs/<task-type>/reports/...` form (byte-for-byte identical across every task of the same task-type, so it cannot identify the task). The same task-qualified rule applies to the team-state path, resume command path, and any other run-artifact path this reply cites.
|
|
354
352
|
|
|
355
353
|
## Run-scoped worker-resource lifecycle
|
|
356
354
|
|
|
@@ -60,12 +60,15 @@ From the report-writer's draft of `## 5.4 Implementation Plan Deliverables`, lea
|
|
|
60
60
|
| `P-Val-<N>` | `4.5.6 Validation Checklist` | one checklist item |
|
|
61
61
|
| `P-Rb-<N>` | `4.5.7 Rollback Strategy` | one rollback path |
|
|
62
62
|
| `P-Req-<N>` | `4.5.8 Requirement Coverage` | one requirement coverage row |
|
|
63
|
+
| `P-Prep-S<stage>-<kind>` | Stage `designSurfaceCoverage` + `5.5.10 Implementation Design Preparation` | exactly one detector-produced `(stage, kind)` |
|
|
63
64
|
|
|
64
65
|
`4.5.2 Trade-off Matrix` and `4.5.3 Recommended Option` are NOT extracted as standalone plan items — the trade-off matrix is evaluated implicitly through each option's `P-Opt-*` verification, and the recommended option is one of those `P-Opt-*` rows.
|
|
65
66
|
|
|
66
67
|
Each plan item inherits the `[TICKETID: ...]` tag of its source section (per the standard ticket-tagging contract).
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
For every detector-produced `(stage, kind)`, extract exactly one plan item named `P-Prep-S<stage>-<kind>`. The V1 detector in `scripts/okstra_ctl/design_surfaces.py` owns the set: extraction consumes its output and never reruns a free-form requirements or keyword analysis. The worker receives the stage trigger evidence and its single `designSurfaceCoverage` row, plus only the referenced `designPreparation` PREP items needed to judge that row. `validators/validate-run.py` `_validate_expected_prep_plan_items` enforces the exact ID set and `_validate_detector_coverage` enforces exactly-once coverage/evidence.
|
|
70
|
+
|
|
71
|
+
When extracting each item, lead also captures a **`subject`** — a plain one-line label (≤12 words) describing *what that item is* in the reader's terms, e.g. `P-Opt-1` → "Option A: split upload v2 into a new module", `P-Step-1.1` → "Stage 1 Step 2: regression-check with `npm run test:v2`". This is a label-capture, not new analysis. The `subject` is what §5.5.9 renders as the per-item heading so the reader knows *what* each AGREE/DISAGREE is about without cross-referencing §4.5; a bare `P-*` ID with no subject is a contract violation. **Enforced:** `validators/validate-run.py` `_validate_plan_item_subject_substance` fails a subject that is a placeholder — under 3 chars, equal to the item id, or shaped like a bare `P-*` id.
|
|
69
72
|
|
|
70
73
|
## Plan-body verdict semantics
|
|
71
74
|
|
|
@@ -80,10 +83,19 @@ The verdict tokens `AGREE` / `DISAGREE` / `SUPPLEMENT` are reused, but their mea
|
|
|
80
83
|
- `e` — item contradicts the trade-off matrix
|
|
81
84
|
- `f` — requirement coverage row cites no concrete option / stage / step, cites a non-existent option / stage / step, or marks a requirement `covered` while the cited plan item does not satisfy the row's stated requirement. A row that cites an existing option / stage / step is concrete for this purpose even if that option's File Structure paths are abbreviated — path imprecision inside the cited option is kind `b` on that option's own item, not `f` on the coverage row.
|
|
82
85
|
- **SUPPLEMENT**: the item is sound but is missing a dependency / edge case / precondition.
|
|
83
|
-
- **fixability** (DISAGREE
|
|
84
|
-
- `planner-fixable` —
|
|
85
|
-
- `needs-user-input` —
|
|
86
|
-
|
|
86
|
+
- **fixability** (DISAGREE-only, required): each `DISAGREE(<kind>)` judges whether the defect can be fixed using only the code you have now + this plan draft + the brief.
|
|
87
|
+
- `planner-fixable` — resolved by correcting the plan itself without external information (abbreviated paths, prose commands, placeholders, requirement-coverage remapping, citing a non-existent stage, etc.).
|
|
88
|
+
- `needs-user-input` — the fix requires an open user clarification (infrastructure / contract decision) or external information.
|
|
89
|
+
One-line criterion: "Can this defect be fixed using only the code I have now + the plan + the brief?" — if so, `planner-fixable`. **Enforced:** `validators/validate-run.py` `_validate_disagree_has_fixability` fails, on a run where the verification round ran (`roundCount >= 1`), any `DISAGREE` verdict whose `fixability` is missing or not one of the allowed values (`planner-fixable` / `needs-user-input`) — so that `_validate_self_fix_before_clarification` cannot let a mislabelled planner-fixable defect be promoted without a self-fix.
|
|
90
|
+
|
|
91
|
+
`P-Prep-S<stage>-<kind>` applies the same verdict tokens and adds these disposition checks:
|
|
92
|
+
|
|
93
|
+
- `inline-contract`: AGREE only when the contract contains the kind-specific fields needed to implement the stage; a label or generic prose is insufficient.
|
|
94
|
+
- `prep-item`: AGREE only when every referenced PREP item has a concrete `aiProposal`, correct `stageRefs`/`kind`, and state-specific safeguards required by `schemas/final-report-v1.0.schema.json`.
|
|
95
|
+
- `not-applicable`: AGREE only when the rationale is consistent with the stage action; otherwise DISAGREE with `fixability` (`planner-fixable` when the plan can supply the missing contract, `needs-user-input` only for genuinely external facts).
|
|
96
|
+
- A declared `blocked` item is not itself a plan-body failure. Missing or duplicate coverage, an empty proposal, a mismatched reference, or an unjustified disposition is a failure and receives `DISAGREE(<kind>)` with `fixability`.
|
|
97
|
+
|
|
98
|
+
The semantic checks above are the plan-body enforcement layer for the schema-valid structures; `validators/validate-run.py` enforces detector coverage and references, while this worker verdict decides whether the content is implementable.
|
|
87
99
|
|
|
88
100
|
Worker non-result handling (`timeout`, `error`, no result file, wrapper `cli-failure`) is identical to finding convergence: do NOT aggregate as DISAGREE, record `contract-violation`, and apply the round-level abort rule below.
|
|
89
101
|
|
|
@@ -121,19 +133,20 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
121
133
|
- any `partial-consensus` / `dissent-isolated` present, no `majority-disagree` → `passed-with-dissent`
|
|
122
134
|
- all items `full-consensus` → `passed`
|
|
123
135
|
6. Lead writes `runs/<task-type>/state/plan-body-verification-<task-type>-<seq>.json` (schema below) and populates `### 5.5.9 Plan Body Verification` in the final report's data.json (`implementationPlanning.planBodyVerification`, schema `schemas/final-report-v1.0.schema.json`; template at `templates/reports/final-report.template.md`). The §5.5.9 body is **grouped by plan item**: `planItems[]`, each carrying its `id`, its plain-language `subject` (rendered as the item heading), an optional `sourceSection`, an optional `clarificationId` (the `C-<N>` this item blocks on when `majority-disagree`), and a `verdicts[]` list (`worker / verdict / breakageKind / note`) — one verdict row per worker under that item. The renderer prints three fixed legends (gate values, verdict tokens, breakage kinds a–f) so the reader can decode every cell without opening this spec. The older flat `#### Verdict details` table (`Plan item / Worker / …`, one row per plan-item × worker pair) is superseded by the grouped layout — it hid *what* each vote was about behind a bare `P-*` ID; the subject heading is the fix. The validator's `Plan Body Verification` + `Gate result:` substring checks still gate this section.
|
|
124
|
-
7. **Self-fix round (
|
|
125
|
-
- lead
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
136
|
+
7. **Self-fix round (at most once, targeting planner-fixable defects).** After aggregation, if at least one `majority-disagree` item has a majority of its `DISAGREE` verdicts at `fixability == planner-fixable`, lead attempts one self-fix **before** promoting it to the user:
|
|
137
|
+
- lead instructs report-writer to rewrite only those planner-fixable items for correction (NOT a full draft regeneration — patch only the plan section each `P-*` points to; procedure in [report-writer](./report-writer.md) §"Self-fix rewrite").
|
|
138
|
+
- missing or weak `P-Prep-*` contracts are repaired by adding kind-specific inline detail or an AI-prepared PREP item with a concrete proposal. Facts that require user or external authority remain `blocked` and keep their request material; never invent those facts during self-fix.
|
|
139
|
+
- lead re-runs plan-body verification once (focused on the corrected items + adjacent items the rewrite touched). After re-verification, overwrite `planItems[].verdicts` with the new verdicts.
|
|
140
|
+
- for an item whose `majority-disagree` was resolved by self-fix, record `self-fixed in round <N>: <what was fixed>` in `planItems[].selfFixNote`. A resolved item does not create a clarification.
|
|
141
|
+
- this round runs **at most once** (infinite-loop cap). If a self-fix round was attempted, record `planBodyVerification.selfFixRoundApplied = true`.
|
|
142
|
+
- a `majority-disagree` item with a majority of `needs-user-input` is NOT a self-fix target — it goes straight to the next step's clarification promotion.
|
|
143
|
+
8. For every `majority-disagree` item **that remains after the self-fix round** (items not resolved by self-fix, or with a `needs-user-input` majority from the start), lead adds a row to `## 1. Clarification Items` with:
|
|
131
144
|
- new `C-<N>` ID (numbering continues from any existing rows)
|
|
132
145
|
- `Statement` summarising the disagreement and the worker breakage `<kind>`
|
|
133
146
|
- `Kind` chosen per the standard policy (usually `decision` for option-level conflicts, `data-point` for path/symbol mismatches)
|
|
134
147
|
- `Blocks=approval`
|
|
135
148
|
- the item's `planItems[].clarificationId` set to that `C-<N>` (1:1 link). `validators/validate-run.py` `_validate_plan_body_clarification_matching` recomputes each item's class and fails when a majority-disagree item's `clarificationId` is missing, dangling, or points at a non-`approval` row.
|
|
136
|
-
- self-fix
|
|
149
|
+
- a `planner-fixable` item that survives the self-fix round is still promoted, but its `Statement` MUST state "planner self-fix attempted but unresolved" (the cap prevents repeating the rewrite). `validators/validate-run.py` `_validate_self_fix_before_clarification` fails when `selfFixRoundApplied != true` yet a planner-fixable majority item is promoted.
|
|
137
150
|
9. The top-of-report `- [ ] Approved` marker line is rendered if and only if the Gate result is `passed` or `passed-with-dissent`. `validators/validate-run.py` `validate_phase_boundary` enforces this correspondence; manually adding the marker line when the gate did not pass is a contract violation.
|
|
138
151
|
|
|
139
152
|
## `plan-body-verification-<task-type>-<seq>.json` schema
|
|
@@ -151,7 +164,7 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
151
164
|
"planItems": [
|
|
152
165
|
{
|
|
153
166
|
"id": "P-Opt-1",
|
|
154
|
-
"subject": "Option A: upload v2
|
|
167
|
+
"subject": "Option A: split upload v2 into a new module",
|
|
155
168
|
"sourceSection": "4.5.1",
|
|
156
169
|
"ticketId": "<id-or-unknown>",
|
|
157
170
|
"votes": {"claude-worker": "AGREE", "codex-worker": "AGREE"},
|
|
@@ -160,7 +173,7 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
160
173
|
},
|
|
161
174
|
{
|
|
162
175
|
"id": "P-Step-3",
|
|
163
|
-
"subject": "Stage 2 Step 3:
|
|
176
|
+
"subject": "Stage 2 Step 3: run migration then regression test",
|
|
164
177
|
"sourceSection": "4.5.4",
|
|
165
178
|
"ticketId": "TICKET-123",
|
|
166
179
|
"votes": {"claude-worker": "DISAGREE(a)", "codex-worker": "DISAGREE(a)"},
|
|
@@ -180,7 +193,7 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
180
193
|
|
|
181
194
|
`planItems[].votes.<worker>` is the verbatim verdict token emitted by the worker — `AGREE | DISAGREE(<a|b|c|d|e|f>) | SUPPLEMENT` — or `verification-error` for terminal non-result dispatches. The `DISAGREE` token retains its `<kind>` suffix so the breakage class is recoverable from the state file alone.
|
|
182
195
|
|
|
183
|
-
`planBodyVerification.selfFixRoundApplied` (bool,
|
|
196
|
+
`planBodyVerification.selfFixRoundApplied` (bool, default false): whether a self-fix round was attempted at least once. `planItems[].verdicts[].fixability` is each `DISAGREE`'s `planner-fixable | needs-user-input` judgement, recorded in the final data.json (`§5.5.9`).
|
|
184
197
|
|
|
185
198
|
## Plan-body reverify prompt
|
|
186
199
|
|
|
@@ -204,7 +217,7 @@ verdict:
|
|
|
204
217
|
(d) rollback violates commit / dependency order,
|
|
205
218
|
(e) item contradicts the trade-off matrix,
|
|
206
219
|
(f) requirement coverage row does not map the stated requirement to a concrete satisfying option / stage / step — citing an existing option counts as concrete even if that option's paths are abbreviated (that is (b) on the option's item, not (f)).
|
|
207
|
-
DISAGREE
|
|
220
|
+
When you give a DISAGREE, also answer **Fixability** — `planner-fixable` if this defect can be fixed using only the code + this plan draft + the brief, `needs-user-input` if an open user clarification / external information is required.
|
|
208
221
|
- **SUPPLEMENT**: The item is sound but a dependency / edge case / precondition
|
|
209
222
|
is missing.
|
|
210
223
|
|
|
@@ -217,6 +230,11 @@ against the cited plan item(s). Do not open the original brief, but do reject
|
|
|
217
230
|
coverage rows that cite no concrete option/stage/step or cite a plan item that
|
|
218
231
|
does not satisfy the row's own requirement.
|
|
219
232
|
|
|
233
|
+
For each `P-Prep-S<stage>-<kind>` item, use only the supplied detector trigger
|
|
234
|
+
evidence, its single `designSurfaceCoverage` row, and referenced PREP items.
|
|
235
|
+
Apply the disposition-specific AGREE/DISAGREE rules in this contract; do not
|
|
236
|
+
rerun a free-form requirements analysis. Every DISAGREE includes Fixability.
|
|
237
|
+
|
|
220
238
|
## Plan items to verify
|
|
221
239
|
|
|
222
240
|
### P-Step-3 [TICKETID: <id>]: <one-line summary>
|
|
@@ -232,15 +250,26 @@ does not satisfy the row's own requirement.
|
|
|
232
250
|
### P-Opt-2 [TICKETID: <id>]: <one-line summary>
|
|
233
251
|
...
|
|
234
252
|
|
|
253
|
+
### P-Prep-S2-external-interface [TICKETID: <id>]: <one-line summary>
|
|
254
|
+
**From section**: Stage 2 designSurfaceCoverage + 5.5.10 Implementation Design Preparation
|
|
255
|
+
**Trigger evidence**: <detector-produced evidence rows>
|
|
256
|
+
**Coverage row**: <the single designSurfaceCoverage row>
|
|
257
|
+
**Referenced PREP items**: <verbatim referenced items, or none>
|
|
258
|
+
|
|
235
259
|
## Response format
|
|
236
260
|
|
|
237
261
|
### P-Step-3
|
|
238
262
|
**Verdict**: AGREE | DISAGREE(<a|b|c|d|e|f>) | SUPPLEMENT
|
|
239
|
-
**Fixability** (
|
|
263
|
+
**Fixability** (only when DISAGREE): planner-fixable | needs-user-input — "planner-fixable if it can be fixed using only the code + this plan + the brief"
|
|
240
264
|
**Explanation**: <2-3 sentences>
|
|
241
265
|
|
|
242
266
|
### P-Opt-2
|
|
243
267
|
...
|
|
268
|
+
|
|
269
|
+
### P-Prep-S2-external-interface
|
|
270
|
+
**Verdict**: AGREE | DISAGREE(<a|b|c|d|e|f>) | SUPPLEMENT
|
|
271
|
+
**Fixability** (DISAGREE only): planner-fixable | needs-user-input
|
|
272
|
+
**Explanation**: <2-3 sentences applying the disposition-specific rule>
|
|
244
273
|
```
|
|
245
274
|
|
|
246
275
|
When `config.adversarial == true`, the lead prepends the adversarial framing from §"Adversarial plan-body posture" to the `## Instructions` block: the burden of proof is on the plan, the verifier opens and confirms every cited path / command, and an item whose cited references cannot be confirmed is answered `DISAGREE(<kind>)` rather than `AGREE`. The verdict tokens, breakage kinds (a–f), classification, and the majority gate threshold are unchanged. This prepended framing supersedes the template's "Judge solely from plan internal consistency" instruction for the adversarial round.
|