okstra 0.34.0 → 0.36.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 (101) hide show
  1. package/README.kr.md +26 -16
  2. package/README.md +26 -16
  3. package/docs/kr/architecture.md +59 -45
  4. package/docs/kr/cli.md +61 -18
  5. package/docs/pr-template-usage.md +65 -0
  6. package/docs/project-structure-overview.md +358 -354
  7. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +1 -1
  8. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +1 -1
  9. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +1 -1
  10. package/docs/superpowers/plans/2026-05-20-final-report-language.md +1501 -0
  11. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +1267 -0
  12. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +1007 -0
  13. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +720 -0
  14. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +681 -0
  15. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +1691 -0
  16. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +383 -0
  17. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +320 -0
  18. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +299 -0
  19. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +335 -0
  20. package/docs/task-process/README.md +74 -0
  21. package/docs/task-process/common-flow.md +166 -0
  22. package/docs/task-process/error-analysis.md +101 -0
  23. package/docs/task-process/final-verification.md +167 -0
  24. package/docs/task-process/implementation-planning.md +128 -0
  25. package/docs/task-process/implementation.md +149 -0
  26. package/docs/task-process/release-handoff.md +206 -0
  27. package/docs/task-process/requirements-discovery.md +115 -0
  28. package/package.json +1 -1
  29. package/runtime/BUILD.json +2 -2
  30. package/runtime/agents/SKILL.md +29 -13
  31. package/runtime/agents/workers/claude-worker.md +26 -0
  32. package/runtime/agents/workers/codex-worker.md +27 -1
  33. package/runtime/agents/workers/gemini-worker.md +27 -1
  34. package/runtime/agents/workers/report-writer-worker.md +8 -1
  35. package/runtime/bin/okstra-central.sh +6 -6
  36. package/runtime/bin/okstra-codex-exec.sh +49 -28
  37. package/runtime/bin/okstra-gemini-exec.sh +39 -21
  38. package/runtime/bin/okstra-render-final-report.py +13 -2
  39. package/runtime/bin/okstra-wrapper-status.py +155 -0
  40. package/runtime/bin/okstra.sh +2 -2
  41. package/runtime/prompts/profiles/_common-contract.md +11 -6
  42. package/runtime/prompts/profiles/error-analysis.md +3 -7
  43. package/runtime/prompts/profiles/implementation-planning.md +22 -21
  44. package/runtime/prompts/profiles/implementation.md +28 -11
  45. package/runtime/prompts/profiles/improvement-discovery.md +42 -0
  46. package/runtime/prompts/profiles/kr/_common-contract.md +92 -0
  47. package/runtime/prompts/profiles/kr/error-analysis.md +36 -0
  48. package/runtime/prompts/profiles/kr/final-verification.md +48 -0
  49. package/runtime/prompts/profiles/kr/implementation-planning.md +90 -0
  50. package/runtime/prompts/profiles/kr/implementation.md +144 -0
  51. package/runtime/prompts/profiles/kr/improvement-discovery.md +42 -0
  52. package/runtime/prompts/profiles/kr/release-handoff.md +104 -0
  53. package/runtime/prompts/profiles/kr/requirements-discovery.md +42 -0
  54. package/runtime/prompts/profiles/release-handoff.md +1 -1
  55. package/runtime/prompts/profiles/requirements-discovery.md +8 -12
  56. package/runtime/prompts/wizard/prompts.ko.json +230 -0
  57. package/runtime/python/lib/okstra/cli.sh +2 -49
  58. package/runtime/python/lib/okstra/globals.sh +21 -21
  59. package/runtime/python/lib/okstra/interactive.sh +7 -7
  60. package/runtime/python/okstra_ctl/clarification_items.py +3 -9
  61. package/runtime/python/okstra_ctl/consumers.py +53 -0
  62. package/runtime/python/okstra_ctl/final_report_schema.py +0 -7
  63. package/runtime/python/okstra_ctl/i18n.py +73 -0
  64. package/runtime/python/okstra_ctl/improvement_lenses.py +44 -0
  65. package/runtime/python/okstra_ctl/index.py +1 -1
  66. package/runtime/python/okstra_ctl/paths.py +23 -20
  67. package/runtime/python/okstra_ctl/render.py +147 -202
  68. package/runtime/python/okstra_ctl/render_final_report.py +53 -10
  69. package/runtime/python/okstra_ctl/run.py +292 -107
  70. package/runtime/python/okstra_ctl/run_context.py +22 -0
  71. package/runtime/python/okstra_ctl/seeding.py +186 -0
  72. package/runtime/python/okstra_ctl/wizard.py +348 -127
  73. package/runtime/python/okstra_ctl/workflow.py +21 -2
  74. package/runtime/python/okstra_ctl/worktree.py +54 -1
  75. package/runtime/python/okstra_project/resolver.py +4 -3
  76. package/runtime/python/okstra_token_usage/report.py +2 -2
  77. package/runtime/schemas/final-report-v1.0.schema.json +22 -16
  78. package/runtime/skills/okstra-brief/SKILL.md +124 -31
  79. package/runtime/skills/okstra-convergence/SKILL.md +2 -3
  80. package/runtime/skills/okstra-report-writer/SKILL.md +35 -15
  81. package/runtime/skills/okstra-run/SKILL.md +5 -4
  82. package/runtime/skills/okstra-schedule/SKILL.md +4 -4
  83. package/runtime/skills/okstra-setup/SKILL.md +27 -0
  84. package/runtime/skills/okstra-team-contract/SKILL.md +1 -1
  85. package/runtime/templates/okstra.CLAUDE.md +104 -0
  86. package/runtime/templates/reports/final-report.template.md +93 -98
  87. package/runtime/templates/reports/i18n/en.json +135 -0
  88. package/runtime/templates/reports/i18n/ko.json +135 -0
  89. package/runtime/templates/reports/implementation-planning-input.template.md +18 -0
  90. package/runtime/templates/reports/improvement-discovery-input.template.md +78 -0
  91. package/runtime/templates/reports/task-brief.template.md +2 -2
  92. package/runtime/validators/lib/fixtures.sh +30 -0
  93. package/runtime/validators/lib/runners.sh +1 -1
  94. package/runtime/validators/validate-implementation-plan-stages.py +211 -0
  95. package/runtime/validators/validate-run.py +121 -26
  96. package/runtime/validators/validate-workflow.sh +2 -2
  97. package/runtime/validators/validate_improvement_report.py +275 -0
  98. package/src/config.mjs +18 -0
  99. package/src/install.mjs +41 -14
  100. package/src/setup.mjs +133 -1
  101. package/src/uninstall.mjs +21 -1
@@ -0,0 +1,206 @@
1
+ # release-handoff process
2
+
3
+ ## Index
4
+
5
+ - [1. 목적](#1-목적)
6
+ - [2. okstra-run wizard 흐름](#2-okstra-run-wizard-흐름)
7
+ - [3. prepare 단계](#3-prepare-단계)
8
+ - [4. entry gate](#4-entry-gate)
9
+ - [5. lead-only 실행 흐름](#5-lead-only-실행-흐름)
10
+ - [6. PR template 결정](#6-pr-template-결정)
11
+ - [7. 산출물](#7-산출물)
12
+ - [8. 금지선](#8-금지선)
13
+ - [9. 확인한 코드](#9-확인한-코드)
14
+
15
+ ## 1. 목적
16
+
17
+ `release-handoff`는 `accepted` verdict가 나온 already-committed implementation branch를 push하거나 PR로 넘기는 terminal phase다. 새 commit을 만들지 않고, 검증된 diff를 그대로 포장한다.
18
+
19
+ 이 phase는 worker dispatch가 없다. `claude`, `codex`, `report-writer` roster를 쓰지 않으며 Claude lead가 inline으로 git/gh inspection, 사용자 질문, PR draft, final report 작성을 모두 수행한다.
20
+
21
+ ## 2. okstra-run wizard 흐름
22
+
23
+ ```mermaid
24
+ flowchart TD
25
+ Start[/okstra-run/] --> Common[공통 task identity flow]
26
+ Common --> Type[task-type = release-handoff]
27
+ Type --> Worktree{active task worktree?}
28
+ Worktree -->|yes| Defaults[Use defaults / Customize]
29
+ Worktree -->|no| BaseRef[base-ref pick/text]
30
+ BaseRef --> Defaults
31
+ Defaults -->|defaults| Confirm[confirmation]
32
+ Defaults -->|customize| Models[lead model prompt]
33
+ Models --> Extras[directive, related tasks, clarification]
34
+ Extras --> Template[PR template override?]
35
+ Template --> Scope[save template to project/global?]
36
+ Scope --> Confirm
37
+ Confirm --> Render[render-bundle]
38
+ ```
39
+
40
+ `release-handoff`는 worker roster prompt가 없다. wizard의 `render_args()`는 `pr-template-path`를 release-handoff일 때만 포함하고, runtime은 worker list를 강제로 empty로 만든다.
41
+
42
+ 주의할 점은 이 phase도 task worktree provisioning 대상이라는 것이다. 정상 흐름은 같은 task-key의 implementation/final-verification worktree를 재사용한다. 새 task로 시작하면 새 branch가 만들어질 수 있고, entry gate의 "implementation commit exists" 조건에서 막힐 가능성이 높다.
43
+
44
+ ## 3. prepare 단계
45
+
46
+ ```mermaid
47
+ sequenceDiagram
48
+ participant W as okstra-run
49
+ participant P as prepare_task_bundle
50
+ participant T as PR template resolver
51
+ participant WT as worktree registry
52
+ participant FS as task artifacts
53
+
54
+ W->>P: task-type=release-handoff, brief, optional pr-template-path
55
+ P->>P: validate profile and brief
56
+ P->>P: force workers=[]
57
+ P->>T: resolve PR template
58
+ P->>WT: reuse or provision task worktree
59
+ P->>FS: write manifests with empty roster
60
+ P->>FS: expose PR_TEMPLATE_PATH and PR_TEMPLATE_SOURCE
61
+ P-->>W: lead prompt for current session
62
+ ```
63
+
64
+ profile에 `Required workers:` block이 없고 `run.py`도 `release-handoff`에서는 worker override를 비운다. 따라서 `agents/SKILL.md`의 일반 TeamCreate / convergence / report-writer 흐름을 타지 않는 것이 의도된 동작이다.
65
+
66
+ ## 4. entry gate
67
+
68
+ ```mermaid
69
+ flowchart TD
70
+ Brief[task brief] --> Source{Source Verification Report present?}
71
+ Source -->|no| Block[blocked<br/>route final-verification]
72
+ Source -->|yes| Verdict{Verdict Token == accepted?}
73
+ Verdict -->|no| Block
74
+ Verdict -->|yes| Status{git status --short clean?}
75
+ Status -->|no| Dirty[blocked<br/>dirty tree]
76
+ Status -->|yes| Branch{current branch is base branch?}
77
+ Branch -->|yes| BaseBlock[blocked<br/>never operate on base branch]
78
+ Branch -->|no| Commits{git log base..HEAD non-empty?}
79
+ Commits -->|no| ImplBlock[blocked<br/>route implementation]
80
+ Commits -->|yes| Ready[handoff questions may begin]
81
+ ```
82
+
83
+ lead는 사용자에게 push/PR 여부를 묻기 전에 다음을 확인한다.
84
+
85
+ - task brief가 `## Source Verification Report`를 가리킨다.
86
+ - 그 report의 `## 2. Final Verdict`에 `Verdict Token = accepted`가 정확히 있다.
87
+ - working tree가 clean이다.
88
+ - 현재 branch가 `main`, `master`, `prod`, `preprod`, `staging`, `dev` 같은 base branch가 아니다.
89
+ - `<base>..HEAD` commit range가 비어 있지 않다.
90
+
91
+ `conditional-accept`, `blocked`, 애매한 문장 verdict는 모두 즉시 종료 대상이다.
92
+
93
+ ## 5. lead-only 실행 흐름
94
+
95
+ ```mermaid
96
+ stateDiagram-v2
97
+ [*] --> Gate: entry gate
98
+ Gate --> Q1: action selection
99
+ Q1 --> ReportOnly: local only
100
+ Q1 --> Skip: skip
101
+ Q1 --> Q2: push + PR
102
+ Q2 --> Probe: choose PR base
103
+ Probe --> Q3: no conflict
104
+ Probe --> Conflict: conflict detected
105
+ Conflict --> Q2: change base branch
106
+ Conflict --> Q3: proceed anyway
107
+ Conflict --> Cancel: cancel
108
+ Q3 --> Push: use as-is or edit then proceed
109
+ Q3 --> Cancel: cancel
110
+ Push --> ReuseOrCreate: git push feature branch
111
+ ReuseOrCreate --> FinalReport: gh pr list / gh pr create
112
+ ReportOnly --> FinalReport
113
+ Skip --> FinalReport
114
+ Cancel --> FinalReport
115
+ FinalReport --> [*]
116
+ ```
117
+
118
+ 사용자 interaction은 정확히 세 단계다.
119
+
120
+ 1. Q1 action: `local only`, `push + PR`, `skip`
121
+ 2. Q2 PR base: `staging`, `preprod`, `main`, 직접 입력 등 profile menu의 branch
122
+ 3. Q3 PR title/body: `use as-is`, `edit then proceed`, `cancel`
123
+
124
+ `push + PR`에서만 merge-conflict probe를 한다.
125
+
126
+ ```mermaid
127
+ flowchart TD
128
+ PushPR[push + PR selected] --> Fetch[git fetch origin chosen-base]
129
+ Fetch --> MergeTree[git merge-tree --write-tree --merge-base<br/>origin/base HEAD origin/base]
130
+ MergeTree --> Conflict{conflict?}
131
+ Conflict -->|no| Draft[show PR draft]
132
+ Conflict -->|yes| Ask[ask proceed/change base/cancel]
133
+ Ask -->|proceed anyway| Draft
134
+ Ask -->|change base branch| Base[return to Q2]
135
+ Ask -->|cancel| Report[final report without push/PR]
136
+ ```
137
+
138
+ probe는 working tree를 바꾸지 않아야 한다. `git merge`, `git rebase`, `git pull`은 이 probe에 포함되지 않는다.
139
+
140
+ ## 6. PR template 결정
141
+
142
+ ```mermaid
143
+ flowchart TD
144
+ Override[--pr-template-path from wizard] --> Chosen{exists?}
145
+ Chosen -->|yes| UseOverride[use override]
146
+ Chosen -->|no| Project[project config template]
147
+ Project -->|exists| UseProject[use project template]
148
+ Project -->|missing| Global[global config template]
149
+ Global -->|exists| UseGlobal[use global template]
150
+ Global -->|missing| Default[okstra skill default template]
151
+ ```
152
+
153
+ customize path에서 사용자가 template을 고르면 okstra-run skill이 render-bundle 전에 project/global scope 저장을 수행한다. runtime은 resolved `PR_TEMPLATE_PATH`와 `PR_TEMPLATE_SOURCE`를 run context에 넣고, lead는 이 파일을 그대로 읽어 HTML comment를 제거한 뒤 placeholder를 채운다. section 구조를 hard-code하면 안 된다.
154
+
155
+ ## 7. 산출물
156
+
157
+ ```mermaid
158
+ flowchart TD
159
+ Verdict[Source Verification Report<br/>accepted token] --> Report[release-handoff final report]
160
+ State[feature branch + clean status] --> Report
161
+ User[Q1/Q2/Q2b/Q3 user selections] --> Report
162
+ Commands[git/gh commands + exit codes] --> Report
163
+ Commits[git log base..HEAD commit list] --> Report
164
+ Probe[Merge Conflict Probe] --> Report
165
+ PR[PR created / reused / skipped] --> Report
166
+ Report --> Done[routing recommendation: done]
167
+ ```
168
+
169
+ final report에는 최소 다음이 필요하다.
170
+
171
+ - originating final-verification report path와 quoted `accepted` verdict row
172
+ - feature branch와 run start `git status --short`
173
+ - 사용자 선택 기록
174
+ - 실행한 모든 git/gh command와 exit code
175
+ - implementation commit list
176
+ - merge-conflict probe 결과
177
+ - PR 생성, 재사용, 생략 결과
178
+ - routing recommendation `done`
179
+
180
+ ## 8. 금지선
181
+
182
+ ```mermaid
183
+ flowchart TD
184
+ RH[release-handoff] --> Allowed[read git/gh, fetch base, merge-tree probe,<br/>push feature branch, create/reuse PR]
185
+ RH -. forbidden .-> Commit[git add / commit / stash]
186
+ RH -. forbidden .-> Force[force push or +refspec]
187
+ RH -. forbidden .-> BasePush[push directly to base branch]
188
+ RH -. forbidden .-> NoVerify[--no-verify / -n]
189
+ RH -. forbidden .-> Publish[release publish / deploy]
190
+ RH -. forbidden .-> Edit[source edit]
191
+ RH -. forbidden .-> Team[TeamCreate or Agent dispatch]
192
+ RH -. forbidden .-> Merge[gh pr merge]
193
+ ```
194
+
195
+ 실패한 `git push`를 더 약한 안전장치로 재시도하면 안 된다. non-fast-forward 같은 실패가 나면 멈추고 사용자 지시를 받아야 하며, `--force` 계열 flag는 사용자 요청이 있어도 금지다.
196
+
197
+ ## 9. 확인한 코드
198
+
199
+ - [`prompts/profiles/release-handoff.md`](../../prompts/profiles/release-handoff.md)
200
+ - [`templates/reports/release-handoff-input.template.md`](../../templates/reports/release-handoff-input.template.md)
201
+ - [`skills/okstra-run/SKILL.md`](../../skills/okstra-run/SKILL.md)
202
+ - [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py)
203
+ - [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
204
+ - [`scripts/okstra_ctl/pr_template.py`](../../scripts/okstra_ctl/pr_template.py)
205
+ - [`src/config.mjs`](../../src/config.mjs)
206
+ - [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py)
@@ -0,0 +1,115 @@
1
+ # requirements-discovery process
2
+
3
+ ## Index
4
+
5
+ - [1. 목적](#1-목적)
6
+ - [2. okstra-run wizard 흐름](#2-okstra-run-wizard-흐름)
7
+ - [3. prepare_task_bundle 처리](#3-prepare_task_bundle-처리)
8
+ - [4. lead 실행 흐름](#4-lead-실행-흐름)
9
+ - [5. 산출물과 routing](#5-산출물과-routing)
10
+ - [6. 확인한 코드](#6-확인한-코드)
11
+
12
+ ## 1. 목적
13
+
14
+ `requirements-discovery`는 구현 전에 요청을 분류한다. bugfix, feature, improvement, refactor, ops-change 중 무엇인지 판단하고, 다음 안전 phase가 `error-analysis`인지 `implementation-planning`인지 고른다. 직접 `implementation`으로 넘기는 것은 profile상 유효하지 않다. implementation은 승인된 `implementation-planning` report가 있어야 시작할 수 있다.
15
+
16
+ ## 2. okstra-run wizard 흐름
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ Start[/okstra-run/] --> Check[ensure-installed / paths / check-project]
21
+ Check --> Pick{new task or existing task?}
22
+ Pick -->|new| Brief[brief path]
23
+ Brief --> Suggest{brief frontmatter suggestions?}
24
+ Suggest -->|yes| GroupPick[task-group pick]
25
+ Suggest -->|no| GroupText[task-group text]
26
+ GroupPick --> Id
27
+ GroupText --> Id
28
+ Id[task-id pick/text] --> Type[task-type = requirements-discovery]
29
+ Pick -->|existing| Type
30
+ Type --> Keep{existing brief?}
31
+ Keep -->|keep| Base
32
+ Keep -->|change/no brief| Brief
33
+ Type --> Base{active task worktree?}
34
+ Base -->|yes| Defaults[Use defaults / Customize]
35
+ Base -->|no| BaseRef[base-ref pick/text]
36
+ BaseRef --> Defaults
37
+ Defaults --> Workers[worker multi-pick<br/>still asked even on defaults]
38
+ Workers --> Custom{customize?}
39
+ Custom -->|yes| ModelsAndExtras[models, directive, related tasks, clarification]
40
+ Custom -->|no| Confirm
41
+ ModelsAndExtras --> Confirm
42
+ Confirm --> Render[render-bundle]
43
+ ```
44
+
45
+ worker multi-pick에서 picker는 `report-writer`를 옵션으로 보여주지 않는다. 사용자가 `claude`만 골라도 wizard가 `report-writer`를 강제 append한다. optional `gemini`는 사용자가 골랐을 때만 포함된다.
46
+
47
+ ## 3. prepare_task_bundle 처리
48
+
49
+ ```mermaid
50
+ sequenceDiagram
51
+ participant W as wizard/render-bundle
52
+ participant P as prepare_task_bundle
53
+ participant Prof as requirements-discovery.md
54
+ participant Git as worktree registry
55
+ participant FS as task artifacts
56
+
57
+ W->>P: task-type=requirements-discovery, brief, base-ref, workers
58
+ P->>Prof: profile exists, Required workers parsed
59
+ P->>P: verify installation, upsert project.json
60
+ P->>P: resolve workers from profile + override
61
+ P->>Git: create or reuse task worktree
62
+ P->>P: expand _common-contract include
63
+ P->>FS: write instruction-set and manifests
64
+ P->>FS: render workflow currentPhase=requirements-discovery
65
+ P-->>W: prepared lead prompt
66
+ ```
67
+
68
+ runtime에서 이 phase만을 위한 추가 hard gate는 없다. 중요한 gate는 profile file 존재, brief file 존재, base-ref가 first phase에서 resolvable해야 한다는 worktree gate, worker override가 profile roster 범위를 벗어나지 않아야 한다는 gate다.
69
+
70
+ ## 4. lead 실행 흐름
71
+
72
+ ```mermaid
73
+ flowchart TD
74
+ P1[Phase 1 intake<br/>manifest, brief, profile, run manifest, team-state] --> P2[Phase 2 prompts]
75
+ P2 --> P3[Phase 3 TeamCreate]
76
+ P3 --> P4[Phase 4/5 dispatch analysers<br/>claude/codex + optional gemini]
77
+ P4 --> C[Phase 5.5 convergence<br/>default maxRounds = 1]
78
+ C --> R[Phase 6 report-writer authors final report]
79
+ R --> P7[Phase 7 token usage, validate, persist]
80
+ ```
81
+
82
+ `requirements-discovery`는 convergence default가 1 round다. 이 예외는 `render._build_convergence_block()`와 `agents/SKILL.md` 모두에서 명시된다.
83
+
84
+ ## 5. 산출물과 routing
85
+
86
+ ```mermaid
87
+ flowchart LR
88
+ RD[requirements-discovery final report] --> Class[work-category classification]
89
+ RD --> Missing[missing materials / clarification items]
90
+ RD --> Domain[Domain Alignment<br/>terminology resolution]
91
+ RD --> Route{next safe phase}
92
+ Route --> EA[error-analysis]
93
+ Route --> IP[implementation-planning]
94
+ Route -. invalid .-> Impl[implementation<br/>not allowed directly]
95
+ ```
96
+
97
+ final report는 다음을 특히 강조한다.
98
+
99
+ - evidence-backed routing decision
100
+ - missing input과 uncertainty boundary
101
+ - 다음 phase 및 safe resume guidance
102
+ - `terminology:*` brief item에 대한 canonical term resolution
103
+ - blocking input이 있으면 `## 5. Clarification Items` unified table에 `Blocks=next-phase`
104
+
105
+ Non-goal은 source edit, plan authoring, build, deployment다.
106
+
107
+ ## 6. 확인한 코드
108
+
109
+ - [`skills/okstra-run/SKILL.md`](../../skills/okstra-run/SKILL.md)
110
+ - [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py)
111
+ - [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
112
+ - [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py)
113
+ - [`prompts/profiles/requirements-discovery.md`](../../prompts/profiles/requirements-discovery.md)
114
+ - [`agents/SKILL.md`](../../agents/SKILL.md)
115
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.34.0",
3
+ "version": "0.36.0",
4
4
  "description": "Multi-agent cross-verification orchestrator runtime + Claude Code skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.34.0",
3
- "builtAt": "2026-05-19T16:31:42.883Z",
2
+ "package": "0.36.0",
3
+ "builtAt": "2026-05-23T15:38:53.956Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -136,7 +136,7 @@ Executor is chosen at run-prep time via `--executor <claude|codex|gemini>` (or `
136
136
  - Location: `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` (override `OKSTRA_HOME` only for tests). All segments are sanitised — `/`, `:`, and other special chars collapse to `-`.
137
137
  - Branch: `<work-category-prefix>-<task-id-segment>` (e.g. `feat-dev-9436`, `fix-dev-7311`). Branched from `HEAD` of the repo's **main** worktree at the first phase's prep time; base SHA is recorded in `EXECUTOR_WORKTREE_BASE_REF`.
138
138
  - A global registry at `~/.okstra/worktrees/registry.json` (flock-guarded) maps each task-key to its path + branch and prevents concurrent runs from colliding. Branch names are globally unique across task-keys on this machine.
139
- - Sync dirs (`.project-docs`, `.scratch`, `graphify-out` by default; override with `OKSTRA_WORKTREE_SYNC_DIRS`) are symlinked from the **main worktree** so every task observes the same shared state irrespective of which checkout invoked okstra.
139
+ - Worktree sync mirrors the configured project-relative directories from the **main worktree** so task checkouts see the same filesystem state. This is filesystem continuity only: okstra-owned context and writes still stay inside `<PROJECT_ROOT>/.project-docs/okstra/**` unless the brief explicitly authorizes a non-okstra path.
140
140
  - The path, branch, base ref, and provisioning status (`created` | `reused` | `skipped-in-worktree` | `skipped-not-git`) are exposed through the launch prompt's `## Executor Worktree` section and the implementation profile's worktree block.
141
141
  - **Skip conditions** (worktree provisioning is a no-op; task uses `project_root` directly):
142
142
  - `project_root` is already inside a non-main worktree (the run reuses the caller's worktree to avoid nesting).
@@ -150,21 +150,27 @@ Executor is chosen at run-prep time via `--executor <claude|codex|gemini>` (or `
150
150
 
151
151
  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 `.project-docs/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 `.project-docs/okstra/discovery/task-catalog.json` first.
152
152
 
153
- After context-loader completes, read the following files. The ordering below reflects logical priority for synthesis; for execution, lead MUST issue all Read calls **in a single message (parallel reads)** these files are independent and serial reads waste several seconds per run with no benefit.
153
+ After context-loader completes, read **only the five mandatory 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 came from observed lead-token bloat: in `fontsninja-classifier-v2:dev-9461:dev-9495` RD-001 the lead burned 71 M tokens (97 % cache_read) largely because every phase entry re-absorbed a 93 KB instruction-set baseline that included files only one downstream phase ever actually used.
154
+
155
+ **Mandatory at Phase 1 start (parallel Read, one message):**
154
156
 
155
157
  1. `task-manifest.json` (found by context-loader)
156
- 2. `task-index.md` only if a quick human summary is useful
157
- 3. `instruction-set/analysis-profile.md`
158
- 4. `instruction-set/analysis-material.md`
159
- 5. `instruction-set/reference-expectations.md`
160
- 6. `instruction-set/task-brief.md`
161
- 7. `instruction-set/final-report-template.md`
162
- 8. the current run manifest under `runs/<task-type>/manifests/`
163
- 9. the current run team-state artifact
158
+ 2. `instruction-set/task-brief.md` needed to compose every worker prompt
159
+ 3. `instruction-set/analysis-profile.md` — needed to compose worker prompts and pick the right `Required workers:` block
160
+ 4. the current run manifest under `runs/<task-type>/manifests/`
161
+ 5. the current run team-state artifact
162
+
163
+ **Lazy reading discipline (do NOT read at Phase 1):**
164
+
165
+ - `task-index.md` — only when the user explicitly asks for a human summary or when history disambiguation is required.
166
+ - `instruction-set/analysis-material.md` — read at Phase 2 only if it is referenced by `analysis-profile.md` or by the brief. Many task bundles have no material file (the placeholder `> 자료가 제공되지 않았습니다` is canonical); in that case skip.
167
+ - `instruction-set/reference-expectations.md` — read at Phase 6 synthesis (or whenever the report-writer worker is dispatched) — it informs the match/gap assessment, not worker dispatch.
168
+ - `instruction-set/final-report-template.md` — never read by Lead. The Report writer worker reads it as part of its own [Required reading]; Lead only references its path when dispatching.
169
+ - `history/timeline.json` — read only on user request or when carry-in resolution requires it.
164
170
 
165
- Extract: task key, task type, work category, workflow lifecycle snapshot, selected worker roster, assigned models, worker result paths, worker prompt history paths, current run prompt directory, final report path, final status path, validator path, resume helper path, config-file references, deployment-manifest references, and their expected values or invariants.
171
+ Extract from the five mandatory files: task key, task type, work category, workflow lifecycle snapshot, selected worker roster, assigned models, worker result paths, worker prompt history paths, current run prompt directory, final report path, final status path, validator path, resume helper path, config-file references, deployment-manifest references, and their expected values or invariants.
166
172
 
167
- If previous run reports exist, use as historical context only. If `history/timeline.json` exists, use it to review past runs. If discovery metadata or current artifacts conflict with a newer user instruction, prefer the user instruction. If `reference-expectations.md` explicitly says expectations were not provided, treat that as missing information and say `I don't know` rather than inventing expected states.
173
+ If previous run reports exist, use as historical context only. If discovery metadata or current artifacts conflict with a newer user instruction, prefer the user instruction. If `reference-expectations.md` explicitly says expectations were not provided (you can confirm this without reading the file if the brief's "Expected state" section is empty), treat that as missing information and say `I don't know` rather than inventing expected states.
168
174
 
169
175
  ## Phase 2 — Phase 5: Prompt preparation, team creation, execution, fallback
170
176
 
@@ -246,6 +252,16 @@ If convergence is disabled, proceed directly to Phase 6 with the raw worker resu
246
252
 
247
253
  If `Report writer worker` is in the selected roster (`recommendedWorkers` / `resultContract.requiredWorkerRoles`), **Lead MUST dispatch it to write `runs/<task-type>/reports/final-report-<task-type>-<seq>.md`**. Lead does NOT write that file. Lead's role in this phase is: prepare the report-writer prompt (carrying convergence output, all worker results, and reference expectations), dispatch, then review the produced file.
248
254
 
255
+ Before constructing the dispatch prompt, the lead MUST:
256
+
257
+ - Resolve report language: read `project.json.reportLanguage` (fallback
258
+ `~/.okstra/config.json.reportLanguage`, then literal `auto`). If the
259
+ resolved value is `auto`, inspect the task brief and pick `en` or `ko`
260
+ based on its main prose language (default `en` when the brief is
261
+ mostly code/identifiers). Pass the final `en` or `ko` value as
262
+ `**Report Language:**` in the report-writer dispatch prompt, and ensure
263
+ the worker writes the same value into `data.json.meta.reportLanguage`.
264
+
249
265
  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:
250
266
 
251
267
  1. Full Consensus
@@ -313,7 +329,7 @@ jq -s 'group_by(.errorType) | map({type: .[0].errorType, count: length})' <runDi
313
329
 
314
330
  The errors log is informational. Its presence/absence does not affect the final verdict. Do not block report writing on it.
315
331
 
316
- After persistence, reply briefly in Korean with: completion status, final report path, team-state path, validator result, resume command path, any remaining blocker.
332
+ 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.
317
333
 
318
334
  ## Common Mistakes
319
335
 
@@ -52,6 +52,8 @@ Unlike the Codex / Gemini workers, you are an in-process Claude subagent — you
52
52
 
53
53
  6. If the task brief includes an `## Available MCP Servers` section in the lead prompt, treat that as the canonical list of MCP tools you may invoke for this run. If a needed server is not listed, record `MCP not available for this run` rather than calling it.
54
54
 
55
+ 7. When `Task Type` is `improvement-discovery`, the lead's Phase 1.5 reflect-back log at `<RUN_DIR>/state/phase-1.5-grilling.md` is the authoritative scope and lens definition. Read its `Resolved scope` and `Resolved lenses` blocks and do NOT re-interpret the brief's raw `scan-scope` / `priority-lenses` fields. Findings that violate the resolved lens whitelist or scope are rejected by `validators/validate-improvement-report.py`.
56
+
55
57
  ## Required Reading Before Any Analysis
56
58
 
57
59
  Before producing any output, you MUST read every input file enumerated in the `[Required reading]` block of the lead's prompt from the very first character to the very last character. For analysis workers this includes the task brief, analysis profile, analysis material (if present), reference expectations, and the carry-in clarification response (if present). Analysis workers do NOT read `final-report-template.md` — that file is for the Report writer worker only (see `okstra-team-contract` "Audience-scoped enumeration"). Producing findings without the template is the intended contract; the report writer in Phase 6 owns final-report structure.
@@ -117,3 +119,27 @@ There is NO `cli-failure` category for this worker — Claude worker has no exte
117
119
  - Return error messages as-is on failure.
118
120
  - Do not summarize or modify your own analysis output beyond the structured sections above.
119
121
  - Sections 1–5 are the common core — same dimensions for every analysis worker. Your specialization (broad reasoning depth, hidden-assumption surfacing, execution-risk decomposition) only enters Section 6 if you have additive content beyond the core. See `skills/okstra-team-contract/SKILL.md` "Worker Output Contract" for the authoritative split.
122
+
123
+ ## Stage evidence emission (BLOCKING, implementation task only)
124
+
125
+ When this run's `task_type` is `implementation` and you are acting as the **Executor**, after the Stage Validation `post` commands all return exit code 0 you MUST emit a single JSON document matching `docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md` §3.2:
126
+
127
+ ```json
128
+ {
129
+ "schemaVersion": 1,
130
+ "sourcePlanPath": "<approved-plan path>",
131
+ "stageNumber": <int>,
132
+ "stageTitle": "<from Stage Map>",
133
+ "completedAt": "<ISO-8601 with tz>",
134
+ "stageCommitRange": { "base": "<sha>", "head": "<sha>" },
135
+ "filesChanged": ["<rel/path>", "..."],
136
+ "newIdentifiers": ["<name>", "..."],
137
+ "stepResults": [{"step": <int>, "status": "done", "commit": "<sha>"}],
138
+ "validationsPassed": ["<label>", "..."],
139
+ "notes": []
140
+ }
141
+ ```
142
+
143
+ Emit this as a fenced ```json``` block in your worker result under the heading `### Stage Carry Evidence`. The lead (`Claude lead`) is responsible for persisting the block as `runs/<impl-task-key>/carry/stage-<N>.json` — you do not write the file yourself.
144
+
145
+ This applies only when `task_type` is `implementation`. For other task types, skip this block entirely.
@@ -79,7 +79,7 @@ The wrapper exists because Claude Code's Bash permission matcher rejects simple-
79
79
  ```
80
80
  Call `Bash` with `run_in_background: true`. Capture the returned `bash_id` (a.k.a. `shell_id`). Pass the positional arguments verbatim — do NOT use environment variables, `cd`, `&&` chains, or pipes from `cat`. Substitute the literal extracted Project Root, model execution value, prompt-history path, and worktree path. The fourth argument is **mandatory for implementation phase** (extract from `EXECUTOR_WORKTREE_PATH` in the lead prompt's run context or the `**Worktree:**` / `cwd for every mutating command:` line) and **may be omitted only for non-implementation analysis phases** that do not mutate the worktree. Omitting it during implementation will cause every Edit/Write to fail with EPERM. The wrapper handles `-C`, `--add-dir`, `--model`, `--sandbox workspace-write`, the stdin redirect from the prompt file, and stderr suppression internally. Calling `codex exec` directly (without the wrapper) is an error in this skill: the redirect tokens disqualify the prefix match against `Bash(codex exec:*)` and produce a permission prompt every dispatch.
81
81
 
82
- **Poll loop (BashOutput-only, 30-minute hard cap):**
82
+ **Poll loop (BashOutput-only, 30-minute cap):**
83
83
  - Record `start_ts` at dispatch time via a single `Bash` call: `date +%s` (output captured).
84
84
  - Repeat:
85
85
  1. Call `BashOutput(bash_id: <shell_id>)`. Inspect `status`. The harness's `BashOutput` primitive already waits internally for new output before returning; back-to-back calls are the canonical wait mechanism for a background shell.
@@ -108,6 +108,8 @@ The wrapper exists because Claude Code's Bash permission matcher rejects simple-
108
108
 
109
109
  d. **Normal return.** Otherwise (`exit_code == 0` AND result file exists), concatenate the wrapper's accumulated stdout from `BashOutput` and return it as-is without modification.
110
110
 
111
+ 9. When `Task Type` is `improvement-discovery`, the lead's Phase 1.5 reflect-back log at `<RUN_DIR>/state/phase-1.5-grilling.md` is the authoritative scope and lens definition. Read its `Resolved scope` and `Resolved lenses` blocks and do NOT re-interpret the brief's raw `scan-scope` / `priority-lenses` fields. Findings that violate the resolved lens whitelist or scope are rejected by `validators/validate-improvement-report.py`.
112
+
111
113
  ## Stop Condition
112
114
 
113
115
  This wrapper is a thin Bash-execution shell over the Codex CLI (via `okstra-codex-exec.sh`). The CLI process itself is the analysis engine; this subagent's only job is to dispatch it and forward output. Therefore:
@@ -227,3 +229,27 @@ pre-flight terminal status, not a runtime CLI error.
227
229
  - Return error messages as-is on failure.
228
230
  - Do not summarize or modify Codex results.
229
231
  - Sections 1–5 of the worker output are the common core shared with the Claude and Gemini workers — the dispatched prompt asks identical questions for all three roles, and the Codex CLI must answer all of them, not only implementation-realism 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 `skills/okstra-team-contract/SKILL.md` "Worker Output Contract".
232
+
233
+ ## Stage evidence emission (BLOCKING, implementation task only)
234
+
235
+ When this run's `task_type` is `implementation` and you are acting as the **Executor**, after the Stage Validation `post` commands all return exit code 0 you MUST emit a single JSON document matching `docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md` §3.2:
236
+
237
+ ```json
238
+ {
239
+ "schemaVersion": 1,
240
+ "sourcePlanPath": "<approved-plan path>",
241
+ "stageNumber": <int>,
242
+ "stageTitle": "<from Stage Map>",
243
+ "completedAt": "<ISO-8601 with tz>",
244
+ "stageCommitRange": { "base": "<sha>", "head": "<sha>" },
245
+ "filesChanged": ["<rel/path>", "..."],
246
+ "newIdentifiers": ["<name>", "..."],
247
+ "stepResults": [{"step": <int>, "status": "done", "commit": "<sha>"}],
248
+ "validationsPassed": ["<label>", "..."],
249
+ "notes": []
250
+ }
251
+ ```
252
+
253
+ Emit this as a fenced ```json``` block in your worker result under the heading `### Stage Carry Evidence`. The lead (`Claude lead`) is responsible for persisting the block as `runs/<impl-task-key>/carry/stage-<N>.json` — you do not write the file yourself.
254
+
255
+ This applies only when `task_type` is `implementation`. For other task types, skip this block entirely.
@@ -79,7 +79,7 @@ The wrapper exists because Claude Code's Bash permission matcher rejects simple-
79
79
  ```
80
80
  Call `Bash` with `run_in_background: true`. Capture the returned `bash_id` (a.k.a. `shell_id`). Pass the positional arguments verbatim — do NOT use environment variables, `cd`, `&&` chains, or pipes from `cat`. Substitute the literal extracted Project Root, model execution value, prompt-history path, and worktree path. The fourth argument is **mandatory for implementation phase** (extract from `EXECUTOR_WORKTREE_PATH` in the lead prompt's run context or the `**Worktree:**` / `cwd for every mutating command:` line) and **may be omitted only for non-implementation analysis phases** that do not mutate the worktree. The wrapper handles `-p -`, `-m`, `-o text`, `--include-directories`, the stdin redirect from the prompt file, and stderr suppression internally. Calling `gemini` directly (without the wrapper) is an error in this skill: the redirect tokens disqualify the prefix match against `Bash(gemini:*)` and produce a permission prompt every dispatch.
81
81
 
82
- **Poll loop (BashOutput-only, 30-minute hard cap):**
82
+ **Poll loop (BashOutput-only, 30-minute cap):**
83
83
  - Record `start_ts` at dispatch time via a single `Bash` call: `date +%s` (output captured).
84
84
  - Repeat:
85
85
  1. Call `BashOutput(bash_id: <shell_id>)`. Inspect `status`. The harness's `BashOutput` primitive already waits internally for new output before returning; back-to-back calls are the canonical wait mechanism for a background shell.
@@ -108,6 +108,8 @@ The wrapper exists because Claude Code's Bash permission matcher rejects simple-
108
108
 
109
109
  d. **Normal return.** Otherwise (`exit_code == 0` AND result file exists), concatenate the wrapper's accumulated stdout from `BashOutput` and return it as-is without modification.
110
110
 
111
+ 9. When `Task Type` is `improvement-discovery`, the lead's Phase 1.5 reflect-back log at `<RUN_DIR>/state/phase-1.5-grilling.md` is the authoritative scope and lens definition. Read its `Resolved scope` and `Resolved lenses` blocks and do NOT re-interpret the brief's raw `scan-scope` / `priority-lenses` fields. Findings that violate the resolved lens whitelist or scope are rejected by `validators/validate-improvement-report.py`.
112
+
111
113
  ## Stop Condition
112
114
 
113
115
  This wrapper is a thin Bash-execution shell over the Gemini CLI (via `okstra-gemini-exec.sh`). The CLI process itself is the analysis engine; this subagent's only job is to dispatch it and forward output. Therefore:
@@ -227,3 +229,27 @@ pre-flight terminal status, not a runtime CLI error.
227
229
  - Return error messages as-is on failure.
228
230
  - Do not summarize or modify Gemini results.
229
231
  - 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 Gemini 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 Gemini result whose Findings section is populated solely with requirement-interpretation items is in breach of contract; see `skills/okstra-team-contract/SKILL.md` "Worker Output Contract".
232
+
233
+ ## Stage evidence emission (BLOCKING, implementation task only)
234
+
235
+ When this run's `task_type` is `implementation` and you are acting as the **Executor**, after the Stage Validation `post` commands all return exit code 0 you MUST emit a single JSON document matching `docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md` §3.2:
236
+
237
+ ```json
238
+ {
239
+ "schemaVersion": 1,
240
+ "sourcePlanPath": "<approved-plan path>",
241
+ "stageNumber": <int>,
242
+ "stageTitle": "<from Stage Map>",
243
+ "completedAt": "<ISO-8601 with tz>",
244
+ "stageCommitRange": { "base": "<sha>", "head": "<sha>" },
245
+ "filesChanged": ["<rel/path>", "..."],
246
+ "newIdentifiers": ["<name>", "..."],
247
+ "stepResults": [{"step": <int>, "status": "done", "commit": "<sha>"}],
248
+ "validationsPassed": ["<label>", "..."],
249
+ "notes": []
250
+ }
251
+ ```
252
+
253
+ Emit this as a fenced ```json``` block in your worker result under the heading `### Stage Carry Evidence`. The lead (`Claude lead`) is responsible for persisting the block as `runs/<impl-task-key>/carry/stage-<N>.json` — you do not write the file yourself.
254
+
255
+ This applies only when `task_type` is `implementation`. For other task types, skip this block entirely.
@@ -16,6 +16,10 @@ tools: ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "TodoWrite", "WebFetch"
16
16
 
17
17
  You are the `Report writer worker` for okstra cross-verification. Your sole responsibility is to **author the final-report data.json** (the JSON SSOT) at the assigned `Result Path`, plus an audit sidecar. You are NOT an analysis worker — you do not produce independent findings, you do not vote in convergence, and you do not re-do the workers' analysis.
18
18
 
19
+ - The `**Report Language:**` header in your dispatch prompt is already
20
+ resolved to `en` or `ko` by the lead. Copy it verbatim into
21
+ `data.json.meta.reportLanguage`. Never write `auto` here.
22
+
19
23
  ## Authority
20
24
 
21
25
  You are the canonical author of `runs/<task-type>/reports/final-report-<task-type>-<seq>.data.json` for this run. Claude lead has explicitly delegated file-authorship to you. The lead reviews your output but does not write the file.
@@ -60,6 +64,8 @@ Before writing the data.json, you MUST read every input file enumerated in the `
60
64
 
61
65
  - `schemas/final-report-v1.0.schema.json` — the JSON Schema you must conform to. The renderer + validator both consume this.
62
66
  - `templates/reports/final-report.template.md` — the Jinja2 template the renderer uses. Read this to understand which data.json fields appear where in the rendered markdown, but do NOT edit it.
67
+ - `templates/reports/i18n/en.json`
68
+ - `templates/reports/i18n/ko.json`
63
69
  - Every analysis worker's result file under `worker-results/`.
64
70
  - `state/convergence-<task-type>-<seq>.json` (if present).
65
71
 
@@ -75,7 +81,7 @@ You author the final-report data.json (the JSON SSOT). The schema is `schemas/fi
75
81
 
76
82
  The rendered markdown (`final-report-<task-type>-<seq>.md`) is produced by `scripts/okstra-render-final-report.py` immediately after you write the data.json. The HTML view (`*.html`) is produced from the markdown by Phase 7 step 1.5 (`scripts/okstra-render-report-views.py`). The data.json is the only file you write; the rest are derived.
77
83
 
78
- Hard rules (the schema enforces most of these — they are listed here so you know *what* to populate, not *how* to validate):
84
+ Rules (the schema enforces most of these — they are listed here so you know *what* to populate, not *how* to validate):
79
85
 
80
86
  - `header.reportAuthor` is `"Report writer worker"`; `header.reportOwner` is `"Claude lead"`. Set author to `"Claude lead"` only for `release-handoff` runs (single-lead by design) or a recorded report-writer dispatch failure fallback.
81
87
  - **Source items (worker:item) preservation.** Every `consensus[].sourceItems`, `differences[].workersPosition[].itemId`, and `evidence.primary[].sourceItems` entry MUST carry the worker:item-id pair (e.g. `claude:F-001`, `codex:1.1`, `gemini:F-3`, or `lead:mcp-1` for lead-only evidence). The schema enforces this via the `SourceItem` regex; bare worker-name lists no longer parse.
@@ -92,6 +98,7 @@ Hard rules (the schema enforces most of these — they are listed here so you kn
92
98
  - If evidence is missing, write `"I don't know"` in the relevant statement field rather than fabricating confidence.
93
99
  - Cite file paths and line numbers in every `evidence.primary[].source` / `consensus[].evidence` cell.
94
100
  - Preserve every analysis worker's ticket tagging — every row's `ticketId` field carries the ticket key or the task-fallback. For single-ticket runs, set `ticketCoverage` to `{"singleTicket": "<ticket>"}`. For runs that do not require ticket tagging (`release-handoff`, `final-verification`), set `ticketCoverage` to `{"omit": true}`.
101
+ - When the `Task Type` is `improvement-discovery`, populate `## 4.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.
95
102
 
96
103
  Write the data.json with your `Write` tool against the absolute `Result Path`. Then invoke the renderer (`Bash`): `python3 scripts/okstra-render-final-report.py <data.json path>`. Confirm both files exist and respond with a short status line: `data.json written to <abs path>; markdown rendered to <abs path>. Sections populated: <count>.`
97
104
 
@@ -102,11 +102,11 @@ print(json.dumps({k: v for k, v in zip(it, it)}, ensure_ascii=False))
102
102
  PROJECT_ROOT "${PROJECT_ROOT-}" \
103
103
  TASK_GROUP "${TASK_GROUP-}" \
104
104
  TASK_ID "${TASK_ID-}" \
105
- ANALYSIS_TYPE "${ANALYSIS_TYPE-}" \
105
+ TASK_TYPE "${TASK_TYPE-}" \
106
106
  OKSTRA_RUN_SEQ "$_run_seq" \
107
107
  RUN_TIMESTAMP_ISO "${RUN_TIMESTAMP_ISO-}" \
108
- SELECTED_REVIEWERS "${SELECTED_REVIEWERS-}" \
109
- LEAD_MODEL_DISPLAY "${LEAD_MODEL_DISPLAY-}" \
108
+ RECOMMENDED_ANALYSERS "${RECOMMENDED_ANALYSERS-}" \
109
+ LEAD_MODEL "${LEAD_MODEL-}" \
110
110
  RUN_DIR_RELATIVE_PATH "${RUN_DIR_RELATIVE_PATH-}" \
111
111
  FINAL_REPORT_RELATIVE_PATH "${FINAL_REPORT_RELATIVE_PATH-}" \
112
112
  FINAL_STATUS_RELATIVE_PATH "${FINAL_STATUS_RELATIVE_PATH-}" \
@@ -134,11 +134,11 @@ with lockfile.open("r+") as lock:
134
134
  project_root=payload["PROJECT_ROOT"],
135
135
  task_group=payload["TASK_GROUP"],
136
136
  task_id=payload["TASK_ID"],
137
- task_type=payload.get("ANALYSIS_TYPE", ""),
137
+ task_type=payload.get("TASK_TYPE", ""),
138
138
  run_seq=int(payload["OKSTRA_RUN_SEQ"]),
139
139
  when=payload["RUN_TIMESTAMP_ISO"],
140
- workers=[w for w in payload.get("SELECTED_REVIEWERS", "").split(",") if w],
141
- lead_model=payload.get("LEAD_MODEL_DISPLAY", ""),
140
+ workers=[w for w in payload.get("RECOMMENDED_ANALYSERS", "").split(",") if w],
141
+ lead_model=payload.get("LEAD_MODEL", ""),
142
142
  run_dir_rel=payload.get("RUN_DIR_RELATIVE_PATH", ""),
143
143
  final_report_rel=payload.get("FINAL_REPORT_RELATIVE_PATH", ""),
144
144
  final_status_rel=payload.get("FINAL_STATUS_RELATIVE_PATH", ""),