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,282 +0,0 @@
1
- # Stage Conformance QA — Phase 3 (validate-run 게이트) Implementation Plan
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:** `validators/validate-run.py` 가 implementation/final-verification 리포트에 대해 run 의 `qa/` 디렉터리(conformance 매니페스트 + 결과 사이드카)를 읽어 Phase 2 의 `evaluate_conformance` 로 게이트를 적용한다. BLOCKING verdict 는 run 검증 실패로 만든다 — DEV-9184 의 "정적 OK, 미검증 → silent pass" 를 실제 FAIL 로 전환하는 강제 지점.
6
-
7
- **Architecture:** Phase 1(매니페스트 검증) + Phase 2(게이트 판정)의 순수 함수를 validate-run 에 wiring 한다. **매니페스트가 없으면 게이트는 inert**(early return) — 따라서 매니페스트를 생성하는 prompt 측(Phase 4)이 없어도 안전하게 단독 출하된다. SSOT: [`docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md`](../specs/2026-06-07-stage-conformance-qa-design.md) §6.
8
-
9
- **Tech Stack:** Python 3 (stdlib + pytest). validate-run.py 는 importlib 로 로드되는 standalone 스크립트.
10
-
11
- **전제:** Phase 1·2 완료 — `scripts/okstra_ctl/conformance.py` 에 `validate_conformance_manifest`, `evaluate_conformance`, `qa_result_from_dict`, `ConformanceVerdict` 존재.
12
-
13
- ---
14
-
15
- ## 결과 사이드카 계약 (이 Phase 에서 확정)
16
-
17
- - 매니페스트: `<run_dir>/qa/conformance-manifest.json` (run_dir = `report_path.parent.parent`, 기존 `validate_worker_results_audit` 의 `report_path.parent.parent / "worker-results"` 패턴과 동형).
18
- - 결과 사이드카(Phase 4 의 verifier 가 작성): `<run_dir>/qa/result-<stageKey>.json` = `{"stageKey","overall","ranAt","requirements"}`. 파일 부재 → 미실행(None) → BLOCKING.
19
-
20
- ---
21
-
22
- ## Task 1: conformance 게이트 함수 + 결과 로더
23
-
24
- **Files:**
25
- - Modify: `validators/validate-run.py`
26
- - Test: `tests/test_validate_run_conformance.py` (신규)
27
-
28
- - [ ] **Step 1: 실패 테스트 작성**
29
-
30
- ```python
31
- # tests/test_validate_run_conformance.py
32
- from __future__ import annotations
33
-
34
- import importlib.util
35
- import json
36
- from pathlib import Path
37
-
38
- REPO_ROOT = Path(__file__).resolve().parent.parent
39
- VALIDATOR_PATH = REPO_ROOT / "validators" / "validate-run.py"
40
-
41
-
42
- def _load_validator():
43
- spec = importlib.util.spec_from_file_location("validate_run", VALIDATOR_PATH)
44
- module = importlib.util.module_from_spec(spec)
45
- assert spec.loader is not None
46
- spec.loader.exec_module(module)
47
- return module
48
-
49
-
50
- def _make_run(tmp_path: Path, entries, results):
51
- run_dir = tmp_path / "runs" / "implementation"
52
- (run_dir / "reports").mkdir(parents=True)
53
- qa = run_dir / "qa"
54
- qa.mkdir()
55
- (qa / "conformance-manifest.json").write_text(json.dumps({"entries": entries}))
56
- for key, overall in results.items():
57
- (qa / f"result-{key}.json").write_text(
58
- json.dumps({"stageKey": key, "overall": overall, "requirements": {}})
59
- )
60
- report = run_dir / "reports" / "final-report-implementation-001.md"
61
- report.write_text("# fixture\n")
62
- return report
63
-
64
-
65
- def _entry(key, **over):
66
- base = {"stageKey": key, "script": f"qa/{key}.ts", "runCommand": f"run {key}",
67
- "requirementIds": ["R-001"], "requires": ["db"],
68
- "passContract": "exit 0 = PASS", "exemption": None, "waiver": None}
69
- base.update(over)
70
- return base
71
-
72
-
73
- def test_no_manifest_is_inert(tmp_path):
74
- v = _load_validator()
75
- run_dir = tmp_path / "runs" / "implementation"
76
- (run_dir / "reports").mkdir(parents=True)
77
- report = run_dir / "reports" / "final-report-implementation-001.md"
78
- report.write_text("# fixture\n")
79
- failures: list[str] = []
80
- v._validate_conformance(report, failures)
81
- assert failures == []
82
-
83
-
84
- def test_passing_result_no_failure(tmp_path):
85
- v = _load_validator()
86
- report = _make_run(tmp_path, [_entry("t-stage-1")], {"t-stage-1": "PASS"})
87
- failures: list[str] = []
88
- v._validate_conformance(report, failures)
89
- assert failures == []
90
-
91
-
92
- def test_missing_result_is_blocking(tmp_path):
93
- v = _load_validator()
94
- report = _make_run(tmp_path, [_entry("t-stage-1")], {}) # no result file
95
- failures: list[str] = []
96
- v._validate_conformance(report, failures)
97
- assert any("BLOCKING" in f and "t-stage-1" in f for f in failures)
98
-
99
-
100
- def test_failing_result_is_blocking(tmp_path):
101
- v = _load_validator()
102
- report = _make_run(tmp_path, [_entry("t-stage-1")], {"t-stage-1": "FAIL"})
103
- failures: list[str] = []
104
- v._validate_conformance(report, failures)
105
- assert any("BLOCKING" in f for f in failures)
106
-
107
-
108
- def test_exemption_passes(tmp_path):
109
- v = _load_validator()
110
- entry = _entry("t-stage-1", exemption={"reason": "doc", "declaredAt": "2026-06-07"})
111
- report = _make_run(tmp_path, [entry], {})
112
- failures: list[str] = []
113
- v._validate_conformance(report, failures)
114
- assert failures == []
115
-
116
-
117
- def test_waiver_passes_but_records_conditional(tmp_path):
118
- v = _load_validator()
119
- entry = _entry("t-stage-1", waiver={"acknowledgedBy": "user", "reason": "replica down",
120
- "at": "2026-06-07", "scope": ["db"]})
121
- report = _make_run(tmp_path, [entry], {})
122
- failures: list[str] = []
123
- v._validate_conformance(report, failures)
124
- assert failures == [] # waiver = ok (conditional, not a failure)
125
-
126
-
127
- def test_malformed_manifest_reported(tmp_path):
128
- v = _load_validator()
129
- report = _make_run(tmp_path, [{"stageKey": ""}], {}) # invalid entry
130
- failures: list[str] = []
131
- v._validate_conformance(report, failures)
132
- assert any("conformance manifest" in f for f in failures)
133
- ```
134
-
135
- - [ ] **Step 2: 실패 확인**
136
-
137
- Run: `python3 -m pytest tests/test_validate_run_conformance.py -q`
138
- Expected: FAIL — `module 'validate_run' has no attribute '_validate_conformance'`
139
-
140
- - [ ] **Step 3: 구현 추가**
141
-
142
- `validators/validate-run.py` 상단의 `from okstra_project.dirs import tasks_root as _okstra_tasks_root` (line 33 부근) 다음에 import 추가:
143
-
144
- ```python
145
- from okstra_ctl.conformance import ( # noqa: E402
146
- evaluate_conformance,
147
- qa_result_from_dict,
148
- validate_conformance_manifest,
149
- )
150
- ```
151
-
152
- `validate_report` 함수 정의 바로 앞(`def validate_report(` 위)에 두 함수 추가:
153
-
154
- ```python
155
- def _load_conformance_results(qa_dir: Path, manifest: dict) -> dict:
156
- """매니페스트 각 entry 에 대응하는 `result-<stageKey>.json` 을 로드.
157
- 파일 부재/파손은 키를 비워 둬 미실행(None→BLOCKING)으로 흐르게 한다."""
158
- results: dict = {}
159
- for entry in manifest.get("entries", []):
160
- key = entry.get("stageKey") if isinstance(entry, dict) else None
161
- if not isinstance(key, str) or not key:
162
- continue
163
- sidecar = qa_dir / f"result-{key}.json"
164
- if not sidecar.is_file():
165
- continue
166
- try:
167
- results[key] = qa_result_from_dict(json.loads(sidecar.read_text()))
168
- except (OSError, json.JSONDecodeError):
169
- results[key] = qa_result_from_dict(None) # → MISSING → BLOCKING
170
- return results
171
-
172
-
173
- def _validate_conformance(report_path: Path, failures: list[str]) -> None:
174
- """Tier 3 conformance 게이트(implementation / final-verification).
175
-
176
- `<run_dir>/qa/conformance-manifest.json` 이 없으면 inert(선언된 conformance
177
- 가 없다는 뜻 — 선언을 강제하는 것은 planning 계약(Phase 4)의 몫). 매니페스트가
178
- 있으면 결과 사이드카와 함께 evaluate_conformance 로 판정하고 BLOCKING verdict
179
- 를 run 검증 실패로 승격한다. WAIVED(conditional)/EXEMPT 는 통과시킨다.
180
- """
181
- qa_dir = report_path.parent.parent / "qa"
182
- manifest_path = qa_dir / "conformance-manifest.json"
183
- if not manifest_path.is_file():
184
- return
185
- try:
186
- manifest = json.loads(manifest_path.read_text())
187
- except (OSError, json.JSONDecodeError) as exc:
188
- failures.append(f"conformance manifest unreadable at {manifest_path}: {exc}")
189
- return
190
- schema_errors = validate_conformance_manifest(manifest)
191
- if schema_errors:
192
- failures.extend(f"conformance manifest: {e}" for e in schema_errors)
193
- return
194
- results = _load_conformance_results(qa_dir, manifest)
195
- for verdict in evaluate_conformance(manifest, results):
196
- if not verdict.ok:
197
- failures.append(
198
- f"conformance gate BLOCKING for stage {verdict.stage_key}: "
199
- f"{verdict.message}. Run the stage's conformance script (or declare "
200
- f"an exemption / user waiver) — see "
201
- f"docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md."
202
- )
203
- ```
204
-
205
- - [ ] **Step 4: 통과 확인**
206
-
207
- Run: `python3 -m pytest tests/test_validate_run_conformance.py -q`
208
- Expected: PASS (7 passed)
209
-
210
- - [ ] **Step 5: 커밋**
211
-
212
- ```bash
213
- git add validators/validate-run.py tests/test_validate_run_conformance.py
214
- git commit -m "feat(validators): conformance Tier3 게이트 함수(_validate_conformance)"
215
- ```
216
-
217
- ## Task 2: 메인 dispatch 에 게이트 wiring
218
-
219
- **Files:**
220
- - Modify: `validators/validate-run.py`
221
-
222
- - [ ] **Step 1: dispatch 에 호출 추가**
223
-
224
- `validate-run.py` 의 메인 dispatch 에서 `validate_worker_results_audit` 호출 블록 다음, `if task_type == "improvement-discovery":` 앞에 추가:
225
-
226
- ```python
227
- if task_type in ("implementation", "final-verification"):
228
- _validate_conformance(report_path, failures)
229
- ```
230
-
231
- (찾을 앵커 — 현재 코드:)
232
-
233
- ```python
234
- if task_type:
235
- validate_worker_results_audit(report_path, task_type, failures)
236
- if task_type == "improvement-discovery":
237
- ```
238
-
239
- - [ ] **Step 2: 기존 스위트 회귀 + workflow validator 확인**
240
-
241
- Run: `python3 -m pytest tests/ -q`
242
- Expected: 전부 통과(신규 7 포함, 회귀 없음). validate-workflow 의 final-verification fixture 는 `qa/` 디렉터리가 없으므로 게이트는 inert → 영향 없음.
243
-
244
- Run: `bash validators/validate-workflow.sh`
245
- Expected: 마지막에 PASS (게이트 inert).
246
-
247
- - [ ] **Step 3: 코드 확인(수동)**
248
-
249
- `grep -n "_validate_conformance" validators/validate-run.py` → 정의 1 + 호출 1 = 2건.
250
-
251
- - [ ] **Step 4: 커밋**
252
-
253
- ```bash
254
- git add validators/validate-run.py
255
- git commit -m "feat(validators): implementation/final-verification 에 conformance 게이트 연결"
256
- ```
257
-
258
- ---
259
-
260
- ## Phase 3 Self-Review 체크
261
-
262
- - [ ] 매니페스트 부재 시 inert(early return) 확인 — 기존 run 들이 깨지지 않는가?
263
- - [ ] BLOCKING(미실행/MISSING/FAIL) → failures 추가, EXEMPT/WAIVED → 통과가 spec §6/§7 과 일치하는가?
264
- - [ ] run_dir 해석(`report_path.parent.parent`)이 기존 `validate_worker_results_audit` 와 동형인가?
265
- - [ ] 전체 pytest + workflow validator 통과(회귀 없음)?
266
-
267
- ---
268
-
269
- ## Phase 4 로 넘길 항목 + ⚠️ 미해결 설계 갬
270
-
271
- 본 게이트는 매니페스트/결과가 존재할 때만 작동한다. 그것을 **생성·실행**하는 다음 작업들은 Phase 4 이며, 일부는 **계획 전 설계 확정이 필요**하다(추측 금지):
272
-
273
- 1. **verifier 실행(prompt)**: `_implementation-verifier.md` 에 Tier 3 추가 — 각 entry 의 `runCommand` 실행 → `parse_qa_result` → `<run_dir>/qa/result-<stageKey>.json` 작성. (env/secret 접근, replica DB, mutation 가드 포함)
274
- 2. **planning 생성(prompt)**: `implementation-planning.md` 가 stage 별 스크립트 + `conformance-manifest.json` + `Conformance exemption:` 라인 산출.
275
- 3. **final-verification(prompt)**: 전 stage 합집합 실행.
276
- 4. **우회 UX**: `--qa-waiver <stageKey>:"<reason>"` CLI(okstra.sh/cli.sh) + wizard picker → `run.py` 가 매니페스트 entry 의 `waiver` 채움.
277
- 5. **env**: `project.json.qaEnv`(replicaDbDsn/appBaseUrl/envFile).
278
-
279
- **⚠️ 설계 확정 필요(Phase 4 계획 전 brainstorm 보강 권장):**
280
- - **매니페스트의 교차-phase 위치**: planning 이 만든 매니페스트/스크립트가 implementation run, 이어서 final-verification run 으로 어떻게 전달되는가? (task-key worktree vs stage worktree vs instruction-set 복사) — stage worktree isolation 과 정합해야 함.
281
- - **"diff 가 surface 를 건드렸는데 매니페스트 entry 자체가 없음"** (planning 누락) 강제: 본 게이트는 선언된 entry 만 강제한다. 누락 탐지는 planning 계약 + diff-surface 휴리스틱이 필요(spec §7.1 선언형 면제 surface 교차검증과 함께).
282
- - **env/secret 운영 모델**: replica DB·실행 env 를 누가 어떻게 주입하는가.
@@ -1,147 +0,0 @@
1
- # Stage Conformance QA — Phase 4a (위치 SSOT + 게이트 task-level 전환) Implementation Plan
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:** conformance 산출물의 단일 출처를 task-level `<task_root>/qa/` 로 확정한다 — `paths.py` 에 `TASK_QA_PATH` 토큰을 추가하고, Phase 3 게이트(`_validate_conformance`)가 run-level 대신 task-level `qa/` 를 읽도록 고친다(Phase 3 의 final-verification 잠복 결함 해소).
6
-
7
- **Architecture:** 순수 경로/검증 변경. SSOT: [`docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md`](../specs/2026-06-07-stage-conformance-qa-design.md) §12.1.
8
-
9
- **Tech Stack:** Python 3 (stdlib + pytest).
10
-
11
- **전제:** Phase 1~3 완료. `validators/validate-run.py` 에 `_validate_conformance` 존재, `tests/test_validate_run_conformance.py` 존재.
12
-
13
- **경로 사실(확정):** report_path = `task_root/runs/<task-type>/reports/final-report-*.md`. 따라서 `run_dir = report_path.parent.parent`(=`runs/<task-type>`), `task_root = run_dir.parent.parent`, `qa_dir = task_root / "qa"`. (`report_path.parent.parent.parent` 는 `runs/` 이므로 잘못 — 한 단계 더 올라가야 함.)
14
-
15
- ---
16
-
17
- ## Task 1: `paths.py` 에 TASK_QA_PATH 토큰 추가
18
-
19
- **Files:**
20
- - Modify: `scripts/okstra_ctl/paths.py`
21
- - Test: `tests/test_task_path_ssot.py`
22
-
23
- - [ ] **Step 1: 실패 테스트 추가**
24
-
25
- `tests/test_task_path_ssot.py` 끝에 추가:
26
-
27
- ```python
28
- def test_task_qa_path_under_task_root():
29
- root = Path("/tmp/proj")
30
- ctx = compute_run_paths(
31
- workspace_root=Path("/ws"),
32
- project_root=root,
33
- project_id="p",
34
- task_group="My Group",
35
- task_id="Task ID 01",
36
- task_type="implementation",
37
- run_seq_override=1,
38
- )
39
- assert ctx["TASK_QA_PATH"] == str(Path(ctx["TASK_ROOT"]) / "qa")
40
- ```
41
-
42
- - [ ] **Step 2: 실패 확인**
43
-
44
- Run: `python3 -m pytest tests/test_task_path_ssot.py -q`
45
- Expected: FAIL — `KeyError: 'TASK_QA_PATH'`
46
-
47
- - [ ] **Step 3: 구현**
48
-
49
- `scripts/okstra_ctl/paths.py` 의 `analysis_packet = instruction_set / "analysis-packet.md"` (line 119 부근) 다음 줄에 추가:
50
-
51
- ```python
52
- task_qa = task_root / "qa"
53
- ```
54
-
55
- 같은 함수의 `abs_paths` 딕셔너리에서 `"ANALYSIS_PACKET_PATH": str(analysis_packet),` 다음 줄에 추가:
56
-
57
- ```python
58
- "TASK_QA_PATH": str(task_qa),
59
- ```
60
-
61
- - [ ] **Step 4: 통과 확인**
62
-
63
- Run: `python3 -m pytest tests/test_task_path_ssot.py -q`
64
- Expected: PASS
65
-
66
- - [ ] **Step 5: 커밋**
67
-
68
- ```bash
69
- git add scripts/okstra_ctl/paths.py tests/test_task_path_ssot.py
70
- git commit -m "feat(okstra_ctl/paths): conformance task-level qa 경로 토큰(TASK_QA_PATH)"
71
- ```
72
-
73
- ## Task 2: 게이트를 task-level `qa/` 로 전환
74
-
75
- **Files:**
76
- - Modify: `validators/validate-run.py`
77
- - Test: `tests/test_validate_run_conformance.py`
78
-
79
- - [ ] **Step 1: 테스트 fixture 를 task-level 로 갱신(먼저 실패 유도)**
80
-
81
- `tests/test_validate_run_conformance.py` 의 `_make_run` 에서 qa 디렉터리를 task_root(=`tmp_path`) 아래로 옮긴다. 현재:
82
-
83
- ```python
84
- run_dir = tmp_path / "runs" / "implementation"
85
- (run_dir / "reports").mkdir(parents=True)
86
- qa = run_dir / "qa"
87
- qa.mkdir()
88
- ```
89
-
90
- 로 바꾼다:
91
-
92
- ```python
93
- run_dir = tmp_path / "runs" / "implementation"
94
- (run_dir / "reports").mkdir(parents=True)
95
- qa = tmp_path / "qa" # task-level: <task_root>/qa (task_root = tmp_path)
96
- qa.mkdir()
97
- ```
98
-
99
- (`test_no_manifest_is_inert` 는 qa 를 만들지 않으므로 그대로 inert — 변경 불필요.)
100
-
101
- - [ ] **Step 2: 실패 확인**
102
-
103
- Run: `python3 -m pytest tests/test_validate_run_conformance.py -q`
104
- Expected: FAIL — 게이트가 아직 run-level(`run_dir/qa`)을 읽어 매니페스트를 못 찾고 inert 처리 → `test_missing_result_is_blocking`/`test_failing_result_is_blocking`/`test_malformed_manifest_reported` 가 기대 실패를 못 내고 FAIL.
105
-
106
- - [ ] **Step 3: 구현 — 게이트 경로 수정**
107
-
108
- `validators/validate-run.py` 의 `_validate_conformance` 에서:
109
-
110
- ```python
111
- qa_dir = report_path.parent.parent / "qa"
112
- ```
113
-
114
- 를 다음으로 바꾼다:
115
-
116
- ```python
117
- # conformance 산출물은 task-level(<task_root>/qa)에 있어 planning/
118
- # implementation/final-verification 가 공유한다. report_path 는
119
- # task_root/runs/<task-type>/reports/final-report.md 이므로 task_root 는
120
- # run_dir(=report_path.parent.parent)에서 두 단계 위.
121
- run_dir = report_path.parent.parent
122
- qa_dir = run_dir.parent.parent / "qa"
123
- ```
124
-
125
- - [ ] **Step 4: 통과 확인 + 전체 회귀 + workflow validator**
126
-
127
- Run: `python3 -m pytest tests/test_validate_run_conformance.py -q` → Expected: PASS (7 passed)
128
- Run: `python3 -m pytest tests/ -q` → Expected: 전부 통과
129
- Run: `bash validators/validate-workflow.sh` → Expected: PASS (fixture 에 `<task_root>/qa` 없음 → inert)
130
-
131
- - [ ] **Step 5: 커밋**
132
-
133
- ```bash
134
- git add validators/validate-run.py tests/test_validate_run_conformance.py
135
- git commit -m "fix(validators): conformance 게이트를 task-level qa 로 전환(final-verification 공유)"
136
- ```
137
-
138
- ---
139
-
140
- ## Phase 4a Self-Review 체크
141
-
142
- - [ ] `TASK_QA_PATH == <task_root>/qa` 인가?
143
- - [ ] 게이트가 task_root/qa 를 읽어 implementation·final-verification 가 같은 위치를 보는가?
144
- - [ ] inert(매니페스트 부재) 동작 유지 — 기존 run/ workflow validator 무영향?
145
- - [ ] 전체 pytest + workflow validator 통과?
146
-
147
- Phase 4a 완료 후 Phase 4b(`detect_surfaces` + diff-surface 교차검증) 계획을 작성한다.