okstra 0.102.2 โ†’ 0.102.3

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