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,456 +0,0 @@
1
- # ๋™์‹œ-run team ๊ฐ€๋“œ ๊ตฌํ˜„ ํ”Œ๋žœ
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:** ๊ฐ™์€ task-key ์˜ implementation run ์ด ๋™์‹œ์— ๋Œ ๋•Œ, ํ›„๋ฐœ run ์ด team ์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ  no-team background ๋กœ worker ๋ฅผ dispatch ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด `~/.claude/teams/` config race ๋ฅผ ์˜ˆ๋ฐฉํ•œ๋‹ค.
6
-
7
- **Architecture:** `prepare_task_bundle` ์˜ stage ์„ ํƒ ๋‹จ๊ณ„๊ฐ€ ์ด๋ฏธ ํ˜ธ์ถœํ•˜๋Š” `list_active_stage_numbers` ๋กœ ๋™์‹œ-run ์„ ๊ฐ์ง€ํ•œ๋‹ค โ†’ `StageSelection.concurrent_stages` ์— ๋‹ด์•„ โ†’ `ctx["CONCURRENT_RUN_STAGES"]` ๋กœ wire โ†’ render ๊ฐ€ "Team Creation Gate" ๋Œ€์‹  "no-team background" ๋ธ”๋ก์„ emit + `PrepareOutputs.extras["concurrent_run"]` ๋กœ ์ง„์ž…์ ์— ๋…ธ์ถœ. ์ƒˆ lockยท์ƒˆ ์ถ”์  ์—†์Œ, enforce ์ง€์ ์€ Python ๋ Œ๋”.
8
-
9
- **Tech Stack:** Python 3 (`scripts/okstra_ctl/`), pytest, Markdown ํ”„๋กฌํ”„ํŠธ/์Šคํ‚ฌ, `npm run build`(์†Œ์Šคโ†’`runtime/` ๋™๊ธฐํ™”).
10
-
11
- **์„ค๊ณ„ ์ถœ์ฒ˜:** [docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md](../specs/2026-06-10-concurrent-run-team-guard-design.md)
12
-
13
- **์ „์—ญ ๊ทœ์น™:**
14
- - `runtime/` ๋Š” build output โ€” ์ง์ ‘ ํŽธ์ง‘ ๊ธˆ์ง€. ์†Œ์Šค(`scripts/`, `prompts/`, `agents/`, `skills/`)๋งŒ ๊ณ ์น˜๊ณ  Task 7 ์—์„œ `npm run build`.
15
- - ์ปค๋ฐ‹ trailer ๊ธˆ์ง€(`Co-Authored-By` / `Generated with` ๋“ฑ). Conventional Commits header `type(scope): โ€ฆ`.
16
- - ๊ฐ Task ๋Š” ์†Œ์Šค + ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ™์€ ์ปค๋ฐ‹์— ๋‹ด๋Š”๋‹ค.
17
-
18
- ---
19
-
20
- ## File Structure
21
-
22
- | ํŒŒ์ผ | ์ฑ…์ž„ | Task |
23
- |---|---|---|
24
- | [scripts/okstra_ctl/render.py](../../../scripts/okstra_ctl/render.py) | `inject_lead_prompt_computed_tokens` ์— no-team ๋ธ”๋ก ๋ถ„๊ธฐ ์ถ”๊ฐ€ | 1 |
25
- | [scripts/okstra_ctl/run.py](../../../scripts/okstra_ctl/run.py) | `StageSelection.concurrent_stages` ํ•„๋“œ + ๊ฐ์ง€ยทwire + `extras` ์ „ํŒŒ | 2, 3 |
26
- | [agents/SKILL.md](../../../agents/SKILL.md), [prompts/profiles/_common-contract.md](../../../prompts/profiles/_common-contract.md) | no-team fallback ์˜ ์ƒˆ legal ์‚ฌ์œ (`status:"skipped"`, `reason:"concurrent-run"`) | 4 |
27
- | [skills/okstra-run/SKILL.md](../../../skills/okstra-run/SKILL.md) | ๋Œ€ํ™”ํ˜• 3-์˜ต์…˜ picker | 5 |
28
- | [tests/test_render_inject_computed_tokens.py](../../../tests/test_render_inject_computed_tokens.py), [tests/test_okstra_run_select_and_apply_implementation_stage.py](../../../tests/test_okstra_run_select_and_apply_implementation_stage.py) | ๋‹จ์œ„ ํ…Œ์ŠคํŠธ | 1, 2 |
29
- | `tests-e2e/scenario-<id>-concurrent-run-no-team.sh` | e2e (extras ์ „ํŒŒ + no-team ๋ธ”๋ก) | 6 |
30
-
31
- ---
32
-
33
- ## Task 1: render โ€” ๋™์‹œ-run no-team ๋ธ”๋ก ๋ถ„๊ธฐ
34
-
35
- **Files:**
36
- - Modify: `scripts/okstra_ctl/render.py:1645-1664` (`inject_lead_prompt_computed_tokens` ๋‚ด team-gate ๋ถ„๊ธฐ)
37
- - Test: `tests/test_render_inject_computed_tokens.py`
38
-
39
- ์ด Task ๊ฐ€ ctx ํ‚ค ๊ณ„์•ฝ(`CONCURRENT_RUN_STAGES`)์„ ๋จผ์ € ์ •์˜ํ•œ๋‹ค. Task 2 ๊ฐ€ ์ด ํ‚ค๋ฅผ ์ฑ„์šด๋‹ค.
40
-
41
- - [ ] **Step 1: ์‹คํŒจ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ** โ€” `tests/test_render_inject_computed_tokens.py` ๋์— ์ถ”๊ฐ€
42
-
43
- ```python
44
- def test_inject_concurrent_run_emits_no_team_block():
45
- """๋™์‹œ-run ๊ฐ์ง€ ์‹œ Team Creation Gate ๋Œ€์‹  no-team background ๋ธ”๋ก์„ emit."""
46
- ctx = _base_ctx()
47
- ctx["TASK_TYPE"] = "implementation"
48
- ctx["EFFECTIVE_STAGES"] = "4"
49
- ctx["CONCURRENT_RUN_STAGES"] = "5"
50
- inject_lead_prompt_computed_tokens(ctx)
51
- gate = ctx["TEAM_CREATION_GATE"]
52
- assert "Concurrent-run: no-team background" in gate
53
- # ์‹ค์ œ team ์ƒ์„ฑ ํ˜ธ์ถœ ํ˜•ํƒœ๋Š” ์—†์–ด์•ผ ํ•œ๋‹ค
54
- assert 'TeamCreate(team_name:' not in gate
55
- assert 'reason: "concurrent-run"' in gate
56
- assert "run_in_background" in gate
57
-
58
-
59
- def test_inject_no_concurrent_keeps_team_gate():
60
- """CONCURRENT_RUN_STAGES ๊ฐ€ ์—†์œผ๋ฉด ๊ธฐ์กด Team Creation Gate ๊ทธ๋Œ€๋กœ(ํšŒ๊ท€ ๋ฐฉ์ง€)."""
61
- ctx = _base_ctx()
62
- ctx["TASK_TYPE"] = "implementation"
63
- ctx["EFFECTIVE_STAGES"] = "4"
64
- inject_lead_prompt_computed_tokens(ctx)
65
- assert "Team Creation Gate (BLOCKING)" in ctx["TEAM_CREATION_GATE"]
66
- assert 'TeamCreate(team_name: "okstra-demo/task-a-s4"' in ctx["TEAM_CREATION_GATE"]
67
- ```
68
-
69
- - [ ] **Step 2: ์‹คํŒจ ํ™•์ธ**
70
-
71
- Run: `python3 -m pytest tests/test_render_inject_computed_tokens.py::test_inject_concurrent_run_emits_no_team_block -v`
72
- Expected: FAIL โ€” `"Concurrent-run: no-team background"` ๊ฐ€ gate ์— ์—†์Œ(ํ˜„์žฌ๋Š” Team Creation Gate ๊ฐ€ ๋‚˜์˜ด).
73
-
74
- - [ ] **Step 3: ๋ถ„๊ธฐ ์ถ”๊ฐ€** โ€” `render.py` ์˜ `task_type = ctx.get("TASK_TYPE", "")` ์ค„(ํ˜„ 1645) ๋ฐ”๋กœ ์•„๋ž˜์— `concurrent_stages` ๋ฅผ ์ฝ๊ณ , `if task_type == "release-handoff" or not selected:` ์™€ `else:` ์‚ฌ์ด์— `elif` ๋ฅผ ๋ผ์šด๋‹ค. ์ตœ์ข… ํ˜•ํƒœ:
75
-
76
- ```python
77
- task_type = ctx.get("TASK_TYPE", "")
78
- concurrent_stages = str(ctx.get("CONCURRENT_RUN_STAGES", "") or "").strip()
79
- if task_type == "release-handoff" or not selected:
80
- team_creation_gate_block = (
81
- "## Single-Lead Phase (no team creation)\n"
82
- "\n"
83
- "This run is single-lead. There is no worker roster, no\n"
84
- "`TeamCreate` call, no `Agent(...)` worker dispatch, and no\n"
85
- "convergence loop. The Claude lead performs every step inline\n"
86
- "(reading inputs, drafting commit / PR text when applicable,\n"
87
- "asking the user, running git / gh, and writing the final\n"
88
- "report). Do NOT call `TeamCreate` or dispatch any sub-agent\n"
89
- "from this run โ€” that would be a contract violation."
90
- )
91
- elif task_type == "implementation" and concurrent_stages:
92
- team_creation_gate_block = (
93
- "## Concurrent-run: no-team background (BLOCKING)\n"
94
- "\n"
95
- "A concurrent implementation run of the same task-key holds stage(s)\n"
96
- f"`{concurrent_stages}` right now. Creating a team would race the shared\n"
97
- "`~/.claude/teams/` config and can make another stage's `config.json`\n"
98
- "unreadable. This run therefore does NOT create a team.\n"
99
- "\n"
100
- "Required actions, in order:\n"
101
- "\n"
102
- "1. Do NOT call `TeamCreate`, and do NOT dispatch any worker with\n"
103
- " `Agent(... team_name: ...)`.\n"
104
- "2. Before any dispatch, record in team-state:\n"
105
- ' `teamCreate: { attempted: false, status: "skipped",'
106
- f' reason: "concurrent-run", concurrentStages: [{concurrent_stages}] }}`.\n'
107
- "3. Dispatch every worker with `run_in_background: true` and NO\n"
108
- " `team_name` (the Phase 5 fallback). Worker completion is detected by\n"
109
- " result-file polling, so analysis output is equivalent โ€” only the\n"
110
- " Teams split-pane view is lost."
111
- )
112
- else:
113
- team_name = f'okstra-{ctx.get("TASK_KEY", "")}'
114
- stage = str(ctx.get("EFFECTIVE_STAGES", "") or "").strip()
115
- if task_type == "implementation" and stage:
116
- # stage ๊ฒฉ๋ฆฌ run ์€ stage ๋ณ„ team โ€” ๊ฐ™์€ task ์˜ ๋‹ค๋ฅธ stage ๊ฐ€ ๋‚จ๊ธด
117
- # team ๊ณผ ์ด๋ฆ„์ด ์ถฉ๋Œํ•˜์ง€ ์•Š๋Š”๋‹ค(worktree branch `-s<N>` ์ ‘๋ฏธ์‚ฌ์™€ ๋™ํ˜•).
118
- team_name = f"{team_name}-s{stage}"
119
- team_creation_gate_block = (
120
- # ... ๊ธฐ์กด "## Team Creation Gate (BLOCKING)" ๋ธ”๋ก ๊ทธ๋Œ€๋กœ ์œ ์ง€ ...
121
- )
122
- ```
123
-
124
- > ์ฃผ์˜: `else:` ์•ˆ์˜ ๊ธฐ์กด Team Creation Gate ๋ธ”๋ก ๋ณธ๋ฌธ(ํ˜„ 1665-1703)์€ **๊ทธ๋Œ€๋กœ ๋‘”๋‹ค**. `elif` ๋งŒ ๋ผ์šฐ๋Š” ๋ณ€๊ฒฝ์ด๋‹ค.
125
-
126
- - [ ] **Step 4: ํ†ต๊ณผ ํ™•์ธ**
127
-
128
- Run: `python3 -m pytest tests/test_render_inject_computed_tokens.py -v`
129
- Expected: PASS (์‹ ๊ทœ 2๊ฐœ + ๊ธฐ์กด ์ „๋ถ€).
130
-
131
- - [ ] **Step 5: ์ปค๋ฐ‹**
132
-
133
- ```bash
134
- git add scripts/okstra_ctl/render.py tests/test_render_inject_computed_tokens.py
135
- git commit -m "feat(okstra-ctl): ๋™์‹œ-run ์‹œ no-team background ๊ฒŒ์ดํŠธ ๋ธ”๋ก ๋ Œ๋”"
136
- ```
137
-
138
- ---
139
-
140
- ## Task 2: run โ€” ๋™์‹œ-run ๊ฐ์ง€ + ctx wire
141
-
142
- **Files:**
143
- - Modify: `scripts/okstra_ctl/run.py:1297-1313` (`StageSelection` ํ•„๋“œ ์ถ”๊ฐ€)
144
- - Modify: `scripts/okstra_ctl/run.py:1340-1412` (`_select_and_provision_implementation_stage` ์ฑ„์šฐ๊ธฐ)
145
- - Modify: `scripts/okstra_ctl/run.py:1426-1429` (`_apply_implementation_stage` ctx wire)
146
- - Test: `tests/test_okstra_run_select_and_apply_implementation_stage.py`
147
-
148
- - [ ] **Step 1: ์‹คํŒจ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ** โ€” ํŒŒ์ผ ๋์— ์ถ”๊ฐ€. registry ์— ๋‹ค๋ฅธ stage ๋ฅผ active ๋กœ ๋ฏธ๋ฆฌ ์˜ˆ์•ฝํ•ด ๋™์‹œ-run ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•œ๋‹ค.
149
-
150
- ```python
151
- def test_select_flags_concurrent_active_stage(tmp_path, monkeypatch):
152
- """๋‹ค๋ฅธ run ์ด stage 6 ์„ active ๋กœ ์ ์œ  ์ค‘์ด๋ฉด, stage 4 ์„ ํƒ ๊ฒฐ๊ณผ์˜
153
- concurrent_stages ์— 6 ์ด ๋‹ด๊ธด๋‹ค."""
154
- sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
155
- from okstra_ctl import worktree_registry as reg
156
- from okstra_ctl.run import _select_and_provision_implementation_stage
157
-
158
- repo = tmp_path / "repo"
159
- head = _init_repo(repo)
160
-
161
- # ๋‹ค๋ฅธ ๋™์‹œ run ์ด stage 6 ์„ active ๋กœ ์ ์œ  ์ค‘์ด๋ผ๊ณ  ๊ฐ€์ •
162
- reg.reserve(
163
- project_id="proj", task_group="grp", task_id="tid",
164
- worktree_path=str(tmp_path / "s6"), branch="feature-tid-s6",
165
- base_ref=head, stage_number=6,
166
- )
167
-
168
- plan = _consumers_dir(tmp_path)
169
- inp = _Inp(project_root=str(repo), approved_plan_path=str(plan), stage="auto")
170
- stages = [_stage(4, []), _stage(6, [])]
171
-
172
- sel = _select_and_provision_implementation_stage(
173
- inp, stages, "grp", "tid", "proj:grp:tid", "ok",
174
- )
175
- assert sel.stage == 4
176
- assert sel.concurrent_stages == [6]
177
-
178
-
179
- def test_select_no_concurrent_when_alone(tmp_path):
180
- """๋™์‹œ run ์ด ์—†์œผ๋ฉด concurrent_stages ๋Š” ๋นˆ ๋ฆฌ์ŠคํŠธ."""
181
- sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
182
- from okstra_ctl.run import _select_and_provision_implementation_stage
183
-
184
- repo = tmp_path / "repo"
185
- head = _init_repo(repo)
186
- plan = _consumers_dir(tmp_path)
187
- inp = _Inp(project_root=str(repo), approved_plan_path=str(plan), stage="auto")
188
- stages = [_stage(4, [])]
189
-
190
- sel = _select_and_provision_implementation_stage(
191
- inp, stages, "grp", "tid", "proj:grp:tid", "ok",
192
- )
193
- assert sel.stage == 4
194
- assert sel.concurrent_stages == []
195
- ```
196
-
197
- > `conftest.py` ๊ฐ€ `OKSTRA_HOME` ๋ฅผ ๊ฒฉ๋ฆฌํ•˜๋ฏ€๋กœ registry ๋Š” ํ…Œ์ŠคํŠธ ์ž„์‹œ ๊ฒฝ๋กœ์— ์“ฐ์ธ๋‹ค. `_init_repo` / `_stage` / `_Inp` / `_consumers_dir` ๋Š” ํŒŒ์ผ ์ƒ๋‹จ์˜ ๊ธฐ์กด ํ—ฌํผ๋‹ค.
198
-
199
- - [ ] **Step 2: ์‹คํŒจ ํ™•์ธ**
200
-
201
- Run: `python3 -m pytest tests/test_okstra_run_select_and_apply_implementation_stage.py::test_select_flags_concurrent_active_stage -v`
202
- Expected: FAIL โ€” `AttributeError: 'StageSelection' object has no attribute 'concurrent_stages'`.
203
-
204
- - [ ] **Step 3a: `StageSelection` ํ•„๋“œ ์ถ”๊ฐ€** โ€” `run.py:1306-1312` ์˜ dataclass ๋(`started_head_commit: str` ๋‹ค์Œ ์ค„)์— ์ถ”๊ฐ€:
205
-
206
- ```python
207
- started_head_commit: str
208
- concurrent_stages: list = field(default_factory=list)
209
- ```
210
-
211
- > ํŒŒ์ผ ์ƒ๋‹จ์— `from dataclasses import dataclass, field` ๊ฐ€ ์ด๋ฏธ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , `field` ๊ฐ€ ์—†์œผ๋ฉด import ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
212
-
213
- - [ ] **Step 3b: ๊ฐ์ง€๊ฐ’ ๊ณ„์‚ฐ + ๋‘ ๋ฐ˜ํ™˜ ๊ฒฝ๋กœ์— ๋‹ด๊ธฐ** โ€” `_select_and_provision_implementation_stage` ์•ˆ, `selected = batch[0]`(ํ˜„ 1350) ๋ฐ”๋กœ ๋‹ค์Œ ์ค„์—:
214
-
215
- ```python
216
- selected = batch[0]
217
- concurrent_stages = sorted(reserved_stages - {selected})
218
- ```
219
-
220
- ๊ทธ๋ฆฌ๊ณ  ์ด ํ•จ์ˆ˜์˜ **๋‘ `return StageSelection(...)`** (degrade ๊ฒฝ๋กœ ํ˜„ 1356, ์ •์ƒ ๊ฒฝ๋กœ ํ˜„ 1404) ๋‘˜ ๋‹ค ๋งˆ์ง€๋ง‰ ์ธ์ž๋กœ ์ถ”๊ฐ€:
221
-
222
- ```python
223
- started_head_commit=head, # degrade ๊ฒฝ๋กœ
224
- concurrent_stages=concurrent_stages,
225
- ```
226
-
227
- ```python
228
- started_head_commit=prov.base_ref, # ์ •์ƒ ๊ฒฝ๋กœ
229
- concurrent_stages=concurrent_stages,
230
- ```
231
-
232
- - [ ] **Step 3c: ctx wire** โ€” `_apply_implementation_stage` ์•ˆ, `ctx["EFFECTIVE_STAGES"] = csv`(ํ˜„ 1429) ๋‹ค์Œ ์ค„์—:
233
-
234
- ```python
235
- ctx["CONCURRENT_RUN_STAGES"] = ",".join(str(s) for s in sel.concurrent_stages)
236
- ```
237
-
238
- - [ ] **Step 4: ํ†ต๊ณผ ํ™•์ธ**
239
-
240
- Run: `python3 -m pytest tests/test_okstra_run_select_and_apply_implementation_stage.py -v`
241
- Expected: PASS (์‹ ๊ทœ 2๊ฐœ + ๊ธฐ์กด ์ „๋ถ€).
242
-
243
- - [ ] **Step 5: ์ปค๋ฐ‹**
244
-
245
- ```bash
246
- git add scripts/okstra_ctl/run.py tests/test_okstra_run_select_and_apply_implementation_stage.py
247
- git commit -m "feat(okstra-ctl): ๋™์‹œ active stage ๋ฅผ StageSelection.concurrent_stages ๋กœ ๊ฐ์ง€ยทwire"
248
- ```
249
-
250
- ---
251
-
252
- ## Task 3: run โ€” `extras.concurrent_run` ์ „ํŒŒ
253
-
254
- **Files:**
255
- - Modify: `scripts/okstra_ctl/run.py:2005-2009` (`prepare_task_bundle` ์˜ `return PrepareOutputs(...)`)
256
-
257
- ์ง„์ž…์ (์Šคํ‚ฌ / okstra.sh)์ด ๋™์‹œ-run ์—ฌ๋ถ€๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก `extras` ์— ์‹ฃ๋Š”๋‹ค. ์ „์ฒด ์‚ฌ์ดํด ๊ฒ€์ฆ์€ Task 6 e2e ๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค.
258
-
259
- - [ ] **Step 1: `return PrepareOutputs(...)` ์ˆ˜์ •** โ€” ํ˜„์žฌ:
260
-
261
- ```python
262
- return PrepareOutputs(
263
- ctx=ctx,
264
- prompt_text=prompt_text,
265
- extras={"profile_content": profile_content},
266
- )
267
- ```
268
-
269
- ๋ฅผ ๋‹ค์Œ์œผ๋กœ:
270
-
271
- ```python
272
- concurrent_run: dict = {}
273
- if impl_stage_selection is not None and impl_stage_selection.concurrent_stages:
274
- concurrent_run = {
275
- "detected": True,
276
- "active_stages": impl_stage_selection.concurrent_stages,
277
- }
278
- return PrepareOutputs(
279
- ctx=ctx,
280
- prompt_text=prompt_text,
281
- extras={
282
- "profile_content": profile_content,
283
- "concurrent_run": concurrent_run,
284
- },
285
- )
286
- ```
287
-
288
- > `impl_stage_selection` ์€ ํ˜„ 1825/1831 ์—์„œ ์ •์˜๋ผ ์ด ์ง€์ ๊นŒ์ง€ ์œ ํšจํ•˜๋‹ค(implementation ์™ธ task-type ์€ `None`).
289
-
290
- - [ ] **Step 2: import ํšŒ๊ท€ ํ™•์ธ** (๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์—†์Œ โ€” ์ฝ”๋“œ ๋‹จ์ˆœ, Task 6 e2e ๊ฐ€ ์‹ค์ธก)
291
-
292
- Run: `python3 -c "import sys; sys.path.insert(0,'scripts'); from okstra_ctl.run import prepare_task_bundle; print('ok')"`
293
- Expected: `ok`
294
-
295
- - [ ] **Step 3: ์ปค๋ฐ‹**
296
-
297
- ```bash
298
- git add scripts/okstra_ctl/run.py
299
- git commit -m "feat(okstra-ctl): PrepareOutputs.extras ๋กœ concurrent_run ๋…ธ์ถœ"
300
- ```
301
-
302
- ---
303
-
304
- ## Task 4: ํ”„๋กฌํ”„ํŠธ/agent ๊ณ„์•ฝ โ€” no-team ์˜ ์ƒˆ legal ์‚ฌ์œ 
305
-
306
- **Files:**
307
- - Modify: `agents/SKILL.md:231`
308
- - Modify: `prompts/profiles/_common-contract.md:53`
309
-
310
- ํ˜„์žฌ no-`team_name` fallback ์€ `teamCreate.status == "error"` ์ผ ๋•Œ๋งŒ legal ์ด๋‹ค. ๋™์‹œ-run ์‚ฌ์ „ skip ์„ legal ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค.
311
-
312
- - [ ] **Step 1: `agents/SKILL.md:231` ์ˆ˜์ •** โ€” ํ˜„์žฌ ๋ฌธ์žฅ:
313
-
314
- > The no-`team_name` fallback (Phase 5) is only legal when team-state's `teamCreate.status` is `"error"` for this run.
315
-
316
- ๋ฅผ ๋‹ค์Œ์œผ๋กœ:
317
-
318
- > The no-`team_name` fallback (Phase 5) is legal when team-state's `teamCreate.status` is `"error"` (TeamCreate attempted and failed) OR `"skipped"` with `reason: "concurrent-run"` (the launch prompt's "Concurrent-run: no-team background" gate pre-decided no team to avoid racing a concurrent same-task run's `~/.claude/teams/` config). In both cases `teamCreate` is recorded in team-state before any dispatch.
319
-
320
- - [ ] **Step 2: `_common-contract.md:53` ์ˆ˜์ •** โ€” ํ˜„์žฌ ๋ฌธ์žฅ:
321
-
322
- > This step applies only when team-state's `teamCreate.status == "ok"` (Teams mode was actually used). In the no-`team_name` fallback there is no team to delete, so silent-skip.
323
-
324
- ๋ฅผ ๋‹ค์Œ์œผ๋กœ:
325
-
326
- > This step applies only when team-state's `teamCreate.status == "ok"` (Teams mode was actually used). In the no-`team_name` fallback โ€” whether `teamCreate.status` is `"error"` or `"skipped"` (`reason: "concurrent-run"`) โ€” there is no team to delete, so silent-skip.
327
-
328
- - [ ] **Step 3: grep ๊ฒ€์ฆ**
329
-
330
- Run: `grep -n 'concurrent-run' agents/SKILL.md prompts/profiles/_common-contract.md`
331
- Expected: ๋‘ ํŒŒ์ผ ๊ฐ๊ฐ ์ตœ์†Œ 1์ค„ ๋งค์นญ.
332
-
333
- - [ ] **Step 4: ์ปค๋ฐ‹**
334
-
335
- ```bash
336
- git add agents/SKILL.md prompts/profiles/_common-contract.md
337
- git commit -m "docs(agents): no-team fallback ์— concurrent-run skipped legal ์‚ฌ์œ  ์ถ”๊ฐ€"
338
- ```
339
-
340
- ---
341
-
342
- ## Task 5: okstra-run ์Šคํ‚ฌ โ€” ๋Œ€ํ™”ํ˜• 3-์˜ต์…˜ picker
343
-
344
- **Files:**
345
- - Modify: `skills/okstra-run/SKILL.md` (conformance-waiver picker ์„น์…˜, ํ˜„ 192 ๋ถ€๊ทผ ๊ทผ์ฒ˜์— ๋™ํ˜• ์„น์…˜ ์ถ”๊ฐ€)
346
-
347
- - [ ] **Step 1: ์„น์…˜ ์ถ”๊ฐ€** โ€” conformance-waiver picker ์„ค๋ช… ๋ธ”๋ก๊ณผ ๊ฐ™์€ ํŒจํ„ด์œผ๋กœ, prepare ํ˜ธ์ถœ ๊ฒฐ๊ณผ์—์„œ `extras.concurrent_run.detected == true` ์ผ ๋•Œ์˜ ๋ถ„๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ณธ๋ฌธ:
348
-
349
- ```markdown
350
- ### ๋™์‹œ-run ๊ฐ์ง€ ๋ถ„๊ธฐ (concurrent-run)
351
-
352
- `prepare_task_bundle` ๊ฒฐ๊ณผ์˜ `extras.concurrent_run.detected` ๊ฐ€ `true` ์ด๋ฉด(๊ฐ™์€
353
- task-key ์˜ ๋‹ค๋ฅธ implementation run ์ด `extras.concurrent_run.active_stages` ๋ฅผ
354
- ์ ์œ  ์ค‘), launch ํ”„๋กฌํ”„ํŠธ๋Š” ์ด๋ฏธ "Concurrent-run: no-team background" ๊ฒŒ์ดํŠธ๋กœ
355
- ๋ Œ๋”๋ผ ์žˆ๋‹ค. dispatch ์ „์— ์‚ฌ์šฉ์ž์—๊ฒŒ 3-์˜ต์…˜ recommendation picker ๋ฅผ ์ œ์‹œํ•œ๋‹ค
356
- (run-prompt recommendation ๊ทœ์น™: 1โ€“2 ์ถ”์ฒœ + ์ง์ ‘ ์ž…๋ ฅ; ์ด picker ๋Š” ์Šคํ‚ฌ์ด
357
- author ํ•˜๋Š” ๊ฒƒ์ด๋ผ wizard `options[]` ์ œ์•ฝ๊ณผ ๋ฌด๊ด€):
358
-
359
- 1. (์ถ”์ฒœ) ์ด๋Œ€๋กœ no-team background ๋กœ ์ง„ํ–‰ โ€” ์ด๋ฏธ ๋ Œ๋”๋œ bundle ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
360
- team ์„ ๋งŒ๋“ค์ง€ ์•Š์•„ `~/.claude/teams/` race ๋ฅผ ํšŒํ”ผํ•œ๋‹ค(Teams split-pane ๊ด€์ฐฐ์„ฑ๋งŒ ํฌ๊ธฐ).
361
- 2. ๋Œ€๊ธฐ โ€” ์ง€๊ธˆ dispatch ๋ฅผ ๋ณด๋ฅ˜ํ•œ๋‹ค. stage worktreeยทrun-context ๋Š” ๋ณด์กด๋˜๋ฏ€๋กœ,
362
- ์ ์œ  ์ค‘์ธ ๋‹ค๋ฅธ run ์ข…๋ฃŒ ํ›„ ๊ฐ™์€ stage ๋ฅผ resume ์œผ๋กœ ์žฌ๊ฐœํ•˜๋ฉด ๊ทธ๋•Œ๋Š” ์ •์ƒ team
363
- ๊ฒฝ๋กœ๋‹ค. resume ๋ช…๋ น(`okstra-inspect` history โ†’ resume)์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ถœ๋ ฅํ•œ๋‹ค.
364
- 3. ์ง์ ‘ ์ž…๋ ฅ.
365
- ```
366
-
367
- > ์œ„์น˜: conformance-waiver picker ์„ค๋ช…([skills/okstra-run/SKILL.md](../../../skills/okstra-run/SKILL.md) ์˜ "Conformance waiver" ์„น์…˜) ๋ฐ”๋กœ ๋‹ค์Œ. ๊ฐ™์€ "์Šคํ‚ฌ์ด author ํ•˜๋Š” picker" ๋ถ€๋ฅ˜์ด๋ฏ€๋กœ ์ธ์ ‘ ๋ฐฐ์น˜ํ•œ๋‹ค.
368
-
369
- - [ ] **Step 2: grep ๊ฒ€์ฆ**
370
-
371
- Run: `grep -n 'concurrent-run\|no-team background\|๋™์‹œ-run' skills/okstra-run/SKILL.md`
372
- Expected: ์ตœ์†Œ 1์ค„ ๋งค์นญ.
373
-
374
- - [ ] **Step 3: ์ปค๋ฐ‹**
375
-
376
- ```bash
377
- git add skills/okstra-run/SKILL.md
378
- git commit -m "feat(skills/okstra-run): ๋™์‹œ-run ์‹œ no-team/๋Œ€๊ธฐ 3-์˜ต์…˜ picker ์ถ”๊ฐ€"
379
- ```
380
-
381
- ---
382
-
383
- ## Task 6: e2e ์‹œ๋‚˜๋ฆฌ์˜ค โ€” extras ์ „ํŒŒ + no-team ๋ธ”๋ก
384
-
385
- **Files:**
386
- - Create: `tests-e2e/scenario-<๋‹ค์Œ๋ฒˆํ˜ธ>-concurrent-run-no-team.sh`
387
-
388
- ๊ธฐ์กด ์‹œ๋‚˜๋ฆฌ์˜ค ๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ด ๋‹ค์Œ ๋ฒˆํ˜ธ๋ฅผ ์“ด๋‹ค: `ls tests-e2e/ | grep -oE 'scenario-[0-9]+' | sort -u | tail -1`.
389
-
390
- - [ ] **Step 1: ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ** โ€” ๊ธฐ์กด ์‹œ๋‚˜๋ฆฌ์˜ค ๊ณจ๊ฒฉ(`mktemp -d` ๋กœ `OKSTRA_HOME`, `trap` EXIT ์ •๋ฆฌ)์„ ๋”ฐ๋ฅธ๋‹ค. ํ•ต์‹ฌ ๋‹จ๊ณ„:
391
- 1. ์ž„์‹œ git repo + `.okstra/project.json` ์…‹์—…, implementation plan(stage 4ยท6) ์ค€๋น„.
392
- 2. registry ์— stage 6 ์„ active ๋กœ reserve(๋‹ค๋ฅธ run ์ ์œ  ์‹œ๋ฎฌ๋ ˆ์ด์…˜).
393
- 3. `prepare_task_bundle`(๋˜๋Š” `okstra.sh --task-type implementation --stage auto`)๋กœ stage 4 run ์„ prepare.
394
- 4. ๊ฒ€์ฆ: ๋ Œ๋”๋œ launch ํ”„๋กฌํ”„ํŠธ์— `"Concurrent-run: no-team background"` ํฌํ•จ + `'TeamCreate(team_name:'` **๋ฏธํฌํ•จ**.
395
- 5. ๊ฒ€์ฆ: prepare ์˜ `extras.concurrent_run.detected == true`, `active_stages == [6]`.
396
-
397
- ```bash
398
- #!/usr/bin/env bash
399
- set -euo pipefail
400
- OKSTRA_HOME="$(mktemp -d)"; export OKSTRA_HOME
401
- trap 'rm -rf "$OKSTRA_HOME"' EXIT
402
- # ... repo/project/plan ์…‹์—… (๊ธฐ์กด scenario-01 ํŒจํ„ด ์ฐธ์กฐ) ...
403
- # ... reg.reserve(stage_number=6) ...
404
- # ... prepare ํ˜ธ์ถœ ํ›„ launch ํ”„๋กฌํ”„ํŠธ grep "Concurrent-run: no-team background" ...
405
- echo "PASS: concurrent-run no-team scenario"
406
- ```
407
-
408
- - [ ] **Step 2: ์‹คํ–‰**
409
-
410
- Run: `bash tests-e2e/scenario-<๋ฒˆํ˜ธ>-concurrent-run-no-team.sh`
411
- Expected: `PASS: concurrent-run no-team scenario`
412
-
413
- - [ ] **Step 3: ์ปค๋ฐ‹**
414
-
415
- ```bash
416
- git add tests-e2e/scenario-<๋ฒˆํ˜ธ>-concurrent-run-no-team.sh
417
- git commit -m "test(e2e): ๋™์‹œ-run no-team background ์‹œ๋‚˜๋ฆฌ์˜ค ์ถ”๊ฐ€"
418
- ```
419
-
420
- ---
421
-
422
- ## Task 7: build + ์ „์ฒด ํšŒ๊ท€
423
-
424
- **Files:**
425
- - Modify: `runtime/**` (build output โ€” ์ง์ ‘ ํŽธ์ง‘ ์•„๋‹˜, `npm run build` ์‚ฐ์ถœ)
426
-
427
- - [ ] **Step 1: build**
428
-
429
- Run: `npm run build`
430
- Expected: ์—๋Ÿฌ ์—†์ด `scripts/`ยท`prompts/`ยท`agents/`ยท`skills/` ๊ฐ€ `runtime/` ๋กœ ๋™๊ธฐํ™”.
431
-
432
- - [ ] **Step 2: ์ „์ฒด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ**
433
-
434
- Run: `python3 -m pytest tests/ -q`
435
- Expected: ์ „๋ถ€ PASS (์‹ ๊ทœ ํฌํ•จ, ํšŒ๊ท€ ์—†์Œ).
436
-
437
- - [ ] **Step 3: phase contract validator**
438
-
439
- Run: `bash validators/validate-workflow.sh`
440
- Expected: PASS.
441
-
442
- - [ ] **Step 4: ์ปค๋ฐ‹**
443
-
444
- ```bash
445
- git add runtime/
446
- git commit -m "chore(build): ๋™์‹œ-run team ๊ฐ€๋“œ runtime ๋™๊ธฐํ™”"
447
- ```
448
-
449
- ---
450
-
451
- ## Self-Review (์ž‘์„ฑ์ž ์ฒดํฌ ์™„๋ฃŒ)
452
-
453
- - **Spec ์ปค๋ฒ„๋ฆฌ์ง€:** ยง4.1 ๊ฐ์ง€โ†’Task 2, ยง4.2 no-team ๋ Œ๋”โ†’Task 1, ยง4.3 ๋Œ€ํ™”ํ˜• pickerโ†’Task 5, ยง4.4 ๋น„๋Œ€ํ™”ํ˜• ๊ธฐ๋ณธ๊ฐ’โ†’Task 1+3(๋ Œ๋”๊ฐ€ ์ž๋™ no-team, ์ง„์ž…์  ๋ถ„๊ธฐ ์—†์Œ), ยง4.5 ๋‹จ์ผ ์ˆ˜๋ ด์ โ†’Task 3(`prepare_task_bundle` ํ•œ ๊ณณ), ยง4.6 legal ์‚ฌ์œ โ†’Task 4, ยง7 ํ…Œ์ŠคํŠธโ†’Task 1ยท2ยท6. ๋ˆ„๋ฝ ์—†์Œ.
454
- - **๋น„๋Œ€ํ™”ํ˜•(ยง4.4)** ์€ ๋ณ„๋„ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ "picker ๋ฅผ ์•ˆ ๋„์šฐ๋ฉด ๋ Œ๋”๋œ no-team bundle ๊ทธ๋Œ€๋กœ ์ง„ํ–‰"์œผ๋กœ ์ž๋™ ์ถฉ์กฑ๋จ โ€” ์ถ”๊ฐ€ Task ๋ถˆํ•„์š”.
455
- - **ํƒ€์ž… ์ผ๊ด€์„ฑ:** `concurrent_stages` ๋Š” `list[int]`(Task 2) โ†’ ctx ์—์„œ csv `str`(Task 2 wire) โ†’ render ๊ฐ€ `str` ์œผ๋กœ ์ฝ์Œ(Task 1) โ†’ `extras.active_stages` ๋Š” `list[int]`(Task 3). ๊ฒฝ๊ณ„๋งˆ๋‹ค ํ˜• ๋ณ€ํ™˜ ๋ช…์‹œ.
456
- - **Placeholder:** ์—†์Œ(์‹œ๋‚˜๋ฆฌ์˜ค ๋ฒˆํ˜ธ๋งŒ ์‹คํ–‰ ์‹œ ํ™•์ • โ€” Task 6 Step 0 ์— ์กฐํšŒ ๋ช…๋ น ์ œ๊ณต).