okstra 0.123.0 → 0.125.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 +1 -0
- package/docs/architecture/storage-model.md +3 -1
- package/docs/architecture.md +16 -2
- package/docs/cli.md +3 -1
- package/docs/for-ai/README.md +41 -35
- 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 +87 -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 +106 -106
- 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 +6 -6
- package/docs/pr-template-usage.md +34 -34
- package/docs/project-structure-overview.md +91 -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 +33 -33
- package/docs/task-process/implementation.md +38 -38
- 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 +1 -1
- package/runtime/prompts/coding-preflight/frameworks/node-server.md +1 -1
- package/runtime/prompts/launch.template.md +1 -1
- package/runtime/prompts/lead/convergence.md +10 -20
- package/runtime/prompts/lead/okstra-lead-contract.md +15 -17
- package/runtime/prompts/lead/plan-body-verification.md +18 -18
- package/runtime/prompts/lead/report-writer.md +46 -44
- 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 +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +1 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +28 -2
- package/runtime/prompts/profiles/error-analysis.md +2 -2
- package/runtime/prompts/profiles/final-verification.md +1 -1
- package/runtime/prompts/profiles/implementation-planning.md +13 -13
- package/runtime/prompts/profiles/implementation.md +2 -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 +17 -18
- package/runtime/python/okstra_ctl/models.py +4 -2
- package/runtime/python/okstra_ctl/run.py +8 -2
- package/runtime/python/okstra_ctl/stage_fix_carry.py +112 -0
- package/runtime/schemas/final-report-v1.0.schema.json +6 -6
- 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 +39 -747
- package/runtime/skills/okstra-inspect/facets/cost.md +84 -0
- package/runtime/skills/okstra-inspect/facets/error-zip.md +41 -0
- package/runtime/skills/okstra-inspect/facets/errors.md +69 -0
- package/runtime/skills/okstra-inspect/facets/history.md +90 -0
- package/runtime/skills/okstra-inspect/facets/logs.md +89 -0
- package/runtime/skills/okstra-inspect/facets/recap.md +96 -0
- package/runtime/skills/okstra-inspect/facets/report.md +61 -0
- package/runtime/skills/okstra-inspect/facets/status.md +145 -0
- package/runtime/skills/okstra-inspect/facets/time.md +56 -0
- package/runtime/skills/okstra-manager/SKILL.md +1 -1
- package/runtime/skills/okstra-memory/SKILL.md +3 -3
- package/runtime/skills/okstra-pr-gen/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-gen/SKILL.md +36 -30
- 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 +15 -3
- package/runtime/templates/prd/brief.template.md +92 -92
- package/runtime/templates/project-docs/task-index.template.md +1 -1
- 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-verification-input.template.md +6 -6
- 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-schedule.py +1 -1
package/runtime/BUILD.json
CHANGED
|
@@ -106,7 +106,7 @@ The wrapper exists because Claude Code's Bash permission matcher rejects simple-
|
|
|
106
106
|
2. Record a `cli-failure` event directly to the run-level error log via the exact `okstra error-log append-observed` template in §"Error reporting" — substitute `--exit-code 0`, `--duration-ms <observed-ms>`, `--message "okstra-antigravity-exec.sh exited 0 but no result file at <abs-path>"`, and `--stderr-excerpt-file <temp-tail-path>`.
|
|
107
107
|
3. Return `ANTIGRAVITY_RESULT_MISSING: agy exited 0 but result file absent at <abs-path>` instead of the raw stdout. The lead is responsible for deciding redispatch per `team-contract` "Lead Redispatch Policy on Result-Missing".
|
|
108
108
|
|
|
109
|
-
d. **Normal return.** Otherwise (`exit_code == 0` AND result file exists), return the wrapper's accumulated stdout from `BashOutput`, prefixed by exactly one model-identity line
|
|
109
|
+
d. **Normal return.** Otherwise (`exit_code == 0` AND result file exists), return the wrapper's accumulated stdout from `BashOutput`, prefixed by exactly one model-identity line per the preamble §"Return message to the lead":
|
|
110
110
|
```
|
|
111
111
|
**Model:** Antigravity worker, <assigned-model-execution-value>
|
|
112
112
|
```
|
|
@@ -151,11 +151,11 @@ Before invoking the Antigravity CLI, you MUST:
|
|
|
151
151
|
1. Extract the absolute path from the lead's `**Worker Preamble Path:**` anchor header and verify the CLI run will Read that file end-to-end (canonical SSOT for the Required Reading + Error Reporting + Output sections contract). The lead's prompt body — which you persist verbatim and feed into Antigravity via stdin — already contains this anchor; do not strip it.
|
|
152
152
|
2. Verify the lead's prompt body lists the per-run primary input files under `## Inputs` (normally `analysis-packet.md` for analysis workers). The source files named inside that packet are fallback/evidence paths to open when needed. Analysis workers do NOT read `final-report-template.md` — that file is for the report writer only.
|
|
153
153
|
|
|
154
|
-
The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/antigravity-worker-audit-<task-type>-<seq>.md`. The sidecar's body begins with `# Antigravity Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading.
|
|
154
|
+
The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/antigravity-worker-audit-<task-type>-<seq>.md`. The sidecar's body begins with `# Antigravity Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading. Section-0 placement follows the worker preamble §"Reading rules" (canonical). If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
|
|
155
155
|
|
|
156
156
|
## Worker Output Structure
|
|
157
157
|
|
|
158
|
-
The Antigravity CLI — not this wrapper — produces the worker result. Its required structure is defined in the preamble (the lead injects the `**Worker Preamble Path:**` anchor into the dispatched prompt you persist and forward, and the CLI Reads it)
|
|
158
|
+
The Antigravity CLI — not this wrapper — produces the worker result. Its required structure is defined in the preamble (the lead injects the `**Worker Preamble Path:**` anchor into the dispatched prompt you persist and forward, and the CLI Reads it): YAML frontmatter with `workerId: "antigravity"`, sections 1–5 (common core) plus optional Section 6, a unique item ID on every item, and ticket tagging on `requirements-discovery` / `error-analysis` / `implementation-planning` / `implementation` runs. This wrapper forwards the CLI's output unmodified except for the single `**Model:**` line (step 8d) — never reshape or summarize it.
|
|
159
159
|
|
|
160
160
|
## Error reporting
|
|
161
161
|
|
|
@@ -219,7 +219,7 @@ pre-flight terminal status, not a runtime CLI error.
|
|
|
219
219
|
- Always specify the assigned `--model` value for the current run.
|
|
220
220
|
- Return error messages as-is on failure.
|
|
221
221
|
- Do not summarize or modify Antigravity results beyond prepending the single `**Model:**` line on a normal return (step 8d).
|
|
222
|
-
- Sections 1–5 of the worker output are the common core shared with the Claude and Codex workers — the dispatched prompt asks identical questions for all three roles, and the Antigravity CLI must answer all of them, not only requirement-interpretation findings. Your specialization (requirement interpretation, consistency, safety, documentation quality, alternative viewpoints) belongs only in optional Section 6 as additive depth. A Antigravity result whose Findings section is populated solely with requirement-interpretation items is in breach of contract; see
|
|
222
|
+
- Sections 1–5 of the worker output are the common core shared with the Claude and Codex workers — the dispatched prompt asks identical questions for all three roles, and the Antigravity CLI must answer all of them, not only requirement-interpretation findings. Your specialization (requirement interpretation, consistency, safety, documentation quality, alternative viewpoints) belongs only in optional Section 6 as additive depth. A Antigravity result whose Findings section is populated solely with requirement-interpretation items is in breach of contract; see the preamble §"Worker output sections".
|
|
223
223
|
|
|
224
224
|
## Stage evidence emission (BLOCKING, implementation task only)
|
|
225
225
|
|
|
@@ -70,7 +70,7 @@ Before producing any output, you MUST:
|
|
|
70
70
|
|
|
71
71
|
## Worker Output Structure
|
|
72
72
|
|
|
73
|
-
Follow the **Worker output
|
|
73
|
+
Follow the **Worker output contract** in the preamble you Read via the `**Worker Preamble Path:**` anchor — it is the canonical source for the frontmatter schema, sections 1–5 + optional Section 6 ordering, item-ID conventions, and ticket tagging. Set `workerId: "claude"`.
|
|
74
74
|
|
|
75
75
|
## Stop Condition (BLOCKING)
|
|
76
76
|
|
|
@@ -78,7 +78,7 @@ When Lead dispatches you with `run_in_background: true`, its `Agent()` call retu
|
|
|
78
78
|
|
|
79
79
|
After your `Write` to the assigned worker-results file (path provided by Lead as `**Result Path:**` — the canonical anchor header defined in `team-contract` "Worker Prompt Composition" — or derived under `runs/<task-type>/worker-results/claude-worker-<task-type>-<seq>.md`) succeeds:
|
|
80
80
|
|
|
81
|
-
1. Return your final assistant message **immediately**. Begin every return with your model identity,
|
|
81
|
+
1. Return your final assistant message **immediately**. Begin every return with your model identity, per the preamble §"Return message to the lead", then the status line — for an analysis dispatch:
|
|
82
82
|
```
|
|
83
83
|
**Model:** Claude worker, <modelExecutionValue>
|
|
84
84
|
Worker results written to <abs path>. Sections 1–5 complete. Findings: <n>.
|
|
@@ -106,7 +106,7 @@ The wrapper exists because Claude Code's Bash permission matcher rejects simple-
|
|
|
106
106
|
2. Record a `cli-failure` event directly to the run-level error log via the exact `okstra error-log append-observed` template in §"Error reporting" — substitute `--exit-code 0`, `--duration-ms <observed-ms>`, `--message "okstra-codex-exec.sh exited 0 but no result file at <abs-path>"`, and `--stderr-excerpt-file <temp-tail-path>`.
|
|
107
107
|
3. Return `CODEX_RESULT_MISSING: codex exited 0 but result file absent at <abs-path>` instead of the raw stdout. The lead is responsible for deciding redispatch per `team-contract` "Lead Redispatch Policy on Result-Missing".
|
|
108
108
|
|
|
109
|
-
d. **Normal return.** Otherwise (`exit_code == 0` AND result file exists), return the wrapper's accumulated stdout from `BashOutput`, prefixed by exactly one model-identity line
|
|
109
|
+
d. **Normal return.** Otherwise (`exit_code == 0` AND result file exists), return the wrapper's accumulated stdout from `BashOutput`, prefixed by exactly one model-identity line per the preamble §"Return message to the lead":
|
|
110
110
|
```
|
|
111
111
|
**Model:** Codex worker, <assigned-model-execution-value>
|
|
112
112
|
```
|
|
@@ -151,11 +151,11 @@ Before invoking the Codex CLI, you MUST:
|
|
|
151
151
|
1. Extract the absolute path from the lead's `**Worker Preamble Path:**` anchor header and verify the CLI run will Read that file end-to-end (canonical SSOT for the Required Reading + Error Reporting + Output sections contract). The lead's prompt body — which you persist verbatim and feed into Codex via stdin — already contains this anchor; do not strip it.
|
|
152
152
|
2. Verify the lead's prompt body lists the per-run primary input files under `## Inputs` (normally `analysis-packet.md` for analysis workers). The source files named inside that packet are fallback/evidence paths to open when needed. Analysis workers do NOT read `final-report-template.md` — that file is for the report writer only.
|
|
153
153
|
|
|
154
|
-
The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/codex-worker-audit-<task-type>-<seq>.md`. The sidecar's body begins with `# Codex Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading.
|
|
154
|
+
The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/codex-worker-audit-<task-type>-<seq>.md`. The sidecar's body begins with `# Codex Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading. Section-0 placement follows the worker preamble §"Reading rules" (canonical). If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
|
|
155
155
|
|
|
156
156
|
## Worker Output Structure
|
|
157
157
|
|
|
158
|
-
The Codex CLI — not this wrapper — produces the worker result. Its required structure is defined in the preamble (the lead injects the `**Worker Preamble Path:**` anchor into the dispatched prompt you persist and forward, and the CLI Reads it)
|
|
158
|
+
The Codex CLI — not this wrapper — produces the worker result. Its required structure is defined in the preamble (the lead injects the `**Worker Preamble Path:**` anchor into the dispatched prompt you persist and forward, and the CLI Reads it): YAML frontmatter with `workerId: "codex"`, sections 1–5 (common core) plus optional Section 6, a unique item ID on every item, and ticket tagging on `requirements-discovery` / `error-analysis` / `implementation-planning` / `implementation` runs. This wrapper forwards the CLI's output unmodified except for the single `**Model:**` line (step 8d) — never reshape or summarize it.
|
|
159
159
|
|
|
160
160
|
## Error reporting
|
|
161
161
|
|
|
@@ -219,7 +219,7 @@ pre-flight terminal status, not a runtime CLI error.
|
|
|
219
219
|
- Ignore stderr warnings from MCP integration.
|
|
220
220
|
- Return error messages as-is on failure.
|
|
221
221
|
- Do not summarize or modify Codex results beyond prepending the single `**Model:**` line on a normal return (step 8d).
|
|
222
|
-
- Sections 1–5 of the worker output are the common core shared with the Claude and Antigravity workers — the dispatched prompt asks identical questions for all three roles, and the Codex CLI must answer all of them, not only implementation-feasibility findings. Your specialization (implementation realism, code-path implications, edge cases, technical trade-offs) belongs only in optional Section 6 as additive depth. A Codex result whose Findings section is populated solely with implementation-feasibility items is in breach of contract; see
|
|
222
|
+
- Sections 1–5 of the worker output are the common core shared with the Claude and Antigravity workers — the dispatched prompt asks identical questions for all three roles, and the Codex CLI must answer all of them, not only implementation-feasibility findings. Your specialization (implementation realism, code-path implications, edge cases, technical trade-offs) belongs only in optional Section 6 as additive depth. A Codex result whose Findings section is populated solely with implementation-feasibility items is in breach of contract; see the preamble §"Worker output sections".
|
|
223
223
|
|
|
224
224
|
## Stage evidence emission (BLOCKING, implementation task only)
|
|
225
225
|
|
|
@@ -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>
|
|
@@ -93,7 +93,7 @@ options:
|
|
|
93
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
|
-
Model for report writer worker. Default: OKSTRA_DEFAULT_REPORT_WRITER_MODEL or
|
|
96
|
+
Model for report writer worker. Default: OKSTRA_DEFAULT_REPORT_WRITER_MODEL or sonnet
|
|
97
97
|
--lead-runtime Lead runtime adapter. Default: claude-code.
|
|
98
98
|
codex is currently render-only and records Codex adapter
|
|
99
99
|
metadata in prepared artifacts without dispatching workers.
|
|
@@ -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}}
|
|
@@ -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)
|
|
@@ -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
|
|
|
@@ -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
|
|
|
@@ -124,7 +124,7 @@ The table below documents those prep-time seed values **for reference only** —
|
|
|
124
124
|
| Role | Seed model | Worker assignment | Source definition |
|
|
125
125
|
|------|-----------|---------------|-------------------|
|
|
126
126
|
| Lead role | opus | -- | runtime-specific role label; orchestration + convergence supervision + final-report review/approval |
|
|
127
|
-
| Report writer worker |
|
|
127
|
+
| Report writer worker | sonnet | report-writer-worker | `agents/workers/report-writer-worker.md` |
|
|
128
128
|
| Claude worker | opus | claude-worker | `agents/workers/claude-worker.md` |
|
|
129
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` |
|
|
@@ -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
|
|
|
@@ -68,7 +68,7 @@ Each plan item inherits the `[TICKETID: ...]` tag of its source section (per the
|
|
|
68
68
|
|
|
69
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
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: upload v2
|
|
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.
|
|
72
72
|
|
|
73
73
|
## Plan-body verdict semantics
|
|
74
74
|
|
|
@@ -83,10 +83,10 @@ The verdict tokens `AGREE` / `DISAGREE` / `SUPPLEMENT` are reused, but their mea
|
|
|
83
83
|
- `e` — item contradicts the trade-off matrix
|
|
84
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.
|
|
85
85
|
- **SUPPLEMENT**: the item is sound but is missing a dependency / edge case / precondition.
|
|
86
|
-
- **fixability** (DISAGREE
|
|
87
|
-
- `planner-fixable` —
|
|
88
|
-
- `needs-user-input` —
|
|
89
|
-
|
|
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
90
|
|
|
91
91
|
`P-Prep-S<stage>-<kind>` applies the same verdict tokens and adds these disposition checks:
|
|
92
92
|
|
|
@@ -133,20 +133,20 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
133
133
|
- any `partial-consensus` / `dissent-isolated` present, no `majority-disagree` → `passed-with-dissent`
|
|
134
134
|
- all items `full-consensus` → `passed`
|
|
135
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.
|
|
136
|
-
7. **Self-fix round (
|
|
137
|
-
- lead
|
|
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
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
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
- `needs-user-input`
|
|
143
|
-
8. For every `majority-disagree` item **that remains after the self-fix round** (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:
|
|
144
144
|
- new `C-<N>` ID (numbering continues from any existing rows)
|
|
145
145
|
- `Statement` summarising the disagreement and the worker breakage `<kind>`
|
|
146
146
|
- `Kind` chosen per the standard policy (usually `decision` for option-level conflicts, `data-point` for path/symbol mismatches)
|
|
147
147
|
- `Blocks=approval`
|
|
148
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.
|
|
149
|
-
- 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.
|
|
150
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.
|
|
151
151
|
|
|
152
152
|
## `plan-body-verification-<task-type>-<seq>.json` schema
|
|
@@ -164,7 +164,7 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
164
164
|
"planItems": [
|
|
165
165
|
{
|
|
166
166
|
"id": "P-Opt-1",
|
|
167
|
-
"subject": "Option A: upload v2
|
|
167
|
+
"subject": "Option A: split upload v2 into a new module",
|
|
168
168
|
"sourceSection": "4.5.1",
|
|
169
169
|
"ticketId": "<id-or-unknown>",
|
|
170
170
|
"votes": {"claude-worker": "AGREE", "codex-worker": "AGREE"},
|
|
@@ -173,7 +173,7 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
"id": "P-Step-3",
|
|
176
|
-
"subject": "Stage 2 Step 3:
|
|
176
|
+
"subject": "Stage 2 Step 3: run migration then regression test",
|
|
177
177
|
"sourceSection": "4.5.4",
|
|
178
178
|
"ticketId": "TICKET-123",
|
|
179
179
|
"votes": {"claude-worker": "DISAGREE(a)", "codex-worker": "DISAGREE(a)"},
|
|
@@ -193,7 +193,7 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
|
|
|
193
193
|
|
|
194
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.
|
|
195
195
|
|
|
196
|
-
`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`).
|
|
197
197
|
|
|
198
198
|
## Plan-body reverify prompt
|
|
199
199
|
|
|
@@ -217,7 +217,7 @@ verdict:
|
|
|
217
217
|
(d) rollback violates commit / dependency order,
|
|
218
218
|
(e) item contradicts the trade-off matrix,
|
|
219
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)).
|
|
220
|
-
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.
|
|
221
221
|
- **SUPPLEMENT**: The item is sound but a dependency / edge case / precondition
|
|
222
222
|
is missing.
|
|
223
223
|
|
|
@@ -260,7 +260,7 @@ rerun a free-form requirements analysis. Every DISAGREE includes Fixability.
|
|
|
260
260
|
|
|
261
261
|
### P-Step-3
|
|
262
262
|
**Verdict**: AGREE | DISAGREE(<a|b|c|d|e|f>) | SUPPLEMENT
|
|
263
|
-
**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"
|
|
264
264
|
**Explanation**: <2-3 sentences>
|
|
265
265
|
|
|
266
266
|
### P-Opt-2
|