okstra 0.102.2 → 0.102.3

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 (161) hide show
  1. package/README.kr.md +5 -5
  2. package/README.md +5 -5
  3. package/docs/kr/architecture/storage-model.md +1 -1
  4. package/docs/kr/architecture.md +7 -11
  5. package/docs/kr/cli.md +4 -4
  6. package/docs/kr/container.md +1 -1
  7. package/docs/kr/performance-improvement-plan-v2.md +2 -2
  8. package/docs/project-structure-overview.md +2 -2
  9. package/package.json +7 -2
  10. package/runtime/BUILD.json +2 -2
  11. package/runtime/bin/okstra-antigravity-exec.sh +1 -2
  12. package/runtime/bin/okstra-codex-exec.sh +1 -2
  13. package/runtime/bin/okstra-render-final-report.py +2 -9
  14. package/runtime/bin/okstra-spawn-followups.py +4 -6
  15. package/runtime/bin/okstra-trace-cleanup.sh +24 -4
  16. package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
  17. package/runtime/prompts/lead/report-writer.md +1 -1
  18. package/runtime/prompts/profiles/_common-contract.md +9 -11
  19. package/runtime/python/okstra_ctl/codex_dispatch.py +4 -12
  20. package/runtime/python/okstra_ctl/consumers.py +35 -0
  21. package/runtime/python/okstra_ctl/container.py +4 -6
  22. package/runtime/python/okstra_ctl/dispatch_core.py +4 -12
  23. package/runtime/python/okstra_ctl/final_report_paths.py +24 -0
  24. package/runtime/python/okstra_ctl/handoff.py +2 -1
  25. package/runtime/python/okstra_ctl/implementation_stage.py +7 -11
  26. package/runtime/python/okstra_ctl/report_view_artifacts.py +14 -0
  27. package/runtime/python/okstra_ctl/report_views.py +7 -4
  28. package/runtime/python/okstra_ctl/run.py +3 -10
  29. package/runtime/python/okstra_ctl/stage_targets.py +18 -0
  30. package/runtime/python/okstra_ctl/wizard.py +24 -25
  31. package/runtime/python/okstra_ctl/wizard_stage_intent.py +54 -0
  32. package/runtime/python/okstra_token_usage/report.py +2 -5
  33. package/runtime/validators/validate-report-views.py +2 -1
  34. package/runtime/validators/validate-run.py +1 -11
  35. package/src/commands/lifecycle/install.mjs +5 -5
  36. package/src/commands/lifecycle/uninstall.mjs +4 -4
  37. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
  38. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
  39. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
  40. package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
  41. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
  42. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
  43. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
  44. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
  45. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
  46. package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
  47. package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
  48. package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
  49. package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
  50. package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
  51. package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
  52. package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
  53. package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
  54. package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
  55. package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
  56. package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
  57. package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
  58. package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
  59. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
  60. package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
  61. package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
  62. package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
  63. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
  64. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
  65. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
  66. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
  67. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
  68. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
  69. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
  70. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
  71. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
  72. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
  73. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
  74. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
  75. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
  76. package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
  77. package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
  78. package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
  79. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
  80. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
  81. package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
  82. package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
  83. package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
  84. package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
  85. package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
  86. package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
  87. package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
  88. package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
  89. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
  90. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
  91. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
  92. package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
  93. package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
  94. package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
  95. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
  96. package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
  97. package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
  98. package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
  99. package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
  100. package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
  101. package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
  102. package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
  103. package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
  104. package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
  105. package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
  106. package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
  107. package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
  108. package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
  109. package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
  110. package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
  111. package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
  112. package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
  113. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
  114. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
  115. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
  116. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
  117. package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
  118. package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
  119. package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
  120. package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
  121. package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
  122. package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
  123. package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
  124. package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
  125. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
  126. package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
  127. package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
  128. package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
  129. package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
  130. package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
  131. package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
  132. package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
  133. package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
  134. package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
  135. package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
  136. package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
  137. package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
  138. package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
  139. package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
  140. package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
  141. package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
  142. package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
  143. package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
  144. package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
  145. package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
  146. package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
  147. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
  148. package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
  149. package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
  150. package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
  151. package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
  152. package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
  153. package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
  154. package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
  155. package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
  156. package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
  157. package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
  158. package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
  159. package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
  160. package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
  161. package/docs/superpowers/specs/2026-06-24-okstra-container-build-rename-design.md +0 -110
@@ -1,98 +0,0 @@
1
- # stage 분할 기준의 비용-인식 재설계 — 설계
2
-
3
- - 작성일: 2026-06-04
4
- - 범위: `implementation-planning` 의 stage 분할 기준과 `implementation` 의 run 실행 단위를 **비용-인식** 구조로 바꾼다. stage 는 계획/PR/검증-증거 단위로 유지하되, 교차검증 기계(verifier·convergence·report·teardown)의 고정비가 stage 수에 비례해 곱해지지 않도록 run 을 별도 단위로 분리한다.
5
- - 비범위
6
- - 신규 task-type 추가 없음. `requirements-discovery` / `error-analysis` / `final-verification` / `release-handoff` 산출 구조 불변.
7
- - sidecar carry-in JSON 스키마(`runs/<impl-key>/carry/stage-<N>.json`) 자체는 불변 — stage 별 방출 유지.
8
- - 다국어/i18n.
9
- - 관계: 본 문서는 [`2026-05-20-implementation-planning-multi-stage-design.md`](2026-05-20-implementation-planning-multi-stage-design.md) 의 **§2.3 "병렬화 최대화 우선(분할 1급 기준)"(line 36–44)** 을 대체한다. 같은 문서의 `step ≤6 cap`(line 46–50), carry-in 모델(§2.4), 데이터 모델(§3) 은 그대로 유지된다. 구현 단계에서 옛 spec 의 §2.3 을 본 결정으로 재작성한다.
10
-
11
- ## 1. 동기 — 1줄 fix 가 고정비 1세트를 통째로 삼킨다
12
-
13
- 실측: `fontradar-v2-api` 의 1줄 fix(await 1개 제거, +1/−3)가 3 stage 로 분할되어 Stage 1 단독으로 교차검증 1세트를 전부 떠안았다. 원인은 코드가 아니라 분할 기준의 구조적 결함이다.
14
-
15
- 1. **고정비는 run 당이다.** 한 `implementation` run 은 executor 1 + verifier 2(claude+codex) + report-writer 를 무조건 단다 ([`prompts/profiles/implementation.md:4`](../../../prompts/profiles/implementation.md)). 여기에 Phase 5.5 convergence 와 Phase 7 teardown 이 더해진다. 이 비용은 변경 크기와 무관한 고정비다.
16
- 2. **그 고정비가 stage 수만큼 곱해진다.** 현재 `1 run = 정확히 1 stage` 가 강제다 ([`prompts/profiles/_implementation-executor.md:41`](../../../prompts/profiles/_implementation-executor.md)). 따라서 stage 수 = 고정비 배수.
17
- 3. **분할 기준에 하한이 없다.** 옛 spec 의 분할 기준은 상한(stage 당 step ≤6)과 "병렬 가능 stage 최대화"(1급) 뿐이다 ([`2026-05-20-...-design.md:36`](2026-05-20-implementation-planning-multi-stage-design.md), [`prompts/profiles/implementation-planning.md:68`](../../../prompts/profiles/implementation-planning.md)). "너무 작으면 합쳐라" 가 없다.
18
- 4. **옛 spec 내부 모순.** §2.2 는 "한 stage 안의 step 은 상호 독립 → 독립이면 같은 stage"([line 31](2026-05-20-implementation-planning-multi-stage-design.md)), §2.3 은 "독립 stage 가 여럿 나오도록 분할"([line 42](2026-05-20-implementation-planning-multi-stage-design.md)). 독립 작업을 묶을지/쪼갤지가 정반대로 읽힌다.
19
- 5. **잘못된 유추.** §2.3 은 step ≤6 cap 을 "함수 50라인 cap 과 같은 정신" 이라 했다 ([line 48](2026-05-20-implementation-planning-multi-stage-design.md)). 함수 분리는 공짜지만 okstra 의 stage 분리는 멀티에이전트 run 1세트를 새로 사는 일이다. 비용 구조가 다른데 같은 규칙을 이식했다.
20
-
21
- ## 2. 핵심 원칙
22
-
23
- ### 2.1 stage 와 run 의 분리
24
-
25
- | 단위 | 의미 | 경계 기준 |
26
- |---|---|---|
27
- | **stage** | 계획·PR·검증-증거(sidecar)의 단위 | `depends-on` 종속 + effective step ≤6 cap |
28
- | **run** | 교차검증 기계(verifier·convergence·report·teardown)의 단위 = 고정비 1세트 | ready-set + run step 예산 |
29
-
30
- 옛 spec 의 `1 run = 1 stage` 등식을 깬다. 한 run 이 여러 stage 를 batch 로 소유할 수 있다.
31
-
32
- ### 2.2 플래너: 응집 기준점 = 파일/모듈 근접성, 한도 = ≤6 cap
33
-
34
- 묶음의 **기준점은 공유 파일/모듈 근접성**이다. "독립이고 크기가 맞으면 아무거나 묶어도 된다" 가 아니라, **같은 파일·디렉터리·모듈을 건드리는 작업끼리 묶는다.** 이래야 diff·PR·rollback 단위가 의미적으로 응집한다.
35
-
36
- - **기본값 = 같은 파일/모듈을 건드리는 작업은 같은 stage 로 묶는다.** §2.2(독립=같은 stage) 를 채택하고 옛 §2.3(병렬화 위해 쪼개라) 을 폐기해 모순을 해소한다.
37
- - stage 를 **분리**하는 조건 (셋 중 하나):
38
- - (a) 실제 `depends-on` 종속이 존재한다 (한 step 의 산출을 다른 step 이 소비), 또는
39
- - (b) 합산 effective step 이 6 을 넘는다, 또는
40
- - (c) **건드리는 파일 집합이 서로소다** (공유 파일/모듈이 없는 독립 작업 — 억지로 한 stage 에 섞지 않는다).
41
- - **병렬화는 분할의 이유가 아니다.** cap 이 만든 여러 stage 가 우연히 `depends-on (none)` 이면 두 run 이 동시에 잡아 병렬 진행할 수 있다 — 그건 부수효과일 뿐, stage 를 더 만들 근거가 아니다.
42
- - `step ≤6 cap`(옛 §2.3 line 46–50) 은 그대로 유지한다.
43
-
44
- **병렬-안전 불변식 (파일 근접성 기준의 enforcement teeth):** 서로 `depends-on (none)` 인 두 stage 의 `Stage Exit Contract` 예측 파일 집합은 **서로소여야 한다.** 안 그러면 두 병렬 run 이 같은 파일을 동시에 편집해 충돌한다. 같은 파일을 건드리는 두 작업은 (i) 같은 stage 로 묶거나 (ii) `depends-on` 으로 순서를 매겨야 한다.
45
-
46
- 효과:
47
- - 같은 파일/모듈을 손대는 독립 버그 → 1 stage 로 합쳐짐 (합산 ≤6 한도).
48
- - 서로 다른 모듈을 손대는 독립 버그 → 별도 stage (응집 보존). 단 고정비는 §2.3 의 run batch 가 흡수하므로 stage 수가 늘어도 비용은 곱해지지 않는다.
49
-
50
- ### 2.3 실행기: "ready-set + run step 예산 batch"
51
-
52
- - 디스패치 시점에, `depends-on` 이 모두 `status:done` 이고 미점유인 stage 들을 **합산 effective step 이 run 예산에 닿을 때까지** 한 run 이 흡수한다.
53
- - **run step 예산 = 8** (stage cap 6 보다 큼). 1줄짜리 잔여 stage 를 더 큰 stage 옆에 흡수하되, stage 경계·검증 정밀도는 거의 그대로 유지하는 보수적 값.
54
- - start-stage 단일 선택([`_implementation-executor.md:30`](../../../prompts/profiles/_implementation-executor.md)) 을 ready-set 선택으로 확장한다. 선택 알고리즘:
55
- 1. ready 집합 = `depends-on` 이 전부 done 이고 `consumers.jsonl` 에 `started`/`done` 행이 없는 stage.
56
- 2. ready 를 stage 번호 오름차순으로 정렬.
57
- 3. 누적 effective step 이 8 을 넘지 않는 한도에서 앞에서부터 담는다. 단일 stage 가 8 을 넘으면(불가능 — cap 6) 그 stage 하나만.
58
- 4. 최소 1개는 보장(빈 batch 금지).
59
- - 점유: `consumers.jsonl` reverse-link 와 `~/.okstra/worktrees/registry.json` 이 run 당 **stage-key 집합**을 원자적으로(flock) 예약한다. batch 안 모든 stage 에 `started` 행을 한 번에 append, 완료 시 각 stage 에 `done` 행 + `carry_path` append.
60
- - **응집은 이미 stage 단위에 있다.** run batch 는 순수 비용 메커니즘 — 응집 기준점(파일 근접성)은 §2.2 에서 stage 형성 시 이미 적용됐고, PR 은 stage 섹션으로 분리되므로 batch 가 서로 다른 모듈의 stage 를 묶어도 리뷰·rollback 응집은 stage 경계에 보존된다. 한 run 은 단일 worktree 에서 stage 순서대로 직렬 실행하므로 batch 내부 충돌은 없다. §2.2 의 병렬-안전 불변식 덕분에 서로 다른 run 이 잡는 stage 들도 파일이 겹치지 않는다.
61
-
62
- ### 2.4 검증·산출물 단위
63
-
64
- - verifier·convergence·report-writer·Phase 7 은 batch **전체 diff 에 대해 run 당 1회.** ← 실제 절감의 핵심.
65
- - executor 는 stage 마다 `Stage Validation post` 통과 시 `carry/stage-N.json` sidecar 를 **stage 별로 방출**한다 ([`_implementation-executor.md:43`](../../../prompts/profiles/_implementation-executor.md)). carry-in 계약 보존. 즉 batch 안에서도 stage 순서대로 실행하며 각 stage 경계에서 post 검증 + sidecar 방출, 마지막에 run 단위 교차검증 1회.
66
- - PR 은 **run 당 1개.** 제목 `Stages <X>–<Y>: <run 요약>`, body 에 stage 섹션 분리 + Previous/Next run 링크. one-PR-per-stage([`_implementation-executor.md:45`](../../../prompts/profiles/_implementation-executor.md)) 를 one-PR-per-run 으로 전환.
67
-
68
- ## 3. 손대는 파일
69
-
70
- | 파일 | 변경 |
71
- |---|---|
72
- | 본 문서 | 신규 설계(옛 §2.3 대체) |
73
- | [`2026-05-20-...-design.md:36`](2026-05-20-implementation-planning-multi-stage-design.md) | §2.3 병렬화-우선 규칙 삭제, §2.1 표에 "run 단위" 추가, run batch·run단위 검증 섹션 추가, 본 문서 참조 |
74
- | [`prompts/profiles/implementation-planning.md:68`](../../../prompts/profiles/implementation-planning.md) | "Parallelisation-first rule (1st-class)" → "응집 기준점=파일/모듈 근접성, cap 이 유일 분할기, 병렬화는 분할 이유 아님" |
75
- | [`prompts/profiles/implementation-planning.md:96`](../../../prompts/profiles/implementation-planning.md) | Stage Map self-check 에 (i) "depends-on 제거 가능하면 재분할" → "병렬화 목적의 분할 금지", (ii) 병렬-안전 불변식 자가검사("`depends-on (none)` stage 들의 예측 파일 집합 서로소") 추가 |
76
- | [`prompts/profiles/_implementation-executor.md:30`](../../../prompts/profiles/_implementation-executor.md) | start-stage 단일 선택 → ready-set batch 선택(§2.3 알고리즘) |
77
- | [`prompts/profiles/_implementation-executor.md:41`](../../../prompts/profiles/_implementation-executor.md) | "owns exactly one stage" → "owns a ready-set batch (run 예산 8 이내)" |
78
- | [`prompts/profiles/_implementation-executor.md:43-49`](../../../prompts/profiles/_implementation-executor.md) | sidecar/consumers 를 batch 안 stage 별로 방출하도록, one-PR-per-stage → one-PR-per-run |
79
- | [`prompts/profiles/implementation.md:4`](../../../prompts/profiles/implementation.md) | (필요 시) Phase 설명에 "검증·report 는 run 단위 1회" 명시 |
80
- | [`validators/validate-implementation-plan-stages.py`](../../../validators/validate-implementation-plan-stages.py) | 기존 ≤6 cap([line 140](../../../validators/validate-implementation-plan-stages.py))·step-count 셀 일치([line 143](../../../validators/validate-implementation-plan-stages.py))·depends-on DAG([line 149](../../../validators/validate-implementation-plan-stages.py)) 유지. **신규 체크 S9** 추가 — `Stage Exit Contract` 의 "추가/변경된 파일 (예측)" 라인에서 경로를 추출해, 서로 `depends-on (none)` 인 stage 쌍의 파일 집합이 겹치면 거부 (병렬-안전 불변식). 예측 기반 best-effort 이며, 실제 충돌의 backstop 은 worktree 직렬성 + flock registry 다 |
81
-
82
- ## 4. 비범위 / 향후
83
-
84
- - run 예산 8 은 상수로 시작. 사용자 노출 플래그(`--run-step-budget`)는 YAGNI — 실제 요구 전까지 도입하지 않는다.
85
- - 명시적 `--stages 1,2,3` batch 지정은 본 설계의 자동 ready-set 으로 충분 — 별도 도입하지 않는다.
86
- - **parallel-run started-exclusion 은 비범위.** ready-set 선택은 다른 run 이 `started` 한 stage 를 배제하지 않는다 — 두 병렬 run 은 같은 ready-set batch 를 잡는다(기존 동작, [`tests/test_e2e_multi_stage_q1_q9.py::test_q7`](../../../tests/test_e2e_multi_stage_q1_q9.py) 가 문서화). consumers.jsonl 의 flock 은 파일 손상만 막을 뿐 batch 분리를 보장하지 않는다. 사용자의 순차 phase-continuation 사용에는 영향 없으며, 진짜 충돌 backstop 은 §2.2 의 파일-서로소 불변식 + worktree 직렬성이다. started-exclusion 도입은 별도 작업으로 남긴다.
87
- - **stage 선택은 Python SOT.** `_resolve_effective_stages`([`scripts/okstra_ctl/run.py`](../../../scripts/okstra_ctl/run.py)) 가 batch 를 선택하고 `prepare_task_bundle` 이 stage 별 `started` row 를 기록한 뒤 `{{STAGE_BATCH_DIRECTIVE}}` 로 lead 프롬프트에 주입한다. 기존의 "lead 가 consumers.jsonl 로 start stage 자가계산" 이중 경로(drift)는 제거됐다.
88
-
89
- ## 5. 검증 방식 (enforcement)
90
-
91
- | 계약 | 강제 위치 |
92
- |---|---|
93
- | stage 당 effective step ≤6 | [`validators/validate-implementation-plan-stages.py`](../../../validators/validate-implementation-plan-stages.py) (기존 유지) |
94
- | 응집 기준점 = 파일/모듈 근접성 | planner 자가검사 prose ([`implementation-planning.md:96`](../../../prompts/profiles/implementation-planning.md)). 정성 기준이라 validator 강제 불가 — 아래 불변식이 그 위반의 대리 신호 |
95
- | 병렬-안전 불변식 (`depends-on (none)` stage 파일 서로소) | validator 신규 체크 S9 (best-effort, 예측 경로 기반). 진짜 backstop 은 worktree 직렬성 + flock registry |
96
- | run batch 합산 step ≤8 | executor 가 ready-set 선택 시 누적 카운트로 자르고, run 시작 로그에 batch 구성을 기록. (planner 산출물이 아니므로 plan validator 대상 아님) |
97
- | stage 별 sidecar 방출 | [`_implementation-executor.md:43`](../../../prompts/profiles/_implementation-executor.md) BLOCKING 규칙 유지 |
98
- | run 단위 검증 1회 | Phase 5.5/6 진입을 run 당 1회로 묶는 lead 오케스트레이션 (sidecar 규칙) |
@@ -1,90 +0,0 @@
1
- # Acceptance devil's-advocate critic — 설계 (sub-project B2)
2
-
3
- - 작성일: 2026-06-05
4
- - 범위: sub-project B1 의 critic dispatch primitive(기존 worker 재사용 + provider/model 선택 + opt-in)를 `final-verification` 으로 확장한다. final-verification 에서 critic 은 **악마의 변호인** 모드로 동작 — "받아들이면 안 되는 이유/놓친 acceptance blocker 를 캐라" — 그리고 후보 blocker 는 **confirm-or-downgrade** 로 검증(확인→Acceptance Blocker, 미확인→Residual Risk, 절대 drop 안 함)되어 verdict 에 반영된다. 선택 UX·`--critic`/`S_CRITIC_PICK`·`convergence.critic` 블록은 B1 것을 그대로 재사용하며, 적용 phase 에 `final-verification` 을 추가한다.
5
- - 비범위
6
- - 새 dispatch 메커니즘·새 설치형 agent·새 selection 플래그 없음 — B1 primitive 전부 재사용.
7
- - convergence 의 finding/plan-body classification·gate enum·verdict↔blocker validator 변경 없음 — 확인된 critic blocker 는 *기존* Acceptance Blockers 경로로 들어가고 기존 verdict 규칙(`accepted` ⇒ blocker 0)이 그대로 작동한다.
8
- - B1 의 coverage critic 동작(3 finding-phase, 적대적-drop 검증) 변경 없음 — B2 는 final-verification 전용 *모드*를 추가할 뿐.
9
- - 관계: B1 [`2026-06-04-coverage-critic-design.md`](2026-06-04-coverage-critic-design.md) 가 만든 critic primitive·`convergence.critic` 블록·`S_CRITIC_PICK` 선택을 재사용한다. final-verification 프로필의 Acceptance Blockers/Residual Risk/Verdict Token 구조([`prompts/profiles/final-verification.md`](../../../prompts/profiles/final-verification.md))에 출력을 연동한다.
10
-
11
- ## 1. 동기
12
-
13
- final-verification 은 수용 판정 직전의 마지막 게이트다. 거짓 합의가 여기서 새면 결함이 그대로 릴리스된다. 그런데 적대적 검증(sub-project 0)을 final-verification 에 그대로 적용하면 역효과다 — finding 이 *결함/blocker* 이므로 finding 을 적대적으로 반박하면 "재현 못 한 진짜 결함" 이 강등·누락된다(결함 민감도 하락). 그래서 final-verification 의 critic 은 finding 을 반박하는 게 아니라, **verdict 에 대한 악마의 변호인** — "이 작업을 받아들이면 안 되는 이유를 적극적으로 찾는" 추가 패스여야 한다. 이는 커버리지를 늘리되(놓친 blocker 발굴) 결함 민감도를 *높이는* 방향이다.
14
-
15
- ## 2. 핵심 설계
16
-
17
- ### 2.1 critic primitive 재사용 + 적용 phase 확장
18
-
19
- B1 의 critic dispatch(선택된 provider 의 기존 subagent + provider model, opt-in)를 그대로 쓴다. 바뀌는 것은 적용 phase 집합뿐:
20
-
21
- - [`scripts/okstra_ctl/render.py`](../../../scripts/okstra_ctl/render.py) `_build_convergence_block` 의 `critic_phases` 에 `final-verification` 을 추가 → `convergence.critic.enabled` 가 final-verification 에서도 true 가능.
22
- - [`scripts/okstra_ctl/wizard.py`](../../../scripts/okstra_ctl/wizard.py) `S_CRITIC_PICK` 의 `applies` phase tuple + summary/confirmation 의 phase 조건에 `final-verification` 추가.
23
- - 선택 UX(`--critic <provider>` / okstra-run select box), `convergence.critic {enabled,provider,modelExecutionValue}` 블록, 모델 해석은 **불변**(B1 그대로).
24
-
25
- ### 2.2 critic 행동은 phase 별로 분기 (B2 의 신규 부분)
26
-
27
- convergence skill 에서 critic 행동을 phase 로 분기한다:
28
- - `requirements-discovery` / `error-analysis` / `implementation-planning` → **coverage critic**(B1: "뭐가 빠졌나", 적대적-drop 검증). 불변.
29
- - `final-verification` → **acceptance devil's-advocate critic**(신규).
30
-
31
- **악마의 변호인 프롬프트(final-verification):**
32
- ```
33
- You are the acceptance devil's advocate for <task-key>. The delivered work is about
34
- to be judged for acceptance. Your ONLY job is to find reasons it should NOT be
35
- accepted — surface candidate acceptance BLOCKERS the verifiers may have missed:
36
- - requirements / acceptance points with no covering evidence,
37
- - DB / IO / SQL changes lacking real-execution evidence,
38
- - regressions or broken error paths,
39
- - scope/contract violations.
40
- For each, emit a candidate blocker with a one-line statement, evidence (file:line /
41
- log / test output), and a severity (critical / major / minor). Do NOT restate an
42
- existing Acceptance Blocker. If you find none, say so explicitly.
43
- ```
44
-
45
- **검증 = confirm-or-downgrade (B1 의 적대적-drop 과 다름, BLOCKING):**
46
- 각 후보 blocker 를 Phase 4 analyser 들(critic 제외)이 검증한다.
47
- - **확인**(재현/증거 인용 성공) → `## 4 Acceptance Blockers` 행으로 승격(severity 유지, follow-up phase 포함).
48
- - **미확인**(재현 불가 또는 증거 약함) → **Residual Risk 로 강등(절대 drop 하지 않음)** — 추적 대상으로 남기고 trigger 를 기록.
49
- - 적대적 finding classifier 의 "불확실하면 기각" 규칙을 여기 적용하는 것은 금지(진짜 결함을 억누름).
50
-
51
- **출력·verdict 연동:**
52
- - 확인된 후보가 Acceptance Blockers 에 들어가면, `accepted` 는 blocker 0 을 요구하므로([`final-verification.md:32`](../../../prompts/profiles/final-verification.md)) verdict 가 자동으로 `conditional-accept` / `blocked` 로 밀린다. 이것이 악마의 변호인의 목적이다.
53
- - 미확인 후보는 Residual Risk 로 — verdict 를 막지는 않으나 추적된다.
54
- - 기존 verdict↔blocker 일관성 validator(`validators/validate-run.py` `_validate_final_verification_consistency`)가 그대로 강제한다. 새 enum/validator 없음.
55
-
56
- ### 2.3 critic 결과의 상태 기록
57
-
58
- - critic 후보 blocker 는 `runs/final-verification/worker-results/<provider>-critic-final-verification-<seq>.md` 에 기록.
59
- - convergence 상태 아티팩트의 `config.critic` 요약(B1 정의)에 `mode: "acceptance-devils-advocate"`, `candidatesProposed`, `confirmedBlockers`, `downgradedToResidual` 를 기록(optional v1.2 필드, reader 는 누락을 null 로). enum 변경 없음.
60
-
61
- ## 3. 변경 파일
62
-
63
- 1. [`scripts/okstra_ctl/render.py`](../../../scripts/okstra_ctl/render.py) — `critic_phases` 에 `final-verification` 추가.
64
- 2. [`tests/test_render_critic_block.py`](../../../tests/test_render_critic_block.py) — `final-verification` 을 비적용→적용 파라미터로 이동(`enabled=True` 검증).
65
- 3. [`scripts/okstra_ctl/wizard.py`](../../../scripts/okstra_ctl/wizard.py) — `S_CRITIC_PICK.applies` + summary/confirmation phase 조건에 `final-verification` 추가.
66
- 4. [`tests/test_wizard_critic_pick.py`](../../../tests/test_wizard_critic_pick.py) — `final-verification` 을 "skipped" → "applies" 로 플립.
67
- 5. [`skills/okstra-convergence/SKILL.md`](../../../skills/okstra-convergence/SKILL.md) — "Coverage critic pass" 절에 phase 분기 + "Acceptance devil's-advocate critic (final-verification)" 하위 모드(프롬프트·confirm-or-downgrade·blocker/residual-risk 출력·상태 요약) 추가.
68
- 6. [`prompts/profiles/final-verification.md`](../../../prompts/profiles/final-verification.md) — 악마의 변호인 critic opt-in 선언 + 출력이 Acceptance Blockers/Residual Risk 로 들어가고 verdict 에 미치는 영향.
69
- 7. [`agents/SKILL.md`](../../../agents/SKILL.md) — critic pass(Phase 5.6)가 final-verification 에도 적용됨을 반영(phase 행/PROGRESS 주석).
70
- 8. (선택) [`prompts/wizard/prompts.ko.json`](../../../prompts/wizard/prompts.ko.json) — `critic_pick` label 을 phase-중립적으로 일반화(예: "추가 critic 패스(놓친 finding/blocker 발굴) — opt-in").
71
- 9. [`CHANGES.md`](../../../CHANGES.md) — 사용자 영향 항목.
72
-
73
- ## 4. Enforcement — 선언과 강제의 구분
74
-
75
- - **machine-강제:** render `critic_phases` 에 final-verification 포함 + wizard `applies` 확장 → 단위/wizard 테스트. 확인된 critic blocker 가 Acceptance Blockers 로 들어갔을 때의 verdict 일관성(`accepted` ⇒ blocker 0)은 *기존* `_validate_final_verification_consistency` 가 그대로 강제.
76
- - **prompt-only(강제 불가):** 악마의 변호인이 실제로 의미 있는 후보를 찾는지, confirm-or-downgrade 가 정확히 분류하는지는 lead/워커(LLM) 프롬프트 지시 — skill/profile 선언으로 유도.
77
-
78
- ## 5. 비용·리스크
79
-
80
- - **비용:** opt-in(기본 off, B1 과 동일). 켜면 critic dispatch 1 + 후보 검증 1라운드(analyser 수만큼). 미선택 final-verification run 비용 0.
81
- - **리스크 — 후보 폭증:** critic 이 약한 후보를 다수 낼 수 있음. 완화: confirm-or-downgrade 가 미확인을 Residual Risk 로 강등하므로 verdict 를 막는 것은 *확인된* blocker 뿐. severity·증거 필수.
82
- - **리스크 — 거짓 통과(억압) 방지가 목적인데 confirm-or-downgrade 가 미확인을 강등:** 미확인을 drop 하지 않고 Residual Risk 로 남기므로 추적은 보존. "확인" 기준은 재현/증거 인용이며, 재현이 불확실한 고-severity 후보는 Residual Risk 의 escalation trigger 로 기록해 사용자가 판단할 수 있게 한다.
83
-
84
- ## 6. 수용 기준
85
-
86
- 1. `final-verification` 의 manifest `convergence.critic` 가 `--critic`/wizard 선택에서 resolve 되어 `enabled=true` 가능(B1 의 3 phase + final-verification = 4 적용 phase).
87
- 2. okstra-run `S_CRITIC_PICK` 이 final-verification 에서도 표시된다.
88
- 3. convergence skill 이 final-verification 의 악마의 변호인 모드(프롬프트·confirm-or-downgrade·blocker/residual-risk 출력)를 정의하고, B1 coverage 모드와 명확히 구분한다.
89
- 4. final-verification 프로필이 critic opt-in 과 verdict 영향을 선언한다.
90
- 5. `python3 -m pytest tests/` + `bash validators/validate-workflow.sh` 통과.
@@ -1,87 +0,0 @@
1
- # 정본 final-report `.md` 표를 compact 하게 (옵션 X) — 설계
2
-
3
- - 작성일: 2026-06-05
4
- - 범위: final-report 정본 `.md` 의 narrative 표(§1 Summary, §1.1 Consensus, §1.2 Differences, §3.1 Primary Evidence, §3.2 Secondary, §4 Risks, Execution Status by Agent)를 **짧은 코드 컬럼을 `<br>` 로 한 셀에 stack 한 meta 컬럼 + 긴 prose 컬럼은 별도 컬럼** 으로 재구성해, markdown 에디터에서도 핵심 본문(요약·근거·이견·위험)이 넓게 읽히도록 한다. 이는 [`templates/reports/final-report.template.md`](../../../templates/reports/final-report.template.md) 의 jinja 레이아웃만 바꾸며, `data.json` 스키마·report-writer 계약은 불변이다.
5
- - 비범위
6
- - **§5 Clarification Items 는 평면 8-컬럼 유지** — [`scripts/okstra_ctl/clarification_items.py`](../../../scripts/okstra_ctl/clarification_items.py) 가 `--resume-clarification` carry-in 을 위해 `|` 8-컬럼으로 파싱하고 validator 가 8-컬럼 스키마를 BLOCKING 으로 강제. §5 의 compact 는 HTML view 의 기존 grouping(이미 Expected form wide 까지 교정됨)이 담당한다.
7
- - `data.json` 스키마·report-writer worker 의 출력 계약·convergence 상태 변경 없음 (같은 필드를 템플릿이 다르게 배치할 뿐).
8
- - implementation-planning §4.5 deliverable 표(Stage Map / Stepwise 등)는 비대상 — validator 가 그 컬럼/헤딩을 substring 검사하므로 손대지 않는다.
9
- - 관계: 직전 작업(브랜치 `fix/report-table-grouping`, 커밋 `2343e30`)은 **HTML view 에서만** §1/§3/§4 를 grouped 로 만들었다. 본 설계(X)는 §1/§3/§4 를 `.md` 자체에서 compact 하게 만들어 그 HTML-only 접근을 **대체**한다 — 해당 표들은 더 이상 별도 `Ticket ID` 컬럼이 없어 report_views 의 generic grouping 분기가 발동하지 않으므로, 그 분기를 정리한다. §5 grouping(+Expected form wide) 은 유지된다.
10
-
11
- ## 1. 동기
12
-
13
- 사용자는 final-report 를 **`.md` 파일로 markdown 에디터에서 읽는다.** markdown 표는 colspan 이 없어, `ID·Ticket ID·Source·Kind·Status` 같은 짧은 코드 컬럼이 각각 한 칸씩 차지하면 정작 긴 prose 컬럼(요약·Statement·Evidence·Disagreement·Item·Risk)이 좁아져 세로로 한 글자씩 뭉개진다(실측: §1 Summary 의 "한 줄 요약"이 1글자/줄). HTML self-contained view 는 grouping 으로 해결되지만 `.md` 를 읽는 사용자에겐 닿지 않는다. 따라서 `.md` 자체에서 짧은 컬럼을 `<br>` 로 한 셀에 모아 컬럼 수를 줄이고 prose 에 폭을 준다.
14
-
15
- ## 2. 핵심 설계
16
-
17
- ### 2.1 대상 표와 meta/wide 분해
18
-
19
- 각 표를 `[meta 컬럼] + [prose 컬럼들]` 로 재구성한다(meta = 짧은 코드 필드를 `<br>` stack):
20
-
21
- | 표 | meta 컬럼(한 셀에 `<br>` stack) | 별도 prose 컬럼 |
22
- |---|---|---|
23
- | §1 Summary | ID, Ticket ID, 출처 | 한 줄 요약 |
24
- | §1.1 Consensus | ID, Ticket ID, Source items | Statement, Evidence |
25
- | §1.2 Differences | ID, Ticket ID, Workers(position+item) | Disagreement, Evidence |
26
- | §3.1 Primary Evidence | ID, Ticket ID, Source items, Source(path:line) | Evidence |
27
- | §3.2 Secondary | ID, Ticket ID | Hypothesis or supporting evidence, Source / confidence |
28
- | §4 Risks | ID, Ticket ID | Item, Risk if ignored, Mitigation Owner |
29
- | Execution Status | Agent, Role, Model, Status, raw/billable tokens, cost, Duration | Summary of Key Findings |
30
-
31
- 빈 상태(empty) 분기는 현행 그대로 유지(`emptyState.*`).
32
-
33
- ### 2.2 meta 셀 포맷 (`<br>` stack, i18n)
34
-
35
- meta 셀은 headline(주 식별자) + `<br>` 로 이어지는 `라벨: 값` 들로 구성한다. 예 §1.1 한 row:
36
-
37
- ```
38
- **C-1**<br>{ticketLabel}: `DEV-9184`<br>{sourceLabel}: claude:F-001, codex:1.1
39
- ```
40
-
41
- - headline 은 ID(또는 Agent/Step)를 `**굵게**`.
42
- - 라벨은 기존 i18n 키를 재사용(`columns.ticketId`, `columns.source`, …); 없으면 신규 키 추가(예 `columns.recordMeta` = meta 컬럼 헤더 "항목"/"Record").
43
- - 값에 코드성인 것(ticket 등)은 기존처럼 백틱 유지.
44
- - meta 컬럼 헤더는 짧은 라벨(예 "항목" / "Record") — 신규 i18n 키.
45
-
46
- ### 2.3 report_views 정합
47
-
48
- 1. **`_inline` 가 `<br>` 를 보존**: 현재 `html.escape` 가 `<br>`→`&lt;br&gt;` 로 깨뜨린다. escape 후 `&lt;br&gt;` / `&lt;br/&gt;` / `&lt;br /&gt;` 를 `<br>` 로 복원(bold/code/link 복원과 동일 패턴). 이로써 HTML view 도 meta 셀이 줄바꿈으로 보인다.
49
- 2. **generic Ticket-ID grouping 분기 제거**: §1/§3/§4 는 이제 `Ticket ID` 단독 컬럼이 없어 그 분기가 발동하지 않는다 — commit `2343e30` 가 추가한 generic 분기(+ 관련 헬퍼·테스트)를 정리한다. Execution Status 도 `.md` 에서 merged 되므로 그 explicit 분기 제거. **§5 Clarification grouping(+Expected form wide)만 남긴다**(§5 는 `.md` 평면 유지 → HTML 에서 grouping).
50
- 3. **plain-table 폭 보강**: merged meta 컬럼은 좁게, prose 컬럼은 넓게 나오도록 plain 경로의 컬럼 폭 처리를 점검(필요 시 meta 컬럼에 narrow, prose 에 min-width).
51
-
52
- ### 2.4 계약 영향
53
-
54
- - `data.json`·report-writer 계약·convergence 상태: **불변**. 템플릿이 같은 데이터를 다르게 배치.
55
- - §5 파서(`clarification_items.py`)·§5 8-컬럼 validator: **불변**(§5 평면 유지).
56
- - §1/§3/§4 컬럼 헤더를 substring 검사하는 validator/테스트는 없음(확인됨); 구현 단계에서 grep + 전체 테스트로 재확인.
57
- - carry-in 으로 다음 run 에 들어가는 `.md` 의 §1/§3/§4 는 LLM 이 컨텍스트로 읽을 뿐 코드가 컬럼 파싱하지 않으므로 `<br>` stack 도 안전.
58
-
59
- ## 3. 변경 파일
60
-
61
- 1. [`templates/reports/final-report.template.md`](../../../templates/reports/final-report.template.md) — §1/§1.1/§1.2/§3.1/§3.2/§4 + Execution Status 표를 meta(`<br>` stack) + prose 형태로 재작성.
62
- 2. [`templates/reports/report.i18n.*`](../../../templates/reports/) (또는 i18n SOT) — meta 컬럼 헤더 + 필요한 라벨 키 추가(ko/en).
63
- 3. [`scripts/okstra_ctl/report_views.py`](../../../scripts/okstra_ctl/report_views.py) — `_inline` `<br>` 보존; generic Ticket-ID grouping 분기 + Execution Status 분기 제거(§5 grouping 유지); plain 폭 보강.
64
- 4. [`tests/test_report_views.py`](../../../tests/test_report_views.py) — `<br>` 보존 테스트; §1/§3/§4 가 더는 grouped 분기 안 타고 `<br>` 가 보존되는지; §5 는 여전히 grouped + Expected form wide.
65
- 5. (필요 시) [`tests/test_render_*`](../../../tests/) — 템플릿 렌더 결과의 표 구조 스냅샷/스모크.
66
- 6. [`CHANGES.md`](../../../CHANGES.md) — 사용자 영향 항목.
67
-
68
- ## 4. Enforcement / 검증
69
-
70
- - 단위: `test_report_views.py` 로 `_inline` `<br>` 보존 + §5 grouping 유지를 잠금.
71
- - 템플릿 렌더: 실제 `data.json`(또는 픽스처)로 렌더해 §1/§3/§4/Exec 표가 meta+prose 형태로 나오는지 + §5 가 평면 8-컬럼인지 확인.
72
- - **실제 재렌더 검증(BLOCKING)**: 기존 사용자 리포트(또는 픽스처)를 렌더해 `.md` 와 HTML view 양쪽이 compact 하게 나오고 §5 carry-in 파서가 여전히 8-컬럼을 파싱하는지 실행 확인.
73
- - `python3 -m pytest tests/` + `bash validators/validate-workflow.sh` + `npm run build` 통과.
74
-
75
- ## 5. 트레이드오프 / 리스크
76
-
77
- - **트레이드오프:** §1/§3/§4 의 HTML view 가 grp-meta "key: value" 폴리시 대신 `<br>` stack 형태가 된다(살짝 덜 꾸며짐). 대신 `.md`↔HTML 레이아웃이 일관되고 `.md` 자체가 어떤 에디터에서도 읽기 쉽다(사용자 목표).
78
- - **리스크 — 전 task-type 영향:** 템플릿이 공유라 모든 phase 의 final-report `.md` 구조가 바뀐다. 기계 파싱은 §5 뿐이라 안전하나, 구현 시 전체 테스트 + 실제 렌더로 회귀 확인.
79
- - **리스크 — `<br>` 미지원 에디터:** 드물게 표 셀 `<br>` 를 literal 로 보이는 렌더러가 있을 수 있음. 주류(GitHub/Obsidian/Typora/VS Code)는 지원. 정본 가독성 목표상 수용.
80
-
81
- ## 6. 수용 기준
82
-
83
- 1. final-report `.md` 의 §1/§1.1/§1.2/§3.1/§3.2/§4 + Execution Status 가 meta(`<br>` stack) + prose 컬럼 형태로 렌더된다.
84
- 2. §5 Clarification 은 평면 8-컬럼 유지, carry-in 파서·validator 통과.
85
- 3. HTML view 가 meta 셀의 `<br>` 를 줄바꿈으로 보여준다(`_inline` 보존).
86
- 4. report_views 의 §1/§3/§4 generic grouping·Execution Status 분기는 제거되고 §5 grouping(+Expected form wide)은 유지.
87
- 5. `python3 -m pytest tests/` + validator + build 통과 + 실제 재렌더 육안 확인.
@@ -1,121 +0,0 @@
1
- # okstra wizard 멀티탭 배치 프롬프트 설계
2
-
3
- - 작성일: 2026-06-05
4
- - 대상: `scripts/okstra_ctl/wizard.py`, `skills/okstra-run/SKILL.md`
5
- - 상태: 설계 승인 대기
6
-
7
- ## 1. 배경 / 문제
8
-
9
- `okstra-run` 스킬은 wizard 상태 머신이 내보내는 프롬프트를 한 개씩
10
- `AskUserQuestion` 으로 렌더하고, 사용자가 답하면 다음 프롬프트를 받는 **답-대기 왕복**
11
- 구조다 ([wizard.py:2238](../../../scripts/okstra_ctl/wizard.py), [SKILL.md:96](../../../skills/okstra-run/SKILL.md)).
12
-
13
- `use_defaults=False`(customize) 분기에서는 서로 의존이 없는 픽이 줄줄이 개별 프롬프트로
14
- 나온다:
15
-
16
- - 모델: `lead_model` → (impl) `executor_model` / (그 외) 로스터별 `claude_model`·`codex_model`·`gemini_model` → `report_writer_model` — 최대 5회
17
- - 옵션: `directive_pick` → `related_tasks_pick` → `clarification_pick` → (release-handoff) `pr_template_pick` — 최대 4회
18
-
19
- 각 픽이 별도 왕복이라 전체 입력에 시간이 오래 걸린다. **비슷한 유형의 독립 질문을 탭으로
20
- 묶어 한 번의 `AskUserQuestion` 으로 받아** 왕복 수를 줄이는 것이 목표다.
21
-
22
- ## 2. 핵심 원칙
23
-
24
- **기존 `Step` 은 그대로 두고 "방출(presentation) 계층" 에만 배치 개념을 추가한다.**
25
-
26
- - `answered` / `owns` / edit-rewind(`_reset_from`) / `_ready_for_confirm` 의 `custom_ids`
27
- 검사는 전부 **개별 step id 단위**로 유지된다 ([wizard.py:2149](../../../scripts/okstra_ctl/wizard.py)).
28
- - 그룹은 "서로 의존이 없는 픽 step 들을 한 화면에 모아 내보내는" 래퍼일 뿐, step 자체를
29
- 대체하지 않는다. 따라서 검증·되감기 로직은 무손상이다.
30
-
31
- ## 3. 변경 사항
32
-
33
- ### 3.1 새 prompt kind `pick_group`
34
-
35
- `Prompt` 직렬화에 멀티-질문 모양을 추가한다 ([wizard.py:299](../../../scripts/okstra_ctl/wizard.py)).
36
-
37
- ```json
38
- {
39
- "step": "<group-id>",
40
- "kind": "pick_group",
41
- "questions": [
42
- { "step": "lead_model", "label": "...", "options": [ {"value":"..","label":".."} ], "multi": false },
43
- { "step": "claude_model", "label": "...", "options": [...], "multi": false }
44
- ]
45
- }
46
- ```
47
-
48
- - `questions[]` 한 항목 = `AskUserQuestion` 탭 하나.
49
- - 각 항목은 기존 step 의 `build()` 가 만든 `label` / `options` 를 그대로 재사용한다(중복 정의 금지).
50
- - 기존 `kind: "pick"` / `"text"` / `"done"` 은 변경 없음.
51
-
52
- ### 3.2 그룹 정의
53
-
54
- customize 분기의 **픽 step 만** 그룹화한다. 순서가 있는 명시적 정의를 wizard.py 에 둔다.
55
-
56
- | 그룹 id | 멤버 step (적용 가능할 때만) |
57
- |---|---|
58
- | `models` | `lead_model`, (impl) `executor_model` / (그 외) `claude_model`·`codex_model`·`gemini_model`, `report_writer_model` |
59
- | `options` | `directive_pick`, `related_tasks_pick`, `clarification_pick`, (release-handoff) `pr_template_pick` |
60
-
61
- **개별 유지(그룹화 금지) 대상**:
62
-
63
- - `*_TEXT` 후속(`directive`, `related_tasks`, `clarification`, `pr_template`): "직접 입력"
64
- 선택 시에만 나타나는 조건부 텍스트 입력. `AskUserQuestion` 은 텍스트 입력을 지원하지
65
- 않으므로 ([SKILL.md:50](../../../skills/okstra-run/SKILL.md)) 개별 텍스트 프롬프트로 유지.
66
- - `workers_override`: 어떤 모델 탭(claude/codex/gemini)이 적용되는지를 결정하므로 `models`
67
- 그룹보다 **반드시 선행**해야 한다. 개별 유지.
68
- - `pr_template_scope`: `pr_template_path` 가 정해진 뒤에야 적용되므로 개별 유지.
69
-
70
- ### 3.3 엔진 `next_prompt` 수정
71
-
72
- [wizard.py:2238](../../../scripts/okstra_ctl/wizard.py) 의 다음-프롬프트 결정 로직:
73
-
74
- 1. 기존대로 첫 번째 "적용 가능 + 미답변" step 을 찾는다.
75
- 2. 그 step 이 그룹 멤버가 아니면 기존 `Prompt` 를 그대로 반환(동작 불변).
76
- 3. 그룹 멤버이면 같은 그룹의 **적용 가능 + 미답변 픽 멤버**를 정의 순서대로 **최대 4개**까지
77
- 모아 `pick_group` 으로 반환한다.
78
- - `AskUserQuestion` 의 질문 수 한도가 4개이기 때문.
79
- - 비-implementation 풀 로스터(lead+claude+codex+gemini+report = 5)는 첫 4개만 한 배치로
80
- 나가고, 답변 후 5번째가 다음 배치로 자동 분리된다. **스킬에 청크 로직 불필요**, 최악 2화면.
81
-
82
- ### 3.4 제출 경로 수정
83
-
84
- [wizard.py:2233](../../../scripts/okstra_ctl/wizard.py) 의 advance, CLI `--answer` 파싱([wizard.py:2363](../../../scripts/okstra_ctl/wizard.py)):
85
-
86
- - 현재 활성 프롬프트가 `pick_group` 이면 `--answer` 를 **JSON 객체 문자열**로 받는다.
87
- ```
88
- okstra wizard step --state-file <path> --answer '{"lead_model":"opus","claude_model":"default","report_writer_model":""}'
89
- ```
90
- - 엔진은 각 키를 해당 멤버 step 의 `submit()` 으로 라우팅하고, 각 멤버를 개별적으로
91
- `answered` 에 추가한다.
92
- - 키 누락 / 빈 값("" 또는 "default")은 기존 `_validate_model` 규칙대로 "phase 기본값"으로
93
- 처리된다 ([wizard.py:418](../../../scripts/okstra_ctl/wizard.py)). 멤버 중 하나라도
94
- 검증 실패하면 `ok:false` 로 같은 그룹을 재-프롬프트한다(부분 적용 금지: 전부 검증 통과해야
95
- `answered` 마킹).
96
-
97
- ### 3.5 SKILL.md 렌더 규칙 추가
98
-
99
- [SKILL.md:41-50](../../../skills/okstra-run/SKILL.md), [SKILL.md:96](../../../skills/okstra-run/SKILL.md):
100
-
101
- - `kind: "pick_group"` → `questions[]` 를 탭(질문)으로 갖는 `AskUserQuestion` **1회** 호출.
102
- 탭마다 `label` + `options`, `multiSelect` 는 `questions[].multi`.
103
- - 사용자의 탭별 선택값(`options[].value`)을 `questions[].step` 키로 묶어 JSON 문자열을 만들고,
104
- 단일 `--answer '<json>'` 으로 제출.
105
- - 리터럴-토큰 권한 규칙 유지: `--answer` 값은 셸 변수/`$(...)` 없이 리터럴 JSON 문자열로 전달.
106
- - 검증 실패(`ok:false`) 시 동일 그룹 재-프롬프트.
107
-
108
- ## 4. 영향 / 비영향
109
-
110
- - **동작 변경**: customize 분기의 모델·옵션 픽이 멀티탭으로 묶여 왕복 횟수 감소
111
- (모델 3~5픽 → 1~2회, 옵션 3~4픽 → 1회).
112
- - **불변**: `use_defaults=True` 경로, identity 단계(task pick/type/base-ref/plan/executor),
113
- confirm/branch_confirm/edit-target, render-bundle 인자 매핑([wizard.py:2249](../../../scripts/okstra_ctl/wizard.py)).
114
- - **"직접 입력"** 을 고른 항목만 텍스트 후속이 개별 프롬프트로 남는다(불가피).
115
-
116
- ## 5. 테스트
117
-
118
- - 기존 wizard 단위 테스트(`tests/`) 가 개별 step 계약을 그대로 통과해야 한다(그룹은 방출 계층만 변경).
119
- - 신규: `pick_group` 방출(멤버 4개 초과 → 2배치 분리), JSON `--answer` 라우팅(부분 검증 실패 시
120
- 재-프롬프트), workers_override 선행 → models 그룹 로스터 반영을 커버하는 테스트 추가.
121
- - `node bin/okstra --version` / `bash validators/validate-workflow.sh` 회귀 확인.
@@ -1,126 +0,0 @@
1
- # final-verification 전체-task 게이트 설계
2
-
3
- - 작성일: 2026-06-06
4
- - 상태: 설계 승인됨 (사용자 승인 2026-06-06)
5
- - 선행: [stage-worktree-isolation-design.md](2026-06-06-stage-worktree-isolation-design.md) (P1–P5), [final-verification-protocol-hardening](../plans/2026-06-02-final-verification-protocol-hardening.md)
6
-
7
- ## 1. 배경 / 문제
8
-
9
- `final-verification` 은 lifecycle 의 마지막 acceptance gate 다 — "완료된 작업의 잔존 결함·회귀 위험을 점검하고 release 판단" ([architecture.md:348](../../kr/architecture.md:348)). 개념상 **모든 stage 가 구현·머지된 뒤 한 번** 도는 게 맞고, 검증 메커니즘인 `git diff <implementation-base>..HEAD` ([final-verification.md:28](../../../prompts/profiles/final-verification.md:28)) 도 base 를 전체 anchor 로 잡으면 task 전체를 한 번에 커버할 수 있다.
10
-
11
- 그러나 현재 entry gate 는 **단일 implementation report** 를 전제로 작성돼 있다:
12
-
13
- - brief 가 **the** originating implementation final-report 1개를 인용해야 하고 ([final-verification.md:26](../../../prompts/profiles/final-verification.md:26)),
14
- - "current checkout 이 그 report 의 commit list / diff summary 와 불일치하면 `blocked`" ([final-verification.md:29](../../../prompts/profiles/final-verification.md:29)).
15
-
16
- stage-worktree-isolation 모델에서는 **한 run = 한 stage** ([stage-worktree-isolation-design.md:51](2026-06-06-stage-worktree-isolation-design.md:51)) 이므로 stage N개 → implementation report N개가 생긴다 ([_implementation-deliverable.md:53](../../../prompts/profiles/_implementation-deliverable.md:53)). 마지막에 한 번 돌릴 때 brief 가 그중 하나만 인용하면, 사용자가 모든 stage 를 머지한 task-key worktree HEAD 에는 다른 stage 의 commit 이 더 있어 line 29 의 단일-report 일치 검사가 mismatch → `blocked` 위험이 있다.
17
-
18
- 즉 "전체-task 단일 게이트" 라는 의도와 "단일 report 전제" 라는 현재 계약이 정합되지 않은 상태다. 본 설계는 이를 해소하고, 추가로 **특정 run(stage)만 단독 검증** 하는 모드를 명시적으로 제공한다.
19
-
20
- ## 2. 목표 / 비목표
21
-
22
- 목표:
23
- - final-verification 이 **두 모드**로 동작: (A) 전체-task 모드(기본), (B) 단독-stage 모드.
24
- - 검증 target(base / HEAD / worktree / stage 목록)을 registry + `consumers.jsonl` + 승인 plan 의 Stage Map 에서 **자동 해소**한다. brief 의 worktree·base 수동 입력 제거.
25
- - entry gate 가 "전부 준비됨" 을 **실제로 강제**한다(선언이 아니라 enforcement).
26
-
27
- 비목표:
28
- - 자동 stage 머지(여전히 사용자 수동 머지 — [stage-worktree-isolation-design.md:7](2026-06-06-stage-worktree-isolation-design.md:7)).
29
- - octopus 머지 base 생성(옵션 B, 보류 유지).
30
- - implementation / 다른 phase 의 worktree 모델 변경.
31
-
32
- ## 3. 두 검증 모드
33
-
34
- `final-verification` 에 `--stage auto|N` 인수 추가(implementation 과 대칭). 격리 모델에서 `1 run = 1 stage` 이므로 "특정 run" ≡ "특정 stage" 다. 모드는 report data.json 의 `verificationScope` 필드로 표기: `whole-task`(전체) | `single-stage`(단독). (기존 convergence 의 `verificationMode` "lightweight"/"full-reanalysis" 와는 별개 필드 — 토큰 충돌 회피.)
35
-
36
- | 항목 | (A) 전체-task 모드 (`--stage auto`, 기본) | (B) 단독-stage 모드 (`--stage N`) |
37
- |---|---|---|
38
- | worktree | task-key worktree (모든 stage 머지된 공유본) | stage-key worktree `…/stage-N/` (registry 키 `<task-key>#stage-N`) |
39
- | base | registry `implementation_base_commit` (전체 anchor) | registry stage-key row `base_ref` (stage N 격리 base) |
40
- | HEAD | task-key worktree `git rev-parse HEAD` | stage-N worktree `git rev-parse HEAD` (= consumers done `head_commit`) |
41
- | stage 범위 | Stage Map 전부 | stage N 단독 |
42
- | gate: done | **모든** Stage Map stage 가 consumers `status:done` | **stage N** 만 consumers `status:done` |
43
- | gate: 머지 | 모든 done stage `head_commit` 이 HEAD 의 ancestor | 해당 없음(격리 worktree, 머지 불요) |
44
- | gate: clean | task-key worktree 가 `.okstra/` 제외 clean (§5) | stage-N worktree 가 `.okstra/` 제외 clean |
45
- | routing | `release-handoff` 허용(verdict `accepted` 시) | `release-handoff` **금지** — `implementation` / `done` 등으로 제한 |
46
-
47
- - **전체-task 모드** = 사용자가 의도한 "전부 머지된 뒤 마지막 한 번". release-handoff 로 가는 정식 게이트.
48
- - **단독-stage 모드** = stage 구현 직후 머지 전, 격리 worktree 에서 그 stage 만 검증. 다른 stage 의 done/머지 여부와 무관. 부분 검증이므로 `accepted` 여도 release-handoff 로 진입 불가.
49
-
50
- ## 4. target 자동 해소
51
-
52
- | 요소 | 출처 |
53
- |---|---|
54
- | base (전체 모드) | `worktree_registry.get_implementation_base(project_id, task_group, task_id)` ([worktree_registry.py:222](../../../scripts/okstra_ctl/worktree_registry.py:222)) |
55
- | base (단독 모드) | registry stage-key row `<task-key>#stage-N` 의 `base_ref` ([stage-worktree-isolation-design.md:78](2026-06-06-stage-worktree-isolation-design.md:78)) |
56
- | worktree / HEAD | 동일 registry row 의 worktree 경로 → 그 worktree 의 `git rev-parse HEAD` |
57
- | 전체 stage 목록 | 승인 plan 의 `## 5.5 Stage Map` 파싱 — `_parse_stage_map` 재사용 ([validate-implementation-plan-stages.py:55](../../../validators/validate-implementation-plan-stages.py:55), run.py 측 `_parse_stage_map_into_ctx` [run.py:381](../../../scripts/okstra_ctl/run.py:381)) |
58
- | done stage + 각 `head_commit` | `consumers.read_consumers(plan_run_root)` 의 `status:done` 행 ([consumers.py:22](../../../scripts/okstra_ctl/consumers.py:22)) |
59
- | stage 별 implementation report 경로(참고자료) | consumers done 행의 새 필드 `report_path` (§6) |
60
-
61
- registry / consumers 는 `~/.okstra/` 아래 okstra artifact 라 read 허용 범위 안이다(artifact-home 규칙 위배 아님). brief 는 worktree·base 를 더 이상 손으로 적지 않는다.
62
-
63
- ## 5. 강제 위치 — Python prep fail-fast
64
-
65
- target 해소와 gate 검사(done · merge-ancestor · clean)는 전부 결정적 데이터·git 연산이므로 **lead 런타임이 아니라** [run.py](../../../scripts/okstra_ctl/run.py) 의 bundle prep 단계에서 수행하고, 위반 시 `PrepareError` 로 막는다. implementation 의 `_resolve_stage_base_commit` PrepareError 패턴과 동일하다 ([run.py:307](../../../scripts/okstra_ctl/run.py:307)).
66
-
67
- - "선언(MUST)" 과 "강제(PrepareError)" 가 분리되지 않는다(전역 원칙 #3).
68
- - 해소된 snapshot 은 launch 템플릿에 `{{VERIFICATION_TARGET}}` 블록으로 주입 — implementation 의 `{{STAGE_BATCH_DIRECTIVE}}` 주입과 대칭 ([launch.template.md:18](../../../prompts/launch.template.md:18)). 모든 analyser 가 동일 target snapshot(worktree / base / head / diff stat / mode / stage 목록)을 받는다.
69
- - profile 의 entry gate 텍스트는 prep 가 보장하는 불변식을 **서술**하는 역할로 남고, 검사 책임은 Python 으로 단일화한다.
70
-
71
- **clean 검사 범위 — `.okstra/` 제외.** "검증한 HEAD = 릴리스될 상태" 를 보장하되, okstra 가 검증 중 만드는 자체 산출물(`.okstra/**` 아래 report·manifest·worktree 메타 등 untracked/변경)이 게이트를 거짓으로 막지 않도록, clean 판정은 **소스 트리 한정**한다: `git status --short -- . ':(exclude).okstra'` 출력이 비어있으면 clean. 즉 `.okstra/` 밖의 staged / unstaged / untracked 변경이 하나라도 있으면 dirty → block. (artifact-home 규칙상 `.okstra/` 만이 okstra 메모리이므로, 그 밖의 미커밋 변경은 검증 누락 위험으로 간주.)
72
-
73
- PrepareError 메시지(actionable):
74
- - 미완료 stage: `"final-verification(whole-task): stage {N} not done — run implementation --stage {N} first"`.
75
- - 미머지 stage: `"final-verification(whole-task): stage {N} done commit {sha} not merged into task worktree HEAD — merge stage branches then retry"`.
76
- - dirty worktree: `"final-verification: worktree has uncommitted source changes (outside .okstra/) — commit or stash before verifying"`.
77
-
78
- ## 6. consumers 행 확장 — `report_path`
79
-
80
- 단독-stage 모드가 stage report 를 참고자료로 인용하고, 전체-task 모드가 stage report 목록을 Source Implementation Report 에 나열하려면, done 행이 그 stage 의 final-report 경로를 가져야 한다.
81
-
82
- - `append_consumer(...)` 는 이미 `**fields` 를 받으므로 시그니처 변경 불필요 ([consumers.py:35](../../../scripts/okstra_ctl/consumers.py:35)). done 행 append 시 `report_path` 를 추가 필드로 전달.
83
- - 기록 책임: lead post-stage persistence — done 행 append 지점 ([_implementation-deliverable.md:52](../../../prompts/profiles/_implementation-deliverable.md:52)) 에 `report_path` 를 포함하도록 계약 갱신.
84
- - 읽기: `read_consumers` 가 dict 를 그대로 돌려주므로 소비 측에서 `row.get("report_path")` 로 읽는다(없으면 None — pre-1.0 라 호환 shim 없이, 새 필드 부재 시 참고자료 섹션만 비움).
85
-
86
- ## 7. report / 라우팅 계약
87
-
88
- - **Source Implementation Report** ([final-verification.md:31](../../../prompts/profiles/final-verification.md:31)): 단일 경로 → **목록**으로 확장. 전체-task 모드는 검증에 포함된 모든 done stage 의 `report_path` 와 stage 번호, 그리고 해소된 base/head SHA·worktree·diff stat·`verificationScope` 를 인용. 단독-stage 모드는 stage N 의 report 1개.
89
- - **routing**: `release-handoff` 추천은 **전체-task 모드 + verdict `accepted`** 일 때만 허용. 단독-stage 모드는 `accepted` 여도 routing 을 `implementation` / `done` 으로 제한. (release-handoff 진입 게이트의 `accepted` 강제는 기존대로 유지 — validate-run 정적 매핑 `final-verification: pending-release-handoff` [validate-run.py:67](../../../validators/validate-run.py:67).)
90
-
91
- ## 8. 영향 범위
92
-
93
- | 파일 | 변경 |
94
- |---|---|
95
- | [run.py](../../../scripts/okstra_ctl/run.py) | final-verification target 해소 + gate(PrepareError) + `--stage auto\|N` 분기. `get_implementation_base` / `_parse_stage_map_into_ctx` / `read_consumers` 재사용. `{{VERIFICATION_TARGET}}` ctx 주입 |
96
- | [consumers.py](../../../scripts/okstra_ctl/consumers.py:35) | done 행에 `report_path` 기록(write 호출부) — 시그니처는 `**fields` 라 불변 |
97
- | [_implementation-deliverable.md:52](../../../prompts/profiles/_implementation-deliverable.md:52) | lead post-stage persistence: done 행에 `report_path` 포함 계약 |
98
- | [final-verification.md:25](../../../prompts/profiles/final-verification.md:25) | entry gate 재작성(두 모드, prep 가 강제함을 서술), Source Implementation Report → 목록, routing 제약(release-handoff = 전체-task 한정) |
99
- | [launch.template.md:18](../../../prompts/launch.template.md:18) | `{{VERIFICATION_TARGET}}` 주입 지점 |
100
- | [wizard.py](../../../scripts/okstra_ctl/wizard.py:1204) | final-verification 서브플로우에 stage 3-옵션 picker(추천=전체 `auto` / 특정 stage N / 직접 입력) 노출. `selected_stage` 를 final-verification 에도 emit ([wizard.py:2353](../../../scripts/okstra_ctl/wizard.py:2353)). brief 단계에서 worktree·base 수동 입력 제거 |
101
- | [validate-run.py](../../../validators/validate-run.py) | release-handoff routing 은 `verificationScope=whole-task` 일 때만, Source Implementation Report 다중 항목 허용, 새 필드(`verificationScope`, stage 목록) 검증 |
102
- | templates / schema | report data.json 필드(`verificationScope`, 검증 stage 목록), [final-verification-input.template.md](../../../templates/reports/final-verification-input.template.md) 갱신 |
103
-
104
- `runtime/` 는 build output — 커밋 제외. 소스 변경 후 `npm run build` 로 동기화.
105
-
106
- ## 9. 테스트
107
-
108
- | ID | 시나리오 | 기대 |
109
- |---|---|---|
110
- | U1 | `_resolve` 전체-task: 모든 stage done + 머지 + clean | target(base=anchor, head=task HEAD, stage 목록 전부) 반환 |
111
- | U2 | 전체-task: stage 하나 미완료 | PrepareError(미완료 stage) |
112
- | U3 | 전체-task: done stage 가 HEAD ancestor 아님(미머지) | PrepareError(미머지) |
113
- | U4 | 전체-task: `.okstra/` 밖 dirty worktree | PrepareError(uncommitted) |
114
- | U4b | 전체-task: `.okstra/` 안에만 변경(소스 clean) | 통과(게이트 안 걸림) |
115
- | U5 | 단독-stage `--stage N`: stage N done | target(base=stage-key base_ref, head=stage worktree HEAD) 반환, 다른 stage 무관 |
116
- | U6 | 단독-stage: stage N 미완료 | PrepareError |
117
- | W1 | wizard final-verification 서브플로우 stage picker | auto / N / 직접입력 3-옵션, `selected_stage` emit |
118
- | E1 | e2e: 2-stage 작업, 둘 다 done+머지 후 전체-task | 통과, release-handoff routing 허용 |
119
- | E2 | e2e: stage 1 done, stage 2 미머지 상태에서 전체-task | block + 안내 |
120
- | E3 | e2e: stage 1 구현 직후 `--stage 1` 단독 | 통과, routing 은 release-handoff 불가 |
121
-
122
- ## 10. 미해결 / 후속
123
-
124
- - 다른 phase(`requirements-discovery` / `error-analysis`)는 stage 개념이 없으므로 `--stage` 무시(현행대로 `""` emit). final-verification 만 신규 대상.
125
- - `plan_run_root` 위치 해소: consumers.jsonl 은 plan-task-key run root 아래. final-verification 이 이 경로를 어떻게 얻는지(report → plan reference 경유 vs registry)는 구현 단계에서 run.py 기존 경로 해소 로직과 정합되게 확정한다.
126
- - 단독-stage 모드의 stage-key worktree 가 teardown 된 뒤(사용자가 정리)에는 단독 검증 불가 — 그 경우 PrepareError 로 "stage worktree 없음, 전체-task 모드 사용" 안내.