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,516 +0,0 @@
1
- # Coverage critic 구현 계획 (sub-project B1)
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** requirements-discovery / error-analysis / implementation-planning 에 opt-in coverage critic pass 를 추가한다 — Phase 5.5 직후 기존 worker 를 critic 프롬프트로 재사용 dispatch 하고, gap 은 1회 적대적 reverify 후 병합. 사용 여부·provider 는 okstra-run select box(또는 `--critic` 플래그)로 고른다.
6
-
7
- **Architecture:** 백엔드는 `convergence.critic {enabled,provider,modelExecutionValue}` manifest 블록 — `render._build_convergence_block` 가 ctx `CRITIC_CHOICE` + 기존 `*_MODEL_EXECUTION_VALUE` 로 해석. 선택은 `--critic` CLI 플래그 + okstra-run wizard `S_CRITIC_PICK` step(플래그 미지정 시에만 표시). critic *행동*(gap 탐색·1회 적대 reverify·병합)은 convergence skill + lead/profile 의 prompt 지시(런타임 강제 아님).
8
-
9
- **Tech Stack:** Python 3 (okstra_ctl: run/render/wizard, pytest), wizard prompts JSON, Markdown skill/prompt 문서. 빌드: `npm run build`.
10
-
11
- **설계 근거:** [`docs/superpowers/specs/2026-06-04-coverage-critic-design.md`](../specs/2026-06-04-coverage-critic-design.md)
12
-
13
- ---
14
-
15
- ## 파일 구조
16
-
17
- | 파일 | 책임 | 작업 |
18
- |---|---|---|
19
- | [`scripts/okstra_ctl/run.py`](../../../scripts/okstra_ctl/run.py) | `--critic` 플래그 + `PrepareInputs.critic` + ctx `CRITIC_CHOICE` + canonical_argv + 값 검증 | Modify |
20
- | [`scripts/okstra_ctl/render.py`](../../../scripts/okstra_ctl/render.py) | `_build_convergence_block` 에 `critic` 블록 (phase-gated) | Modify (899–) |
21
- | `tests/test_render_critic_block.py` | critic 블록 resolve 단위 테스트 | Create |
22
- | [`scripts/okstra_ctl/wizard.py`](../../../scripts/okstra_ctl/wizard.py) | `S_CRITIC_PICK` step (state/constant/build/submit/Step/finalize/summary) | Modify |
23
- | [`prompts/wizard/prompts.ko.json`](../../../prompts/wizard/prompts.ko.json) | `critic_pick` step label/options | Modify |
24
- | `tests/test_wizard_critic_pick.py` | wizard step build/submit/applies 테스트 | Create |
25
- | [`skills/okstra-convergence/SKILL.md`](../../../skills/okstra-convergence/SKILL.md) | "Coverage critic pass" 절 | Modify |
26
- | [`agents/SKILL.md`](../../../agents/SKILL.md) | Phase 5.5→6 critic pass + PROGRESS 라인 | Modify |
27
- | [`prompts/profiles/requirements-discovery.md`](../../../prompts/profiles/requirements-discovery.md) / [`error-analysis.md`](../../../prompts/profiles/error-analysis.md) / [`implementation-planning.md`](../../../prompts/profiles/implementation-planning.md) | coverage critic opt-in 선언 | Modify |
28
- | [`CHANGES.md`](../../../CHANGES.md) | 사용자 영향 항목 | Modify |
29
-
30
- 작업 순서: 백엔드(run+render+test) → wizard(step+json+test) → convergence skill → agents+profiles → CHANGES+검증.
31
-
32
- ---
33
-
34
- ### B1-Task1: 백엔드 — `--critic` 플래그 + manifest `convergence.critic` 블록
35
-
36
- **Files:**
37
- - Modify: `scripts/okstra_ctl/run.py`
38
- - Modify: `scripts/okstra_ctl/render.py` (`_build_convergence_block`)
39
- - Create: `tests/test_render_critic_block.py`
40
-
41
- - [ ] **Step 1: 실패하는 render 테스트 작성**
42
-
43
- Create `tests/test_render_critic_block.py`:
44
-
45
- ```python
46
- """_build_convergence_block — coverage critic 블록 phase-gated resolve.
47
-
48
- critic 은 requirements-discovery / error-analysis / implementation-planning 에서만
49
- enabled 가능. provider 는 ctx CRITIC_CHOICE, 모델은 해당 provider 의
50
- *_MODEL_EXECUTION_VALUE 에서. 미지정/off/비적용 phase 면 disabled.
51
- """
52
- from __future__ import annotations
53
-
54
- import sys
55
- from pathlib import Path
56
-
57
- import pytest
58
-
59
- _REPO_ROOT = Path(__file__).resolve().parents[1]
60
- sys.path.insert(0, str(_REPO_ROOT / "scripts"))
61
-
62
- from okstra_ctl.render import _build_convergence_block # noqa: E402
63
-
64
- _MODEL_CTX = {
65
- "CLAUDE_WORKER_MODEL_EXECUTION_VALUE": "opus",
66
- "CODEX_WORKER_MODEL_EXECUTION_VALUE": "gpt-5.5",
67
- "GEMINI_WORKER_MODEL_EXECUTION_VALUE": "auto",
68
- }
69
-
70
-
71
- def _ctx(task_type, critic_choice):
72
- return {"TASK_TYPE": task_type, "CRITIC_CHOICE": critic_choice, **_MODEL_CTX}
73
-
74
-
75
- def test_critic_disabled_when_unset():
76
- block = _build_convergence_block(_ctx("error-analysis", ""))
77
- assert block["critic"] == {"enabled": False, "provider": None, "modelExecutionValue": None}
78
-
79
-
80
- def test_critic_disabled_when_off():
81
- block = _build_convergence_block(_ctx("error-analysis", "off"))
82
- assert block["critic"]["enabled"] is False
83
-
84
-
85
- @pytest.mark.parametrize("task_type", ["requirements-discovery", "error-analysis", "implementation-planning"])
86
- def test_critic_enabled_for_applicable_phases(task_type):
87
- block = _build_convergence_block(_ctx(task_type, "claude"))
88
- assert block["critic"] == {"enabled": True, "provider": "claude", "modelExecutionValue": "opus"}
89
-
90
-
91
- def test_critic_model_follows_provider():
92
- block = _build_convergence_block(_ctx("error-analysis", "codex"))
93
- assert block["critic"]["provider"] == "codex"
94
- assert block["critic"]["modelExecutionValue"] == "gpt-5.5"
95
-
96
-
97
- @pytest.mark.parametrize("task_type", ["implementation", "final-verification", "release-handoff"])
98
- def test_critic_disabled_for_non_applicable_phases(task_type):
99
- block = _build_convergence_block(_ctx(task_type, "claude"))
100
- assert block["critic"]["enabled"] is False
101
- ```
102
-
103
- - [ ] **Step 2: 실패 확인**
104
-
105
- Run: `python3 -m pytest tests/test_render_critic_block.py -q`
106
- Expected: FAIL — `block` 에 `"critic"` 키 없음 (`KeyError`).
107
-
108
- - [ ] **Step 3: render `_build_convergence_block` 에 critic 블록 추가**
109
-
110
- `scripts/okstra_ctl/render.py` `_build_convergence_block` 의 `return { ... }` 직전(현재 `plan_verify_enabled = ...` 다음)에 삽입:
111
-
112
- ```python
113
- critic_choice = (ctx.get("CRITIC_CHOICE", "") or "").strip().lower()
114
- critic_phases = {"requirements-discovery", "error-analysis", "implementation-planning"}
115
- critic_exec_key = {
116
- "claude": "CLAUDE_WORKER_MODEL_EXECUTION_VALUE",
117
- "codex": "CODEX_WORKER_MODEL_EXECUTION_VALUE",
118
- "gemini": "GEMINI_WORKER_MODEL_EXECUTION_VALUE",
119
- }
120
- critic_enabled = critic_choice in critic_exec_key and task_type in critic_phases
121
- critic_block = {
122
- "enabled": critic_enabled,
123
- "provider": critic_choice if critic_enabled else None,
124
- "modelExecutionValue": (ctx.get(critic_exec_key[critic_choice]) or None) if critic_enabled else None,
125
- }
126
- ```
127
-
128
- 그리고 같은 함수의 반환 dict 에 `"planBodyVerification": {...}` 항목 **앞에** `"critic": critic_block,` 한 줄 추가. docstring 의 ctx knobs 목록에 한 줄 추가:
129
-
130
- ```python
131
- - `CRITIC_CHOICE`: "" | "off" | "claude" | "codex" | "gemini" — coverage critic
132
- backing provider (enabled only for requirements-discovery / error-analysis /
133
- implementation-planning); model taken from that provider's execution value.
134
- ```
135
-
136
- - [ ] **Step 4: render 테스트 통과 확인**
137
-
138
- Run: `python3 -m pytest tests/test_render_critic_block.py -q`
139
- Expected: PASS.
140
-
141
- - [ ] **Step 5: run.py — `--critic` 플래그 + PrepareInputs + ctx + canonical_argv + 검증**
142
-
143
- (5a) `PrepareInputs` dataclass 의 `executor: str = ""` 줄 다음에 추가:
144
- ```python
145
- critic: str = ""
146
- ```
147
-
148
- (5b) argparse 의 `p.add_argument("--executor", default="")` 다음 줄에 추가:
149
- ```python
150
- p.add_argument("--critic", default="")
151
- ```
152
- 그리고 argparse 결과를 `PrepareInputs(...)` 로 묶는 생성부에 `critic=args.critic,` 를 (executor 인자 옆에) 추가. (생성부는 argparse 직후 `PrepareInputs(` 호출 — `executor=args.executor` 패턴을 그대로 따라 한 줄 추가.)
153
-
154
- (5c) `_canonical_argv` 의 pairs 리스트에서 `("--executor", ...)` 다음에 추가:
155
- ```python
156
- ("--critic", inp.critic or ctx.get("CRITIC_CHOICE", "")),
157
- ```
158
-
159
- (5d) 모델 메타데이터 resolve 직후(executor binding 블록 시작 `# ---- executor binding` 줄 **앞**)에 critic 검증 + ctx 변수 삽입:
160
- ```python
161
- # ---- coverage critic choice (validated; phase-gating happens in render) ----
162
- critic_choice = (inp.critic or "").strip().lower()
163
- if critic_choice not in ("", "off", "claude", "codex", "gemini"):
164
- raise PrepareError(
165
- f"--critic must be one of: off, claude, codex, gemini (got: {critic_choice!r})"
166
- )
167
- ```
168
- (use whatever error type the file already raises for `--executor` validation — match the executor validator's exception class, seen near the `--executor must be one of` raise.)
169
-
170
- (5e) ctx dict 빌드부(`"RENDER_ONLY": ...` 등이 있는 dict)에 한 줄 추가:
171
- ```python
172
- "CRITIC_CHOICE": critic_choice,
173
- ```
174
-
175
- - [ ] **Step 6: run.py 검증 동작 테스트 (수동)**
176
-
177
- Run: `python3 -c "import sys; sys.path.insert(0,'scripts'); from okstra_ctl.run import build_arg_parser" 2>/dev/null; python3 -m pytest tests/ -q -k "convergence or critic or plan_body"`
178
- Expected: PASS (critic 블록 테스트 + 기존 convergence/plan-body 테스트 무회귀).
179
-
180
- - [ ] **Step 7: 전체 빠른 회귀 + 커밋**
181
-
182
- Run: `python3 -m pytest tests/ -q`
183
- Expected: PASS (전체).
184
-
185
- ```bash
186
- git add scripts/okstra_ctl/run.py scripts/okstra_ctl/render.py tests/test_render_critic_block.py
187
- git commit -m "feat(okstra_ctl): --critic flag + convergence.critic manifest block (phase-gated)"
188
- ```
189
-
190
- ---
191
-
192
- ### B1-Task2: okstra-run wizard `S_CRITIC_PICK` step
193
-
194
- **Files:**
195
- - Modify: `scripts/okstra_ctl/wizard.py`
196
- - Modify: `prompts/wizard/prompts.ko.json`
197
- - Create: `tests/test_wizard_critic_pick.py`
198
-
199
- - [ ] **Step 1: 실패하는 wizard 테스트 작성**
200
-
201
- Create `tests/test_wizard_critic_pick.py`:
202
-
203
- ```python
204
- """S_CRITIC_PICK wizard step — coverage critic 선택.
205
-
206
- 3 적용 phase 에서만 표시, 미선택 시. provider/off 를 state.critic 에 기록.
207
- """
208
- from __future__ import annotations
209
-
210
- import sys
211
- from pathlib import Path
212
-
213
- import pytest
214
-
215
- _REPO_ROOT = Path(__file__).resolve().parents[1]
216
- sys.path.insert(0, str(_REPO_ROOT / "scripts"))
217
-
218
- from okstra_ctl import wizard as W # noqa: E402
219
-
220
-
221
- def _state(task_type="error-analysis", critic=""):
222
- s = W.WizardState(workspace_root=str(_REPO_ROOT))
223
- s.task_type = task_type
224
- s.critic = critic
225
- return s
226
-
227
-
228
- def test_critic_pick_build_offers_off_and_provider_and_custom():
229
- p = W._build_critic_pick(_state())
230
- values = [o["value"] if isinstance(o, dict) else o.value for o in p.options]
231
- assert "off" in values
232
- assert "claude" in values
233
-
234
-
235
- def test_critic_pick_submit_records_provider():
236
- s = _state()
237
- W._submit_critic_pick(s, "codex")
238
- assert s.critic == "codex"
239
-
240
-
241
- def test_critic_pick_submit_records_off():
242
- s = _state()
243
- W._submit_critic_pick(s, "off")
244
- assert s.critic == "off"
245
-
246
-
247
- def test_critic_pick_submit_rejects_unknown():
248
- s = _state()
249
- with pytest.raises(W.WizardError):
250
- W._submit_critic_pick(s, "bogus")
251
-
252
-
253
- @pytest.mark.parametrize("task_type", ["requirements-discovery", "error-analysis", "implementation-planning"])
254
- def test_critic_step_applies_for_three_phases_when_unset(task_type):
255
- step = next(st for st in W.STEPS if st.id == W.S_CRITIC_PICK)
256
- assert step.applies(_state(task_type=task_type, critic="")) is True
257
-
258
-
259
- @pytest.mark.parametrize("task_type", ["implementation", "final-verification", "release-handoff"])
260
- def test_critic_step_skipped_for_other_phases(task_type):
261
- step = next(st for st in W.STEPS if st.id == W.S_CRITIC_PICK)
262
- assert step.applies(_state(task_type=task_type, critic="")) is False
263
-
264
-
265
- def test_critic_step_skipped_when_preseeded():
266
- step = next(st for st in W.STEPS if st.id == W.S_CRITIC_PICK)
267
- assert step.applies(_state(task_type="error-analysis", critic="claude")) is False
268
- ```
269
-
270
- NOTE (confirmed against wizard.py): the step list is the module-level `STEPS: list[Step]` (≈line 1806) and the `Step` dataclass field is `id` (≈line 617: `id`, `applies`, `build`, `submit`, `owns`). `Prompt` is constructed with `step=` (see `_build_executor`). `_opt(value, label)` returns `Option(value, label, description)`. The test above is already written to these confirmed names.
271
-
272
- - [ ] **Step 2: 실패 확인**
273
-
274
- Run: `python3 -m pytest tests/test_wizard_critic_pick.py -q`
275
- Expected: FAIL — `_build_critic_pick` / `S_CRITIC_PICK` 미정의 (`AttributeError`).
276
-
277
- - [ ] **Step 3: wizard 구현**
278
-
279
- (3a) `S_EXECUTOR = "executor"` 류 상수 근처에 추가:
280
- ```python
281
- S_CRITIC_PICK = "critic_pick"
282
- ```
283
-
284
- (3b) `WizardState` 의 `executor: str = ""` 줄 다음에 추가:
285
- ```python
286
- critic: str = ""
287
- ```
288
-
289
- (3c) `_build_executor` / `_submit_executor` 패턴을 그대로 따라 새 함수 추가(파일 내 다른 `_build_*`/`_submit_*` 모음 근처):
290
- ```python
291
- CRITIC_CHOICES = ["off", "claude", "codex", "gemini"]
292
-
293
-
294
- def _build_critic_pick(state: WizardState) -> Prompt:
295
- t = _p(state.workspace_root, "critic_pick")
296
- return Prompt(
297
- step=S_CRITIC_PICK, kind="pick",
298
- label=t["label"],
299
- options=[_opt(k, v) for k, v in t["options"].items() if not k.startswith("_")],
300
- echo_template=t["echo_template"],
301
- )
302
-
303
-
304
- def _submit_critic_pick(state: WizardState, value: str) -> Optional[str]:
305
- if value not in CRITIC_CHOICES:
306
- raise WizardError(f"critic must be one of {CRITIC_CHOICES}, got: {value!r}")
307
- state.critic = value
308
- return f"critic: {value}"
309
- ```
310
- (If `Prompt`/`_opt`/`_p` signatures differ from what `_build_executor` uses, mirror `_build_executor` exactly — it is the canonical static-pick precedent.)
311
-
312
- (3d) `Step(...)` 리스트(STEPS)에 `S_DEFAULTS_OR_CUSTOM` Step **앞에** 추가:
313
- ```python
314
- Step(S_CRITIC_PICK,
315
- applies=lambda s: (s.task_type in ("requirements-discovery", "error-analysis", "implementation-planning")
316
- and not s.critic
317
- and S_CRITIC_PICK not in s.answered),
318
- build=_build_critic_pick, submit=_submit_critic_pick,
319
- owns=("critic",)),
320
- ```
321
-
322
- (3e) finalize dict(반환 dict, `"executor": state.executor,` 가 있는 곳)에 추가:
323
- ```python
324
- "critic": state.critic,
325
- ```
326
-
327
- (3f) summary 출력부(`executor` summary line 근처)에, 3 적용 phase 일 때 critic 줄 추가:
328
- ```python
329
- if state.task_type in ("requirements-discovery", "error-analysis", "implementation-planning"):
330
- lines.append(f" critic : {state.critic or '(off)'}")
331
- ```
332
-
333
- (3g) wizard `_cli` 의 argparse(pre-seed 용)에 `--critic` 추가하고 초기 state 에 반영 — `executor` 가 pre-seed 되는 방식을 그대로 따라 `--critic` 를 받아 `state.critic` 에 넣는다(없으면 빈 문자열). 이로써 플래그가 넘어오면 `not s.critic` 가 거짓이 되어 step 이 건너뛰어진다. (executor 의 pre-seed 경로를 grep 해 동일하게 배선.)
334
-
335
- - [ ] **Step 4: prompts.ko.json `critic_pick` 항목 추가**
336
-
337
- `prompts/wizard/prompts.ko.json` 에 새 키 추가(다른 step 항목과 같은 형식):
338
- ```json
339
- "critic_pick": {
340
- "label": "coverage critic 를 추가로 돌릴까요? (놓친 finding·각도를 캐는 검증 패스 — opt-in)",
341
- "echo_template": "critic: {value}",
342
- "options": {
343
- "off": "사용 안 함 (기본·추천)",
344
- "claude": "claude critic (추천)",
345
- "직접 입력": "직접 입력 (codex / gemini 등 provider 직접 지정)"
346
- }
347
- }
348
- ```
349
- NOTE — "직접 입력" custom row (REQUIRED by the user's standing picker convention: 추천 1~2개 + 마지막 "직접 입력"). The codebase's custom-input mechanism is `PICK_TYPE_CUSTOM = "__free_input__"` (≈line 87) plus a per-field `*_pending_text` flag, used by pickers like `directive` / `task_group`. The fixed-choice `executor` step does NOT use it. So model the critic picker on a custom-input picker (grep `pending_text` and `PICK_TYPE_CUSTOM` and read e.g. the `directive` build/submit pair): the "직접 입력" row emits `PICK_TYPE_CUSTOM`, the wizard then prompts free text, and `_submit_critic_pick` receives that text (a provider string `codex`/`gemini`) and validates it against `CRITIC_CHOICES`. If wiring a full pending-text round is disproportionate for a closed 4-value enum, the acceptable fallback is to list all four values (`off`/`claude`/`codex`/`gemini`) as explicit options with "직접 입력" still present as the trailing custom row — but do NOT silently drop the custom row. Confirm the chosen approach in the implementer report.
350
-
351
- - [ ] **Step 5: wizard 테스트 통과 확인**
352
-
353
- Run: `python3 -m pytest tests/test_wizard_critic_pick.py -q`
354
- Expected: PASS.
355
-
356
- - [ ] **Step 6: 커밋**
357
-
358
- ```bash
359
- git add scripts/okstra_ctl/wizard.py prompts/wizard/prompts.ko.json tests/test_wizard_critic_pick.py
360
- git commit -m "feat(okstra_ctl/wizard): S_CRITIC_PICK step for coverage critic selection"
361
- ```
362
-
363
- ---
364
-
365
- ### B1-Task3: convergence SKILL.md — "Coverage critic pass" 절
366
-
367
- **Files:**
368
- - Modify: `skills/okstra-convergence/SKILL.md`
369
-
370
- - [ ] **Step 1: "Coverage critic pass" 절 추가**
371
-
372
- `## Output` 절(Phase 6 로 넘기는 정보) **앞에**(또는 §"Plan-body verification mode" 앞 적절한 위치에) 새 절 삽입:
373
-
374
- ```markdown
375
- ## Coverage critic pass
376
-
377
- Runs only when `convergence.critic.enabled == true` (set by `--critic <provider>` or the okstra-run `critic_pick` step; default off). Applies to `requirements-discovery`, `error-analysis`, and `implementation-planning`. This pass targets **coverage** (missed findings), distinct from convergence which targets **agreement quality**.
378
-
379
- ### When
380
- After Phase 5.5 finding convergence completes (findings classified) and BEFORE the Phase 6 report-writer dispatch.
381
-
382
- ### Dispatch (reused worker)
383
- Dispatch ONE pass to the `config.critic.provider`'s existing subagent (`claude-worker` / `codex-worker` / `gemini-worker`) with `model = config.critic.modelExecutionValue` — no new agent type. Result path: `runs/<task-type>/worker-results/<provider>-critic-<task-type>-<seq>.md`. The critic prompt seeds the consolidated findings and asks ONLY for coverage gaps:
384
-
385
- ```
386
- You are the coverage critic for <task-key>. Below are the findings the workers
387
- already agreed on. Your ONLY job is to name what is MISSING:
388
- - files / directories / execution paths nobody inspected,
389
- - requirements or acceptance points with zero findings,
390
- - claims raised but never verified.
391
- For each gap, emit a NEW finding with evidence (file:line or the requirement quote).
392
- Do NOT restate an existing finding. If nothing is missing, say so explicitly.
393
- ```
394
-
395
- ### Gap verification (1 adversarial reverify round)
396
- Each critic gap enters the verification queue as a finding with `originWorker = "<provider>-critic"` and `source = "critic"`. The lead runs ONE adversarial reverify round (§"Adversarial Verification Mode" classifier) with the Phase 4 analysers (excluding the critic itself) as voters. Only gaps classified `full-consensus` / `partial-consensus` merge into the final report findings; `contested` / `worker-unique` gaps are treated as hallucinations and dropped (recorded in the convergence state, not promoted). If fewer than one non-critic analyser is available to vote, the gaps are surfaced as unverified `clarification` items rather than merged, and that fact is recorded.
397
-
398
- ### State
399
- - `convergence.critic` manifest block: `{ enabled, provider, modelExecutionValue }`.
400
- - Convergence state artifact: critic gaps appear in `findings[]` with `source: "critic"`. Add a `config.critic` summary `{ provider, modelExecutionValue, gapsProposed, gapsMerged }`. `source` and `config.critic` are optional v1.2 fields (readers treat absence as null); no enum changes.
401
- ```
402
-
403
- - [ ] **Step 2: 빌드 + 검증**
404
-
405
- Run: `npm run build && bash validators/validate-workflow.sh`
406
- Expected: build 22/22 synced, validator PASS.
407
-
408
- - [ ] **Step 3: 커밋**
409
-
410
- ```bash
411
- git add skills/okstra-convergence/SKILL.md runtime/
412
- git commit -m "feat(skills/okstra-convergence): define coverage critic pass"
413
- ```
414
-
415
- ---
416
-
417
- ### B1-Task4: agents/SKILL.md 흐름 + 3 프로필 opt-in 선언
418
-
419
- **Files:**
420
- - Modify: `agents/SKILL.md`
421
- - Modify: `prompts/profiles/requirements-discovery.md`, `error-analysis.md`, `implementation-planning.md`
422
-
423
- - [ ] **Step 1: agents/SKILL.md — Phase 5.5→6 critic pass + PROGRESS**
424
-
425
- (1a) lead phase 표/Phase 6 설명에서 Phase 5.5 와 Phase 6 사이에 한 줄 추가(Phase 5.5 행 설명 끝 또는 Phase 6 행 앞):
426
- ```markdown
427
- | 5.6 Coverage critic | (opt-in) reused-worker critic pass for missed findings, 1 adversarial reverify round | `okstra-convergence` "Coverage critic pass" |
428
- ```
429
- (표 컬럼 수에 맞춰 기존 행 형식대로.)
430
-
431
- (1b) Progress reporting 체크포인트 목록에서 `PROGRESS: phase-6-synthesis ...` 줄 **앞에** 추가:
432
- ```markdown
433
- - `PROGRESS: phase-5.6-critic provider=<provider> gaps=<n>` — when the coverage critic pass runs (Phase 5.6, opt-in). Omitted when `convergence.critic.enabled == false`.
434
- ```
435
-
436
- - [ ] **Step 2: 3 프로필에 coverage critic opt-in 선언**
437
-
438
- 세 파일 각각의 `- Cross-verification mode:` bullet(requirements-discovery / error-analysis 는 직전 sub-project 가 추가한 bullet; implementation-planning 도 동일 bullet 존재) 아래에 sub-bullet 추가. requirements-discovery 예:
439
- ```markdown
440
- - **Coverage critic (opt-in)**: when `convergence.critic.enabled=true` (chosen via `--critic` or the okstra-run picker), a reused-worker critic pass runs after convergence to surface missed findings; its gaps are merged only after a 1-round adversarial reverify. See `skills/okstra-convergence/SKILL.md` "Coverage critic pass".
441
- ```
442
- error-analysis / implementation-planning 도 동일 문장(phase 명만 자연스럽게). requirements-discovery / error-analysis 가 `- Cross-verification mode:` bullet 을 아직 안 가졌다면(직전 sub-project 가 error-analysis 에 추가했는지 확인 — 안 했으면 새 `- Cross-verification mode:` top-level bullet 을 `- Non-goals:` 앞에 만들고 그 안에 이 sub-bullet 을 넣는다).
443
-
444
- - [ ] **Step 3: 빌드 + 검증**
445
-
446
- Run: `npm run build && bash validators/validate-workflow.sh`
447
- Expected: build 성공, validator PASS.
448
-
449
- - [ ] **Step 4: 커밋**
450
-
451
- ```bash
452
- git add agents/SKILL.md prompts/profiles/requirements-discovery.md prompts/profiles/error-analysis.md prompts/profiles/implementation-planning.md runtime/
453
- git commit -m "feat(agents,prompts/profiles): declare opt-in coverage critic pass"
454
- ```
455
-
456
- ---
457
-
458
- ### B1-Task5: CHANGES + 전체 검증 + 최종 커밋
459
-
460
- **Files:**
461
- - Modify: `CHANGES.md`
462
-
463
- - [ ] **Step 1: CHANGES.md 항목 추가**
464
-
465
- `## 2026-06-04` 헤더 바로 다음, 기존 첫 `###` 블록 앞에 삽입:
466
-
467
- ```markdown
468
- ### feat(convergence): opt-in coverage critic — 놓친 finding 을 캐는 검증 패스
469
-
470
- - 워커들은 설계상 같은 질문을 triangulate 하므로 "아무도 안 본 각도" 는 구조적으로 비어 있다(커버리지 갭). requirements-discovery / error-analysis / implementation-planning 에 **opt-in coverage critic** 을 추가 — Phase 5.5 직후, 선택한 provider 의 기존 worker 를 critic 프롬프트로 재사용 dispatch 해 "빠진 파일/각도/요구사항" 을 새 finding 으로 내게 하고, 그 gap 은 **1회 적대적 reverify** 를 거쳐 살아남은 것만 최종 리포트에 병합한다(환각 gap 기각). 사용 여부·provider 는 okstra-run 초기 select box(추천 + 직접 입력) 또는 `--critic <off|claude|codex|gemini>` 로 고른다 — 플래그를 넘기면 선택 단계는 건너뛴다. 모델은 선택한 provider 의 모델을 따른다. **기본 off** 라 미선택 run 의 비용은 0.
471
- - 사용자 영향: 다음 release + `npx -y okstra@latest install` 후 적용. 이제 세 phase 에서 교차검증이 끝난 뒤 원하면 critic 패스를 켜 놓친 finding 을 한 번 더 캘 수 있다(기본 꺼짐). critic gap 은 적대적 검증을 통과해야 리포트에 들어가므로 근거 약한 gap 은 걸러진다. critic *행동*은 lead/워커 prompt 지시(LLM)이며, 강제되는 건 `--critic` 해석·`convergence.critic` manifest 형태·wizard step 뿐이다.
472
- ```
473
-
474
- - [ ] **Step 2: 전체 검증**
475
-
476
- Run:
477
- ```bash
478
- npm run build
479
- python3 -m pytest tests/ -q
480
- bash validators/validate-workflow.sh
481
- node bin/okstra --version
482
- ```
483
- ALL must pass. pytest 실패가 1건이라도 있으면(단, `tests/test_okstra_worktree.py` 의 알려진 간헐 격리 flake 는 단독 재실행으로 확인) STOP + BLOCKED 보고.
484
-
485
- - [ ] **Step 3: 일관성 self-review**
486
-
487
- Run:
488
- ```bash
489
- grep -rn "convergence.critic\|CRITIC_CHOICE\|critic_pick\|S_CRITIC_PICK\|Coverage critic" scripts/okstra_ctl/ skills/okstra-convergence/SKILL.md agents/SKILL.md prompts/ tests/ CHANGES.md
490
- ```
491
- Confirm: `--critic`/CRITIC_CHOICE(run+render), critic_pick/S_CRITIC_PICK(wizard+json+test), convergence.critic(render+skill+profiles), Coverage critic(skill+agents+profiles+CHANGES) 가 정의/참조 일관. 댕글링 토큰 없음.
492
-
493
- - [ ] **Step 4: 최종 커밋**
494
-
495
- ```bash
496
- git add CHANGES.md
497
- git commit -m "docs(changes): log opt-in coverage critic pass"
498
- ```
499
-
500
- ---
501
-
502
- ## Self-Review (작성자 체크리스트)
503
-
504
- **1. Spec coverage**
505
- - §2.1 critic primitive(dispatch·1회 적대 reverify·병합·모델) → Task3(skill 정의) + Task1(모델/블록).
506
- - §2.2 wizard select + CLI bypass → Task2(S_CRITIC_PICK, pre-seed bypass) + Task1(`--critic`).
507
- - §2.3 manifest critic 블록 + render resolve → Task1.
508
- - §2.4 3 적용 phase → Task1(render phase-gate) + Task4(프로필 선언).
509
- - §3 데이터(manifest/state source/config.critic) → Task1 + Task3.
510
- - §4 변경 파일 → Task1–5 전부.
511
- - §5 enforcement(테스트 강제 vs prompt-only) → Task1/Task2 테스트, Task3/4 prompt 선언.
512
- - §7 수용기준 1–5 → Task2(wizard), Task1(manifest), Task3(skill), Task4(profile), Task5(검증).
513
-
514
- **2. Placeholder scan:** 코드 블록은 실제 내용. wizard 의 일부 anchor(STEPS 리스트명·Prompt 필드명·custom-input 인코딩)는 "read-before-edit + mirror executor step" 으로 명시 — 추측 금지 지시. TBD/TODO 없음.
515
-
516
- **3. 식별자 일관성:** `critic`(PrepareInputs/WizardState field), `CRITIC_CHOICE`(ctx), `S_CRITIC_PICK`/`critic_pick`(wizard step/json), `convergence.critic`(manifest), `source:"critic"`(state) — Task 간 동일 철자 확인.