okstra 0.102.1 → 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 (162) hide show
  1. package/README.kr.md +5 -6
  2. package/README.md +5 -6
  3. package/docs/kr/architecture/storage-model.md +1 -1
  4. package/docs/kr/architecture.md +8 -12
  5. package/docs/kr/cli.md +6 -6
  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/cli-registry.mjs +1 -1
  36. package/src/commands/lifecycle/install.mjs +10 -20
  37. package/src/commands/lifecycle/uninstall.mjs +7 -10
  38. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
  39. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
  40. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
  41. package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
  42. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
  43. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
  44. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
  45. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
  46. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
  47. package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
  48. package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
  49. package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
  50. package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
  51. package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
  52. package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
  53. package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
  54. package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
  55. package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
  56. package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
  57. package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
  58. package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
  59. package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
  60. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
  61. package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
  62. package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
  63. package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
  64. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
  65. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
  66. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
  67. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
  68. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
  69. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
  70. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
  71. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
  72. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
  73. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
  74. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
  75. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
  76. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
  77. package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
  78. package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
  79. package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
  80. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
  81. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
  82. package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
  83. package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
  84. package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
  85. package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
  86. package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
  87. package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
  88. package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
  89. package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
  90. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
  91. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
  92. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
  93. package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
  94. package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
  95. package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
  96. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
  97. package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
  98. package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
  99. package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
  100. package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
  101. package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
  102. package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
  103. package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
  104. package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
  105. package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
  106. package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
  107. package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
  108. package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
  109. package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
  110. package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
  111. package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
  112. package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
  113. package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
  114. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
  115. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
  116. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
  117. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
  118. package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
  119. package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
  120. package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
  121. package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
  122. package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
  123. package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
  124. package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
  125. package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
  126. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
  127. package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
  128. package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
  129. package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
  130. package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
  131. package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
  132. package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
  133. package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
  134. package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
  135. package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
  136. package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
  137. package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
  138. package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
  139. package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
  140. package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
  141. package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
  142. package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
  143. package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
  144. package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
  145. package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
  146. package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
  147. package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
  148. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
  149. package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
  150. package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
  151. package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
  152. package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
  153. package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
  154. package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
  155. package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
  156. package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
  157. package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
  158. package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
  159. package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
  160. package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
  161. package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
  162. 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 교차검증) 계획을 작성한다.