okstra 0.48.0 → 0.50.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 (60) hide show
  1. package/docs/kr/architecture.md +8 -8
  2. package/docs/kr/cli.md +2 -2
  3. package/docs/project-structure-overview.md +3 -3
  4. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +323 -0
  5. package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +559 -0
  6. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +87 -0
  7. package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +121 -0
  8. package/docs/task-process/error-analysis.md +1 -1
  9. package/docs/task-process/final-verification.md +1 -1
  10. package/docs/task-process/release-handoff.md +1 -1
  11. package/docs/task-process/requirements-discovery.md +1 -1
  12. package/package.json +1 -1
  13. package/runtime/BUILD.json +2 -2
  14. package/runtime/agents/SKILL.md +3 -3
  15. package/runtime/agents/workers/claude-worker.md +1 -1
  16. package/runtime/agents/workers/codex-worker.md +1 -1
  17. package/runtime/agents/workers/gemini-worker.md +1 -1
  18. package/runtime/agents/workers/report-writer-worker.md +3 -3
  19. package/runtime/bin/lib/okstra/tmux-pane.sh +40 -0
  20. package/runtime/bin/okstra-codex-exec.sh +17 -21
  21. package/runtime/bin/okstra-gemini-exec.sh +12 -15
  22. package/runtime/bin/okstra-render-report-views.py +1 -1
  23. package/runtime/bin/okstra-trace-cleanup.sh +13 -1
  24. package/runtime/prompts/launch.template.md +1 -1
  25. package/runtime/prompts/profiles/_common-contract.md +15 -15
  26. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  27. package/runtime/prompts/profiles/_implementation-executor.md +1 -1
  28. package/runtime/prompts/profiles/_implementation-verifier.md +1 -1
  29. package/runtime/prompts/profiles/error-analysis.md +1 -1
  30. package/runtime/prompts/profiles/final-verification.md +2 -2
  31. package/runtime/prompts/profiles/implementation-planning.md +9 -9
  32. package/runtime/prompts/profiles/improvement-discovery.md +5 -5
  33. package/runtime/prompts/profiles/release-handoff.md +2 -2
  34. package/runtime/prompts/profiles/requirements-discovery.md +2 -2
  35. package/runtime/python/okstra_ctl/clarification_items.py +11 -11
  36. package/runtime/python/okstra_ctl/render.py +1 -1
  37. package/runtime/python/okstra_ctl/render_final_report.py +1 -1
  38. package/runtime/python/okstra_ctl/report_views.py +26 -39
  39. package/runtime/python/okstra_ctl/run.py +3 -3
  40. package/runtime/python/okstra_ctl/wizard.py +90 -3
  41. package/runtime/python/okstra_ctl/workflow.py +1 -1
  42. package/runtime/skills/okstra-brief/SKILL.md +1 -1
  43. package/runtime/skills/okstra-convergence/SKILL.md +8 -8
  44. package/runtime/skills/okstra-report-writer/SKILL.md +22 -22
  45. package/runtime/skills/okstra-run/SKILL.md +2 -0
  46. package/runtime/skills/okstra-team-contract/SKILL.md +1 -1
  47. package/runtime/templates/project-docs/task-index.template.md +1 -8
  48. package/runtime/templates/reports/final-report.template.md +194 -198
  49. package/runtime/templates/reports/i18n/en.json +16 -17
  50. package/runtime/templates/reports/i18n/ko.json +16 -17
  51. package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
  52. package/runtime/templates/reports/release-handoff-input.template.md +1 -1
  53. package/runtime/templates/reports/schedule.template.md +3 -7
  54. package/runtime/templates/reports/user-response.template.md +1 -1
  55. package/runtime/templates/worker-prompt-preamble.md +1 -1
  56. package/runtime/validators/lib/fixtures.sh +2 -2
  57. package/runtime/validators/validate-implementation-plan-stages.py +9 -9
  58. package/runtime/validators/validate-report-views.py +10 -10
  59. package/runtime/validators/validate-run.py +36 -36
  60. package/runtime/validators/validate_improvement_report.py +8 -8
@@ -760,7 +760,7 @@ If the list is non-empty, run **one** `AskUserQuestion`:
760
760
  1. `Yes — collect now (Recommended)` — proceed to 6.5c.
761
761
  2. `No — leave for the downstream phase` — set
762
762
  `reporter-confirmations: skipped`. The phase will promote each
763
- pending row into its own `## 5. Clarification Items` as
763
+ pending row into its own `## 1. Clarification Items` as
764
764
  `Blocks=next-phase` (`Blocks=approval` only in
765
765
  `implementation-planning`); see each phase profile's "Brief
766
766
  consumption" addendum.
@@ -77,7 +77,7 @@ Read the worker result files generated in Phase 4/5 and extract individual findi
77
77
  - For bullet/numbered findings, parse `[TICKETID: <id>]` from the item title.
78
78
  - Items with multiple tickets (e.g. `TICKET-123, TICKET-456`) expand to a set of ticket keys.
79
79
  - Items tagged `unknown` keep the literal `unknown` as their ticket key.
80
- 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 `## 1.1 Consensus` / `## 1.2 Differences` / `## 3.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.
80
+ 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.
81
81
  3. Claude Lead groups findings based on semantic similarity AND ticket-set equality:
82
82
  - Same semantics + same ticket set across 2+ workers → immediately reach `full consensus`.
83
83
  - Same semantics but disjoint ticket sets → keep as separate groups (do NOT over-merge across tickets).
@@ -561,12 +561,12 @@ existing Acceptance Blocker. If you find none, say so explicitly.
561
561
  ### Verification — confirm-or-downgrade (BLOCKING)
562
562
 
563
563
  Each candidate blocker is verified by the Phase 4 analysers (excluding the critic). Do NOT use the adversarial finding classifier's "uncertain → reject" rule here.
564
- - **Confirmed** (an analyser reproduces it or cites supporting evidence) → promote to a `## 4 Acceptance Blockers` row (keep severity + recommended follow-up phase).
564
+ - **Confirmed** (an analyser reproduces it or cites supporting evidence) → promote to a `## 5.8 Acceptance Blockers` row (keep severity + recommended follow-up phase).
565
565
  - **Not confirmed** (cannot reproduce, or evidence is weak) → **downgrade to a Residual Risk row — never drop it.** Record the escalation trigger so the user can re-judge a high-severity-but-unconfirmed candidate.
566
566
 
567
567
  ### Verdict impact
568
568
 
569
- Promoted blockers enter `## 4 Acceptance Blockers`; since `accepted` requires zero blockers, the verdict moves to `conditional-accept` / `blocked` automatically. The existing verdict↔blocker consistency validator (`validators/validate-run.py` `_validate_final_verification_consistency`) enforces this unchanged — no new enum or validator.
569
+ Promoted blockers enter `## 5.8 Acceptance Blockers`; since `accepted` requires zero blockers, the verdict moves to `conditional-accept` / `blocked` automatically. The existing verdict↔blocker consistency validator (`validators/validate-run.py` `_validate_final_verification_consistency`) enforces this unchanged — no new enum or validator.
570
570
 
571
571
  ### State
572
572
 
@@ -630,7 +630,7 @@ Default values are emitted into the manifest by `scripts/okstra_ctl/render.py` (
630
630
 
631
631
  ### Plan-item extraction (Round 0 equivalent)
632
632
 
633
- From the report-writer's draft of `## 4.5 Implementation Plan Deliverables`, lead extracts plan items with the following prefixes (see also `templates/reports/final-report.template.md` §4.5.9):
633
+ From the report-writer's draft of `## 5.5 Implementation Plan Deliverables`, lead extracts plan items with the following prefixes (see also `templates/reports/final-report.template.md` §5.5.9):
634
634
 
635
635
  | Prefix | Source sub-section | One row per |
636
636
  |--------|--------------------|-------------|
@@ -689,13 +689,13 @@ Plan-body verification stays **lightweight** even under this posture — the `ve
689
689
  - all dispatches non-result → `aborted-non-result`
690
690
  - any `partial-consensus` / `dissent-isolated` present, no `majority-disagree` → `passed-with-dissent`
691
691
  - all items `full-consensus` → `passed`
692
- 6. Lead writes `runs/<task-type>/state/plan-body-verification-<task-type>-<seq>.json` (schema below) and populates `### 4.5.9 Plan Body Verification` in the final report (template at `templates/reports/final-report.template.md`). The §4.5.9 body uses a single `#### Verdict details` table (`Plan item / Worker / Verdict / Breakage kind / Note` — one row per plan-item × worker pair). The older wide `| Plan item | <worker1> | <worker2> | … | Classification |` matrix and the former narrow `#### Verdict summary` card are both removed — the matrix scaled horizontally with the worker count, and the summary only restated per-item classifications already derivable from the details table. The validator's `Plan Body Verification` + `Gate result:` substring checks gate this section.
693
- 7. For every `majority-disagree` item, lead adds a row to `## 5. Clarification Items` with:
692
+ 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 (template at `templates/reports/final-report.template.md`). The §5.5.9 body uses a single `#### Verdict details` table (`Plan item / Worker / Verdict / Breakage kind / Note` — one row per plan-item × worker pair). The older wide `| Plan item | <worker1> | <worker2> | … | Classification |` matrix and the former narrow `#### Verdict summary` card are both removed — the matrix scaled horizontally with the worker count, and the summary only restated per-item classifications already derivable from the details table. The validator's `Plan Body Verification` + `Gate result:` substring checks gate this section.
693
+ 7. For every `majority-disagree` item, lead adds a row to `## 1. Clarification Items` with:
694
694
  - new `C-<N>` ID (numbering continues from any existing rows)
695
695
  - `Statement` summarising the disagreement and the worker breakage `<kind>`
696
696
  - `Kind` chosen per the standard policy (usually `decision` for option-level conflicts, `data-point` for path/symbol mismatches)
697
697
  - `Blocks=approval`
698
- - the §4.5.9 verdict table's `Classification` column for that row reads `majority-disagree → C-<N>` (1:1 ID match — orphan on either side is a contract violation per `prompts/profiles/implementation-planning.md` self-review step 6).
698
+ - the §5.5.9 verdict table's `Classification` column for that row reads `majority-disagree → C-<N>` (1:1 ID match — orphan on either side is a contract violation per `prompts/profiles/implementation-planning.md` self-review step 6).
699
699
  8. 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.
700
700
 
701
701
  ### `plan-body-verification-<task-type>-<seq>.json` schema
@@ -802,4 +802,4 @@ Mirrors finding convergence (§"Worker failure handling in reverify"). Concretel
802
802
 
803
803
  - A dispatch that returns terminal non-result MUST NOT be aggregated as `DISAGREE`.
804
804
  - If at least one dispatch was issued AND **all** plan-body dispatches return non-result, the Gate result is `aborted-non-result`. Record one `contract-violation` event per non-result dispatch.
805
- - When the gate is `aborted-non-result`, report-writer MUST keep the frontmatter `approved: false` (publishing `approved: true` under this gate result is a validator failure). A single row is added to `## 5. Clarification Items` with `Statement="plan-body verification could not run — all workers returned non-result"`, `Kind=decision`, `Blocks=approval`, allowing the user to either retry the phase or override by manually flipping the frontmatter to `approved: true` (or running `--approve` on the resume command).
805
+ - When the gate is `aborted-non-result`, report-writer MUST keep the frontmatter `approved: false` (publishing `approved: true` under this gate result is a validator failure). A single row is added to `## 1. Clarification Items` with `Statement="plan-body verification could not run — all workers returned non-result"`, `Kind=decision`, `Blocks=approval`, allowing the user to either retry the phase or override by manually flipping the frontmatter to `approved: true` (or running `--approve` on the resume command).
@@ -48,9 +48,9 @@ The prompt MUST include, in this order at the top:
48
48
  6. `**Model:** Report writer worker, <modelExecutionValue>` (resolved per Phase 5.5 anchor-header rules)
49
49
  7. The full `[Required reading]` clause (see [okstra-team-contract](../okstra-team-contract/SKILL.md)) — for Phase 6 it adds two **per-task-type, instruction-set-local** read-only files, both scoped to this run's task-type by `okstra-ctl` at prep time:
50
50
  - `<instruction-set>/final-report-schema.json` — a task-type excerpt of the data.json schema (the other task-types' deliverable blocks and their unreachable `$defs` are stripped; ~38% of the full schema is `$defs` alone). This is your authoring contract for the data.json shape. Do **NOT** pull the full `schemas/final-report-v1.0.schema.json` — it carries all task-types and its `schemas/...` path is not part of the task bundle. (Validation still runs against the full schema post-hoc via the renderer, so the excerpt never relaxes the contract.)
51
- - `<instruction-set>/final-report-template.md` — the **phase-stripped** template (every other task-type's §4.x deliverable block removed by `render.py`'s `_strip_phase_blocks`, leaving only your run's §4.x). Do **NOT** also pull the full `templates/reports/final-report.template.md` source (it re-adds ~330 lines of other phases' deliverables and is not in the task bundle).
51
+ - `<instruction-set>/final-report-template.md` — the **phase-stripped** template (every other task-type's §5.x deliverable block removed by `render.py`'s `_strip_phase_blocks`, leaving only your run's §5.x). Do **NOT** also pull the full `templates/reports/final-report.template.md` source (it re-adds ~330 lines of other phases' deliverables and is not in the task bundle).
52
52
  8. A one-line MCP pointer instead of the verbatim block — `**MCP servers:** follow the task brief's "## Available MCP Servers" section (already in your Required reading).` The brief is already in the report-writer's Required reading (item 7), so the verbatim block is redundant.
53
- 9. The convergence classifications (Full/Partial/Contested/Worker-Unique), the round history data (`roundHistory[]`), the `round2SkippedReason` value, and pointers to all worker result files under `worker-results/`. The report-writer worker populates `crossVerification.roundHistory` in the data.json so Section 1 can show which rounds executed, queue sizes, and why Round 2 was (or was not) skipped. The renderer prints the full per-round table only when more than one round ran; single-round or zero-round histories are auto-collapsed to a one-line summary.
53
+ 9. The convergence classifications (Full/Partial/Contested/Worker-Unique), the round history data (`roundHistory[]`), the `round2SkippedReason` value, and pointers to all worker result files under `worker-results/`. The report-writer worker populates `crossVerification.roundHistory` in the data.json so Section 6 can show which rounds executed, queue sizes, and why Round 2 was (or was not) skipped. The renderer prints the full per-round table only when more than one round ran; single-round or zero-round histories are auto-collapsed to a one-line summary.
54
54
  10. `**Report Language:** <en|ko>` — must be either `en` or `ko`; `auto`
55
55
  has been resolved by the lead from project.json / global config
56
56
  before the dispatch is constructed. The worker copies this verbatim
@@ -78,9 +78,9 @@ Speculative reasons such as "session resume constraint", "team object no longer
78
78
 
79
79
  ## Phase 6 → Phase 7 execution sequence (BLOCKING order)
80
80
 
81
- The four steps below MUST execute in this exact order. Reordering them is the recurring root cause of reports shipping with `--` token cells (Phase 7 not run yet), Section 6 missing follow-up entries, or Section 7 rows never spawning.
81
+ The four steps below MUST execute in this exact order. Reordering them is the recurring root cause of reports shipping with `--` token cells (Phase 7 not run yet), Section 3 missing follow-up entries, or Section 4 rows never spawning.
82
82
 
83
- 1. **Phase 6 — Report writer worker drafts the final-report data.json** at `runs/<task-type>/reports/final-report-<task-type>-<seq>.data.json`, then invokes `scripts/okstra-render-final-report.py` to produce the sibling markdown. Token Usage cells in the data.json are `null` at this point (renderer emits `--` for nulls); Section 6 lists prioritized actions but does NOT yet include auto-spawned follow-ups (they don't exist yet).
83
+ 1. **Phase 6 — Report writer worker drafts the final-report data.json** at `runs/<task-type>/reports/final-report-<task-type>-<seq>.data.json`, then invokes `scripts/okstra-render-final-report.py` to produce the sibling markdown. Token Usage cells in the data.json are `null` at this point (renderer emits `--` for nulls); Section 3 lists prioritized actions but does NOT yet include auto-spawned follow-ups (they don't exist yet).
84
84
  2. **Phase 7 step 1 — Token-usage collector with `--substitute-data`** (BLOCKING). One invocation aggregates `leadUsage` / `workers[].usage` / `usageSummary` into team-state AND populates `tokenUsage` + `executionStatus[].totalTokens` etc. in the data.json AND re-invokes the renderer so the sibling markdown carries the real numbers. Skipping the flag ships a markdown full of `--` cells.
85
85
 
86
86
  ```bash
@@ -103,7 +103,7 @@ The four steps below MUST execute in this exact order. Reordering them is the re
103
103
  - When the report has **no** `C-*` clarification rows, the html carries no interactive forms (it would only duplicate the MD), so the renderer prints `html: skipped (...)` and writes nothing. This is the expected state for clarification-free runs — `validators/validate-report-views.py` treats "no C-* rows + no html" as a pass, not a missing artifact.
104
104
 
105
105
  Must run AFTER step 1 (so token placeholders are substituted in any rendered html) and BEFORE step 2 (so the html artifact, when generated, exists for the validator step that checks it).
106
- 4. **Phase 7 step 2 — Follow-up task spawner** (BLOCKING when Section 7 is non-empty). Turns the report's `## 7. Follow-up Tasks (후속 작업)` rows into `tasks/<task-group>/<new-task-id>/` stubs.
106
+ 4. **Phase 7 step 2 — Follow-up task spawner** (BLOCKING when Section 4 is non-empty). Turns the report's `## 4. Follow-up Tasks (후속 작업)` rows into `tasks/<task-group>/<new-task-id>/` stubs.
107
107
 
108
108
  ```bash
109
109
  python3 scripts/okstra-spawn-followups.py \
@@ -115,11 +115,11 @@ The four steps below MUST execute in this exact order. Reordering them is the re
115
115
 
116
116
  Behaviour contract:
117
117
  - Idempotent: rows whose target dir exists are reported as `existing` and skipped. Reruns of the same parent task are safe.
118
- - Rows with `autoSpawn != "yes"` are reported as `skipped` and never written; surface them in Section 6 if manual action is still needed.
118
+ - Rows with `autoSpawn != "yes"` are reported as `skipped` and never written; surface them in Section 3 if manual action is still needed.
119
119
  - Rows whose `origin` is `phase-continuation` are reported as `skipped (no new task dir)` and never spawn — they advance the same task-key via `/okstra-run` instead.
120
120
  - An invalid `origin`, `suggestedTaskType`, missing `title`, missing `reason`, or missing `newTaskId` exits `1`. (Schema validation in Phase 6 catches most of these before the spawner runs.)
121
121
  - **Canonical spawn rule (single source of truth):** the spawner runs when `task-type` ∈ {`implementation`, `final-verification`, `release-handoff`}, OR when `followUpTasks` is non-empty for any other task-type. For the listed task-types `followUpTasks` must be present (schema enforces the phase-continuation row for non-terminal task-types); an empty array is permitted only for `release-handoff`. Missing arrays are no-ops (exit `0`). All other references to this rule (including the Persistence Checklist) defer to this statement.
122
- 5. **Phase 7 step 3 — Update Section 6** after the spawner. The report-writer MUST append one row per newly spawned task-key with its entry command:
122
+ 5. **Phase 7 step 3 — Update Section 3** after the spawner. The report-writer MUST append one row per newly spawned task-key with its entry command:
123
123
 
124
124
  ```
125
125
  - Follow-up: `<task-group>/<new-task-id>` — Claude Code 세션 안 `/okstra-run task-key=<task-group>/<new-task-id> task-type=<suggested>` / 별도 터미널 `scripts/okstra.sh --task-key <task-group>/<new-task-id> --task-type <suggested>`
@@ -215,16 +215,16 @@ When the run's `task-type` is `implementation-planning`, the final report MUST c
215
215
  | 5 | `Dependency` | `### Dependency / Migration Risk (의존성·마이그레이션 위험)` |
216
216
  | 6 | `Validation Checklist` | `### Validation Checklist (검증 체크리스트)` |
217
217
  | 7 | `Rollback` | `### Rollback Strategy (롤백 전략)` |
218
- | 8 | `User Approval Request` | Satisfied by the top-of-report `## User Approval Request (사용자 승인 게이트)` block. Do NOT recreate a `### 4.5.8 User Approval Request` body stub — the validator now fails reports that contain one. |
219
- | 9 | `Plan Body Verification` + `Gate result:` | `### Plan Body Verification (계획 본문 검증)` containing a `Gate result:` line — copy `templates/reports/final-report.template.md §4.5.9` verbatim. Validator checks both substrings. |
218
+ | 8 | `User Approval Request` | Satisfied by the top-of-report `## User Approval Request (사용자 승인 게이트)` block. Do NOT recreate a `### 5.5.8 User Approval Request` body stub — the validator now fails reports that contain one. |
219
+ | 9 | `Plan Body Verification` + `Gate result:` | `### Plan Body Verification (계획 본문 검증)` containing a `Gate result:` line — copy `templates/reports/final-report.template.md §5.5.9` verbatim. Validator checks both substrings. |
220
220
 
221
221
  The Korean translation in parentheses is optional but the English keyword is mandatory. The body of each section is written in the Report Language per the writing rules below. For non-`implementation-planning` runs, omit this entire block — these headings are NOT validator-checked for other task-types.
222
222
 
223
- The final-report template `templates/reports/final-report.template.md` Section 4.5 already encodes this contract — copy that block verbatim and fill in.
223
+ The final-report template `templates/reports/final-report.template.md` Section 5.5 already encodes this contract — copy that block verbatim and fill in.
224
224
 
225
225
  ### Final-verification verdict token contract (BLOCKING)
226
226
 
227
- When the run's `task-type` is `final-verification`, the report's `## 2. Final Verdict` table MUST contain a `Verdict Token` row whose value is **exactly one of** the literal strings below. The `release-handoff` profile reads this row as its entry gate; any other value blocks the next phase.
227
+ When the run's `task-type` is `final-verification`, the report's `## 7. Final Verdict` table MUST contain a `Verdict Token` row whose value is **exactly one of** the literal strings below. The `release-handoff` profile reads this row as its entry gate; any other value blocks the next phase.
228
228
 
229
229
  | # | Required substring | Meaning |
230
230
  |---|--------------------|---------|
@@ -234,15 +234,15 @@ When the run's `task-type` is `final-verification`, the report's `## 2. Final Ve
234
234
 
235
235
  For every other task-type, set the `Verdict Token` cell to `not-applicable`. Do NOT omit the row — the template renders it for all task-types and downstream tooling expects the field to exist.
236
236
 
237
- The final-report template `templates/reports/final-report.template.md` Section 2 already encodes this contract — copy that block verbatim and fill in.
237
+ The final-report template `templates/reports/final-report.template.md` Section 7 already encodes this contract — copy that block verbatim and fill in.
238
238
 
239
239
  ### Release-handoff section contract (release-handoff runs only)
240
240
 
241
- When the run's `task-type` is `release-handoff`, the final report MUST include Section `## 4.6 Release Handoff Deliverables` with all eight sub-sections (`4.6.1` Source Verification Report, `4.6.2` Feature Branch & Working-Tree State, `4.6.3` User Selections, `4.6.4` Executed Commands, `4.6.5` Commit List, `4.6.6` Merge Conflict Probe, `4.6.7` Pull Request Outcome, `4.6.8` Routing Recommendation). Every entry is dictated by the lead's recorded git/gh command log and the user's verbatim answers to the H1/H2/H3 menu prompts. H1 choices are `local only`, `push + PR`, or `skip`; release-handoff records existing implementation commits and MUST NOT create new commits. If the user picked `skip` (H1) or `cancel` (H3), keep 4.6.3 populated but leave 4.6.4–4.6.6 explicitly empty per the template's empty-state lines.
241
+ When the run's `task-type` is `release-handoff`, the final report MUST include Section `## 5.6 Release Handoff Deliverables` with all eight sub-sections (`5.6.1` Source Verification Report, `5.6.2` Feature Branch & Working-Tree State, `5.6.3` User Selections, `5.6.4` Executed Commands, `5.6.5` Commit List, `5.6.6` Merge Conflict Probe, `5.6.7` Pull Request Outcome, `5.6.8` Routing Recommendation). Every entry is dictated by the lead's recorded git/gh command log and the user's verbatim answers to the H1/H2/H3 menu prompts. H1 choices are `local only`, `push + PR`, or `skip`; release-handoff records existing implementation commits and MUST NOT create new commits. If the user picked `skip` (H1) or `cancel` (H3), keep 5.6.3 populated but leave 5.6.4–5.6.6 explicitly empty per the template's empty-state lines.
242
242
 
243
243
  **Single-lead authorship (release-handoff only):** release-handoff has no worker roster (no `Report writer worker`, no `Claude worker` drafter). The Claude lead authors the final-report file directly — there is no `Report writer worker` dispatch to perform in Phase 6, no resume-safe dispatch concern, and no mandatory worker-results file for a report-writer role. The rest of this skill's dispatch / resume / fallback machinery applies ONLY when `Report writer worker` is in the roster (i.e. every task-type other than `release-handoff`).
244
244
 
245
- The final-report template `templates/reports/final-report.template.md` Section 4.6 already encodes this contract — copy that block verbatim and fill in. For non-`release-handoff` runs, omit Section 4.6 entirely.
245
+ The final-report template `templates/reports/final-report.template.md` Section 5.6 already encodes this contract — copy that block verbatim and fill in. For non-`release-handoff` runs, omit Section 5.6 entirely.
246
246
 
247
247
  ### Mandatory worker-results file (BLOCKING)
248
248
 
@@ -260,16 +260,16 @@ Skipping this file because "the real report is in `reports/`" is wrong. Both fil
260
260
 
261
261
  ### Main Body Section
262
262
 
263
- Section numbering follows `templates/reports/final-report.template.md` exactly — that file is the documentation SSOT for section names and ordering. For full body structure at authoring time, consult your run's **phase-stripped** `final-report-template.md` (the instruction-set copy of the same template, with other task-types' §4.x deliverable blocks removed); the "copy that block verbatim" references below mean the §-block as it appears in that stripped copy, not a re-read of the full source.
263
+ Section numbering follows `templates/reports/final-report.template.md` exactly — that file is the documentation SSOT for section names and ordering. For full body structure at authoring time, consult your run's **phase-stripped** `final-report-template.md` (the instruction-set copy of the same template, with other task-types' §5.x deliverable blocks removed); the "copy that block verbatim" references below mean the §-block as it appears in that stripped copy, not a re-read of the full source.
264
264
 
265
- **Verdict Card (top-of-report, mandatory).** Render `## Verdict Card` between the report header and the (conditional) Approval block. Its `Verdict Token` / `Direction` / `Next Step` cells MUST byte-match the corresponding cells in `## 2. Final Verdict` and the first item of `## 6.`. Divergence is `contract-violated`.
265
+ **Verdict Card (top-of-report, mandatory).** Render `## Verdict Card` between the report header and the (conditional) Approval block. Its `Verdict Token` / `Direction` / `Next Step` cells MUST byte-match the corresponding cells in `## 7. Final Verdict` and the first item of `## 6.`. Divergence is `contract-violated`.
266
266
 
267
- 0. **Clarification Response Carried In** — render this `## 0.` heading ONLY when `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}` is non-empty. Walk every `C-*` row of the prior report's `## 5. Clarification Items` table, reconcile against new evidence, and record the outcome (`resolved` / `obsolete`) with citation before drafting the verdict. When no carry-in path was provided, OMIT the `## 0.` heading entirely — the validator fails an empty Section 0 stub.
267
+ 0. **Clarification Response Carried In** — render this `## 0.` heading ONLY when `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}` is non-empty. Walk every `C-*` row of the prior report's `## 1. Clarification Items` table, reconcile against new evidence, and record the outcome (`resolved` / `obsolete`) with citation before drafting the verdict. When no carry-in path was provided, OMIT the `## 0.` heading entirely — the validator fails an empty Section 0 stub.
268
268
  1. **Cross Verification Results** — 4 categories (Full / Partial / Contested / Worker-Unique) when convergence is enabled, per `okstra-convergence`. Prepend the Round History sub-table (columns: `Round | inputQueueSize | resolvedCount | carriedForwardCount | dispatches | skippedWorkers`) plus a `round2SkippedReason: <value>` note, pulled verbatim from `convergence-<task-type>-<seq>.json`. Empty contested list renders as `- 합의 미달 항목 없음.`. Convergence-disabled runs use the legacy Consensus/Differences format and omit the round table.
269
269
  2. **Final Verdict** — `Direction` ∈ `continue-investigation` / `begin-implementation` / `approve` / `reject` / `hold`. **Verdict Token** is `not-applicable` for every task-type except `final-verification` — see "Final-verification verdict token contract" below for that case.
270
270
  3. **Evidence and Detailed Analysis** — primary evidence rows (file path, line, snippet); secondary evidence / alternate interpretations. If `reference-expectations.md` lists explicit expected values, record match/gap per row.
271
- 4. **Missing Information and Risks** — uncertain / "I don't know" items. `implementation-planning` adds §4.5 (see heading contract below); `release-handoff` adds §4.6.
272
- 5. **Clarification Items** — single unified `C-*` table; column schema, ID convention, and rerun behaviour are owned by `_common-contract.md §Clarification request policy` (8-column SSOT). The deprecated `4.5.9 Open Questions` / `5.1 추가 자료 요청` / `5.2 사용자 확인 질문` sub-sections are removed; the validator fails reports that reintroduce them.
271
+ 4. **Missing Information and Risks** — uncertain / "I don't know" items. `implementation-planning` adds §5.5 (see heading contract below); `release-handoff` adds §5.6.
272
+ 5. **Clarification Items** — single unified `C-*` table; column schema, ID convention, and rerun behaviour are owned by `_common-contract.md §Clarification request policy` (8-column SSOT). The deprecated `5.5.9 Open Questions` / `1.1 추가 자료 요청` / `1.2 사용자 확인 질문` sub-sections are removed; the validator fails reports that reintroduce them.
273
273
  6. **Recommended Next Steps** — prioritized actions. After Phase 7's follow-up spawner runs, append a row per newly created task-key (see "Phase 6 → Phase 7 execution sequence" above).
274
274
  7. **Follow-up Tasks** — auto-spawn-eligible table. Each row drives `okstra-spawn-followups.py`; see template §7 for the row schema.
275
275
 
@@ -281,8 +281,8 @@ Section numbering follows `templates/reports/final-report.template.md` exactly
281
281
  empty-states, token summary, column headers, release-handoff labels)
282
282
  are i18n-rendered by `okstra-render-final-report.py` from
283
283
  `templates/reports/i18n/<lang>.json`; do not translate those — focus
284
- on the prose you author (Section 1 categories, Section 3 evidence
285
- narratives, Section 4 risks, Section 6 recommendations, etc.).
284
+ on the prose you author (Section 6 categories, Section 2 evidence
285
+ narratives, Section 5 risks, Section 3 recommendations, etc.).
286
286
  Code identifiers, file paths, model names, status tokens, and the
287
287
  validator-checked English substrings (`Option Candidates`,
288
288
  `Verdict Token`, `accepted`/`conditional-accept`/`blocked`, etc.)
@@ -296,7 +296,7 @@ Section numbering follows `templates/reports/final-report.template.md` exactly
296
296
  - Write the actual analysis text instead of a meta-description
297
297
  - Do not make unfounded assertions
298
298
  - Include findings from all four categories. Do not omit "contested" or "worker-unique" findings
299
- - Include the convergence round history sub-table (Section 1) so the reader can audit which rounds executed and what `round2SkippedReason` indicates (e.g. `"not-skipped"` when Round 2 ran, or one of the three skip reasons). Pull values verbatim from `convergence-<task-type>-<seq>.json`; do NOT recompute.
299
+ - Include the convergence round history sub-table (Section 6) so the reader can audit which rounds executed and what `round2SkippedReason` indicates (e.g. `"not-skipped"` when Round 2 ran, or one of the three skip reasons). Pull values verbatim from `convergence-<task-type>-<seq>.json`; do NOT recompute.
300
300
  - For each finding, include a brief summary of votes per worker across executed rounds. `verification-error` votes are listed as such — never as `DISAGREE`.
301
301
  - The report writer worker does not participate in the re-verification vote. It is responsible only for drafting the final report
302
302
 
@@ -42,6 +42,7 @@ The wizard tells you *which UI to use* via `kind` (and the optional `multi` flag
42
42
 
43
43
  - `kind: "pick"` + `multi: false` (default) → render `AskUserQuestion` with `label`, `options[].label`, and `multiSelect: false`. Use the chosen `options[].value` (single string) as the answer.
44
44
  - `kind: "pick"` + `multi: true` → render `AskUserQuestion` with `label`, `options[].label`, and `multiSelect: true`. Join the chosen `options[].value` entries with `,` into a single CSV string and submit that as `--answer "csv,values"`. If the user selects nothing, still submit `--answer ""` — the wizard will reply `ok: false` and re-prompt the same step (do not skip the call).
45
+ - `kind: "pick_group"` → render a SINGLE `AskUserQuestion` whose questions array maps 1:1 to the wizard's `questions[]`. For each entry use `questions[].label`, `questions[].options[].label`, and `multiSelect: questions[].multi`. Collect the user's chosen `options[].value` per tab, build a JSON object keyed by each `questions[].step`, and submit it as a single literal `--answer '{"lead_model":"opus","claude_model":"default",...}'`. A tab the user leaves at its default still gets its `"default"`/`""` value in the JSON. Never split a `pick_group` into multiple `AskUserQuestion` calls — the wizard already capped it at 4 tabs and emits any remainder as the next prompt.
45
46
  - `kind: "text"` → write `label` as a plain text message and consume the user's NEXT message as the answer.
46
47
  - `kind: "done"` → input collection finished; move to Step 5.
47
48
 
@@ -96,6 +97,7 @@ Repeat until `next.kind == "done"`:
96
97
  1. **Render** the prompt according to `kind` (and `multi` for pick):
97
98
  - `pick` + `multi: false` → `AskUserQuestion` with `multiSelect: false`, `label`, and `options`. The user's chosen option's `value` is the answer string.
98
99
  - `pick` + `multi: true` → `AskUserQuestion` with `multiSelect: true`, `label`, and `options`. Join the selected `value`s with `,` into a single literal CSV string (e.g. `"claude,codex,gemini"`) and submit it as a single `--answer "claude,codex,gemini"`. Empty selection submits `--answer ""` and the wizard re-prompts.
100
+ - `pick_group` → one `AskUserQuestion` with one question per `questions[]` entry (tab). Map each tab's selected `value` back by `questions[].step`, assemble a JSON object, and submit it as a single literal `--answer '<json>'`.
99
101
  - `text` → plain text message containing `label`. Consume the user's next reply verbatim as the answer string (empty reply = empty string).
100
102
  2. **Submit** the answer — call `okstra wizard step` with the literal state-file path from Step 2 and the literal user answer (no shell variables, no `$(...)`):
101
103
  ```bash
@@ -213,7 +213,7 @@ Every item in sections 1–5 MUST be tagged with the ticket(s) it relates to. Th
213
213
 
214
214
  - **Table-form items**: include a `Ticket ID` column. The column is placed immediately after the row-ID column (e.g. after `F-001`, `M-001`).
215
215
  - **Bullet / numbered-list items**: prepend `[TICKETID: <id>]` to the item title, immediately after the row ID and before the body text. Example: `- F-001 [TICKETID: TICKET-123] — <summary> (path:line)`.
216
- - **Section headers in the final report** (e.g. `### 4.5.3 Recommended Option`): append `[TICKETID: <id>]` to the header when the section is scoped to a specific ticket. Headers that span all tickets in the run omit the tag.
216
+ - **Section headers in the final report** (e.g. `### 5.5.3 Recommended Option`): append `[TICKETID: <id>]` to the header when the section is scoped to a specific ticket. Headers that span all tickets in the run omit the tag.
217
217
 
218
218
  Ticket ID fill rule (in order):
219
219
 
@@ -68,11 +68,4 @@ taskType: "{{FM_TASK_TYPE}}"
68
68
 
69
69
  ## Notes
70
70
 
71
- - 이 문서는 사람용 quick summary입니다.
72
- - canonical metadata는 항상 `task-manifest.json`을 기준으로 확인합니다.
73
- - 동일한 버그나 작업을 다시 이어갈 때는 같은 `Task Group`과 `Task ID`를 재사용합니다.
74
- - `requirements-discovery`는 work category와 다음 phase routing 결정을 남기기 위한 초기 triage 단계입니다.
75
- - run directory는 `runs/<task-type>/` 규칙을 사용하여 서로 다른 task-type 실행을 경로 수준에서 분리합니다.
76
- - run directory 내부는 `manifests/`, `state/`, `prompts/`, `reports/`, `status/`, `sessions/`, `worker-results/`처럼 유형별 하위 폴더로 나뉩니다.
77
- - current run의 `prompts/` 디렉터리는 lead prompt snapshot과 worker prompt history file의 canonical 저장 위치입니다.
78
- - run-level artifact와 result 파일명은 같은 task-type 재실행을 구분하기 위해 `-YYYY-MM-DD_HH-MM-SS` suffix를 사용합니다.
71
+ - 이 문서는 사람이 빠르게 훑어보기 위한 요약입니다. 정본·상세 metadata 는 `task-manifest.json` 을 참조하세요.