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,320 +0,0 @@
1
- # implementation run-산출물 stage 격리 — 활성화 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:** `implementation` run 의 산출물을 `runs/implementation/stage-<N>/` 로 격리해, 같은 task 의 독립 stage 를 동시 실행해도 보고서·state·worker-results 가 섞이지 않게 한다.
6
-
7
- **Architecture:** foundation(`paths.py`/`run_context.py` 의 `stage` 파라미터, 이미 커밋 `baafa40`)은 `stage` 인자가 오면 `RUN_DIR=runs/implementation/stage-<N>` 를 만든다(현재 무동작). 본 plan 은 `prepare_task_bundle` 의 **stage 선택을 경로 계산 앞으로 옮겨** 그 stage 를 `compute_and_write_run_context` 에 전달해 활성화한다. 동시성 불변(`select == registry flock 예약` 원자성)을 보존하기 위해, stage 선택+base 결정+stage-worktree 예약(=registry flock)을 **하나의 함수로 묶어 경로 계산 전에 1회** 호출한다. `consumers.jsonl` 은 approved-plan 경로 기준이라 격리 대상이 아니다(공유 유지).
8
-
9
- **Tech Stack:** Python (okstra_ctl), pytest(+ 실 git/flock 기반 e2e), okstra build(`npm run build`).
10
-
11
- 설계 근거: [docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md](../specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md)
12
-
13
- ---
14
-
15
- ## File Structure
16
-
17
- - Modify: `scripts/okstra_ctl/run.py` — `_reserve_implementation_stages` 를 (a) 경로-무관 **선택+예약+provision** 부분과 (b) `ctx` 의존 **wiring(EXECUTOR_WORKTREE_* 세팅 + consumers append)** 부분으로 분리. `prepare_task_bundle` 에서 (a)를 `compute_and_write_run_context` 앞으로 이동하고 selected stage 를 전달.
18
- - Modify: `scripts/okstra_ctl/run_context.py` — (foundation 에서 이미 `stage` param 수용) 변경 없음 예상. 확인만.
19
- - Test: `tests/test_e2e_impl_stage_artifact_isolation.py` (신규) — 동시 stage-1/stage-2 가 분리된 `stage-<N>/` 산출물 트리 + 분리 `lead-pane.id` + 공유 `consumers.jsonl` 을 갖는지.
20
- - Test: `tests/test_okstra_ctl_paths.py` (기존 있으면 확장; 없으면 신규) — `compute_run_paths(task_type="implementation", stage=N)` 가 `runs/implementation/stage-N/...` 를 반환, `stage=None`/비-impl 은 불변.
21
- - Modify(필요 시): `validators/validate-run.py`, `scripts/okstra_ctl/{render.py,report_views.py,context_cost.py,index.py,reconcile.py,backfill.py}` — `runs/implementation` hard-coded 경로가 있으면 stage-aware 로. (대부분 ctx/path-dict 경유라 무변경; Task 5 에서 grep 로 확정.)
22
- - Modify: `CHANGES.md`, `docs/kr/architecture.md` — 사용자 영향 + 팀 lifecycle 절.
23
-
24
- `runtime/` 는 빌드 출력 — source 수정 후 `npm run build`.
25
-
26
- ---
27
-
28
- ## Task 1: paths 단위 테스트로 foundation 동작 고정
29
-
30
- **Files:**
31
- - Test: `tests/test_okstra_ctl_paths.py`
32
-
33
- - [ ] **Step 1: 실패/통과 테스트 작성**
34
-
35
- `tests/test_okstra_ctl_paths.py` 에 추가(파일 없으면 신규 생성, 상단에 `from okstra_ctl.paths import compute_run_paths` + `from pathlib import Path`):
36
-
37
- ```python
38
- def _common(**over):
39
- base = dict(
40
- project_root=Path("/tmp/proj"), workspace_root=Path("/tmp/ws"),
41
- project_id="p", task_group="g", task_id="t",
42
- task_type="implementation", run_seq_override=1,
43
- )
44
- base.update(over)
45
- return base
46
-
47
-
48
- def test_implementation_stage_namespaces_run_dir():
49
- ctx = compute_run_paths(stage=3, **_common())
50
- assert ctx["RUN_DIR"].endswith("/runs/implementation/stage-3")
51
- assert ctx["RUN_REPORTS_DIR"].endswith("/runs/implementation/stage-3/reports")
52
- assert ctx["RUN_STATE_DIR"].endswith("/runs/implementation/stage-3/state")
53
- assert ctx["RUN_STAGE"] == "3"
54
-
55
-
56
- def test_implementation_without_stage_is_flat():
57
- ctx = compute_run_paths(stage=None, **_common())
58
- assert ctx["RUN_DIR"].endswith("/runs/implementation")
59
- assert ctx["RUN_STAGE"] == ""
60
-
61
-
62
- def test_non_implementation_ignores_stage():
63
- ctx = compute_run_paths(stage=3, **_common(task_type="final-verification"))
64
- assert ctx["RUN_DIR"].endswith("/runs/final-verification")
65
- assert "stage-3" not in ctx["RUN_DIR"]
66
- ```
67
-
68
- - [ ] **Step 2: 실행해서 통과 확인** (foundation 이 이미 land 됨)
69
-
70
- Run: `python3 -m pytest tests/test_okstra_ctl_paths.py -v`
71
- Expected: 3개 PASS. 실패하면 foundation(`paths.py` stage 분기) 회귀이므로 먼저 수정.
72
-
73
- - [ ] **Step 3: 커밋**
74
-
75
- ```bash
76
- git add tests/test_okstra_ctl_paths.py
77
- git commit -m "test(paths): pin implementation stage-namespaced RUN_DIR"
78
- ```
79
-
80
- ---
81
-
82
- ## Task 2: `_reserve_implementation_stages` 를 선택/예약 vs wiring 으로 분리
83
-
84
- **Files:**
85
- - Modify: `scripts/okstra_ctl/run.py` (`_reserve_implementation_stages` 1274–1386 영역)
86
-
87
- 현재 함수는 한 덩어리로 (1) consumers/registry 읽기 → `_resolve_effective_stages` 선택, (2) base anchor + `_resolve_stage_base_commit` + `provision_stage_worktree`(registry 원자 예약), (3) `ctx["EXECUTOR_WORKTREE_*"]` 세팅 + `append_consumer(started)` 를 한다. (1)+(2)는 run-경로와 무관하지만 (3)은 `ctx` 가 필요하다.
88
-
89
- - [ ] **Step 1: 선택+예약+provision 을 반환 객체로 추출**
90
-
91
- `scripts/okstra_ctl/run.py` 에 신규 헬퍼 추가(`_reserve_implementation_stages` 위). `ctx` 대신 segment 값을 인자로 받아 **경로-무관**하게 만든다. (segment 는 `slugify_task_segment(inp.task_group/task_id)` 로 직접 도출 — `ctx` 불필요.)
92
-
93
- ```python
94
- from dataclasses import dataclass
95
-
96
- @dataclass
97
- class StageSelection:
98
- stage: int
99
- worktree_path: str
100
- worktree_branch: str
101
- worktree_base_ref: str
102
- worktree_status: str
103
- worktree_note: str
104
- started_head_commit: str # consumers append 용 (degrade 경로는 HEAD sha)
105
-
106
-
107
- def _select_and_provision_implementation_stage(
108
- inp: "PrepareInputs", ctx_stage_map: list,
109
- task_group_segment: str, task_id_segment: str, task_key: str,
110
- executor_worktree_status: str,
111
- ) -> StageSelection:
112
- """run 경로 계산 전에 호출: ready stage 1개 선택 → (degrade 가 아니면)
113
- base 결정 + stage worktree 발급(registry flock 으로 stage-key 원자 예약).
114
- 선택과 예약이 한 호출에 묶여 동시성 불변(spec §2.3)을 보존한다.
115
- consumers append 는 호출자가 ctx 확정 후 수행한다(반환값 사용)."""
116
- from .consumers import read_consumers
117
- from . import worktree as _worktree
118
- from . import worktree_registry as _reg
119
-
120
- plan_run_root = Path(inp.approved_plan_path).resolve().parents[1]
121
- consumed = read_consumers(plan_run_root)
122
- done_stages = {r["stage"] for r in consumed if r.get("status") == "done"}
123
- started_stages = {r["stage"] for r in consumed if r.get("status") == "started"}
124
- reserved_stages = _reg.list_active_stage_numbers(
125
- inp.project_id, inp.task_group, inp.task_id,
126
- )
127
- batch = _resolve_effective_stages(
128
- ctx_stage_map, done_stages, inp.stage,
129
- started_stages=started_stages, reserved_stages=reserved_stages,
130
- )
131
- selected = batch[0]
132
-
133
- # degradation(non-git / nested-worktree): worktree 미발급, consumers 만.
134
- if executor_worktree_status.startswith("skipped"):
135
- head = _git_out(inp.project_root, "rev-parse", "HEAD")
136
- return StageSelection(selected, "", "", "", executor_worktree_status, "", head)
137
-
138
- head_sha = _git_out(inp.project_root, "rev-parse", "HEAD")
139
- if head_sha:
140
- _reg.set_implementation_base(inp.project_id, inp.task_group, inp.task_id, head_sha)
141
- anchor = _reg.get_implementation_base(inp.project_id, inp.task_group, inp.task_id) or ""
142
- selected_stage = next(s for s in ctx_stage_map if s["stage_number"] == selected)
143
- consumer_done_rows = [r for r in consumed if r.get("status") == "done"]
144
- stage_base = _resolve_stage_base_commit(
145
- selected_stage, consumer_done_rows, anchor_base_commit=anchor,
146
- candidate_base=head_sha, project_root=Path(inp.project_root),
147
- )
148
- try:
149
- prov = _worktree.provision_stage_worktree(
150
- project_root=Path(inp.project_root), project_id=inp.project_id,
151
- task_group_segment=task_group_segment, task_id_segment=task_id_segment,
152
- work_category=inp.work_category, stage_number=selected, base_commit=stage_base,
153
- )
154
- except RuntimeError as exc:
155
- raise PrepareError(f"stage worktree provisioning failed: {exc}") from exc
156
- return StageSelection(
157
- selected, prov.path, prov.branch, prov.base_ref, prov.status, prov.note, prov.base_ref,
158
- )
159
- ```
160
-
161
- - [ ] **Step 2: wiring 헬퍼로 교체** — `_reserve_implementation_stages` 본문을 selection 결과를 ctx 에 반영 + consumers append 로 축소:
162
-
163
- ```python
164
- def _apply_implementation_stage(
165
- inp: "PrepareInputs", ctx: dict, ctx_stage_map: list, sel: "StageSelection",
166
- ) -> None:
167
- """이미 선택·예약된 stage(sel)를 ctx 에 반영하고 consumers 에 started 기록."""
168
- from .consumers import append_consumer
169
- import datetime as _dt
170
- ctx["parsed_stage_map"] = ctx_stage_map
171
- ctx["effective_stages"] = [sel.stage]
172
- ctx["EFFECTIVE_STAGES"] = str(sel.stage)
173
- ctx["STAGE_BATCH_DIRECTIVE"] = (
174
- f"- **Stage for this implementation run:** `{sel.stage}`. "
175
- "Execute exactly this Stage Map stage — this is the authoritative scope. "
176
- "Do NOT recompute from `consumers.jsonl`; the runtime already selected "
177
- "and reserved this stage."
178
- )
179
- inp.stage = str(sel.stage)
180
- if sel.worktree_status and not sel.worktree_status.startswith("skipped"):
181
- ctx["EXECUTOR_WORKTREE_PATH"] = sel.worktree_path
182
- ctx["EXECUTOR_WORKTREE_BRANCH"] = sel.worktree_branch
183
- ctx["EXECUTOR_WORKTREE_BASE_REF"] = sel.worktree_base_ref
184
- ctx["EXECUTOR_WORKTREE_STATUS"] = sel.worktree_status
185
- ctx["EXECUTOR_WORKTREE_NOTE"] = sel.worktree_note
186
- plan_run_root = Path(inp.approved_plan_path).resolve().parents[1]
187
- now = _dt.datetime.now(_dt.timezone.utc).isoformat()
188
- append_consumer(
189
- plan_run_root, impl_task_key=ctx["TASK_KEY"], stage=sel.stage,
190
- status="started", started_at=now, head_commit=sel.started_head_commit,
191
- )
192
- ```
193
-
194
- - [ ] **Step 3: 정적 검사**
195
-
196
- Run: `python3 -c "import ast; ast.parse(open('scripts/okstra_ctl/run.py').read()); print('ok')"`
197
- Expected: `ok`
198
-
199
- - [ ] **Step 4: 커밋**
200
-
201
- ```bash
202
- git add scripts/okstra_ctl/run.py
203
- git commit -m "refactor(run): split impl stage select+reserve (path-independent) from ctx wiring"
204
- ```
205
-
206
- ---
207
-
208
- ## Task 3: `prepare_task_bundle` reorder — stage 를 경로 계산 전에 선택
209
-
210
- **Files:**
211
- - Modify: `scripts/okstra_ctl/run.py` (`prepare_task_bundle` 1651–1810)
212
-
213
- - [ ] **Step 1: 현재 흐름 확인** — `compute_and_write_run_context`(1686) 호출 직전에 `ctx_stage_map` 와 `inp.task_type == "implementation"` 가용한지, `EXECUTOR_WORKTREE_STATUS` 의 초기값(task worktree provision 결과)을 어디서 얻는지 read 로 확인. (degrade 신호가 task-worktree provision 에서 오면, stage select 는 그 신호가 필요 → task worktree provision 을 stage select 보다 먼저 두거나, stage select 안에서 자체 degrade 판정.)
214
-
215
- - [ ] **Step 2: reorder 적용** — implementation 분기에서:
216
- 1. `compute_and_write_run_context` **앞에서** `sel = _select_and_provision_implementation_stage(...)` 호출(`executor_worktree_status` 는 task-worktree provision 결과 또는 `provision_task_worktree` 의 사전 판정값 전달).
217
- 2. `compute_and_write_run_context(..., stage=sel.stage)` 호출 → stage-namespaced ctx.
218
- 3. ctx 생성 후 `_apply_implementation_stage(inp, ctx, ctx_stage_map, sel)` 로 wiring.
219
- 4. 기존 `_reserve_implementation_stages(inp, ctx, ctx_stage_map)` 호출(1807) **제거**(위 1~3 이 대체). 비-implementation 경로는 불변.
220
-
221
- > 핵심 불변: registry stage-key 예약은 `provision_stage_worktree`(sel 단계) **1회**만. 재선택/재예약 없음.
222
-
223
- - [ ] **Step 3: 전체 단위 테스트**
224
-
225
- Run: `python3 -m pytest tests/ -q`
226
- Expected: 전부 PASS(2 skip 허용). 특히 `tests/test_e2e_multi_stage_q1_q9.py`, `tests/test_okstra_ctl_rerun_*` 회귀 없을 것. 실패 시 reorder 의 ctx_stage_map/worktree-status 전달 누락 점검.
227
-
228
- - [ ] **Step 4: 커밋**
229
-
230
- ```bash
231
- git add scripts/okstra_ctl/run.py
232
- git commit -m "feat(run): resolve implementation stage before run-path compute (activate stage isolation)"
233
- ```
234
-
235
- ---
236
-
237
- ## Task 4: 동시 stage 격리 e2e
238
-
239
- **Files:**
240
- - Test: `tests/test_e2e_impl_stage_artifact_isolation.py` (신규)
241
-
242
- - [ ] **Step 1: e2e 작성** — 기존 `tests/test_e2e_multi_stage_q1_q9.py` 의 픽스처(임시 git project + approved plan with ≥2 독립 stage)를 재사용/모사. 두 `prepare_task_bundle` 를 **순차 호출**(동시성은 flock 으로 직렬화되므로 순차 2회가 동치)해 각각 다른 ready stage 를 잡게 한 뒤:
243
-
244
- ```python
245
- def test_two_runs_isolate_stage_artifacts(tmp_impl_project):
246
- out1 = prepare_task_bundle(tmp_impl_project.inputs(stage="auto"))
247
- out2 = prepare_task_bundle(tmp_impl_project.inputs(stage="auto"))
248
- d1, d2 = Path(out1.ctx["RUN_DIR"]), Path(out2.ctx["RUN_DIR"])
249
- # 서로 다른 stage-<N> 트리
250
- assert d1 != d2
251
- assert d1.name.startswith("stage-") and d2.name.startswith("stage-")
252
- # lead-pane.id 가 분리(부모 공유 아님)
253
- assert d1.parent == d2.parent == (tmp_impl_project.task_root / "runs" / "implementation")
254
- # consumers.jsonl 은 공유(plan-run-root 1개)
255
- cons = tmp_impl_project.plan_run_root / "consumers.jsonl"
256
- rows = [json.loads(l) for l in cons.read_text().splitlines() if l.strip()]
257
- stages = sorted(r["stage"] for r in rows if r["status"] == "started")
258
- assert stages == [out1.ctx["RUN_STAGE"] and int(out1.ctx["RUN_STAGE"]),
259
- int(out2.ctx["RUN_STAGE"])] or len(set(stages)) == 2
260
- ```
261
-
262
- (픽스처 정확한 형태는 기존 e2e 의 헬퍼에 맞춰 작성 — 실행 시 `tests/test_e2e_multi_stage_q1_q9.py` 의 setup 함수를 import/모방.)
263
-
264
- - [ ] **Step 2: 실행**
265
-
266
- Run: `python3 -m pytest tests/test_e2e_impl_stage_artifact_isolation.py -v`
267
- Expected: PASS. tmux/flock 불가 환경이면 skip 마커. 실패 시 두 run 이 같은 `RUN_DIR` 를 잡는지(=stage select 가 reorder 에서 실제 적용됐는지) 확인.
268
-
269
- - [ ] **Step 3: 커밋**
270
-
271
- ```bash
272
- git add tests/test_e2e_impl_stage_artifact_isolation.py
273
- git commit -m "test(e2e): concurrent implementation stages isolate run artifacts"
274
- ```
275
-
276
- ---
277
-
278
- ## Task 5: reader/validator sweep + 문서 + 빌드
279
-
280
- **Files:**
281
- - Modify(조건부): `validators/validate-run.py`, `scripts/okstra_ctl/{render.py,report_views.py,context_cost.py,index.py,reconcile.py,backfill.py,workflow.py}`
282
- - Modify: `CHANGES.md`, `docs/kr/architecture.md`
283
-
284
- - [ ] **Step 1: hard-coded 경로 grep**
285
-
286
- Run: `grep -rn "runs/implementation\|/runs/\" *+\|task_type_segment *== *.implementation" scripts/okstra_ctl/ validators/`
287
- 점검: `runs/implementation` 를 **stage 없이 직접** 조립/스캔하는 곳을 찾는다. ctx/path-dict(`RUN_DIR`, `RUN_REPORTS_DIR` 등) 경유면 자동 흡수되어 무변경. 직접 조립이면 stage-aware 로 수정(예: timeline/index 가 `runs/<type>/reports/*` 글롭이면 `runs/<type>/**/reports/*` 로).
288
-
289
- - [ ] **Step 2: 발견 건 수정 + 회귀 테스트** — 수정한 모듈별로 해당 테스트 재실행. 없으면 Step 1 결과를 `없음(모두 ctx 경유)` 으로 기록.
290
-
291
- - [ ] **Step 3: 문서 + 빌드**
292
-
293
- `CHANGES.md` 최상단:
294
- ```
295
- ## 2026-06-09 — implementation 산출물 stage 격리
296
- - 변경: implementation run 산출물이 `runs/implementation/stage-<N>/` 로 stage 별 격리. stage 선택을 경로 계산 전에 수행하고 registry flock 으로 1회 예약.
297
- - 사용자 영향: 같은 task 의 여러 stage 를 동시 실행해도 보고서·state·worker-results 가 섞이지 않는다. (무호환: 이전 `runs/implementation/` 루트 산출물은 자동 인식 안 됨 — 재실행 권장.)
298
- ```
299
-
300
- `docs/kr/architecture.md` 의 stage worktree 절에 "run-산출물도 `runs/implementation/stage-<N>/` 로 격리; consumers.jsonl·registry 는 공유" 1문장 추가.
301
-
302
- Run: `cd <repo> && npm run build && python3 -m pytest tests/ -q && bash validators/validate-workflow.sh`
303
- Expected: 빌드 24/24, 테스트 PASS, validator exit 0.
304
-
305
- - [ ] **Step 4: 커밋**
306
-
307
- ```bash
308
- git add -A
309
- git commit -m "docs(changes,architecture): implementation run-artifact stage isolation; reader sweep"
310
- ```
311
-
312
- ---
313
-
314
- ## Self-Review (작성자 체크)
315
-
316
- - **Spec coverage**: D1(stage-namespace RUN_DIR)=Task1+foundation, D2(seq in stage dir)=foundation(자동), D3(consumers 공유)=Task2/3 가 plan_run_root 유지 + Task4 e2e 가드, D4(lead-pane.id 격리)=Task4 e2e(부모 분리 확인), D5(degrade fallback)=Task2 `executor_worktree_status.startswith("skipped")` 분기. 전 D 매핑됨.
317
- - **동시성 불변**: registry stage-key 예약은 `provision_stage_worktree` 1회만 — Task2 추출 + Task3 가 기존 `_reserve_implementation_stages` 호출 제거로 이중예약 차단.
318
- - **Placeholder scan**: TBD/TODO 없음. Task4 픽스처는 기존 e2e 헬퍼 재사용 명시(코드 형태 제시).
319
- - **식별자 일관성**: `StageSelection`, `_select_and_provision_implementation_stage`, `_apply_implementation_stage`, `stage` param 이 Task2/3/4 에서 동일.
320
- - **알려진 한계**: 무호환(이전 루트 산출물), consumers/registry 공유는 spec 에 명시.