okstra 0.102.2 → 0.102.4

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