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,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 에 명시.