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.
Files changed (98) hide show
  1. package/README.md +1 -0
  2. package/docs/architecture/storage-model.md +3 -1
  3. package/docs/architecture.md +16 -2
  4. package/docs/cli.md +3 -1
  5. package/docs/for-ai/README.md +41 -35
  6. package/docs/for-ai/skills/okstra-brief-gen.md +105 -105
  7. package/docs/for-ai/skills/okstra-container-build.md +61 -61
  8. package/docs/for-ai/skills/okstra-graphify.md +64 -0
  9. package/docs/for-ai/skills/okstra-inspect.md +87 -86
  10. package/docs/for-ai/skills/okstra-manager.md +32 -32
  11. package/docs/for-ai/skills/okstra-memory.md +49 -50
  12. package/docs/for-ai/skills/okstra-pr-gen.md +48 -0
  13. package/docs/for-ai/skills/okstra-rollup.md +58 -58
  14. package/docs/for-ai/skills/okstra-run.md +95 -95
  15. package/docs/for-ai/skills/okstra-schedule-gen.md +106 -106
  16. package/docs/for-ai/skills/okstra-setup.md +63 -64
  17. package/docs/for-ai/skills/okstra-user-response.md +48 -0
  18. package/docs/performance-improvement-plan-v2.md +6 -6
  19. package/docs/pr-template-usage.md +34 -34
  20. package/docs/project-structure-overview.md +91 -70
  21. package/docs/task-process/README.md +33 -33
  22. package/docs/task-process/common-flow.md +26 -26
  23. package/docs/task-process/error-analysis.md +20 -21
  24. package/docs/task-process/final-verification.md +41 -41
  25. package/docs/task-process/implementation-planning.md +33 -33
  26. package/docs/task-process/implementation.md +38 -38
  27. package/docs/task-process/release-handoff.md +46 -46
  28. package/docs/task-process/requirements-discovery.md +22 -23
  29. package/package.json +1 -1
  30. package/runtime/BUILD.json +2 -2
  31. package/runtime/agents/workers/antigravity-worker.md +4 -4
  32. package/runtime/agents/workers/claude-worker.md +2 -2
  33. package/runtime/agents/workers/codex-worker.md +4 -4
  34. package/runtime/agents/workers/report-writer-worker.md +4 -4
  35. package/runtime/bin/lib/okstra/usage.sh +1 -1
  36. package/runtime/prompts/coding-preflight/frameworks/node-server.md +1 -1
  37. package/runtime/prompts/launch.template.md +1 -1
  38. package/runtime/prompts/lead/convergence.md +10 -20
  39. package/runtime/prompts/lead/okstra-lead-contract.md +15 -17
  40. package/runtime/prompts/lead/plan-body-verification.md +18 -18
  41. package/runtime/prompts/lead/report-writer.md +46 -44
  42. package/runtime/prompts/lead/team-contract.md +11 -122
  43. package/runtime/prompts/profiles/_common-contract.md +15 -22
  44. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  45. package/runtime/prompts/profiles/_implementation-executor.md +1 -1
  46. package/runtime/prompts/profiles/_implementation-verifier.md +28 -2
  47. package/runtime/prompts/profiles/error-analysis.md +2 -2
  48. package/runtime/prompts/profiles/final-verification.md +1 -1
  49. package/runtime/prompts/profiles/implementation-planning.md +13 -13
  50. package/runtime/prompts/profiles/implementation.md +2 -1
  51. package/runtime/prompts/profiles/improvement-discovery.md +1 -1
  52. package/runtime/prompts/profiles/release-handoff.md +3 -3
  53. package/runtime/prompts/profiles/requirements-discovery.md +17 -18
  54. package/runtime/python/okstra_ctl/models.py +4 -2
  55. package/runtime/python/okstra_ctl/run.py +8 -2
  56. package/runtime/python/okstra_ctl/stage_fix_carry.py +112 -0
  57. package/runtime/schemas/final-report-v1.0.schema.json +6 -6
  58. package/runtime/skills/_fragments/bash-invocation-rule.md +1 -0
  59. package/runtime/skills/_fragments/preflight-outdated-cli.md +1 -0
  60. package/runtime/skills/_fragments/python-bootstrap-note.md +1 -0
  61. package/runtime/skills/okstra-brief-gen/SKILL.md +117 -122
  62. package/runtime/skills/okstra-container-build/SKILL.md +24 -14
  63. package/runtime/skills/okstra-graphify/SKILL.md +12 -4
  64. package/runtime/skills/okstra-inspect/SKILL.md +39 -747
  65. package/runtime/skills/okstra-inspect/facets/cost.md +84 -0
  66. package/runtime/skills/okstra-inspect/facets/error-zip.md +41 -0
  67. package/runtime/skills/okstra-inspect/facets/errors.md +69 -0
  68. package/runtime/skills/okstra-inspect/facets/history.md +90 -0
  69. package/runtime/skills/okstra-inspect/facets/logs.md +89 -0
  70. package/runtime/skills/okstra-inspect/facets/recap.md +96 -0
  71. package/runtime/skills/okstra-inspect/facets/report.md +61 -0
  72. package/runtime/skills/okstra-inspect/facets/status.md +145 -0
  73. package/runtime/skills/okstra-inspect/facets/time.md +56 -0
  74. package/runtime/skills/okstra-manager/SKILL.md +1 -1
  75. package/runtime/skills/okstra-memory/SKILL.md +3 -3
  76. package/runtime/skills/okstra-pr-gen/SKILL.md +3 -3
  77. package/runtime/skills/okstra-rollup/SKILL.md +12 -6
  78. package/runtime/skills/okstra-run/SKILL.md +49 -88
  79. package/runtime/skills/okstra-schedule-gen/SKILL.md +36 -30
  80. package/runtime/skills/okstra-setup/SKILL.md +1 -1
  81. package/runtime/skills/okstra-setup/references/project-config.md +17 -16
  82. package/runtime/skills/okstra-usage/SKILL.md +5 -2
  83. package/runtime/skills/okstra-user-response/SKILL.md +15 -3
  84. package/runtime/templates/prd/brief.template.md +92 -92
  85. package/runtime/templates/project-docs/task-index.template.md +1 -1
  86. package/runtime/templates/reports/error-analysis-input.template.md +1 -1
  87. package/runtime/templates/reports/fan-out-unit.template.md +6 -6
  88. package/runtime/templates/reports/final-verification-input.template.md +6 -6
  89. package/runtime/templates/reports/implementation-input.template.md +1 -1
  90. package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
  91. package/runtime/templates/reports/improvement-discovery-input.template.md +1 -1
  92. package/runtime/templates/reports/quick-input.template.md +1 -1
  93. package/runtime/templates/reports/release-handoff-input.template.md +1 -1
  94. package/runtime/templates/reports/schedule.template.md +22 -22
  95. package/runtime/templates/reports/task-brief.template.md +3 -3
  96. package/runtime/templates/reports/user-response.template.md +20 -20
  97. package/runtime/templates/worker-prompt-preamble.md +111 -13
  98. package/runtime/validators/validate-schedule.py +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.123.0",
3
- "builtAt": "2026-07-17T16:03:35.624Z",
2
+ "package": "0.125.0",
3
+ "builtAt": "2026-07-19T16:21:54.855Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -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 copied verbatim from the `**Model:** Antigravity worker, <execution-value>` line in the lead prompt (per Worker Preamble → "Return message to the lead"):
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. The main Antigravity output MUST NOT contain a `## 0. Reading Confirmation` heading — the validator fails worker-results that contain one. If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
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) plus the team-contract resource (`prompts/lead/team-contract.md`) "Worker Output Contract": 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.
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 `prompts/lead/team-contract.md` "Worker Output Contract".
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 sections** contract in the preamble you Read via the `**Worker Preamble Path:**` anchor: YAML frontmatter, then sections 1–5 (common core) plus optional Section 6 (your specialization lens), every item carrying a unique worker-internal item ID, with ticket tagging on `requirements-discovery` / `error-analysis` / `implementation-planning` / `implementation` runs. Set `workerId: "claude"`. The full frontmatter schema, item-ID conventions, and authoritative section ordering live in the team-contract resource (`prompts/lead/team-contract.md`) "Worker Output Contract" — the SSOT if anything is ambiguous.
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, copied verbatim from the `**Model:** Claude worker, <modelExecutionValue>` line in your dispatch prompt (per Worker Preamble → "Return message to the lead"), then the status line — for an analysis dispatch:
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 copied verbatim from the `**Model:** Codex worker, <execution-value>` line in the lead prompt (per Worker Preamble → "Return message to the lead"):
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. The main Codex output MUST NOT contain a `## 0. Reading Confirmation` heading — the validator fails worker-results that contain one. If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
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) plus the team-contract resource (`prompts/lead/team-contract.md`) "Worker Output Contract": 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.
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 `prompts/lead/team-contract.md` "Worker Output Contract".
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`. The main final-report and the main worker-results file MUST NOT contain a `## 0. Reading Confirmation` heading. If you cannot truthfully confirm a file end-to-end, record a `tool-failure` in the errors sidecar instead of fabricating the report.
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 추가 자료 요청`, no `5.2 사용자 확인 질문` — clarifications go under the unified `clarificationItems[]` array.
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** lives in the audit sidecar (`runs/<task-type>/worker-results/report-writer-worker-audit-<task-type>-<seq>.md`), never in the data.json or the main worker-results file.
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, copied verbatim from the `**Model:** Report writer worker, <modelExecutionValue>` line in your dispatch prompt (per Worker Preamble → "Return message to the lead"):
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 lead model default
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 "다음 단계 진행해" or similar.
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. 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") are unchanged by this contract. The lead operating phases (Phase 1 Intake → Phase 7 Persist, see [okstra-lead-contract](./okstra-lead-contract.md) "Quick Reference") describe how the lead drives a *single* task-type run.
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
- - Immediately after all workers have completed Phases 4 and 5
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 `team-contract` "Worker Output Contract"). 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.
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 who identified it, **the worker-internal item ID assigned by that worker** (e.g. `F-001`, `1.1`, `F-3` — see `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT), and the parsed ticket set. The item ID is persisted on the finding record as `findings[].discoveredBy.<worker>.itemId` and on each cross-worker confirmation as `findings[].sourceItems[]` (one entry per contributing `<worker>:<item-id>` pair). The final-report's `## 6.1 Consensus` / `## 6.2 Differences` / `## 2.1 Primary Evidence` tables read this list verbatim into their `Source items` columns without this, the synthesised `C-NNN` row has no traceable link back to the original worker wording.
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
- Decisions are made based solely on the findings and evidence presented by other reviewers. The original code or data is not reanalyzed.
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 the findings as a guide, but reanalyze the original code/data yourself.
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"). When `false`, every rule in this section is inert and the collaborative behaviour documented elsewhere in this contract applies unchanged.
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 is enough to deny a claim consensus (it cannot rise above `contested` no matter how many others AGREE), while a single `burden-not-met` doubt does not by itself sink an otherwise-surviving claim — only a majority of burden-not-met doubts does. When every non-discoverer refutes (all_others_disagree), the finding is worker-unique regardless of whether those refutes were counter-evidence or burden-not-met — only the discoverer still holds it. A SUPPLEMENT/caveat with zero disagrees lands partial-consensus rather than full-consensus, because a caveat means the claim does not pass cleanly (this differs from the collaborative classifier, where SUPPLEMENT counts as full agreement).
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
- > The example above shows an abbreviated artifact: the `findings[]` array contains only `F-001` even though `finalClassificationCounts` totals 7 — a real artifact has one `findings[]` entry per finding. The example uses a clean one-round queue-drained run for clarity; runs that hit Round 2 add a second `roundHistory[]` entry with the same shape.
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
- - "다음 단계 진행해" / "proceed 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."
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 of wall-clock time with multi-minute silent windows while workers run. Without explicit progress signals the user cannot distinguish "still working" from "hung", so Lead MUST emit a single short progress line at each of the checkpoints below — as 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.
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>` — 이전 배치 pane·완료 teammate 정리한 직후, 배치 경계에서(① `phase-5.5-convergence` round 직전 ② `phase-6-synthesis` report-writer dispatch 직전). 카운트만 노출하고 `%NNN`/lead-pane.id/raw worker handle 절대 노출하지 않는다. 배치(분석 워커 dispatch) 직전엔 치울 없어 no-op 이며 마커도 생략.
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
- These lines are the only structured signal the user has during a long run. 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.
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. No path requires additional formatting from Lead — emit the literal `PROGRESS:` prefix and the rest of the line as plain text.
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 | opus | report-writer-worker | `agents/workers/report-writer-worker.md` |
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 (a fresh CLI session) so the diff is reviewed by a context-isolated session. Session isolation is the primary self-review safeguard — same-model executor and same-provider verifier is acceptable when running in distinct sessions. Selecting a different model variant (e.g. executor=opus / Claude verifier=sonnet) is recommended but no longer mandatory.
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 was the dominant observed source of lead-token bloat — most of that baseline is files only one downstream phase ever uses.
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 the profile's "Lazy section pointers" table (`prompts/profiles/implementation.md`) — the profile arrives in the Phase 1 intake via `analysis-profile.md`, so that table is already in context whenever this discipline applies.
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 진입 거부 — 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.
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 remembering content from a prior run — each implementation run reads the sidecar fresh, because the sidecars are part of the runtime shipped via `okstra install` and may have been updated between runs.
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 class where every run's `errors-<task-type>-<seq>.jsonl` stayed empty because workers had only template placeholders to work from.
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
- Do not write the final verdict until every analysis worker role has either a saved result or a terminal status entry. The convergence output provides four finding categories:
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. The lead operating-phase model (Phase 1 Intake → Phase 7 Persist, with the labels in the "Quick Reference" table above as the single source of truth) is preserved.
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` (the full path rooted at the task bundle), NOT the bare `runs/<task-type>/reports/...` form. The bare `runs/...` prefix is byte-for-byte identical across every task-group / task-id of the same task-type, so it cannot tell one task's report from another's — always emit the `.okstra/tasks/<task-group>/<task-id>/` prefix. The same task-qualified rule applies to the team-state path, resume command path, and any other run-artifact path this reply cites.
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 신규 모듈로 분리", `P-Step-1.1` → "Stage 1 Step 2: `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.
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 전용, 필수): `DISAGREE(<kind>)` 결함을 지금 가진 코드 + 계획 draft + brief 만으로 고칠 있는지 판정한다.
87
- - `planner-fixable` — 외부 정보 없이 계획 자체를 교정하면 해소된다(경로 축약, prose command, placeholder, requirement-coverage 재매핑, 존재하지 않는 stage 인용 등).
88
- - `needs-user-input` — 교정에 열린 사용자 clarification(인프라·계약 결정) 또는 외부 정보가 필요하다.
89
- 기준 줄: "지금 가진 코드 + 계획 + brief 만으로 결함을 고칠 있는가?" — 그렇다면 `planner-fixable`. **Enforced:** `validators/validate-run.py` `_validate_disagree_has_fixability` verification round (`roundCount >= 1`) run 에서 `fixability` 없거나 허용값(`planner-fixable` / `needs-user-input`) 아닌 `DISAGREE` verdict 를 실패시킨다 — 그래야 `_validate_self_fix_before_clarification` mislabel planner-fixable 결함을 self-fix 없이 승격시키지 못한다.
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 (최대 1회, planner-fixable 결함 대상).** aggregation `majority-disagree` 항목 `DISAGREE` verdict 다수가 `fixability == planner-fixable` 항목이 하나 이상이면, lead 사용자에게 승격하기 **전에** 자가수정을 1회 시도한다:
137
- - lead report-writer 에게 planner-fixable 항목들만 교정 재작성을 지시한다(전체 draft 재생성 아님 해당 `P-*` 가리키는 계획 섹션만 patch; 절차는 [report-writer](./report-writer.md) §"Self-fix rewrite").
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 regenerationpatch 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 plan-body 검증을 1회 재실행한다(교정된 항목 + 재작성이 건드린 인접 항목 중심). 재검증 verdict `planItems[].verdicts` 덮어쓴다.
140
- - self-fix `majority-disagree` 해소된 항목은 `planItems[].selfFixNote` `self-fixed in round <N>: <무엇을 고쳤는지>` 기록한다. 해소된 항목은 clarification 만들지 않는다.
141
- - 라운드는 **최대 1회**다(무한루프 상한). self-fix 라운드를 시도했으면 `planBodyVerification.selfFixRoundApplied = true` 로 기록한다.
142
- - `needs-user-input` 다수인 `majority-disagree` 항목은 self-fix 대상이 아니다 곧바로 다음 step clarification 승격으로 간다.
143
- 8. For every `majority-disagree` item **that remains after the self-fix round** (self-fix 해소되지 않았거나 처음부터 `needs-user-input` 다수인 항목), lead adds a row to `## 1. Clarification Items` with:
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 targetit 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 라운드를 거치고도 남은 `planner-fixable` 항목은 승격하되 `Statement` "planner self-fix 시도했으나 미해소" 를 명시한다(상한 때문에 재작성을 반복하지 않는다). `validators/validate-run.py` `_validate_self_fix_before_clarification` `selfFixRoundApplied != true` 인데 planner-fixable 다수 항목이 승격되면 실패시킨다.
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, 기본 false): self-fix 라운드를 1회라도 시도했는지. `planItems[].verdicts[].fixability` `DISAGREE` `planner-fixable | needs-user-input` 판정으로, 최종 data.json(`§5.5.9`)에 기록된다.
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 때는 **Fixability** 함께 답하라 결함을 코드 + 계획 draft + brief 만으로 고칠 있으면 `planner-fixable`, 열린 사용자 clarification / 외부 정보가 필요하면 `needs-user-input`.
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** (DISAGREE 때만): planner-fixable | needs-user-input — "코드 + 계획 + brief 만으로 고칠 있으면 planner-fixable"
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