okstra 0.20.0 → 0.21.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 (39) hide show
  1. package/docs/kr/architecture.md +1 -1
  2. package/docs/kr/performance-improvement-plan-v2.md +330 -0
  3. package/docs/kr/performance-improvement-plan.md +125 -0
  4. package/docs/project-structure-overview.md +386 -0
  5. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +1568 -0
  6. package/package.json +1 -1
  7. package/runtime/BUILD.json +2 -2
  8. package/runtime/agents/SKILL.md +7 -1
  9. package/runtime/agents/workers/codex-worker.md +6 -4
  10. package/runtime/agents/workers/gemini-worker.md +6 -4
  11. package/runtime/agents/workers/report-writer-worker.md +4 -0
  12. package/runtime/bin/okstra-codex-exec.sh +36 -6
  13. package/runtime/bin/okstra-gemini-exec.sh +6 -8
  14. package/runtime/prompts/profiles/final-verification.md +8 -2
  15. package/runtime/prompts/profiles/implementation-planning.md +1 -1
  16. package/runtime/prompts/profiles/release-handoff.md +26 -28
  17. package/runtime/prompts/profiles/requirements-discovery.md +1 -1
  18. package/runtime/python/okstra_ctl/render.py +78 -4
  19. package/runtime/python/okstra_ctl/run.py +0 -6
  20. package/runtime/python/okstra_ctl/run_context.py +5 -0
  21. package/runtime/python/okstra_ctl/workflow.py +8 -7
  22. package/runtime/python/okstra_ctl/worktree.py +155 -15
  23. package/runtime/python/okstra_token_usage/blocks.py +0 -2
  24. package/runtime/python/okstra_token_usage/claude.py +0 -2
  25. package/runtime/skills/okstra-brief/SKILL.md +523 -0
  26. package/runtime/skills/okstra-convergence/SKILL.md +149 -37
  27. package/runtime/skills/okstra-report-writer/SKILL.md +8 -6
  28. package/runtime/templates/prd/brief.template.md +12 -0
  29. package/runtime/templates/project-docs/task-index.template.md +12 -0
  30. package/runtime/templates/reports/error-analysis-input.template.md +12 -0
  31. package/runtime/templates/reports/final-report.template.md +39 -12
  32. package/runtime/templates/reports/final-verification-input.template.md +22 -0
  33. package/runtime/templates/reports/implementation-input.template.md +12 -0
  34. package/runtime/templates/reports/implementation-planning-input.template.md +12 -0
  35. package/runtime/templates/reports/quick-input.template.md +12 -0
  36. package/runtime/templates/reports/release-handoff-input.template.md +23 -10
  37. package/runtime/templates/reports/schedule.template.md +12 -0
  38. package/runtime/templates/reports/settings.template.json +83 -30
  39. package/runtime/templates/reports/task-brief.template.md +12 -0
@@ -836,7 +836,7 @@ Claude가 작성하는 최종 보고서는 brief에 더 구체적인 형식이
836
836
  ### Live-log mirror (codex / gemini wrapper)
837
837
 
838
838
  - `scripts/okstra-codex-exec.sh`, `scripts/okstra-gemini-exec.sh` 는 dispatch 마다 prompt path 옆에 `<prompt>.log` sidecar 를 만들고 stdout 을 거기로 mirror 합니다 (`tee`, `PIPESTATUS[0]` 로 종료코드 보존). stderr 은 같은 파일에 append (subagent stderr 캡처 contract 보존), 매 dispatch 시 truncate. 호출 subagent 의 `BashOutput` 폴링은 60s 간격이라 long-running run (analysis 의 large-codebase scan, implementation 의 cargo / pytest) 동안 사용자가 stalled state 를 탐지할 수 없는 문제를 해소합니다.
839
- - `$TMUX` 가 셋팅된 lead 환경이면 wrapper 가 sibling pane 을 자동 분할해 `tail -F <log-path>` 를 띄웁니다. pane title 은 `<cli>-<role>-trace` (e.g. `codex-executor-trace`, `gemini-worker-trace`); role 은 wrapper 의 5번째 optional positional 인자로 명시 가능하며, 누락 시 worktree-path 인자 유무에 따라 `executor` / `worker` 자동 결정. focus 는 caller pane 으로 복귀하고, CLI 종료 후 pane 은 유지돼 스크롤백 가능. `$TMUX` 미설정, split 실패, 구버전 tmux 등 모든 경로는 silent degrade.
839
+ - `$TMUX` 가 셋팅된 lead 환경이면 wrapper 가 sibling pane 을 자동 분할해 `tail -F <log-path>` 를 띄웁니다. pane title 은 `<cli>-<role>-trace` (e.g. `codex-worker-trace`, `gemini-worker-trace`); role 은 wrapper 의 5번째 optional positional 인자이며, 누락 시 기본값 `worker` 떨어집니다. caller 가 다른 라벨(예: `executor`)을 원하면 5번째 인자로 명시해야 합니다. focus 는 caller pane 으로 복귀하고, CLI 종료 후 pane 은 유지돼 스크롤백 가능. `$TMUX` 미설정, split 실패, 구버전 tmux 등 모든 경로는 silent degrade.
840
840
  - 디스크 누적은 `okstra-logs` skill 이 read-only 로 인벤토리 + cleanup 명령을 제안합니다 (실행은 사용자 copy-paste).
841
841
 
842
842
  ### Linked-worktree `.git/` write 권한 (codex / gemini)
@@ -0,0 +1,330 @@
1
+ # okstra-run 성능 개선 계획 v2
2
+
3
+ ## 1. 목적
4
+
5
+ `okstra-run` 스킬 또는 `scripts/okstra.sh`로 시작하는 cross-verification run이 무겁게 느껴지는 문제를 줄인다. 이 문서는 현재 구조를 정확한 레이어로 나누고, 개선 후보의 우선순위, 측정 기준, 병렬 작업 가능성, 1차 구현 범위를 정리한다.
6
+
7
+ 핵심 판단:
8
+
9
+ - 가장 큰 비용은 prepare 단계가 아니라 worker dispatch 이후의 반복 검증과 장문 prompt 소비에서 발생한다.
10
+ - 먼저 convergence 재검증 범위를 줄여 worker 호출 수와 wall-clock을 낮춘다.
11
+ - fast-track, prompt 캐싱, 템플릿/worker 정의 축소는 서로 다른 레이어를 건드리므로 별도 작업으로 분리한다.
12
+
13
+ ## 2. 현재 구조 요약
14
+
15
+ ### 2.1 진입점
16
+
17
+ `scripts/okstra.sh`와 `skills/okstra-run/SKILL.md`는 모두 `scripts/okstra_ctl/run.py`의 `prepare_task_bundle()`을 호출한다. 이 단일 reference point는 유지해야 한다.
18
+
19
+ - `scripts/okstra.sh`: CLI 인자 파싱, `prepare_task_bundle()` 호출, non-render-only에서는 `claude` 실행.
20
+ - `okstra-run` skill: 현재 Claude 세션 안에서 입력을 모은 뒤 같은 Python entrypoint를 호출하고 lead 역할을 이어받음.
21
+ - shared prepare 로직: `scripts/okstra_ctl/run.py`.
22
+
23
+ ### 2.2 두 종류의 phase를 구분한다
24
+
25
+ 현재 문서/코드에는 이름이 비슷한 phase가 두 층에 존재한다. 성능 개선 작업은 이 둘을 섞으면 안 된다.
26
+
27
+ #### Task-type lifecycle
28
+
29
+ `scripts/okstra_ctl/workflow.py`의 `PHASE_SEQUENCE`는 다음 6개 task-type만 가진다.
30
+
31
+ | 순서 | task-type | 책임 |
32
+ |---|---|---|
33
+ | 1 | `requirements-discovery` | work-category 분류, 안전한 다음 phase 라우팅, missing input 정리 |
34
+ | 2 | `error-analysis` | 증상, 원인 가설, 재현 갭, 검증 경로 분석 |
35
+ | 3 | `implementation-planning` | 최소 2개 구현 옵션, trade-off, 실행 순서, validation/rollback, 승인 요청 |
36
+ | 4 | `implementation` | 승인된 plan 실행, commit, verifier 검증, rollback evidence |
37
+ | 5 | `final-verification` | 수용성 검증, residual risk, release-handoff 진입 판단 |
38
+ | 6 | `release-handoff` | 사용자가 선택한 commit/push/PR 전달 작업 |
39
+
40
+ 각 okstra invocation은 정확히 하나의 task-type만 수행한다. 다음 task-type으로 넘어가려면 새 invocation이 필요하다.
41
+
42
+ #### Claude lead 운영 단계
43
+
44
+ `agents/SKILL.md` 안의 Phase 1~7은 하나의 task-type run 내부에서 lead가 수행하는 운영 단계다.
45
+
46
+ | 운영 단계 | 이름 | 책임 |
47
+ |---|---|---|
48
+ | 1 | Intake | task bundle 읽기 |
49
+ | 2~5 | Prompt / Team / Execution / Fallback | worker prompt 준비, team 생성, worker dispatch |
50
+ | 5.5 | Convergence | worker findings 재검증과 consensus 분류 |
51
+ | 6 | Synthesis | report-writer dispatch 또는 lead fallback |
52
+ | 7 | Persist | token usage 수집, final report placeholder 치환, manifest/status 정리 |
53
+
54
+ 따라서 본 문서에서 "P1 convergence 개선"은 task-type lifecycle을 바꾸는 작업이 아니라 `agents/SKILL.md` / `skills/okstra-convergence/SKILL.md`가 정의하는 lead 운영 단계의 비용을 줄이는 작업이다.
55
+
56
+ ### 2.3 prepare 단계의 비용 특성
57
+
58
+ `prepare_task_bundle()`은 instruction-set과 manifest 계열 파일을 순차 작성한다.
59
+
60
+ - instruction-set: `analysis-profile.md`, `analysis-material.md`, `task-brief.md`, optional carry-in/directive, `reference-expectations.md`, `final-report-template.md`, `claude-execution-prompt.md`, prompt snapshot.
61
+ - manifest/discovery: `team-state`, `task-manifest`, `task-index`, `run-manifest`, `timeline`, task catalog, latest task.
62
+
63
+ 이 단계의 직렬 render는 개선 여지가 있지만, 일반적으로 external worker dispatch보다 비용이 작다. 따라서 render 병렬화는 1차 목표가 아니다.
64
+
65
+ ### 2.4 worker 구조
66
+
67
+ 기본 worker 정의는 `agents/workers/` 아래 4종이다.
68
+
69
+ - `claude-worker.md`: Claude subagent.
70
+ - `codex-worker.md`: `okstra-codex-exec.sh` wrapper를 통해 Codex CLI 호출.
71
+ - `gemini-worker.md`: `okstra-gemini-exec.sh` wrapper를 통해 Gemini CLI 호출.
72
+ - `report-writer-worker.md`: final-report author. 분석 worker가 아니며 convergence 투표에서 제외된다.
73
+
74
+ ## 3. 성능 병목 가설
75
+
76
+ | ID | 병목 | 영향도 | 근거 / 확인 위치 | 판정 |
77
+ |---|---|---:|---|---|
78
+ | B1 | Convergence reverify round가 worker 수만큼 추가 dispatch를 만든다 | 높음 | `skills/okstra-convergence/SKILL.md` Round 1-N | 1차 개선 대상 |
79
+ | B2 | analysis worker prompt와 required reading이 길다 | 높음 | `agents/SKILL.md`, `okstra-team-contract`, worker definitions | 별도 prompt diet 작업 |
80
+ | B3 | report-writer가 worker 결과 + convergence + final-report-template을 다시 읽는다 | 중간 | `skills/okstra-report-writer/SKILL.md` | 구조상 필요. 중복 축소만 검토 |
81
+ | B4 | prepare 단계에서 여러 render/write가 직렬 수행된다 | 낮음~중간 | `scripts/okstra_ctl/run.py` render block | 후순위 |
82
+ | B5 | token usage collector가 session jsonl을 선형 스캔한다 | 낮음~중간 | `scripts/okstra_token_usage/` | run 종료 시 비용. 후순위 |
83
+ | B6 | 단순 작업도 같은 full workflow를 탄다 | 중간 | task-type lifecycle / requirements routing | fast-track 설계 필요 |
84
+
85
+ 확정 전제:
86
+
87
+ - `contested`는 2라운드 진입 전 존재하는 분류가 아니다. 현재 알고리즘에서 `contested`는 max round에 도달한 뒤 unresolved finding에 붙는 최종 분류다.
88
+ - 그러므로 "contested 항목만 2라운드"가 아니라 "1라운드 이후에도 mixed/unresolved인 verification queue만 2라운드"가 올바른 표현이다.
89
+
90
+ ## 4. 측정 기준
91
+
92
+ 개선 작업은 최소한 아래 지표를 전후 비교한다.
93
+
94
+ | 지표 | 수집 방법 | 목표 |
95
+ |---|---|---|
96
+ | worker dispatch 수 | team-state `workers[]`, convergence state round history, prompt 파일 수 | P1 적용 run에서 reverify dispatch 감소 |
97
+ | wall-clock | team-state worker usage `durationMs`, run start/end timestamp | convergence-heavy run에서 20~40% 단축 |
98
+ | raw token | token usage collector의 lead/worker total | reverify prompt 관련 worker token 감소 |
99
+ | billable equivalent | `usageSummary.*BillableEquivalentTokens` | 비용 감소 확인 |
100
+ | 품질 손상 여부 | final report의 contested/worker-unique 누락 여부, validator 통과 | 기존 contract 유지 |
101
+
102
+ P1 구현 전 최소 fixture:
103
+
104
+ 1. early convergence 사례: Round 0 또는 Round 1에서 verification queue가 비는 run.
105
+ 2. mixed/unresolved 사례: Round 1 후 일부 finding만 남아 선택적 Round 2가 필요한 run.
106
+ 3. worker failure 사례: reverify dispatch 일부가 `timeout`/`error`인 run.
107
+
108
+ ## 5. 개선 우선순위
109
+
110
+ ### P0. Baseline 계측과 용어 정리
111
+
112
+ 목표:
113
+
114
+ - 문서와 코드에서 task-type lifecycle과 lead 운영 단계를 혼동하지 않게 한다.
115
+ - convergence state에 `effectiveMaxRounds`, `roundsExecuted`, `dispatchCount`, `queueSizeByRound`, `finalClassificationCounts`를 명시하도록 P1에서 사용할 기준을 정한다.
116
+
117
+ 주요 변경 후보:
118
+
119
+ - `skills/okstra-convergence/SKILL.md`
120
+ - `agents/SKILL.md`
121
+ - 필요 시 convergence state schema 설명
122
+
123
+ 완료 기준:
124
+
125
+ - 문서가 `contested`를 중간 queue 이름으로 쓰지 않는다.
126
+ - 전후 비교에 필요한 지표가 final report 또는 state artifact에서 확인 가능하다.
127
+
128
+ ### P1. Convergence 재검증 범위 축소
129
+
130
+ 목표:
131
+
132
+ - 기본 동작은 1라운드에서 확정 가능한 finding을 즉시 종료한다.
133
+ - 2라운드는 Round 1 이후에도 `mixed` 또는 `unresolved` 상태로 남은 verification queue에만 수행한다.
134
+ - `full-consensus`, `partial-consensus`, `worker-unique`로 이미 확정된 finding은 다시 worker에게 보내지 않는다.
135
+
136
+ 현재 문제:
137
+
138
+ - `maxRounds=2`인 task-type에서 Round 1 이후 남은 항목과 이미 확정된 항목의 경계가 문서상 충분히 강하지 않다.
139
+ - "모든 항목 재검증"으로 운영되면 worker 수만큼 불필요한 re-dispatch가 늘어난다.
140
+
141
+ 개선 알고리즘:
142
+
143
+ ```text
144
+ Round 0:
145
+ worker 결과를 parsing/grouping한다.
146
+ 2명 이상이 같은 semantics + 같은 ticket set에 동의하면 full-consensus로 확정한다.
147
+ 단일 worker finding만 verification queue에 넣는다.
148
+
149
+ Round 1:
150
+ queue 항목만 worker별 batch로 재검증한다.
151
+ all agree/supplement -> full-consensus로 확정하고 queue에서 제거한다.
152
+ majority agree/supplement -> partial-consensus로 확정하고 queue에서 제거한다.
153
+ all disagree -> worker-unique로 확정하고 queue에서 제거한다.
154
+ mixed/error/insufficient evidence -> unresolved queue에 남긴다.
155
+
156
+ Optional Round 2:
157
+ unresolved queue가 비어 있으면 실행하지 않는다.
158
+ unresolved queue가 있으면 해당 항목만 재검증한다.
159
+ Round 2 이후에도 남은 항목은 최종 분류한다:
160
+ majority agreement -> partial-consensus
161
+ otherwise -> contested
162
+ ```
163
+
164
+ 2라운드 진입 조건:
165
+
166
+ - `effectiveMaxRounds >= 2`
167
+ - Round 1 종료 후 unresolved queue가 비어 있지 않음
168
+ - unresolved 원인이 단순 worker failure 전부가 아님. 모든 재검증 worker가 terminal non-result이면 추가 dispatch 대신 `verification-error`/blocked evidence를 기록한다.
169
+
170
+ 변경 대상:
171
+
172
+ - `skills/okstra-convergence/SKILL.md`: Round 1 이후 queue pruning, Round 2 gate, state artifact 필드 명시.
173
+ - `agents/SKILL.md`: `convergence.maxRounds` 설명을 queue-pruned 동작과 맞춘다.
174
+ - `skills/okstra-report-writer/SKILL.md`: final report가 round history와 skipped Round 2 사유를 기록하도록 확인.
175
+ - 필요 시 validator 또는 tests: convergence state에 새 필드를 요구하는 경우에만 추가.
176
+
177
+ 완료 기준:
178
+
179
+ - Round 1에서 확정된 finding이 Round 2 prompt에 다시 포함되지 않는다.
180
+ - Round 2가 실행되지 않은 경우 state에 `skippedReason`이 남는다.
181
+ - final report에는 네 분류(`Full Consensus`, `Partial Consensus`, `Contested`, `Worker-Unique`)가 계속 모두 표현된다.
182
+
183
+ ### P2. Prompt diet: analysis worker 입력 축소
184
+
185
+ 목표:
186
+
187
+ - analysis worker에게 final-report-template을 읽히지 않는 현재 원칙을 유지하고, 실제 dispatch prompt에도 불필요한 report-writer 전용 자료가 섞이지 않게 한다.
188
+ - worker definitions의 반복 문구는 줄이되, path extraction / model line / error sidecar 같은 blocking contract는 유지한다.
189
+
190
+ 주의:
191
+
192
+ - `agents/workers/_common.md` 추출은 설치/packaging 경로와 skill/agent 로더가 include를 지원하는지 먼저 확인해야 한다.
193
+ - 단순히 별도 파일로 빼는 것은 runtime에서 자동 inline되지 않으면 오히려 worker가 파일을 더 읽어야 하므로 비용이 줄지 않을 수 있다.
194
+
195
+ 변경 대상:
196
+
197
+ - `agents/workers/codex-worker.md`
198
+ - `agents/workers/gemini-worker.md`
199
+ - `skills/okstra-team-contract/SKILL.md`
200
+ - 설치/build packaging
201
+
202
+ ### P3. Fast-track routing
203
+
204
+ 목표:
205
+
206
+ - 단순 docs-only, typo, 명확한 1-file fix처럼 full lifecycle이 과한 작업을 더 짧은 경로로 보낸다.
207
+
208
+ 권장 설계:
209
+
210
+ - task-type lifecycle 자체를 임의로 건너뛰기보다 `requirements-discovery`가 `route=lite-implementation-planning` 또는 `route=direct-implementation-planning` 같은 명시적 routing token을 남긴다.
211
+ - source edit은 여전히 `implementation` task-type에서만 수행한다.
212
+ - 최소 검증은 `final-verification` 또는 equivalent read-only check로 남긴다.
213
+
214
+ 변경 대상:
215
+
216
+ - `prompts/profiles/requirements-discovery.md`
217
+ - `scripts/okstra_ctl/workflow.py`
218
+ - `skills/okstra-run/SKILL.md`의 next phase 선택 UI
219
+ - `skills/okstra-status/SKILL.md`
220
+ - validator 기대값
221
+
222
+ 주의:
223
+
224
+ - "fast-track"이 implementation-planning approval gate를 우회하면 single reference point와 승인 계약이 깨진다. 승인 게이트를 줄일지 없앨지는 별도 사용자 결정이 필요하다.
225
+
226
+ ### P4. Prompt caching 가능성 검증
227
+
228
+ 목표:
229
+
230
+ - 지원되는 transport에서만 prompt cache를 활용한다.
231
+
232
+ 현재 불확실성:
233
+
234
+ - `render.py`는 Markdown 파일을 렌더링한다.
235
+ - Codex/Gemini wrapper는 prompt 파일을 CLI stdin으로 전달한다.
236
+ - 이 경로에서 `cache_control: ephemeral` 같은 API-level metadata가 실제로 전달되는지 명확하지 않다.
237
+
238
+ 따라서 P4는 바로 구현하지 말고 spike로 시작한다.
239
+
240
+ 검증 항목:
241
+
242
+ - Claude Agent dispatch prompt에서 cache hint를 표현할 수 있는지.
243
+ - Codex CLI stdin prompt에서 cache hint가 의미를 갖는지.
244
+ - Gemini CLI에서 대응 기능이 있는지.
245
+ - token usage collector가 cache read/create 변화를 관측할 수 있는지.
246
+
247
+ ### P5. Prepare render 병렬화
248
+
249
+ 목표:
250
+
251
+ - prepare 단계의 독립 파일 render/write를 병렬화한다.
252
+
253
+ 주의:
254
+
255
+ - `prepare_task_bundle()`이 single authority이므로 병렬화를 하더라도 호출자는 그대로 유지한다.
256
+ - manifest/discovery render는 같은 ctx와 파일 순서 의존성이 있으므로 무리하게 섞지 않는다.
257
+ - 우선 instruction-set의 독립 write만 검토한다.
258
+
259
+ 예상 효과:
260
+
261
+ - worker dispatch 비용에 비해 작다.
262
+ - render-only smoke test가 많은 환경에서는 체감될 수 있다.
263
+
264
+ ### P6. Token usage 증분화
265
+
266
+ 목표:
267
+
268
+ - 매번 전체 session jsonl을 선형 스캔하지 않고, 이전 offset 또는 session summary cache를 활용한다.
269
+
270
+ 주의:
271
+
272
+ - Phase 7에서 final-report placeholder substitution과 연결되어 있으므로 정확성이 성능보다 중요하다.
273
+ - 재실행/재시도/여러 subagent session aggregate를 깨뜨리면 안 된다.
274
+
275
+ ## 6. 병렬 작업 계획
276
+
277
+ | 트랙 | 작업 | 주요 파일 | 병렬 가능성 | 선행 조건 |
278
+ |---|---|---|---|---|
279
+ | A | P1 convergence queue pruning | `skills/okstra-convergence/SKILL.md`, `agents/SKILL.md`, report-writer contract | 높음 | P0 용어 정리 |
280
+ | B | P3 fast-track routing | requirements profile, workflow/status/run UI | 중간 | P0 완료, 승인 게이트 정책 결정 |
281
+ | C | P5 prepare render 병렬화 | `scripts/okstra_ctl/run.py`, render tests | 높음 | 없음 |
282
+ | D | P2 prompt diet | worker definitions, team contract, packaging | 중간 | P1 후 권장 |
283
+ | E | P4 prompt cache spike | wrapper/dispatch 경로별 실험 | 높음 | 없음 |
284
+ | F | P6 token usage 증분화 | `scripts/okstra_token_usage/` | 높음 | collector fixture 필요 |
285
+
286
+ 권장 순서:
287
+
288
+ 1. 트랙 A(P1)를 먼저 수행한다. 가장 큰 비용을 직접 줄이고, 계약 변경 범위가 문서/lead 운영 단계에 집중된다.
289
+ 2. 트랙 C(P5) 또는 E(P4 spike)는 병렬로 가능하다.
290
+ 3. 트랙 B(P3)는 승인 게이트와 lifecycle semantics를 건드리므로 별도 설계 리뷰 후 진행한다.
291
+ 4. 트랙 D(P2)는 P1 이후 prompt contract가 안정된 뒤 진행한다.
292
+
293
+ ## 7. P1 구현 체크리스트
294
+
295
+ 1. `skills/okstra-convergence/SKILL.md`의 Round 1-N pseudocode를 queue pruning 방식으로 수정한다.
296
+ 2. `contested`를 중간 상태로 쓰지 않고, `unresolved` 또는 `mixed-after-round-1`을 2라운드 후보 이름으로 쓴다.
297
+ 3. convergence state artifact에 다음 필드를 명시한다.
298
+ - `config.effectiveMaxRounds`
299
+ - `rounds[].inputQueueSize`
300
+ - `rounds[].resolvedCount`
301
+ - `rounds[].carriedForwardCount`
302
+ - `rounds[].dispatches[]`
303
+ - `rounds[].skippedWorkers[]`
304
+ - `finalClassificationCounts`
305
+ - `round2SkippedReason`
306
+ 4. report-writer contract가 round history와 final classification counts를 final report에 반영하도록 점검한다.
307
+ 5. 단순 early convergence fixture와 mixed/unresolved fixture를 만들어 dry-run 또는 contract-level test를 수행한다.
308
+ 6. token usage collector 결과로 dispatch/token/wall-clock 전후를 기록한다.
309
+
310
+ ## 8. 리스크와 방어선
311
+
312
+ - **동조 hallucination 위험**: 1라운드에서 다수 worker가 같은 잘못된 결론을 내면 추가 검증이 줄어든다. 방어선은 `verificationMode=full-reanalysis` opt-in과 evidence quality check다.
313
+ - **worker failure 오분류 위험**: worker가 timeout/error인데 disagreement처럼 처리하면 `contested`가 왜곡된다. terminal non-result는 vote가 아니라 `verification-error` evidence로 분리한다.
314
+ - **fast-track 오판 위험**: 단순 작업으로 오분류하면 승인/검증이 부족해질 수 있다. P3는 approval gate 우회 여부를 별도 정책으로 결정해야 한다.
315
+ - **캐싱 착시 위험**: API-level cache hint가 CLI stdin 경로에서 무시될 수 있다. P4는 구현 전 spike가 필수다.
316
+ - **템플릿 축소로 validator 실패**: final-report heading이나 token placeholder를 줄이면 `validate-run.py`와 Phase 7 substitution이 깨질 수 있다. P2/P4는 validator 계약을 먼저 열거해야 한다.
317
+
318
+ ## 9. 이번 계획의 결론
319
+
320
+ 현재 작업 계획은 P1을 최우선으로 둔 방향은 맞지만, 기존 표현의 "7-phase lifecycle"과 "contested-only 2라운드"는 코드와 맞지 않았다. 개선된 계획은 다음처럼 재정렬한다.
321
+
322
+ 1. P0로 용어와 측정 기준을 고정한다.
323
+ 2. P1에서 convergence queue pruning을 구현한다.
324
+ 3. P3 fast-track과 P4 prompt caching은 별도 설계/검증이 필요한 후속 작업으로 둔다.
325
+ 4. prepare render 병렬화와 token usage 증분화는 효과가 작거나 종료 단계 비용이므로 P1 이후 병렬 보조 작업으로 처리한다.
326
+
327
+ ### 구현 plan 링크
328
+
329
+ - P0 + P1: `docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md`
330
+ - P2 / P3 / P4 / P5 / P6: 미작성 (각 트랙별로 별도 plan 작성 필요)
@@ -0,0 +1,125 @@
1
+ # okstra-run 성능 개선 계획
2
+
3
+ ## 1. 배경
4
+
5
+ `okstra-run` 스킬(또는 `scripts/okstra.sh`)을 통한 cross-verification 실행이 무겁게 느껴진다는 사용자 피드백을 바탕으로, 현재 파이프라인 구조를 분석하고 개선 후보를 도출한다. 본 문서는 분석 결과와 우선순위, 그리고 병렬 작업 가능성을 정리한다.
6
+
7
+ ## 2. 현재 구조 요약
8
+
9
+ ### 2.1 진입점
10
+
11
+ - `scripts/okstra.sh:127-132` 및 `skills/okstra-run/SKILL.md` 는 모두 `scripts/okstra_ctl/run.py` 의 `prepare_task_bundle()` 함수를 호출한다.
12
+ - 단일 reference point는 유지되고 있다.
13
+
14
+ ### 2.2 라이프사이클 (Phase 1~7)
15
+
16
+ `scripts/okstra_ctl/workflow.py:12-31` 의 `PHASE_SEQUENCE` 정의에 따라 다음 단계가 순차 실행된다.
17
+
18
+ | Phase | 이름 | 책임 |
19
+ |---|---|---|
20
+ | 1 | requirements-discovery | 라우팅 결정, 분류 |
21
+ | 2 | error-analysis | 근본 원인 분석 (read-only) |
22
+ | 3 | implementation-planning | 옵션 2개 이상 제시, 사용자 승인 요청 |
23
+ | 4 | implementation | 승인된 계획 실행 (executor 1 + verifier 2~3) |
24
+ | 5 | final-verification | 수용성 검증 |
25
+ | 5.5 | convergence | 워커 결과 cross-verify, 최대 2라운드 |
26
+ | 6 | release-handoff | lead 단독, git push + PR |
27
+ | 7 | final-report | report-writer-worker 또는 lead가 최종 보고서 생성 |
28
+
29
+ ### 2.3 워커 구조
30
+
31
+ `agents/workers/` 하위 4종:
32
+
33
+ - `claude-worker.md` (113줄) — in-process subagent
34
+ - `codex-worker.md` (209줄) — `okstra-codex-exec.sh` CLI 호출
35
+ - `gemini-worker.md` (209줄) — `okstra-gemini-exec.sh` CLI 호출
36
+ - `report-writer-worker.md` (117줄) — Phase 6/7 전용
37
+
38
+ ### 2.4 핵심 파이프라인
39
+
40
+ - `scripts/okstra_ctl/run.py` (≈900줄) 가 중앙 오케스트레이터.
41
+ - `prepare_task_bundle()` 내부에서 9개의 render 함수가 순차 호출됨 (`run.py:715-777`).
42
+ - 템플릿: `templates/reports/final-report.template.md` (378줄), `templates/launch.template.md` (88줄), task-type profile 6종.
43
+
44
+ ## 3. 무거움의 원인 분석
45
+
46
+ | # | 원인 | 영향도 | 위치 |
47
+ |---|---|---|---|
48
+ | A | Phase 5.5 convergence 의 최대 2라운드 × 3~4 워커 = 6~8회 re-dispatch | 大 | `skills/okstra-convergence/SKILL.md:55-77` |
49
+ | B | 워커 프롬프트(20~40K 토큰) × 워커 수 × 라운드의 토큰 비용. 캐싱 없음 | 大 | `scripts/okstra_ctl/render.py` |
50
+ | C | 거대 템플릿의 매 run 재렌더링 (final-report.template.md 378줄) | 中 | `templates/reports/` |
51
+ | D | 9개 render 함수의 직렬 호출 | 中 | `run.py:715-777` |
52
+ | E | 모든 task 가 동일한 7-phase 통과 (단순 typo 도 포함) | 中 | `workflow.py:12-31` |
53
+ | F | codex-worker / gemini-worker 정의 209줄 중 공통부 중복 | 中 | `agents/workers/` |
54
+ | G | token usage 집계의 전체 JSONL 선형 스캔 | 小 | `scripts/okstra-token-usage.py` |
55
+
56
+ ## 4. 개선 방안 우선순위
57
+
58
+ ### 4.1 (P1) Convergence 루프 축소 ← 본 작업의 1번 대상
59
+
60
+ - **현재**: 최대 2라운드를 기본으로 모든 항목에 대해 재검증.
61
+ - **개선**: 1라운드를 기본으로 하고, **contested 분류 항목만 선택적 2라운드**. full/partial consensus 항목은 1라운드에서 즉시 확정.
62
+ - **기대 효과**: 워커 호출 30~50% 감소, wall-clock 동등 비율 감소.
63
+ - **변경 대상**:
64
+ - `skills/okstra-convergence/SKILL.md` (라운드 트리거 조건, contested 게이트 정의)
65
+ - 관련 render/state 정의 — `templates/reports/final-report.template.md` 의 consensus 섹션 헤더가 라운드 정보와 일치하도록 점검
66
+ - 필요 시 `scripts/okstra_ctl/` 내 convergence state 핸들링 코드
67
+
68
+ ### 4.2 (P2) 프롬프트 캐싱 적용
69
+
70
+ - 거의 불변인 worker 정의 / launch profile 부분을 `cache_control: ephemeral` 로 마킹.
71
+ - 변경 대상: `scripts/okstra_ctl/render.py` 의 worker prompt 조립부.
72
+
73
+ ### 4.3 (P3) Phase 1 fast-track 라우팅
74
+
75
+ - 단순 작업(typo, docs-only, 명확한 1-file fix)은 Phase 2~5 우회. 안전망으로 Phase 5(final-verification)만 잔류시키는 "lite" 흐름.
76
+ - 변경 대상: `scripts/okstra_ctl/workflow.py`, requirements-discovery 프롬프트.
77
+
78
+ ### 4.4 (P4) 워커 정의 공통부 추출 / 템플릿 슬림화
79
+
80
+ - `agents/workers/_common.md` 추출, codex/gemini 차별점만 남김.
81
+ - final-report 템플릿은 Phase 6/7 외에는 inline expansion 제거하고 참조 링크만 전달.
82
+
83
+ ### 4.5 (P5~) Render 병렬화, token-usage 증분화
84
+
85
+ - 효과는 작지만 난이도 낮음. 여유 있을 때 처리.
86
+
87
+ ## 5. 병렬 작업 가능성
88
+
89
+ 개선 후보들은 대부분 **서로 다른 파일에 작용**하므로 worktree 기반 병렬 작업이 가능하다.
90
+
91
+ ### 5.1 의존성 매트릭스
92
+
93
+ | 작업 | 주요 변경 파일 | 충돌 가능성 |
94
+ |---|---|---|
95
+ | P1 Convergence 축소 | `skills/okstra-convergence/SKILL.md`, convergence state 코드 | P4 워커 공통화와 약한 충돌 (consensus 분류 텍스트) |
96
+ | P2 프롬프트 캐싱 | `scripts/okstra_ctl/render.py` | P4 와 일부 겹침 (render 경유) |
97
+ | P3 Fast-track 라우팅 | `workflow.py`, Phase 1 프롬프트 | 독립 |
98
+ | P4 워커 공통부 / 템플릿 슬림 | `agents/workers/*.md`, `templates/` | P1, P2 와 약한 충돌 |
99
+ | P5 Render 병렬화 | `run.py:715-777` | 독립 |
100
+
101
+ ### 5.2 권장 분할
102
+
103
+ - **트랙 A (현재 작업)**: P1 — Convergence 1라운드 + contested-only 2라운드
104
+ - **트랙 B (병렬 가능)**: P3 — Phase 1 fast-track 라우팅 (P1 과 파일 비중복)
105
+ - **트랙 C (병렬 가능)**: P5 — Render 병렬화 / token-usage 증분화 (독립)
106
+
107
+ P2 와 P4 는 P1 완료 후에 진행하는 편이 안전하다(템플릿/워커 정의가 함께 닿이기 때문).
108
+
109
+ ### 5.3 실행 형태
110
+
111
+ - 각 트랙을 별도 git worktree 로 분리.
112
+ - 트랙별 작업은 독립 PR 로 머지, 충돌 시 P1 우선.
113
+
114
+ ## 6. P1 작업 착수 시 다음 단계
115
+
116
+ 1. `skills/okstra-convergence/SKILL.md` 현재 라운드 로직 정밀 독해.
117
+ 2. consensus 분류(full / partial / contested / unique)가 어디서 산출되는지 확정.
118
+ 3. 1라운드 후 종료 조건과 2라운드 진입 조건(=contested 존재 여부 + 임계치)을 명세.
119
+ 4. `final-report.template.md` 의 라운드 표시부 정합성 검사.
120
+ 5. 변경 후 dry-run 으로 단순 task 1건 + contested 발생 task 1건을 비교 실행.
121
+
122
+ ## 7. 트레이드오프 / 리스크
123
+
124
+ - 1라운드 기본화는 full consensus 항목의 추가 안전망을 제거한다. 만약 워커 간 hallucination 동조 위험이 우려되면, contested 외에도 "unique 비율이 임계 이상"인 경우를 2라운드 트리거에 포함시키는 방어선이 필요.
125
+ - Fast-track 라우팅은 분류 오판 시 release-handoff 단계에서 검증 부족 위험. Phase 5 잔류로 완화.