okstra 0.45.1 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +570 -0
- package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +351 -0
- package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +457 -0
- package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +2 -0
- package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +176 -0
- package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +98 -0
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/SKILL.md +2 -1
- package/runtime/prompts/launch.template.md +1 -0
- package/runtime/prompts/profiles/_common-contract.md +1 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +4 -3
- package/runtime/prompts/profiles/_implementation-executor.md +10 -12
- package/runtime/prompts/profiles/error-analysis.md +2 -0
- package/runtime/prompts/profiles/implementation-planning.md +3 -2
- package/runtime/prompts/profiles/implementation.md +1 -0
- package/runtime/prompts/profiles/requirements-discovery.md +2 -0
- package/runtime/python/okstra_ctl/render.py +13 -5
- package/runtime/python/okstra_ctl/run.py +69 -42
- package/runtime/skills/okstra-convergence/SKILL.md +114 -5
- package/runtime/validators/validate-implementation-plan-stages.py +61 -13
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Plan A — 플래너 측 응집 기준 + 병렬-안전 불변식 구현 계획
|
|
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:** implementation-planning 의 stage 분할 기준을 "파일/모듈 근접성 응집 + ≤6 cap 유일 분할기"로 바꾸고, 서로 `depends-on (none)` 인 stage 들의 예측 파일 집합이 겹치면 거부하는 병렬-안전 불변식(S9)을 validator 로 강제한다.
|
|
6
|
+
|
|
7
|
+
**Architecture:** 두 갈래 — (1) `validators/validate-implementation-plan-stages.py` 에 텍스트 파싱 기반 S9 체크를 TDD 로 추가(순수 함수, DB/IO 없음 → pytest 로 검증 완결), (2) `prompts/profiles/implementation-planning.md` 의 분할 규칙 프로즈를 응집 기준으로 재작성하고 옛 설계 스펙 §2.3 을 대체 표시. run batching(비용 절감)은 본 계획의 비범위 — 별도 Plan B.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python 3 (stdlib `re`, `dataclasses`), pytest, Node 빌드(`npm run build` → runtime 동기화), markdown 프롬프트 프로파일.
|
|
10
|
+
|
|
11
|
+
> **이 계획의 범위:** 플래너 산출물의 구조 제약과 검증만. `_implementation-executor.md` / `run.py` / registry / run 단위 검증은 손대지 않는다. 따라서 `1 run = 1 stage` 동작은 그대로 유지되고 비용은 아직 줄지 않는다 — plan 품질·병렬 안전성만 개선된다.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 파일 구조
|
|
16
|
+
|
|
17
|
+
| 파일 | 책임 | 작업 |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `validators/validate-implementation-plan-stages.py` | Stage Map 구조 검증(S1–S8) → S9 추가 | 수정 |
|
|
20
|
+
| `tests/test_validate_implementation_plan_stages.py` | validator 유닛 커버리지 | 수정 |
|
|
21
|
+
| `tests/fixtures/plans/invalid_parallel_file_overlap.md` | S9 위반 fixture | 신규 |
|
|
22
|
+
| `prompts/profiles/implementation-planning.md` | 플래너 phase 프롬프트 | 수정(프로즈) |
|
|
23
|
+
| `docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md` | 옛 설계 스펙 | 수정(§2.3 대체 표시) |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Task 1: S9 — 병렬-안전 불변식 validator 체크 (TDD)
|
|
28
|
+
|
|
29
|
+
**Files:**
|
|
30
|
+
- Create: `tests/fixtures/plans/invalid_parallel_file_overlap.md`
|
|
31
|
+
- Modify: `tests/test_validate_implementation_plan_stages.py`
|
|
32
|
+
- Modify: `validators/validate-implementation-plan-stages.py`
|
|
33
|
+
|
|
34
|
+
S9 규칙: 서로 `depends-on (none)` 인 stage 쌍의 `### Stage Exit Contract` 에서 추출한 **슬래시를 포함한 경로 토큰** 집합이 겹치면 거부. 경로 추출은 best-effort(슬래시 포함 토큰만 — endpoint `/bar`·env var·확장자 없는 토큰은 제외해 오탐을 줄인다).
|
|
35
|
+
|
|
36
|
+
- [ ] **Step 1: S9 위반 fixture 작성**
|
|
37
|
+
|
|
38
|
+
Create `tests/fixtures/plans/invalid_parallel_file_overlap.md`:
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
# Final Report
|
|
42
|
+
|
|
43
|
+
## 4.5 Stage Map
|
|
44
|
+
|
|
45
|
+
| stage | title | depends-on | step-count | exit-contract-summary |
|
|
46
|
+
|-------|-------|-----------|------------|------------------------|
|
|
47
|
+
| 1 | fix bug A in pricing | (none) | 2 | src/pricing/calc.ts |
|
|
48
|
+
| 2 | fix bug B in pricing | (none) | 2 | src/pricing/calc.ts |
|
|
49
|
+
|
|
50
|
+
> Stage 1 과 Stage 2 는 둘 다 `depends-on (none)` 인데 같은 파일을 건드린다 — 병렬-안전 불변식 위반.
|
|
51
|
+
|
|
52
|
+
## 4.5.1 Stage 1: fix bug A in pricing
|
|
53
|
+
|
|
54
|
+
### Carry-In
|
|
55
|
+
- task-brief 의 요구사항만
|
|
56
|
+
|
|
57
|
+
### Stepwise Execution Order
|
|
58
|
+
|
|
59
|
+
| step | action | files | command | expected |
|
|
60
|
+
|------|--------|-------|---------|----------|
|
|
61
|
+
| 1 | write failing test | tests/pricing.test.ts | npm test | FAIL |
|
|
62
|
+
| 2 | fix bug A | src/pricing/calc.ts | npm test | PASS |
|
|
63
|
+
|
|
64
|
+
### Stage Exit Contract
|
|
65
|
+
- 추가/변경된 파일 (예측): src/pricing/calc.ts
|
|
66
|
+
|
|
67
|
+
### Stage Validation
|
|
68
|
+
- post: npm run test:unit
|
|
69
|
+
|
|
70
|
+
## 4.5.2 Stage 2: fix bug B in pricing
|
|
71
|
+
|
|
72
|
+
### Carry-In
|
|
73
|
+
- task-brief 의 요구사항만
|
|
74
|
+
|
|
75
|
+
### Stepwise Execution Order
|
|
76
|
+
|
|
77
|
+
| step | action | files | command | expected |
|
|
78
|
+
|------|--------|-------|---------|----------|
|
|
79
|
+
| 1 | write failing test | tests/pricing2.test.ts | npm test | FAIL |
|
|
80
|
+
| 2 | fix bug B | src/pricing/calc.ts | npm test | PASS |
|
|
81
|
+
|
|
82
|
+
### Stage Exit Contract
|
|
83
|
+
- 추가/변경된 파일 (예측): src/pricing/calc.ts
|
|
84
|
+
|
|
85
|
+
### Stage Validation
|
|
86
|
+
- post: npm run test:unit
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- [ ] **Step 2: 실패 테스트 + 회귀 테스트 추가**
|
|
90
|
+
|
|
91
|
+
Modify `tests/test_validate_implementation_plan_stages.py` — 파일 끝에 추가:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
def test_parallel_file_overlap_rejected():
|
|
95
|
+
r = _run_validator("invalid_parallel_file_overlap.md")
|
|
96
|
+
assert r.returncode == 1
|
|
97
|
+
assert "S9" in r.stderr
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_three_stage_parallel_still_valid():
|
|
101
|
+
# Stage 1·2 are depends-on (none) with disjoint files → S9 must NOT fire.
|
|
102
|
+
r = _run_validator("valid_three_stage_parallel.md")
|
|
103
|
+
assert r.returncode == 0, r.stderr
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- [ ] **Step 3: 테스트 실행 → 실패 확인**
|
|
107
|
+
|
|
108
|
+
Run: `python3 -m pytest tests/test_validate_implementation_plan_stages.py::test_parallel_file_overlap_rejected -v`
|
|
109
|
+
Expected: FAIL — 현재 validator 는 S9 를 모르므로 returncode 0 → assert 실패.
|
|
110
|
+
|
|
111
|
+
- [ ] **Step 4: validator 에 S9 구현**
|
|
112
|
+
|
|
113
|
+
Modify `validators/validate-implementation-plan-stages.py`.
|
|
114
|
+
|
|
115
|
+
(a) 모듈 docstring 1번째 줄 `"""S1–S8 checks for the Stage Map structure of an approved` → `"""S1–S9 checks for the Stage Map structure of an approved`.
|
|
116
|
+
|
|
117
|
+
(b) `ValidationError` 의 필드 주석 `code: str # S1..S8` → `code: str # S1..S9`.
|
|
118
|
+
|
|
119
|
+
(c) 상수 블록(`REQUIRED_SUBSECTIONS` 정의 직후)에 추가:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
EXIT_CONTRACT_HEADING = re.compile(r"^###\s+Stage Exit Contract\b", re.M)
|
|
123
|
+
# best-effort path token: only slash-containing paths count as files, so
|
|
124
|
+
# endpoints (`/bar`), env vars (`BAZ_MODE`), and extensionless tokens are skipped.
|
|
125
|
+
PATH_TOKEN = re.compile(r"(?:[\w.@-]+/)+[\w.@-]+")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
(d) 기존 `_check_each_stage_section` 안의 인라인 섹션 슬라이싱을 공유 헬퍼로 추출(DRY). `_count_effective_steps` 정의 위에 추가:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
def _slice_stage_section(text: str, stage_number: int) -> str:
|
|
132
|
+
"""Return the body of `## 4.5.<n> Stage <n>:` up to the next stage heading."""
|
|
133
|
+
start_m = re.search(
|
|
134
|
+
rf"^##\s+4\.5\.{stage_number}\s+Stage\s+{stage_number}\s*:", text, re.M
|
|
135
|
+
)
|
|
136
|
+
if not start_m:
|
|
137
|
+
return ""
|
|
138
|
+
start = start_m.end()
|
|
139
|
+
nxt = re.search(
|
|
140
|
+
rf"^##\s+4\.5\.{stage_number + 1}\s+Stage\s+", text[start:], re.M
|
|
141
|
+
)
|
|
142
|
+
return text[start: start + nxt.start()] if nxt else text[start:]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
그리고 `_check_each_stage_section` 안의 다음 블록을
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
pattern = rf"^##\s+4\.5\.{s.stage_number}\s+Stage\s+{s.stage_number}\s*:"
|
|
149
|
+
start_m = re.search(pattern, text, re.M)
|
|
150
|
+
if not start_m:
|
|
151
|
+
errs.append(ValidationError("S3", s.stage_number,
|
|
152
|
+
f"stage section '## 4.5.{s.stage_number} Stage {s.stage_number}:' missing"))
|
|
153
|
+
continue
|
|
154
|
+
# Slice the stage's section body
|
|
155
|
+
start = start_m.end()
|
|
156
|
+
nxt = re.search(
|
|
157
|
+
rf"^##\s+4\.5\.{s.stage_number + 1}\s+Stage\s+",
|
|
158
|
+
text[start:], re.M,
|
|
159
|
+
)
|
|
160
|
+
section = text[start: start + nxt.start()] if nxt else text[start:]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
다음으로 교체:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
if not re.search(
|
|
167
|
+
rf"^##\s+4\.5\.{s.stage_number}\s+Stage\s+{s.stage_number}\s*:", text, re.M
|
|
168
|
+
):
|
|
169
|
+
errs.append(ValidationError("S3", s.stage_number,
|
|
170
|
+
f"stage section '## 4.5.{s.stage_number} Stage {s.stage_number}:' missing"))
|
|
171
|
+
continue
|
|
172
|
+
section = _slice_stage_section(text, s.stage_number)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
(e) `_check_depends_on` 정의 뒤에 S9 함수 추가:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
def _extract_exit_contract_files(section: str) -> set:
|
|
179
|
+
m = EXIT_CONTRACT_HEADING.search(section)
|
|
180
|
+
if not m:
|
|
181
|
+
return set()
|
|
182
|
+
body = section[m.end():]
|
|
183
|
+
nxt = re.search(r"^###\s+\w", body, re.M)
|
|
184
|
+
if nxt:
|
|
185
|
+
body = body[: nxt.start()]
|
|
186
|
+
return set(PATH_TOKEN.findall(body))
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _check_parallel_safety(text: str, stages: List[StageMeta]) -> List[ValidationError]:
|
|
190
|
+
"""S9: two `depends-on (none)` stages must not predict the same file —
|
|
191
|
+
otherwise two parallel implementation runs would edit it concurrently."""
|
|
192
|
+
files = {
|
|
193
|
+
s.stage_number: _extract_exit_contract_files(
|
|
194
|
+
_slice_stage_section(text, s.stage_number)
|
|
195
|
+
)
|
|
196
|
+
for s in stages
|
|
197
|
+
if not s.depends_on
|
|
198
|
+
}
|
|
199
|
+
errs: List[ValidationError] = []
|
|
200
|
+
nums = sorted(files)
|
|
201
|
+
for i in range(len(nums)):
|
|
202
|
+
for j in range(i + 1, len(nums)):
|
|
203
|
+
a, b = nums[i], nums[j]
|
|
204
|
+
shared = files[a] & files[b]
|
|
205
|
+
if shared:
|
|
206
|
+
errs.append(ValidationError("S9", 0,
|
|
207
|
+
f"parallel stages {a} and {b} share predicted file(s): "
|
|
208
|
+
f"{', '.join(sorted(shared))}"))
|
|
209
|
+
return errs
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
(f) `collect_validation_errors` 안 `if stages:` 블록에 한 줄 추가:
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
if stages:
|
|
216
|
+
errors.extend(_check_each_stage_section(text, stages))
|
|
217
|
+
errors.extend(_check_depends_on(stages))
|
|
218
|
+
errors.extend(_check_parallel_safety(text, stages))
|
|
219
|
+
return errors
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- [ ] **Step 5: 테스트 실행 → 통과 확인**
|
|
223
|
+
|
|
224
|
+
Run: `python3 -m pytest tests/test_validate_implementation_plan_stages.py -v`
|
|
225
|
+
Expected: 7 passed — 기존 5 + S9 위반 1 + 병렬 회귀 1. 특히 `test_three_stage_parallel_still_valid` 가 PASS(disjoint 파일이라 S9 미발동) 여야 한다.
|
|
226
|
+
|
|
227
|
+
- [ ] **Step 6: 커밋**
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
git add validators/validate-implementation-plan-stages.py tests/test_validate_implementation_plan_stages.py tests/fixtures/plans/invalid_parallel_file_overlap.md
|
|
231
|
+
git commit -m "feat(validators): add S9 parallel-safety check to stage-map validator"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Task 2: 플래너 프롬프트 — 응집 기준 프로즈 재작성
|
|
237
|
+
|
|
238
|
+
**Files:**
|
|
239
|
+
- Modify: `prompts/profiles/implementation-planning.md:68` (Parallelisation-first rule)
|
|
240
|
+
- Modify: `prompts/profiles/implementation-planning.md:96` (Stage Map self-check #7)
|
|
241
|
+
|
|
242
|
+
프로즈 변경이라 유닛 테스트는 없다. 검증은 빌드 동기화(Task 4) + 사람이 읽어 의미 일치 확인.
|
|
243
|
+
|
|
244
|
+
- [ ] **Step 1: 분할 규칙(line 68) 교체**
|
|
245
|
+
|
|
246
|
+
`prompts/profiles/implementation-planning.md` 에서 다음 한 줄(line 68)을 찾는다:
|
|
247
|
+
|
|
248
|
+
```markdown
|
|
249
|
+
- **Parallelisation-first rule (1st-class):** the writer MUST prefer the partition that maximises the number of `depends-on (none)` stages. Given two partitions with equal total step count, the one with fewer `depends-on` edges wins. Conservative `let's serialise to be safe` groupings are forbidden — each `depends-on` link is justified by a concrete data/contract dependency, not a vague risk concern.
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
다음으로 교체:
|
|
253
|
+
|
|
254
|
+
```markdown
|
|
255
|
+
- **Cohesion-first partition rule (1st-class):** the grouping anchor is **shared file/module proximity** — steps touching the same file/directory/module go in the same stage so the diff, PR, and rollback unit are semantically cohesive. A stage is split ONLY when (a) a real `depends-on` data/contract dependency exists, (b) effective steps would exceed 6, or (c) the file sets are disjoint (unrelated work touching no shared file is not crammed together). Maximising the number of parallel stages is NOT a reason to split — parallelism is an emergent property of independent stages, never a partitioning goal.
|
|
256
|
+
- **Parallel-safety invariant (BLOCKING):** any two stages that are both `depends-on (none)` MUST predict disjoint file sets in their `Stage Exit Contract`. Two parallel `implementation` runs would otherwise edit the same file concurrently. Work touching a shared file must either go in one stage or be ordered with `depends-on`. Enforced by `validators/validate-implementation-plan-stages.py` check S9.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- [ ] **Step 2: Stage Map self-check #7(line 96) 교체**
|
|
260
|
+
|
|
261
|
+
다음 한 줄(line 96)을 찾는다:
|
|
262
|
+
|
|
263
|
+
```markdown
|
|
264
|
+
7. **Stage Map self-check** — for every stage, count the effective rows of its `Stepwise Execution Order` table by hand; reject the draft if any stage exceeds 6. Walk the `depends-on` graph and confirm it is a DAG (no cycle, no self-reference). For each `depends-on` link, ask "can this be removed by re-partitioning?" — if yes, re-partition and re-count.
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
다음으로 교체:
|
|
268
|
+
|
|
269
|
+
```markdown
|
|
270
|
+
7. **Stage Map self-check** — for every stage, count the effective rows of its `Stepwise Execution Order` table by hand; reject the draft if any stage exceeds 6. Walk the `depends-on` graph and confirm it is a DAG (no cycle, no self-reference). For each `depends-on` link, confirm it encodes a real data/contract dependency — do NOT add links to serialise unrelated work, and do NOT split a stage merely to create more parallel stages. **Parallel-safety:** for every pair of `depends-on (none)` stages, confirm their `Stage Exit Contract` predicted file sets are disjoint; if they share a file, merge them or add a `depends-on` link (validator S9 rejects overlap).
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
- [ ] **Step 3: 토큰 정합성 확인**
|
|
274
|
+
|
|
275
|
+
새 식별자 "Cohesion-first" / "Parallel-safety invariant" / "S9" 가 다른 곳에서 충돌 의미로 쓰이지 않는지 확인.
|
|
276
|
+
|
|
277
|
+
Run: `grep -rn "Parallelisation-first\|Cohesion-first\|Parallel-safety\|S9" prompts/ validators/ docs/superpowers/`
|
|
278
|
+
Expected: 옛 "Parallelisation-first" 잔여 없음(runtime/ 제외), "S9" 는 validator·새 프로즈·설계 스펙에서만 등장하고 의미 일치.
|
|
279
|
+
|
|
280
|
+
- [ ] **Step 4: 커밋**
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
git add prompts/profiles/implementation-planning.md
|
|
284
|
+
git commit -m "feat(prompts/implementation-planning): replace parallelisation-first with cohesion-first partition rule"
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Task 3: 옛 설계 스펙 §2.3 대체 표시
|
|
290
|
+
|
|
291
|
+
**Files:**
|
|
292
|
+
- Modify: `docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md:36`
|
|
293
|
+
|
|
294
|
+
옛 스펙의 §2.3 "병렬화 최대화 우선" 은 본 변경과 정면 충돌한다. 역사 보존을 위해 본문을 지우지 않고 대체 배너만 단다(Rule 2 — 같은 토큰의 silent drift 방지).
|
|
295
|
+
|
|
296
|
+
- [ ] **Step 1: §2.3 병렬화 규칙 아래 대체 배너 추가**
|
|
297
|
+
|
|
298
|
+
`docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md` 에서 `### 2.3 병렬화 최대화 우선 (분할 1 급 기준)` 헤딩을 찾아, 그 헤딩 바로 아래 줄에 삽입:
|
|
299
|
+
|
|
300
|
+
```markdown
|
|
301
|
+
> **[2026-06-04 대체됨]** 본 절의 "병렬화 최대화 우선" 은 [`2026-06-04-stage-splitting-cost-aware-design.md`](2026-06-04-stage-splitting-cost-aware-design.md) §2.2 의 "응집 기준점=파일/모듈 근접성, ≤6 cap 유일 분할기" 로 대체되었다. 병렬화는 더 이상 분할의 1급 기준이 아니다. 아래 원문은 역사 참조용. (같은 문서의 `step ≤6 cap`(§2.3 line 46–50)·carry-in(§2.4)·데이터 모델(§3) 은 유효.)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
- [ ] **Step 2: 커밋**
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
git add docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md
|
|
308
|
+
git commit -m "docs(specs): mark multi-stage §2.3 parallelisation rule superseded by cohesion-first"
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Task 4: 빌드 동기화 + 전체 회귀 검증
|
|
314
|
+
|
|
315
|
+
**Files:** (없음 — 빌드·검증만)
|
|
316
|
+
|
|
317
|
+
- [ ] **Step 1: runtime 동기화**
|
|
318
|
+
|
|
319
|
+
Run: `npm run build`
|
|
320
|
+
Expected: 종료 코드 0. `runtime/` 에 수정된 `prompts/profiles/implementation-planning.md` 와 `validators/validate-implementation-plan-stages.py` 가 반영됨.
|
|
321
|
+
|
|
322
|
+
- [ ] **Step 2: validator 단위 테스트 재확인**
|
|
323
|
+
|
|
324
|
+
Run: `python3 -m pytest tests/test_validate_implementation_plan_stages.py -v`
|
|
325
|
+
Expected: 7 passed.
|
|
326
|
+
|
|
327
|
+
- [ ] **Step 3: 전체 테스트 스위트(회귀)**
|
|
328
|
+
|
|
329
|
+
Run: `python3 -m pytest tests/`
|
|
330
|
+
Expected: 전부 통과. 특히 stage 관련 테스트([test_auto_stage_selection.py](../../../tests/test_auto_stage_selection.py), [test_run_stage_arg.py](../../../tests/test_run_stage_arg.py), [test_wizard_stage_pick.py](../../../tests/test_wizard_stage_pick.py), [test_e2e_multi_stage_q1_q9.py](../../../tests/test_e2e_multi_stage_q1_q9.py))가 깨지지 않아야 한다 — Plan A 는 실행기 동작을 안 바꾸므로 영향 없어야 정상. 깨지면 그 테스트가 plan-fixture 를 검증에 통과시키는지 확인하고 fixture 의 파일 충돌 여부를 점검.
|
|
331
|
+
|
|
332
|
+
- [ ] **Step 4: 워크플로 계약 validator**
|
|
333
|
+
|
|
334
|
+
Run: `bash validators/validate-workflow.sh`
|
|
335
|
+
Expected: 종료 코드 0.
|
|
336
|
+
|
|
337
|
+
- [ ] **Step 5: 최종 커밋(빌드 산출물)**
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
git add runtime/
|
|
341
|
+
git commit -m "chore(build): sync runtime after stage cohesion planner change"
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Self-Review (작성자 체크 — 실행 전 1회)
|
|
347
|
+
|
|
348
|
+
- **Spec coverage:** 신규 스펙 §2.2(응집 기준)→Task 2, §2.2 병렬-안전 불변식→Task 1(S9)+Task 2(프로즈), §5 enforcement S9→Task 1, 옛 §2.3 대체→Task 3, 빌드 동기화→Task 4. run batching(§2.3·§2.4) 은 의도적 비범위(Plan B).
|
|
349
|
+
- **Placeholder scan:** 모든 코드 step 에 실제 코드/명령/기대값 포함. TBD 없음.
|
|
350
|
+
- **Type consistency:** `_slice_stage_section`(Task1 Step4d 정의) 를 `_check_each_stage_section`·`_check_parallel_safety` 가 동일 시그니처로 사용. `_extract_exit_contract_files` → `set` 반환, `&` 교집합. `PATH_TOKEN`·`EXIT_CONTRACT_HEADING` 상수 한 곳 정의.
|
|
351
|
+
- **주의(검증 한계):** S9 경로 추출은 best-effort(슬래시 포함 토큰만). 확장자만 있고 슬래시 없는 파일(`.env.example`)·예측 누락은 못 잡는다 — 진짜 backstop 은 Plan B 의 worktree 직렬성 + flock registry. 이 한계는 신규 스펙 §5 에 명시됨.
|