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,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 ์— ์กฐํšŒ ๋ช…๋ น ์ œ๊ณต).