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
package/README.kr.md CHANGED
@@ -76,7 +76,7 @@ okstra/ npm 패키지 = repo 루트
76
76
  └── .locks/ central/task mutex 파일
77
77
 
78
78
  ~/.claude/skills/ Claude Code 가 자동 인식 (`~/.claude` 가 있을 때)
79
- ~/.agent/skills/ Agent 호환 host 가 인식 (`install` 이 생성)
79
+ ~/.agents/skills/ Agent 호환 host 가 인식 (`install` 이 생성)
80
80
  └── okstra-*/SKILL.md 사용자 노출 스킬 7종만 (setup/brief/run/memory/inspect/schedule/container)
81
81
 
82
82
  ~/.claude/agents/ Claude Code 가 자동 인식 (`~/.claude` 가 있을 때)
@@ -97,7 +97,7 @@ okstra/ npm 패키지 = repo 루트
97
97
  |---|---|---|
98
98
  | 런타임 코드 (python + bash) | `~/.okstra/{lib/python, bin}` | `okstra install` |
99
99
  | agents/prompts/schemas/templates/validators | npm 패키지의 `runtime/` | `okstra` 패키지 자체 (`okstra paths` 로 해석) |
100
- | 스킬 마크다운 | `~/.claude/skills` 또는 `~/.agent/skills` | `okstra install` (`installed-skills.json` 에 target별 트래킹) |
100
+ | 스킬 마크다운 | `~/.claude/skills` 또는 `~/.agents/skills` | `okstra install` (`installed-skills.json` 에 target별 트래킹) |
101
101
  | 워커 에이전트 마크다운 | `~/.claude/agents/<worker>.md` | `~/.claude` 가 있을 때 `okstra install` (`installed-agents.json` 에 트래킹) |
102
102
  | 프로젝트 메타데이터 | `<project>/.okstra/` | `/okstra-setup` + 프로젝트 자체 |
103
103
  | Run 인덱스 | `~/.okstra/{recent,active}.jsonl` | `prepare_task_bundle` |
@@ -110,7 +110,7 @@ okstra/ npm 패키지 = repo 루트
110
110
  npx -y okstra@latest install
111
111
  ```
112
112
 
113
- `~/.okstra/{lib/python, bin, templates, prompts, version}` 과 `~/.okstra/` 의 설치 asset manifest 를 생성합니다. 스킬 설치는 host home 기준입니다. `~/.claude` 가 있으면 public skill 을 `~/.claude/skills/` 에, worker agent 를 `~/.claude/agents/` 에 설치하고, `~/.agent/skills/` 는 항상 생성해 Agent 호환 host 용 public skill 을 설치합니다. 사용자 진입점 스킬만 목록에 보이고, lead/support 운영 계약은 `~/.okstra/prompts/` 아래 runtime resource 로 설치되어 skill discovery 대상이 아닙니다. 재실행은 idempotent — 파일별 hash 를 비교하고 바뀐 파일만 갱신합니다.
113
+ `~/.okstra/{lib/python, bin, templates, prompts, version}` 과 `~/.okstra/` 의 설치 asset manifest 를 생성합니다. 스킬 설치는 host home 기준입니다. `~/.claude` 가 있으면 public skill 을 `~/.claude/skills/` 에, worker agent 를 `~/.claude/agents/` 에 설치하고, `~/.agents/skills/` 는 항상 생성해 Agent 호환 host 용 public skill 을 설치합니다. 사용자 진입점 스킬만 목록에 보이고, lead/support 운영 계약은 `~/.okstra/prompts/` 아래 runtime resource 로 설치되어 skill discovery 대상이 아닙니다. 재실행은 idempotent — 파일별 hash 를 비교하고 바뀐 파일만 갱신합니다.
114
114
 
115
115
  검증:
116
116
 
@@ -130,7 +130,7 @@ okstra --version # CLI 가 PATH 에 잡혔는지 확인
130
130
  okstra install # 'npx -y okstra@latest install' 과 동일
131
131
  ```
132
132
 
133
- 글로벌 설치는 Node CLI 를 PATH 에 등록할 뿐입니다. 런타임(`~/.okstra/`) 과 host skill directory(`~/.claude/skills/` 또는 `~/.agent/skills/`) 는 여전히 `okstra install` 이 생성합니다 — `npm i -g` 에 포함되지 않습니다. 이후 업그레이드: `npm i -g okstra@latest && okstra install`. 글로벌 바이너리 제거: `npm uninstall -g okstra` (`~/.okstra/` 는 그대로; 그것까지 지우려면 `okstra uninstall`).
133
+ 글로벌 설치는 Node CLI 를 PATH 에 등록할 뿐입니다. 런타임(`~/.okstra/`) 과 host skill directory(`~/.claude/skills/` 또는 `~/.agents/skills/`) 는 여전히 `okstra install` 이 생성합니다 — `npm i -g` 에 포함되지 않습니다. 이후 업그레이드: `npm i -g okstra@latest && okstra install`. 글로벌 바이너리 제거: `npm uninstall -g okstra` (`~/.okstra/` 는 그대로; 그것까지 지우려면 `okstra uninstall`).
134
134
 
135
135
  **글로벌 설치 시 스킬 동작.** 모든 okstra 스킬은 PATH 에 잡힌 `okstra` 를 자동 감지하여 `npx -y okstra@latest` 대신 우선 사용합니다. 즉 글로벌 설치를 해두면 매 스킬 호출(`okstra-run`, `okstra-inspect`, `okstra-schedule`, `okstra-setup` Step 2 의 Step 0) 마다 npx 가 패키지 fetch / 버전 체크하던 비용이 사라집니다. 스킬이 본인이 설치한 버전을 그대로 쓰므로 **업그레이드 타이밍은 사용자가 통제** 합니다 — 더 이상 호출마다 `@latest` 가 강제되지 않습니다. 새 릴리스를 받으려면 원하는 시점에 `npm i -g okstra@latest && okstra install` 을 실행하세요. `okstra` 가 PATH 에 없으면 스킬은 자동으로 npx fallback 으로 동작하므로 글로벌 설치가 없는 환경에서도 변경 없이 그대로 동작합니다.
136
136
 
@@ -191,7 +191,7 @@ Claude Code 세션 밖에서 task 를 시작하려면:
191
191
 
192
192
  0.8.0 이후 `main` 에 추가된 workflow 변경:
193
193
 
194
- - **모든 task-type 격리 worktree 자동 provisioning** — prepare 단계에서 `okstra-ctl` 이 task-key 당 한 번 `git worktree add ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>` 를 수행해 격리된 working tree 와 브랜치 `<work-category-prefix>-<task-id-segment>` (예: `feat-dev-9436`, `fix-dev-7311`) 를 만듭니다. base ref 는 사용자가 `--base-ref` 로 지정 (release-handoff PR base picker 와 동일한 메뉴: `main` / `dev` / `staging` / `preprod` / `prod` / 직접 입력). 첫 phase 에서는 필수이며, okstra-run skill 이 `AskUserQuestion` 으로 수집합니다 — 비대화형 호출자는 `--base-ref` 플래그를 직접 전달해야 prepare 가 통과합니다. 같은 task-key 의 후속 **비-`implementation`** phase(`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`)는 같은 path/branch를 재사용합니다. 반면 `implementation` run 은 **stage 격리** 로 동작합니다 — 각 run 이 자신의 `.../<task>/stage-<N>/` worktree(브랜치 `<prefix>-<task>-s<N>`)에서 한 stage 만 실행하므로, 독립(`depends-on (none)`) stage 를 별도 run 으로 **동시에 병렬 구현** 할 수 있습니다(트리 공유 없음). registry 는 task-key 와 **stage-key** 를 함께 flock 예약합니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 됩니다(stage 격리도 평면 경로로 degrade). 수동 cleanup: `git worktree remove <path>` → `git branch -D <branch>` + registry 항목 release/remove. 상세: [`docs/kr/architecture.md`](docs/kr/architecture.md) *Task type* 섹션, [`docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md`](docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md), [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
194
+ - **모든 task-type 격리 worktree 자동 provisioning** — prepare 단계에서 `okstra-ctl` 이 task-key 당 한 번 `git worktree add ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>` 를 수행해 격리된 working tree 와 브랜치 `<work-category-prefix>-<task-id-segment>` (예: `feat-dev-9436`, `fix-dev-7311`) 를 만듭니다. base ref 는 사용자가 `--base-ref` 로 지정 (release-handoff PR base picker 와 동일한 메뉴: `main` / `dev` / `staging` / `preprod` / `prod` / 직접 입력). 첫 phase 에서는 필수이며, okstra-run skill 이 `AskUserQuestion` 으로 수집합니다 — 비대화형 호출자는 `--base-ref` 플래그를 직접 전달해야 prepare 가 통과합니다. 같은 task-key 의 후속 **비-`implementation`** phase(`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`)는 같은 path/branch를 재사용합니다. 반면 `implementation` run 은 **stage 격리** 로 동작합니다 — 각 run 이 자신의 `.../<task>/stage-<N>/` worktree(브랜치 `<prefix>-<task>-s<N>`)에서 한 stage 만 실행하므로, 독립(`depends-on (none)`) stage 를 별도 run 으로 **동시에 병렬 구현** 할 수 있습니다(트리 공유 없음). registry 는 task-key 와 **stage-key** 를 함께 flock 예약합니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 됩니다(stage 격리도 평면 경로로 degrade). 수동 cleanup: `git worktree remove <path>` → `git branch -D <branch>` + registry 항목 release/remove. 상세: [`docs/kr/architecture.md`](docs/kr/architecture.md) *Task type* 섹션, [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
195
195
  - **`release-handoff` lifecycle phase** — `final-verification` 이 `verdict=accepted` 를 반환한 직후에 실행되는 신규 phase. lead 가 Claude worker (drafter) 를 통해 commit message · PR body 후보를 만들고, `AskUserQuestion` 으로 사용자에게 (1) action (`commit only` / `commit + PR` / `skip`), (2) PR base branch (`staging` / `preprod` / `prod` / `main` / `dev` / 직접 입력), (3) message handling (`use as-is` / `edit then proceed` / `cancel`) 세 가지를 순서대로 묻습니다. 사용자가 메뉴로 선택한 git / gh 명령만 실행되고, force-push, base 브랜치 직접 push, hook bypass (`--no-verify`), release publish (`gh release`, `npm publish`, ...) 는 금지됩니다. 이 phase 에서는 소스 코드를 수정하지 않습니다. profile: [`prompts/profiles/release-handoff.md`](prompts/profiles/release-handoff.md).
196
196
  - **PR 본문 템플릿 설정** (release-handoff) — PR 본문은 마크다운 템플릿에서 채워집니다. 해석 우선순위: 1회성 override (`--pr-template-path` 또는 okstra-run Step 6 prompt) → `<project_root>/.okstra/project.json` 의 `prTemplatePath` → `~/.okstra/config.json` 의 `prTemplatePath` → 스킬 디폴트 `~/.claude/skills/templates/prd/pr-body.template.md`. 템플릿 등록 명령: `okstra config set pr-template-path <path> [--scope project|global]` (project 스코프는 project root 기준 상대경로 허용, global 스코프는 절대경로 또는 `~/` 시작 경로만 허용). 현재 설정 확인: `okstra config get pr-template-path --scope all` 은 각 스코프 값 + 실제로 우승하는 경로(effective) 까지 보여줍니다. 디폴트 템플릿은 `## Summary` / `## Changes` / `## Test plan` / `## Linked issues` 4 섹션 + HTML 주석으로 lead 작성 가이드를 포함하며, PR 생성 직전에 lead 가 주석을 제거합니다.
197
197
  - **프로파일 워커 로스터 검증** — `--workers <csv>` 와 okstra-run Step 6 의 워커 prompt 는 해당 프로파일의 `Required workers:` 블록에 선언된 워커 ID 만 허용합니다. 프로파일에 없는 워커 (예: `release-handoff` 에서 `codex` / `antigravity`) 를 요청하면 명확한 에러로 거절되고, 인터랙티브 prompt 도 프로파일이 실제로 받는 워커만 보여줍니다.
package/README.md CHANGED
@@ -74,7 +74,7 @@ okstra/ npm package = repo root
74
74
  └── .locks/ central/task mutex files
75
75
 
76
76
  ~/.claude/skills/ discovered automatically by Claude Code (if ~/.claude exists)
77
- ~/.agent/skills/ discovered by Agent-compatible hosts (created by install)
77
+ ~/.agents/skills/ discovered by Agent-compatible hosts (created by install)
78
78
  └── okstra-*/SKILL.md user-facing skills only (setup/brief/run/memory/inspect/schedule/container)
79
79
 
80
80
  ~/.claude/agents/ discovered automatically by Claude Code (if ~/.claude exists)
@@ -95,7 +95,7 @@ okstra/ npm package = repo root
95
95
  |---|---|---|
96
96
  | Runtime code (python + bash) | `~/.okstra/{lib/python, bin}` | `okstra install` |
97
97
  | agents/prompts/schemas/templates/validators | npm package's `runtime/` | the `okstra` package (resolved via `okstra paths`) |
98
- | Skill markdown | `~/.claude/skills` or `~/.agent/skills` | `okstra install` (tracked per target in `installed-skills.json`) |
98
+ | Skill markdown | `~/.claude/skills` or `~/.agents/skills` | `okstra install` (tracked per target in `installed-skills.json`) |
99
99
  | Worker agent markdown | `~/.claude/agents/<worker>.md` | `okstra install` when `~/.claude` exists (tracked in `installed-agents.json`) |
100
100
  | Project metadata | `<project>/.okstra/` | `/okstra-setup` + the project itself |
101
101
  | Run index | `~/.okstra/{recent,active}.jsonl` | `prepare_task_bundle` |
@@ -108,7 +108,7 @@ okstra/ npm package = repo root
108
108
  npx -y okstra@latest install
109
109
  ```
110
110
 
111
- Provisions `~/.okstra/{lib/python, bin, templates, prompts, version}` and the installed-asset manifests in `~/.okstra/`. Skill installation is host-home driven: if `~/.claude` exists, okstra copies public skills to `~/.claude/skills/` and worker agents to `~/.claude/agents/`; it always creates `~/.agent/skills/` and copies public skills there for Agent-compatible hosts. Lead/support contracts ship as runtime resources under `~/.okstra/prompts/` and are not agent skills. Re-running is idempotent — per-file hashes are compared and only changed files are touched.
111
+ Provisions `~/.okstra/{lib/python, bin, templates, prompts, version}` and the installed-asset manifests in `~/.okstra/`. Skill installation is host-home driven: if `~/.claude` exists, okstra copies public skills to `~/.claude/skills/` and worker agents to `~/.claude/agents/`; it always creates `~/.agents/skills/` and copies public skills there for Agent-compatible hosts. Lead/support contracts ship as runtime resources under `~/.okstra/prompts/` and are not agent skills. Re-running is idempotent — per-file hashes are compared and only changed files are touched.
112
112
 
113
113
  Verify:
114
114
 
@@ -128,7 +128,7 @@ okstra --version # confirm the CLI is on PATH
128
128
  okstra install # same as 'npx -y okstra@latest install'
129
129
  ```
130
130
 
131
- The global install only registers the Node CLI on your PATH. The runtime (`~/.okstra/`) and host skill directories (`~/.claude/skills/` or `~/.agent/skills/`) are still provisioned by `okstra install` — they are not part of `npm i -g`. To upgrade later: `npm i -g okstra@latest && okstra install`. To remove the global binary: `npm uninstall -g okstra` (leaves `~/.okstra/` untouched; remove that with `okstra uninstall`).
131
+ The global install only registers the Node CLI on your PATH. The runtime (`~/.okstra/`) and host skill directories (`~/.claude/skills/` or `~/.agents/skills/`) are still provisioned by `okstra install` — they are not part of `npm i -g`. To upgrade later: `npm i -g okstra@latest && okstra install`. To remove the global binary: `npm uninstall -g okstra` (leaves `~/.okstra/` untouched; remove that with `okstra uninstall`).
132
132
 
133
133
  **Skill behaviour with a global install.** All okstra skills auto-detect a PATH-resolved `okstra` and prefer it over `npx -y okstra@latest`. That means a global install removes the per-call npx fetch / version-check from every skill invocation (Step 0 of `okstra-run`, `okstra-inspect`, `okstra-schedule`, `okstra-setup` Step 2). Since the skill uses your globally installed version directly, *you* control upgrade timing — `@latest` is no longer forced on each call. Run `npm i -g okstra@latest && okstra install` whenever you want to pull a new release. If `okstra` is not on PATH the skill silently falls back to npx, so machines without a global install keep working unchanged.
134
134
 
@@ -189,7 +189,7 @@ Notable flags added in 0.7.0 / 0.8.0:
189
189
 
190
190
  Recent workflow additions (post-0.8.0, on `main`):
191
191
 
192
- - **Isolated task worktree for every task-type** — prepare automatically runs `git worktree add ~/.okstra/worktrees/<project>/<group>/<task>/` on a fresh branch `<work-category-prefix>-<task-id-segment>` branched from the **user-chosen base ref** (`--base-ref`, mirroring the `release-handoff` PR-base picker: `main` / `dev` / `staging` / `preprod` / `prod` / any local ref) the first time a task-key is seen. `--base-ref` is required on first phase; the okstra-run skill collects it via `AskUserQuestion`, non-interactive callers must pass the flag explicitly. Every subsequent **non-`implementation`** phase of the same task-key (`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`) reuses the same path and branch, so phase N inherits the working-tree state phase N-1 left behind. `implementation` runs are **stage-isolated** instead — each run owns exactly one stage in its own `.../<task>/stage-<N>/` worktree on branch `<prefix>-<task>-s<N>`, so independent (`depends-on (none)`) stages can be implemented in parallel across simultaneous runs without sharing a tree. A global registry at `~/.okstra/worktrees/registry.json` (flock-guarded) reserves task-keys **and stage-keys** across concurrent runs; all path/branch segments are sanitised (`/`, `:`, etc. → `-`). The worktree is preserved after every run for follow-up phases, PR authoring, and rollback. Skip paths: when the caller is already inside another worktree or `project_root` is not a git repo, provisioning no-ops (stage isolation degrades to the flat path too). Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` plus releasing/removing the key from the registry. Details: [`docs/kr/architecture.md`](docs/kr/architecture.md) (*Task type* section), [`docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md`](docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md), and [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
192
+ - **Isolated task worktree for every task-type** — prepare automatically runs `git worktree add ~/.okstra/worktrees/<project>/<group>/<task>/` on a fresh branch `<work-category-prefix>-<task-id-segment>` branched from the **user-chosen base ref** (`--base-ref`, mirroring the `release-handoff` PR-base picker: `main` / `dev` / `staging` / `preprod` / `prod` / any local ref) the first time a task-key is seen. `--base-ref` is required on first phase; the okstra-run skill collects it via `AskUserQuestion`, non-interactive callers must pass the flag explicitly. Every subsequent **non-`implementation`** phase of the same task-key (`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`) reuses the same path and branch, so phase N inherits the working-tree state phase N-1 left behind. `implementation` runs are **stage-isolated** instead — each run owns exactly one stage in its own `.../<task>/stage-<N>/` worktree on branch `<prefix>-<task>-s<N>`, so independent (`depends-on (none)`) stages can be implemented in parallel across simultaneous runs without sharing a tree. A global registry at `~/.okstra/worktrees/registry.json` (flock-guarded) reserves task-keys **and stage-keys** across concurrent runs; all path/branch segments are sanitised (`/`, `:`, etc. → `-`). The worktree is preserved after every run for follow-up phases, PR authoring, and rollback. Skip paths: when the caller is already inside another worktree or `project_root` is not a git repo, provisioning no-ops (stage isolation degrades to the flat path too). Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` plus releasing/removing the key from the registry. Details: [`docs/kr/architecture.md`](docs/kr/architecture.md) (*Task type* section) and [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
193
193
  - **`release-handoff` lifecycle phase** — runs after `final-verification` returns `verdict=accepted`. The lead drafts a commit message and PR body via a Claude worker, then prompts the user with `AskUserQuestion` for three choices: action (`commit only` / `commit + PR` / `skip`), PR base branch (`staging` / `preprod` / `prod` / `main` / `dev` / free-form), and message handling (`use as-is` / `edit then proceed` / `cancel`). Only user-selected mutating git/gh commands run. Force-push, base-branch direct push, hook bypass (`--no-verify`), and release publishing (`gh release`, `npm publish`, ...) are forbidden. Source code is not edited in this phase. Profile: [`prompts/profiles/release-handoff.md`](prompts/profiles/release-handoff.md).
194
194
  - **Configurable PR body template** (release-handoff) — the PR body is filled from a markdown template chosen in priority order: per-run override (`--pr-template-path` or the okstra-run Step 6 prompt) → `<project_root>/.okstra/project.json` `prTemplatePath` → `~/.okstra/config.json` `prTemplatePath` → bundled skill default at `~/.claude/skills/templates/prd/pr-body.template.md`. Register a template with `okstra config set pr-template-path <path> [--scope project|global]` (project scope accepts paths relative to the project root; global scope requires absolute or `~/`-prefixed). `okstra config get pr-template-path --scope all` reports every scope plus the effective winner. The bundled default ships `## Summary` / `## Changes` / `## Test plan` / `## Linked issues` with HTML comment guidance that the lead strips before opening the PR.
195
195
  - **Profile-roster worker validation** — `--workers <csv>` (and the okstra-run Step 6 worker prompt) are now restricted to the worker IDs declared by the chosen profile's `Required workers:` block. Asking for `codex` / `antigravity` on a profile that does not list them (e.g. `release-handoff`) is rejected with a clear error, and the interactive prompt only offers workers the profile actually accepts.
@@ -113,7 +113,7 @@ scripts/okstra.sh workflow가 사용하는 project-local Claude assets는 아래
113
113
  - `.okstra/discovery/latest-task.json`: 현재 프로젝트에서 가장 최근에 준비된 okstra task bundle을 가리키는 current-task convenience pointer
114
114
  - `.okstra/discovery/task-catalog.json`: 현재 프로젝트에 준비된 okstra task bundle 목록을 `taskKey`, `taskGroup`, `taskId` 기준으로 유지하는 canonical project-level catalog
115
115
  - `instruction-set/reference-expectations.md`: 현재 task가 참조해야 할 config files, deployment manifests, expected values를 task-level canonical artifact로 정리한 파일
116
- - `~/.claude/skills/okstra-*/...`, `~/.agent/skills/okstra-*/...`, `~/.claude/agents/...`: `okstra install` 이 사용자 홈에 seed하는 skill/agent asset (project-local 시딩은 더 이상 발생하지 않음 — `okstra install --refresh` 로 갱신)
116
+ - `~/.claude/skills/okstra-*/...`, `~/.agents/skills/okstra-*/...`, `~/.claude/agents/...`: `okstra install` 이 사용자 홈에 seed하는 skill/agent asset (project-local 시딩은 더 이상 발생하지 않음 — `okstra install --refresh` 로 갱신)
117
117
 
118
118
  이전의 아래 파일들은 더 이상 okstra 생성 대상이 아닙니다.
119
119
 
@@ -158,6 +158,7 @@ scripts/okstra.sh workflow가 사용하는 project-local Claude assets는 아래
158
158
  - `workflow.awaitingApproval`
159
159
  - `workflow.routingStatus`
160
160
  - `workflow.lastSafeCheckpoint`
161
+ - `phaseOutcome` *(artifact-derived semantic phase outcome; 예: implementation carry 가 모든 stage 통과를 증명하면 run contract validation 실패가 남아 있어도 implementation phase outcome 은 completed 로 기록될 수 있음)*
161
162
  - `inputs`
162
163
  - `artifacts`
163
164
  - `resultContract`
@@ -197,7 +198,11 @@ canonical metadata는 항상 `task-manifest.json`을 기준으로 확인합니
197
198
 
198
199
  각 실행은 `runs/<task-type>/manifests/run-manifest-<task-type>-<seq>.json`에 현재 run 계약을 남깁니다.
199
200
 
200
- `manifests/run-manifest-<task-type>-<seq>.json`의 path 계열 필드는 모두 대상 프로젝트 루트 기준 상대경로만 저장합니다.
201
+ `manifests/run-context-<task-type>-<seq>.json`은 schemaVersion `2.0`부터 모든 legacy path key를 직접 저장하지 않고 `identity` + `pathHints`를 저장합니다. host-side reader는 `pathHints`를 hydrate해 기존 flat key(`RUN_MANIFEST_RELATIVE_PATH`, `TEAM_STATE_PATH` 등)를 메모리에서 재구성합니다.
202
+
203
+ `state/active-run-context-<task-type>-<seq>.json`도 schemaVersion `2.0`부터 lead Phase 1용 compact intake입니다. 반복 path 문자열 대신 `identity` + `pathHints`와 worker identity만 저장하고, deterministic dispatcher는 읽을 때 legacy active context shape로 hydrate합니다.
204
+
205
+ `manifests/run-manifest-<task-type>-<seq>.json`의 path 계열 필드는 아직 validator / team dispatch / inspect 호환을 위해 대상 프로젝트 루트 기준 상대경로로 저장합니다.
201
206
  `okstra`가 Claude handoff를 시작한 직후에는 현재 run 상태가 보통 `in-progress`로 기록됩니다.
202
207
  이후 최종 결과 저장과 상태 갱신은 Claude가 이어서 수행합니다.
203
208
  또한 `okstra`는 launch 전에 session ID를 선할당하고, 같은 run의 `sessions/` 아래에 `claude-resume-<task-type>-<seq>.sh`를 생성합니다.
@@ -253,7 +258,7 @@ canonical metadata는 항상 `task-manifest.json`을 기준으로 확인합니
253
258
  1. task browsing 또는 task-id disambiguation이 필요하면 `.okstra/discovery/task-catalog.json`을 먼저 읽습니다.
254
259
  2. 현재 task key나 task path가 명시되지 않았다면 `.okstra/discovery/latest-task.json`을 current-task pointer로 읽습니다.
255
260
  3. `task-manifest.json`을 읽습니다.
256
- 4. current `state/active-run-context-<task-type>-<seq>.json`이 있으면 lead Phase 1의 1차 입력으로 읽습니다. 없으면 current `manifests/run-manifest-<task-type>-<seq>.json`과 `team-state`로 fallback합니다.
261
+ 4. current `state/active-run-context-<task-type>-<seq>.json`이 있으면 lead Phase 1의 1차 입력으로 읽습니다. 이 파일은 `identity` + `pathHints` 단서로 run artifact 경로를 재구성하는 compact intake입니다. 없으면 current `manifests/run-manifest-<task-type>-<seq>.json`과 `team-state`로 fallback합니다.
257
262
  5. `instruction-set/analysis-profile.md`와 `instruction-set/analysis-packet.md`를 읽습니다.
258
263
  6. `task-index.md`는 quick summary가 필요할 때만 선택적으로 읽습니다.
259
264
  7. `analysis-material.md`, `reference-expectations.md`, `task-brief.md`, `final-report-template.md`는 packet이 불충분하거나 source citation/보고서 작성에 필요할 때 lazy read합니다.
@@ -18,7 +18,7 @@
18
18
  - **Single python authority**: 모든 prepare wiring(profile/workers/model 해소, path 계산, render, central record_start)이 [`okstra_ctl.run.prepare_task_bundle()`](../../scripts/okstra_ctl/run.py) 한 함수에 모여 있습니다. `okstra.sh` 와 `okstra-run` skill 은 같은 함수를 호출하는 thin caller 이며, 환경 변수로 상태를 전달하지 않습니다 — task 정체성·경로·workflow 상태는 모두 디스크 권위 파일에서 매번 계산됩니다.
19
19
  - **Claude handoff (두 모드)**: (a) `okstra.sh` 가 새 `claude` 프로세스를 띄우는 전통 방식, (b) `okstra-run` skill 이 현재 claude 세션 안에서 prepare 후 lead 역할을 그대로 인계받는 in-session 모드. 둘 다 `prepare_task_bundle` 의 산출물(instruction-set 등)을 그대로 사용합니다.
20
20
  - **Required team contract**: 각 phase profile의 `Required workers:` 블록이 roster의 권위입니다. 일반 분석 phase는 Claude/Codex analyser + report-writer를 기본으로 하고, Antigravity는 profile과 `--workers`가 허용할 때만 포함됩니다. `release-handoff`처럼 lead-only에 가까운 phase는 별도 roster를 가집니다.
21
- - **User-home install + project-local task bundles**: `npx okstra@latest install` 한 명령이 런타임(`~/.okstra/{lib/python, bin, templates, prompts}`)을 설치하고, public skill 을 `~/.agent/skills/` 에 기본 설치합니다. `~/.claude` 가 있으면 Claude skills + worker agent 4종(`~/.claude/agents/*-worker.md`)도 함께 설치합니다. 사용자 진입점 스킬만 목록에 노출되고 lead/support 운영 계약은 `~/.okstra/prompts/` 아래 runtime resource 로 설치되어 skill discovery 대상이 아닙니다. 전역 대화 메모리는 프로젝트와 분리된 `~/.okstra/memory-book/` 에 저장됩니다. 대상 프로젝트에는 task bundle 과 discovery metadata 가 `.okstra/` 아래 저장되고, **추가로 `<PROJECT_ROOT>/.claude/settings.local.json` 이 `~/.okstra/templates/settings.local.json` 을 가리키는 symlink 로 provisioning** 됩니다 (`okstra setup` 또는 `okstra-ctl` prepare 가 idempotent 하게 관리; 기존에 일반 파일이 있었다면 `.bak.<timestamp>` 로 보존 후 교체).
21
+ - **User-home install + project-local task bundles**: `npx okstra@latest install` 한 명령이 런타임(`~/.okstra/{lib/python, bin, templates, prompts}`)을 설치하고, public skill 을 `~/.agents/skills/` 에 기본 설치합니다. `~/.claude` 가 있으면 Claude skills + worker agent 4종(`~/.claude/agents/*-worker.md`)도 함께 설치합니다. 사용자 진입점 스킬만 목록에 노출되고 lead/support 운영 계약은 `~/.okstra/prompts/` 아래 runtime resource 로 설치되어 skill discovery 대상이 아닙니다. 전역 대화 메모리는 프로젝트와 분리된 `~/.okstra/memory-book/` 에 저장됩니다. 대상 프로젝트에는 task bundle 과 discovery metadata 가 `.okstra/` 아래 저장되고, **추가로 `<PROJECT_ROOT>/.claude/settings.local.json` 이 `~/.okstra/templates/settings.local.json` 을 가리키는 symlink 로 provisioning** 됩니다 (`okstra setup` 또는 `okstra-ctl` prepare 가 idempotent 하게 관리; 기존에 일반 파일이 있었다면 `.bak.<timestamp>` 로 보존 후 교체).
22
22
  - **Resume and clarification**: `--task-key`, `--resume-clarification`, `--clarification-response`로 같은 task 재개와 lead의 추가 질문 응답 흐름을 지원합니다.
23
23
  - **Derived views and telemetry**: final-report data.json → Markdown → slim MD / self-contained HTML view, worker error sidecar, wrapper log sidecar, token usage / cost accounting을 제공합니다.
24
24
 
@@ -149,7 +149,7 @@ okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_ta
149
149
  - 사용자 호출 가능 스킬은 `skills/okstra-setup/SKILL.md`, `skills/okstra-brief/SKILL.md`, `skills/okstra-run/SKILL.md`, `skills/okstra-memory/SKILL.md`, `skills/okstra-inspect/SKILL.md`, `skills/okstra-schedule/SKILL.md`, `skills/okstra-container-build/SKILL.md` 7종뿐이며, 이것만 agent skill home 으로 복사됩니다 — brief 작성, phase 진행, 전역 Memory Book 저장/검색, status/history/report/time/logs/cost/errors/recap read-side, schedule 보조, 그리고 `okstra-container-build` 는 검증 완료된 task 코드를 docker compose 그룹으로 배포하고 컨테이너별 watcher 로 감시하는 비선형(PHASE_SEQUENCE 외부) 컨테이너 배포/감시 스킬. `okstra-inspect` 의 read-side facet 은 `skills/okstra-inspect/SKILL.md` 의 sub-command 표가 정본인 8종입니다. `okstra-inspect logs` 는 codex/antigravity wrapper 가 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` 로 남기는 live-log sidecar 의 인벤토리·정리 안내(read-only), `okstra-inspect cost` 는 `okstra context-cost` 결과 요약, `okstra-inspect errors` 는 task 의 okstra-run 에러 로그를 타임스탬프 markdown error-report 로 모아 렌더하고 요약을 출력, `okstra-inspect recap` 은 task 의 run 간 phase 전·후 요약에 더해 `.okstra` 산출물에 대한 자유 Q&A 까지 답합니다.
150
150
  - 내부 운영 계약 — `context-loader` / `team-contract` / `convergence` / `report-writer` 와 lead 계약 — 은 `prompts/lead/*.md` 로, 구현/검증 워커의 언어별 coding preflight 는 `prompts/coding-preflight/*` (overview 라우터 + clean-code + languages/frameworks/architectures 3단계 선택) 로 이동했습니다. 모두 `~/.okstra/prompts/` 에 설치되는 런타임 리소스이며 skill discovery 대상이 아닙니다. generated launch prompt 가 lead 에게 절대 경로를 제공하고, 재설치 시 과거 `okstra-context-loader` / `okstra-team-contract` / `okstra-convergence` / `okstra-report-writer` / `okstra-coding-preflight` / `okstra` skill 디렉터리는 exact-name prune 됩니다.
151
151
  - 플러그인 매니페스트: [`../../.claude-plugin/plugin.json`](../../.claude-plugin/plugin.json) — `npx skills@latest add Devonshin/okstra` 보조 채널이 참조. 일반 셋업에는 `npx okstra@latest install` 을 사용한다. 플러그인 매니페스트는 사용자 진입점 7개(`okstra-setup`, `okstra-brief`, `okstra-run`, `okstra-memory`, `okstra-inspect`, `okstra-schedule`, `okstra-container-build`)만 노출한다.
152
- - 설치 위치: `~/.claude/skills/<name>/SKILL.md` 또는 `~/.agent/skills/<name>/SKILL.md`.
152
+ - 설치 위치: `~/.claude/skills/<name>/SKILL.md` 또는 `~/.agents/skills/<name>/SKILL.md`.
153
153
  - 릴리스 절차: [`../../RELEASING.md`](../../RELEASING.md) — npm publish 흐름과 release-please / manual fallback.
154
154
 
155
155
  ## Architecture: python authority + thin callers
@@ -190,7 +190,7 @@ per-process 환경 변수에 task 정체성·경로·workflow 상태를 보관
190
190
  | task 후보 목록 | `<PROJECT_ROOT>/.okstra/discovery/task-catalog.json` |
191
191
  | 최신 task 포인터 | `<PROJECT_ROOT>/.okstra/discovery/latest-task.json` |
192
192
  | run 입력값 | `<run-dir>/manifests/run-inputs-<task-type>-<seq>.json` |
193
- | run paths / seq | `<run-dir>/manifests/run-context-<task-type>-<seq>.json` |
193
+ | run path hints / seq | `<run-dir>/manifests/run-context-<task-type>-<seq>.json` |
194
194
  | run 이력 | `<task-root>/history/timeline.json` |
195
195
  | 글로벌 인덱스 | `~/.okstra/{active,recent}.jsonl`, `~/.okstra/projects/<id>/{index.jsonl, meta.json}` |
196
196
 
@@ -198,7 +198,7 @@ per-process 환경 변수에 task 정체성·경로·workflow 상태를 보관
198
198
 
199
199
  두 종류의 파일 락이 모든 동시성을 처리합니다.
200
200
 
201
- - `~/.okstra/.locks/<task-key>.lock` — per-task mutex. `compute_and_write_run_context` 가 seq 계산과 `run-context.json` 영속화를 한 트랜잭션으로 묶음. 같은 task 의 두 호출은 직렬화.
201
+ - `~/.okstra/.locks/<task-key>.lock` — per-task mutex. `compute_and_write_run_context` 가 seq 계산과 compact `run-context.json` 영속화를 한 트랜잭션으로 묶음. 같은 task 의 두 호출은 직렬화.
202
202
  - `~/.okstra/.lock` — 중앙 인덱스 mutex. `record_start` / `reconcile` / `rotate_recent_if_needed` 에서 사용.
203
203
 
204
204
  다른 (project, task-group, task-id) 사이에는 직렬화가 없습니다 — 디스크 경로가 분리되므로 충돌 자체가 없음. 환경 변수 race 가 사라졌으므로 같은 claude 세션이 여러 task 를 병렬 진행해도 안전.
@@ -347,7 +347,7 @@ okstra phase 는 PRD / issue file 을 직접 쓰지 않습니다. 동등한 결
347
347
 
348
348
  - `implementation`을 제외한 모든 phase는 source code edit, build, migration, deployment, 그 밖의 state-mutating 명령을 금지합니다(`final-verification`은 read-only 테스트 명령만 허용). `implementation`은 승인된 plan의 파일 목록 안에서만 edit/commit이 허용되며, `git push`·publish·deploy·실제 migration·third-party write API는 여전히 금지됩니다.
349
349
  - **모든 task-type 격리 worktree (BLOCKING)**: 모든 task-type 의 첫 번째 phase prepare 단계에서 `okstra-ctl` 이 자동으로 task-key 단위 `git worktree` 를 생성하고, 같은 task-key 의 이후 phase (`requirements-discovery` → `error-analysis` → `implementation-planning` → `implementation`) 는 동일한 worktree·브랜치를 재사용합니다. 위치는 `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` (segment 의 `/`·`:` 등 특수문자는 `-` 로 정규화) 이고, 브랜치 이름은 `<work-category-prefix>-<task-id-segment>` (예: `feat-dev-9436`, `fix-dev-7311`) 입니다. base ref 는 첫 phase prepare 시점의 main worktree `HEAD`. `~/.okstra/worktrees/registry.json` (flock-guarded) 가 task-key → path/branch 매핑을 전역 관리해 동시 실행 시 path·branch 충돌을 방지합니다. configured sync dirs 는 main worktree 에서 symlink 로 연결되어 task checkout 사이의 filesystem continuity 를 제공합니다 (sync 대상 목록은 `project.json` 의 `worktreeSyncDirs` 또는 `OKSTRA_WORKTREE_SYNC_DIRS` 환경변수로 override 가능; 빈 배열이면 sync 비활성화). 이 sync 는 okstra context/write boundary 를 확장하지 않습니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 되고 executor 는 project_root 에서 그대로 작업합니다. worktree 는 run 종료 후 자동 삭제되지 않으며 후속 phase·PR 작성·rollback 검증의 권위 artefact 입니다. 수동 cleanup: `git -C <main-worktree> worktree remove <path>` → `git -C <main-worktree> branch -D <branch>` + registry 항목 삭제. 자세한 동작은 `prompts/profiles/implementation.md` 의 *Task worktree* 블록과 `prompts/lead/okstra-lead-contract.md` 의 *Task worktree (BLOCKING for every task-type)* 섹션 참고.
350
- - **implementation stage 격리 worktree (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 의 모델입니다. `implementation` task 는 **stage 격리** 로 동작합니다 (spec `docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md`) — **한 run = 한 stage**, 각 run 이 `.../<task-id-segment>/stage-<N>/` (브랜치 `<prefix>-<task-id-segment>-s<N>`) 격리 worktree 를 발급받습니다. registry 가 task-key 와 **stage-key** (`<task-key>#stage-<N>`) 를 함께 flock 예약하고, `_resolve_effective_stages` 가 `consumers.jsonl` 의 `started` + registry 예약 stage 를 ready 집합에서 제외하므로(점유 SSOT = registry), 사용자가 두 `implementation` run 을 동시에 띄우면 서로 다른 독립 stage 를 충돌 없이 진행합니다. base 결정: 독립 = 공통 anchor(첫 stage 진입 HEAD 고정), 단일 의존 = 선행 done commit, 다중 의존 = 선행이 모두 ancestor 인 task worktree HEAD(`git merge-base --is-ancestor`; 미머지 시 `PrepareError`). cost-aware-design 의 ready-set batch 는 stage 마다 격리 branch 가 필요해 의미를 잃으므로(같은 branch 에 두 stage-key reserve 시 branch-uniqueness 충돌) 폐기되었고, 순차 진행은 stage done 후 다음 run, 동시 진행은 별도 run 으로 — cost 등가. `--stage <auto|N>` 또는 wizard `stage_pick` 으로 stage 를 선택합니다. wizard `stage_pick` 은 각 stage 의 상태(`[완료]`/`[진행중]`/`[준비됨]`/`[대기]`)를 라벨에 표시하는 멀티선택이며, 선택분의 의존성 closure 를 Kahn 위상정렬(`stage_targets.order_stage_closure`)해 render-args 의 `chain-stages` CSV 로 내보냅니다. `okstra-run` SKILL 이 이 큐를 받아 의존성 순서대로 단일-stage run 을 N 회 순차 실행(무인 연쇄)하되, 각 stage 의 Phase 6 `done` 행을 확인한 뒤 다음으로 넘어갑니다. 이는 오케스트레이션 계층일 뿐이며 wizard·prepare 의 **한 run = 한 stage** 격리 불변은 그대로입니다. worktree 뿐 아니라 **run 산출물(report·state·worker-results·manifest)도 `runs/implementation/stage-<N>/` 로 stage 별 격리**되므로 동시 실행하는 두 stage 의 보고서·상태가 섞이지 않습니다. 반면 `consumers.jsonl` 과 worktree registry 는 stage 간 공유되는 조율 SSOT 라 task-type 루트(`runs/implementation/`)에 그대로 둡니다.
350
+ - **implementation stage 격리 worktree (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 의 모델입니다. `implementation` task 는 **stage 격리** 로 동작합니다 — **한 run = 한 stage**, 각 run 이 `.../<task-id-segment>/stage-<N>/` (브랜치 `<prefix>-<task-id-segment>-s<N>`) 격리 worktree 를 발급받습니다. registry 가 task-key 와 **stage-key** (`<task-key>#stage-<N>`) 를 함께 flock 예약하고, `_resolve_effective_stages` 가 `consumers.jsonl` 의 `started` + registry 예약 stage 를 ready 집합에서 제외하므로(점유 SSOT = registry), 사용자가 두 `implementation` run 을 동시에 띄우면 서로 다른 독립 stage 를 충돌 없이 진행합니다. base 결정: 독립 = 공통 anchor(첫 stage 진입 HEAD 고정), 단일 의존 = 선행 done commit, 다중 의존 = 선행이 모두 ancestor 인 task worktree HEAD(`git merge-base --is-ancestor`; 미머지 시 `PrepareError`). cost-aware-design 의 ready-set batch 는 stage 마다 격리 branch 가 필요해 의미를 잃으므로(같은 branch 에 두 stage-key reserve 시 branch-uniqueness 충돌) 폐기되었고, 순차 진행은 stage done 후 다음 run, 동시 진행은 별도 run 으로 — cost 등가. `--stage <auto|N>` 또는 wizard `stage_pick` 으로 stage 를 선택합니다. wizard `stage_pick` 은 각 stage 의 상태(`[완료]`/`[진행중]`/`[준비됨]`/`[대기]`)를 라벨에 표시하는 멀티선택이며, 선택분의 의존성 closure 를 Kahn 위상정렬(`stage_targets.order_stage_closure`)해 render-args 의 `chain-stages` CSV 로 내보냅니다. `okstra-run` SKILL 이 이 큐를 받아 의존성 순서대로 단일-stage run 을 N 회 순차 실행(무인 연쇄)하되, 각 stage 의 Phase 6 `done` 행을 확인한 뒤 다음으로 넘어갑니다. 이는 오케스트레이션 계층일 뿐이며 wizard·prepare 의 **한 run = 한 stage** 격리 불변은 그대로입니다. worktree 뿐 아니라 **run 산출물(report·state·worker-results·manifest)도 `runs/implementation/stage-<N>/` 로 stage 별 격리**되므로 동시 실행하는 두 stage 의 보고서·상태가 섞이지 않습니다. 반면 `consumers.jsonl` 과 worktree registry 는 stage 간 공유되는 조율 SSOT 라 task-type 루트(`runs/implementation/`)에 그대로 둡니다.
351
351
  - **단일-stage final-verification 의 run 산출물 격리 (동시 병렬)**: 단독-stage `final-verification`(`--stage <N>`)도 implementation 과 동일하게 run 산출물을 `runs/final-verification/stage-<N>/` 하위에 격리하고(seq 도 stage 별 독립), 팀 이름에 `-fv-s<N>` 접미사를 붙입니다 — `-fv-` 구분자로 같은 stage 의 implementation 팀(`-s<N>`)과도, 전체-task 검증의 기본 이름과도 충돌하지 않습니다. 따라서 여러 stage 의 final-verification 을 동시에 띄워도 state·worker-results·보고서·팀이 섞이지 않습니다. worktree 는 새로 만들지 않고 해당 implementation stage worktree 를 registry 에서 read-only 로 재사용하며, 그래서 registry stage-key 예약도 하지 않습니다. `teamName` 라벨에 `-fv-s<N>` 접미사를 붙이는 것은 audit/표시용 구분일 뿐이며, 실제 팀은 세션별 implicit team(`session-<leadSid>`)이라 v2.1.178 이전의 `TeamCreate` 이름 충돌 hard-fail 은 더 이상 발생하지 않습니다. 전체-task 검증(stage 빈 값)은 기존 평면 `runs/final-verification/` 구조를 유지합니다.
352
352
  - `implementation` 과 `release-handoff` 를 제외한 모든 phase 는 source code edit, build, migration, deployment, 그 밖의 state-mutating 명령을 금지합니다 (`final-verification` 은 read-only 테스트 명령만 허용). `implementation` 은 승인된 plan 의 파일 목록 안에서만 edit/commit 이 허용되며, `git push`·publish·deploy·실제 migration·third-party write API 는 여전히 금지됩니다. `release-handoff` 는 source code 자체는 수정하지 않고, 사용자가 메뉴로 선택한 commit / push / PR 명령만 실행합니다 (force push, base 브랜치 직접 push, hook bypass, release publish 는 여전히 금지).
353
353
  - 사용자가 "다음 단계 진행해" 같은 표현을 보내도, 그 발화만으로 다음 phase가 자동 시작되지 않습니다. 다음 phase는 새 `okstra.sh` 실행으로만 시작합니다.
@@ -372,7 +372,7 @@ release-handoff 까지 완료된 task 의 산출물에서 버그가 발견되면
372
372
 
373
373
  ### release-handoff stage-group 모드
374
374
 
375
- `release-handoff` 는 두 모드로 동작합니다 (설계 `docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md`).
375
+ `release-handoff` 는 두 모드로 동작합니다.
376
376
 
377
377
  - **whole-task (기본)**: task 전체를 1개 PR 로 내보냅니다. 기존 동작입니다.
378
378
  - **stage-group**: 단독-stage final-verification 에서 `accepted` 를 받은 stage 들 중 일부를 골라, 수집(collector) 브랜치로 묶어 1개 PR 로 내보냅니다. task 전체가 끝나기를 기다리지 않고 검증 완료된 stage 묶음 단위로 PR 을 낼 수 있습니다.
@@ -604,6 +604,7 @@ scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --task-type fin
604
604
  - `workflow.awaitingApproval`
605
605
  - `workflow.routingStatus`
606
606
  - `workflow.lastSafeCheckpoint`
607
+ - `phaseOutcome`
607
608
 
608
609
  프로젝트 전체 상태를 훑을 때는 `.okstra/discovery/task-catalog.json`을 사용합니다.
609
610
  특정 task의 최신 상태를 볼 때는 `.okstra/discovery/latest-task.json`, `task-manifest.json`, 최신 `run-manifest`, `history/timeline.json` 순서로 확인합니다.
@@ -682,8 +683,8 @@ Phase 7 step 1.5 가 final-report MD 한 본을 입력으로 두 view 를 결정
682
683
  - `scripts/okstra-codex-exec.sh`, `scripts/okstra-antigravity-exec.sh` 는 dispatch 마다 prompt path 옆에 `<prompt>.log` sidecar 를 만들고 stdout 을 거기로 mirror 합니다 (`tee`, `PIPESTATUS[0]` 로 종료코드 보존). stderr 은 같은 파일에 append (subagent stderr 캡처 contract 보존), 매 dispatch 시 truncate. 호출 subagent 의 `BashOutput` 폴링은 60s 간격이라 long-running run (analysis 의 large-codebase scan, implementation 의 cargo / pytest) 동안 사용자가 stalled state 를 탐지할 수 없는 문제를 해소합니다.
683
684
  - tmux 가 reachable 한 lead 환경이면 wrapper 가 sibling pane 을 자동 분할해 `tail -F <log-path>` 를 띄웁니다. trace pane title 은 caller (worker) pane title 에 `-tail` 을 붙인 `<cli>-<role>-<pid>-tail` (e.g. `codex-worker-93421-tail`); 동일 시점에 caller (worker) pane title 은 `<cli>-<role>-<pid>` 로 셋팅됩니다. `<pid>` 는 wrapper 자기 자신의 PID 라서 동일 role 의 worker 가 둘 이상 동시에 spawn 돼도 서로 구분되고, 운영자는 `<caller> ↔ <caller>-tail` 로 시각적으로 매핑할 수 있습니다. **caller pane 해석** — Claude Code Bash tool 은 이제 `$TMUX` 와 `$TMUX_PANE` 를 둘 다 환경에서 제거하므로 env 변수에 의존하지 않습니다. wrapper 는 (1) prompt path 로부터 `<RUN_DIR>` (= `dirname(dirname(prompt_path))`, paths.py SSOT) 를 도출하고, (2) lead 가 자기 foreground pane 에서 1회 기록한 `<RUN_DIR>/state/lead-pane.id` 를 읽어 split anchor 로 씁니다 (background dispatch 에서도 신뢰 가능 — active-pane 추정과 달리 사용자가 pane 을 옮겨도 안전). 기록 파일이 없거나 pane 이 stale 이면 `tmux display-message -p '#{pane_id}'` (active pane) 으로 fallback. trace pane split 은 그 caller pane 을 `-t` 로 명시 anchor 합니다. role 은 wrapper 의 5번째 optional positional 인자이며, 누락 시 기본값 `worker`. caller pane title 은 capture 해두고 EXIT trap 에서 복원하므로 dispatch 사이의 stale title 이 남지 않습니다. focus 는 caller pane 으로 복귀하고, CLI 종료 후 pane 은 유지돼 스크롤백 가능. tmux 미reachable, split 실패, 구버전 tmux 등 모든 경로는 silent degrade.
684
685
  - **run-scoped 태깅으로 정리**: trace pane 의 `tail -F` 는 tmux 셸의 자식이라 Claude 가 종료돼도 살아남습니다. wrapper 는 spawn 한 pane 을 `tmux set-option -p @okstra_trace_run=<RUN_DIR>` 로 태깅하고, `okstra-trace-cleanup.sh` 는 `tmux list-panes -a` 에서 그 태그로 pane 을 server-wide 발견해 `tmux kill-pane` 합니다. tmux env 변수·pane-id registry 없이 동작하며, run-scoped 태그라 동시에 도는 다른 okstra run 의 trace pane 을 죽이지 않습니다. cleanup 은 두 진입 형태를 가집니다 — lead 가 `--run-dir <RUN_DIR>` 로 호출(해당 run 의 trace + worker-agent pane 정리)하거나, `templates/reports/settings.template.json` 의 `hooks.SessionEnd` 가 `--reap` 로 호출(`$CLAUDE_PROJECT_DIR/.okstra/` 하위 태그를 가진 trace pane 일괄 정리; 단일 run-dir 이 없는 종료 시점용). tmux 가 없거나 stale pane id 인 경우 silent degrade.
685
- - **phase 전환 시 자동 정리 + worker-agent pane 포함**: `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` 는 태깅된 trace pane 뿐 아니라 dispatch 된 서브에이전트가 점유하는 worker-agent pane(title `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`)도 lead 세션(`tmux list-panes -s -t <lead-pane>`) 범위에서 title allowlist 로 식별해 닫습니다(worker-agent pane 은 harness 소유라 태깅 불가). 세션 scope 와 lead 자기 pane 제외는 `<RUN_DIR>/state/lead-pane.id` 로 결정되며, lead 자신의 pane 은 title 이 걸려도 절대 죽이지 않습니다. lead 는 새 phase 의 worker 를 dispatch 하기 직전(`PROGRESS: phase-5.5-convergence` / `phase-6-synthesis` 마커 직전) 이 스크립트를 `--run-dir` 로 호출해 이전 phase 의 pane 을 prompt 없이 정리합니다.
686
- - **Phase 종료 시 사용자 확인**: run 최종 종료 시점(마지막 단계)에 lead 가 `okstra-trace-cleanup.sh --list --run-dir <RUN_DIR>` 로 잔여 okstra pane(worker-agent + trace) 목록을 출력한 뒤 사용자에게 "모두 닫기 / 그대로 두기" 양자택일을 묻고 응답대로 처리합니다 (`prompts/profiles/_common-contract.md` 의 *Phase wrap-up* 항목). 다음 split-pane run 경우 worker teammate 정리할지 별도로 묻고, 승인 시 `okstra-team-reconcile.sh` 로 dead-pane 멤버를 inactive 로 정리한 각 완료 teammate 에 `SendMessage` shutdown_request 를 보냅니다(`TeamDelete` 는 v2.1.178 에서 제거 — implicit team 은 세션 종료와 함께 사라짐). lead 는 이 pane 단계를 `lead-pane.id` 를 직접 해석해 게이트하지 않고 **항상** 스크립트를 호출하며, tmux 밖이면 스크립트가 빈 pane 목록으로 안전하게 no-op 합니다. teammate 단계는 `teamCreate.status` 가 아니라 on-disk team config(`~/.claude/teams/session-*/config.json` 의 `leadSessionId` 매칭) 존재로 판단합니다. `--list` 모드는 pane 을 죽이지 않고 `<pane_id>\t<pane_title>` 만 출력하므로 사용자가 무엇이 닫힐지 시각적으로 확인할 수 있습니다.
686
+ - **phase 전환 시 자동 정리 + worker-agent pane 포함**: `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` 는 태깅된 trace pane 뿐 아니라 dispatch 된 서브에이전트가 점유하는 worker-agent pane(title `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`)도 lead 세션(`tmux list-panes -s -t <lead-pane>`) 범위에서 title allowlist 로 식별해 닫습니다(worker-agent pane 은 harness 소유라 태깅 불가). implementation role title(`claude-executor` / `codex-verifier` / `agy-executor-tail` 등)과 FleetView teammate prefix(`✳ ` / `⠂ `)도 같은 okstra pane 으로 취급합니다. 세션 scope 와 lead 자기 pane 제외는 `<RUN_DIR>/state/lead-pane.id` 로 결정되며, lead 자신의 pane 은 title 이 걸려도 절대 죽이지 않습니다. lead 는 새 phase 의 worker 를 dispatch 하기 직전(`PROGRESS: phase-5.5-convergence` / `phase-6-synthesis` 마커 직전) 이 스크립트를 `--run-dir` 로 호출해 이전 phase 의 pane 을 prompt 없이 정리합니다.
687
+ - **Phase 종료 시 사용자 확인**: run 최종 종료 시점(마지막 단계)에 lead 가 `okstra-trace-cleanup.sh --list --run-dir <RUN_DIR>` 로 잔여 okstra pane(worker-agent + trace) 목록을 출력한 뒤 사용자에게 "모두 닫고 팀원 정리 / 그대로 두기" 양자택일을 한 번만 묻고 응답대로 처리합니다 (`prompts/profiles/_common-contract.md` 의 *Phase wrap-up* 항목). 승인 lead pane cleanup 실행한 뒤, split-pane run 이면 `okstra-team-reconcile.sh` 로 dead-pane 멤버를 inactive 로 정리하고 각 완료 teammate 에 `SendMessage` shutdown_request 를 보냅니다(`TeamDelete` 는 v2.1.178 에서 제거 — implicit team 은 세션 종료와 함께 사라짐). lead 는 이 pane 단계를 `lead-pane.id` 를 직접 해석해 게이트하지 않고 **항상** 스크립트를 호출하며, tmux 밖이면 스크립트가 빈 pane 목록으로 안전하게 no-op 합니다. teammate 단계는 `teamCreate.status` 가 아니라 on-disk team config(`~/.claude/teams/session-*/config.json` 의 `leadSessionId` 매칭) 존재로 판단합니다. `--list` 모드는 pane 을 죽이지 않고 `<pane_id>\t<pane_title>` 만 출력하므로 사용자가 무엇이 닫힐지 시각적으로 확인할 수 있습니다.
687
688
  - 디스크 누적은 `okstra-inspect logs` 흐름이 read-only 로 인벤토리 + cleanup 명령을 제안합니다 (실행은 사용자 copy-paste).
688
689
 
689
690
  ### Linked-worktree `.git/` write 권한 (codex / antigravity)
@@ -691,8 +692,6 @@ Phase 7 step 1.5 가 final-report MD 한 본을 입력으로 두 view 를 결정
691
692
  - `--executor codex|antigravity` 의 worktree 안에서 `git add` / `git commit` 은 main repo 의 per-worktree metadata (`<main-repo>/.git/worktrees/<name>/index`, refs, HEAD) 와 shared object DB (`<main-repo>/.git/objects/`) 에 써야 하지만, 이 경로는 worktree directory 밖이라 단순히 worktree path 만 sandbox 에 열어주면 index.lock 생성 시 EPERM 으로 실패합니다 (executor 가 step commit contract 를 만족하지 못해 edit 을 revert 하고 종료).
692
693
  - wrapper 가 worktree 안에서 `git -C <worktree> rev-parse --git-common-dir` 로 main repo `.git/` 절대경로를 해석하고 `--add-dir <main-repo>/.git` (codex) 또는 `--include-directories <main-repo>/.git` append (antigravity) 로 sandbox 에 함께 forward 합니다.
693
694
 
694
- 상세 설계 및 jq 회고 레시피는 `docs/superpowers/specs/2026-04-28-worker-error-collection-design.md`를 참고합니다.
695
-
696
695
  ## Token usage and cost accounting
697
696
 
698
697
  각 run에 사용된 토큰을 lead/worker 세션 트랜스크립트에서 수집해 `team-state.json`의 `leadUsage` / `workers[].usage`에 다시 기록합니다.
@@ -718,6 +717,8 @@ phase 산출물의 출고 가능 여부를 강제하는 진입점:
718
717
 
719
718
  각 validator 는 contract 위반 시 `contract-violated` exit code 로 phase 를 차단합니다. 위반은 다음 phase 실행 시점에 적용되므로 이전 산출물은 그대로 둡니다.
720
719
 
720
+ `contractValidation.status=failed`는 run artifact contract 실패를 뜻하며, 구현 결과 자체가 항상 미완이라는 뜻은 아닙니다. implementation run 은 `runs/implementation/carry/stage-<N>.json`, `runs/implementation-planning/consumers.jsonl`, 승인된 Stage Map 을 함께 읽어 `phaseOutcome.implementation`을 도출합니다. 모든 Stage Map stage 가 pass-grade carry evidence 를 가지면 contract failure 는 감사 정보로 유지하면서 `workflow.nextRecommendedPhase`를 `final-verification`으로 보정할 수 있습니다.
721
+
721
722
  ## Practical notes
722
723
 
723
724
  - `okstra`는 brief 없이 쓰는 옛 방식이 아닙니다.
@@ -737,7 +738,7 @@ phase 산출물의 출고 가능 여부를 강제하는 진입점:
737
738
  - Executor 별 worktree cwd 주입: codex / antigravity executor 는 wrapper(`okstra-codex-exec.sh -C` / `okstra-antigravity-exec.sh --include-directories`) 가 CLI layer 에서 cwd 를 worktree 로 고정합니다. Claude executor 는 Bash tool 에 per-call cwd 인자가 없어 cwd 민감 toolchain (`cargo`/`npm`/`pnpm`/`bun`/`pytest`/`make`/`go`) 호출을 같은 Bash invocation 안에서 `cd {{EXECUTOR_WORKTREE_PATH}} && <cmd>` 로 prefix 합니다 — `bash -lc`/`bash -c` 래핑은 금지되며 (`cd` leading token 이 가려져 permission auto-allow 우회 실패), 작업 디렉터리 플래그 (`git -C`, `cargo --manifest-path` 등) 가 있으면 그것을 우선합니다. 자세한 규약은 `prompts/profiles/implementation.md` 의 *Executor Worktree* 블록과 `agents/workers/claude-worker.md` 의 Executor exception 항목 참고.
738
739
  - project-level current-task convenience pointer는 `.okstra/discovery/latest-task.json`입니다.
739
740
  - project-level canonical task inventory는 `.okstra/discovery/task-catalog.json`입니다.
740
- - okstra skill asset은 `okstra install` 시점에 `~/.agent/skills/` 로 기본 seed 되고, `~/.claude` 가 있으면 `~/.claude/skills/` + `~/.claude/agents/` 도 함께 seed 됩니다(per-project seeding은 더 이상 수행되지 않음).
741
+ - okstra skill asset은 `okstra install` 시점에 `~/.agents/skills/` 로 기본 seed 되고, `~/.claude` 가 있으면 `~/.claude/skills/` + `~/.claude/agents/` 도 함께 seed 됩니다(per-project seeding은 더 이상 수행되지 않음).
741
742
  - seeded okstra Claude assets는 세션의 implicit team 에 `Agent(name: ...)` 로 워커를 dispatch 하는 규칙을 Claude에게 제공합니다(v2.1.178 이 `TeamCreate`/`TeamDelete` 제거). Agent targets 는 skill markdown 만 받습니다.
742
743
  - 최종 판단은 스크립트가 아니라 Claude가 수행합니다.
743
744
  - stable task key를 유지해야 이후 bug 추적, 재수정, 재검증이 가능합니다.
@@ -754,8 +755,6 @@ phase 산출물의 출고 가능 여부를 강제하는 진입점:
754
755
  - `templates/reports/task-brief.template.md`
755
756
  - `templates/reports/final-report.template.md`
756
757
  - `prompts/lead/okstra-lead-contract.md`
757
- - `docs/superpowers/specs/2026-04-28-worker-error-collection-design.md`
758
- - `docs/superpowers/plans/2026-04-28-worker-error-collection.md`
759
758
  - `scripts/okstra-error-log.py`
760
759
  - `scripts/okstra-token-usage.py`
761
760
 
package/docs/kr/cli.md CHANGED
@@ -320,7 +320,7 @@ Lead runtime independence boundary:
320
320
  - `codex`: Codex lead adapter 용 runtime marker 입니다. `okstra codex-run` 이 `--render-only --lead-runtime codex` 를 소유해 task bundle 을 준비하고, 준비된 run manifest 는 `okstra codex-dispatch` 로 CLI-backed worker 실행에 넘길 수 있습니다.
321
321
  - `external`: Claude Code Teams 없이 `--render-only --lead-runtime external` 로 task bundle 과 external lead prompt 를 준비하고, lead 는 `okstra team dispatch` / `okstra team await` / `okstra team teardown` 으로 tmux-pane worker lifecycle 을 관리합니다. 이 path 는 `TeamCreate` / `Agent(...)` 를 쓰지 않고 artifact-only accounting 을 사용합니다.
322
322
 
323
- 현재 Claude Code 독립 범위는 external lead prompt + `okstra team *` worker dispatch 입니다. non-render `okstra_ctl.run --lead-runtime external` remains blocked; 완전한 external lead driver 는 아직 별도 구현 대상입니다. `--runtime external` 은 runtime adapter 선택만 의미하며, `okstra install` 은 `~/.agent/skills/` 를 기본 생성하고 `~/.claude` 가 있으면 Claude skill/agent 도 설치합니다. `claude` worker 선택은 여전히 local Claude CLI wrapper 를 필요로 합니다.
323
+ 현재 Claude Code 독립 범위는 external lead prompt + `okstra team *` worker dispatch 입니다. non-render `okstra_ctl.run --lead-runtime external` remains blocked; 완전한 external lead driver 는 아직 별도 구현 대상입니다. `--runtime external` 은 runtime adapter 선택만 의미하며, `okstra install` 은 `~/.agents/skills/` 를 기본 생성하고 `~/.claude` 가 있으면 Claude skill/agent 도 설치합니다. `claude` worker 선택은 여전히 local Claude CLI wrapper 를 필요로 합니다.
324
324
 
325
325
  ### Runtime auto-detection (`auto`)
326
326
 
@@ -330,7 +330,7 @@ Lead runtime independence boundary:
330
330
  - Codex host: `okstra run` 이 `codex-run` -> `codex-dispatch` 를 orchestration 합니다.
331
331
  - generic terminal + tmux: `okstra run` 이 `render-bundle --lead-runtime external` -> `okstra team dispatch` -> `okstra team await` 를 orchestration 합니다.
332
332
 
333
- `doctor` / `render-bundle` 도 `auto` 를 기본값으로 받지만, host signal 이 없는 plain terminal 에서는 host 지정이 필요합니다. `okstra install` / `ensure-installed` 는 예외입니다. 설치는 runtime host 가 아니라 agent home 기준으로 공유 runtime 과 skill target 을 배치하므로, host signal 이 없어도 `auto` 요청과 미해결 상태를 manifest 에 기록하고 설치를 계속합니다. 스킬 복사 대상은 runtime resolution 이 아니라 agent home 존재 여부와 기본 Agent target 정책입니다. `~/.agent/skills/` 는 항상 생성하고, `~/.claude` 가 있으면 Claude skills/agents 도 설치합니다. Claude Code skill 들은 `--runtime claude-code` / `--lead-runtime claude-code` 를 명시하므로 실행 단계에서 host auto-detection 에 의존하지 않습니다.
333
+ `doctor` / `render-bundle` 도 `auto` 를 기본값으로 받지만, host signal 이 없는 plain terminal 에서는 host 지정이 필요합니다. `okstra install` / `ensure-installed` 는 예외입니다. 설치는 runtime host 가 아니라 agent home 기준으로 공유 runtime 과 skill target 을 배치하므로, host signal 이 없어도 `auto` 요청과 미해결 상태를 manifest 에 기록하고 설치를 계속합니다. 스킬 복사 대상은 runtime resolution 이 아니라 agent home 존재 여부와 기본 Agent target 정책입니다. `~/.agents/skills/` 는 항상 생성하고, `~/.claude` 가 있으면 Claude skills/agents 도 설치합니다. Claude Code skill 들은 `--runtime claude-code` / `--lead-runtime claude-code` 를 명시하므로 실행 단계에서 host auto-detection 에 의존하지 않습니다.
334
334
 
335
335
  `installed-runtimes.json` 은 schemaVersion 2 로 `installRequest`, `runtimeResolution`, `installedRuntimes`, `installedAssets` 를 분리합니다. `installed-skills.json` 은 schemaVersion 2 target 목록(`provider`, `root`, `skills`)으로 Claude/Agent skill target 을 기록하며, uninstall 은 이 target 목록을 기준으로 제거합니다. 이전 `codexAdapter` / `externalAdapter` 는 v1 manifest read 호환 경로에서만 해석됩니다.
336
336
 
@@ -625,7 +625,7 @@ chmod +x ~/.local/bin/okstra-ctl
625
625
  | 명령 | 용도 |
626
626
  |---|---|
627
627
  | `okstra paths [--field <name>\|--shell]` | package/runtime/home/bin/pythonpath/version 경로 출력 |
628
- | `okstra install [--runtime claude-code\|codex\|external\|all] [--refresh\|--dry-run\|--link <repo>]` | runtime, templates, skills, agents 설치/갱신. 기본 runtime 은 `auto`; 스킬 대상은 runtime 이 아니다. `~/.agent/skills/` 는 항상 생성하고, `~/.claude` 가 있으면 Claude skills + agents 도 설치한다 |
628
+ | `okstra install [--runtime claude-code\|codex\|external\|all] [--refresh\|--dry-run\|--link <repo>]` | runtime, templates, skills, agents 설치/갱신. 기본 runtime 은 `auto`; 스킬 대상은 runtime 이 아니다. `~/.agents/skills/` 는 항상 생성하고, `~/.claude` 가 있으면 Claude skills + agents 도 설치한다 |
629
629
  | `okstra ensure-installed [--runtime claude-code\|codex\|external\|all] [-q]` | 설치 상태 확인, stale이면 같은 runtime 으로 재설치. 기본 `auto` 는 host signal 이 없어도 설치를 계속하며, Agent skill target 과 존재하는 Claude target 의 drift 를 검사한다 |
630
630
  | `okstra uninstall [--purge -y]` | 설치 자산 제거. 기본값은 `installed-skills.json` target 목록과 `installed-agents.json` 기준으로 제거하고 사용자 데이터는 보존 |
631
631
  | `okstra doctor [--runtime claude-code\|codex\|external\|all] [--phase <phase>] [--json]` | runtime + Python import + skill/agent 설치 진단. `codex` / `external` runtime 은 Claude skill checks 를 제외한다. `--phase` 는 `implementation`, `final-verification`, `release-handoff`, `improvement-discovery` 실행 전 readiness 체크를 추가한다 |
@@ -650,4 +650,4 @@ chmod +x ~/.local/bin/okstra-ctl
650
650
 
651
651
  ### Live-log sidecar
652
652
 
653
- codex / antigravity wrapper 는 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` sidecar 를 만들고 stdout / stderr 를 mirror 합니다. tmux 안에서 lead 를 띄우면 wrapper 가 자동으로 `tail -F` pane 을 분할합니다 (trace pane title: `<cli>-<role>-<pid>-tail`, caller (worker) pane title: `<cli>-<role>-<pid>` — wrapper PID 가 동일 role 의 동시 dispatch 를 구분합니다). 분할된 trace pane 은 `@okstra_trace_run=<RUN_DIR>`, tmux-pane backend worker-compute pane 은 `@okstra_worker_run=<RUN_DIR>` pane user-option 으로 태깅돼, Claude `/exit` 시 `SessionEnd` 훅이 `okstra-trace-cleanup.sh --reap` 로 (`$CLAUDE_PROJECT_DIR/.okstra/` scope) 자동 정리합니다. 같은 스크립트를 lead 가 `--run-dir <RUN_DIR>` 로 호출하면 그 run 의 trace pane + worker-compute pane + dispatch 된 worker-agent pane(title `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`)을 lead 세션 범위에서 함께 정리하며(lead 자신의 pane 은 제외), lead 는 새 phase 진입 전 `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` 를 한 번 실행해 stale pane 을 비웁니다.
653
+ codex / antigravity wrapper 는 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` sidecar 를 만들고 stdout / stderr 를 mirror 합니다. tmux 안에서 lead 를 띄우면 wrapper 가 자동으로 `tail -F` pane 을 분할합니다 (trace pane title: `<cli>-<role>-<pid>-tail`, caller (worker) pane title: `<cli>-<role>-<pid>` — wrapper PID 가 동일 role 의 동시 dispatch 를 구분합니다). 분할된 trace pane 은 `@okstra_trace_run=<RUN_DIR>`, tmux-pane backend worker-compute pane 은 `@okstra_worker_run=<RUN_DIR>` pane user-option 으로 태깅돼, Claude `/exit` 시 `SessionEnd` 훅이 `okstra-trace-cleanup.sh --reap` 로 (`$CLAUDE_PROJECT_DIR/.okstra/` scope) 자동 정리합니다. 같은 스크립트를 lead 가 `--run-dir <RUN_DIR>` 로 호출하면 그 run 의 trace pane + worker-compute pane + dispatch 된 worker-agent pane(title `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`, implementation role title, FleetView teammate prefix `✳ ` / `⠂ `)을 lead 세션 범위에서 함께 정리하며(lead 자신의 pane 은 제외), lead 는 새 phase 진입 전 `okstra-trace-cleanup.sh --run-dir <RUN_DIR>` 를 한 번 실행해 stale pane 을 비웁니다.
@@ -1,6 +1,6 @@
1
1
  # okstra container — CLI 레퍼런스 (한국어)
2
2
 
3
- > `okstra container` 는 검증된 task 의 코드를 로컬 docker compose 그룹으로 띄우고 컨테이너별로 감시하는 비선형 도구입니다. `okstra.sh` 의 phase 플래그와는 별개 진입점이라 [cli.md](cli.md) 가 아닌 이 문서에서 다룹니다. 내부 설계는 [스펙](../superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md), 모듈 위치는 [project-structure-overview](../project-structure-overview.md) §4.3 을 참고하세요.
3
+ > `okstra container` 는 검증된 task 의 코드를 로컬 docker compose 그룹으로 띄우고 컨테이너별로 감시하는 비선형 도구입니다. `okstra.sh` 의 phase 플래그와는 별개 진입점이라 [cli.md](cli.md) 가 아닌 이 문서에서 다룹니다. 모듈 위치는 [project-structure-overview](../project-structure-overview.md) §4.3 을 참고하세요.
4
4
 
5
5
  ---
6
6
 
@@ -368,7 +368,7 @@ Optional Round 2:
368
368
 
369
369
  ### 구현 plan 링크
370
370
 
371
- - P0 + P1: `docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md` (구현 완료 — convergence state v1.2 에 반영)
372
- - P6: `docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md` (구현 완료)
371
+ - P0 + P1: 구현 완료 — convergence state v1.2 에 반영
372
+ - P6: 구현 완료 — token usage 증분 스캔에 반영
373
373
  - critic 병렬화 + phaseTimeline 계측: plan 없이 직접 구현 (2026-06-11, `CHANGES.md` 해당 항목 참조)
374
374
  - P3 / P4 / P5 / B7: 미작성 (각 트랙별로 별도 plan 작성 필요)
@@ -124,7 +124,7 @@ Runtime/install asset changes follow this checklist:
124
124
  - `runtime/python/*` → `~/.okstra/lib/python/`
125
125
  - `runtime/bin/*` → `~/.okstra/bin/`
126
126
  - `runtime/templates/*` → `~/.okstra/templates/`
127
- - `runtime/skills/<name>` (the seven user-facing skills only) → `~/.agent/skills` always, plus `~/.claude/skills` when `~/.claude` exists
127
+ - `runtime/skills/<name>` (the seven user-facing skills only) → `~/.agents/skills` always, plus `~/.claude/skills` when `~/.claude` exists
128
128
  - `runtime/prompts/*` → `~/.okstra/prompts/` (lead contracts under `prompts/lead/`, coding-preflight pack under `prompts/coding-preflight/`)
129
129
  - `runtime/agents/workers/*.md` → `~/.claude/agents/*-worker.md` when `~/.claude` exists
130
130
  - install manifests → `~/.okstra/installed-skills.json` (target-aware), `~/.okstra/installed-agents.json`
@@ -132,7 +132,7 @@ Runtime/install asset changes follow this checklist:
132
132
 
133
133
  `--link <repo>` mode is for development and symlinks installed files back to repo sources.
134
134
 
135
- `src/lib/runtime-resolver.mjs` is the single reference point for runtime auto-detection. `okstra install` defaults to `--runtime auto`, records the request and any successful resolution in `installed-runtimes.json` schemaVersion 2, and still copies the shared runtime payload from the installed package `runtime/` tree even when host detection is unavailable. Skill targets always include the default Agent-compatible `~/.agent/skills` target, with `~/.claude/skills` also populated when `~/.claude` exists. Dynamic capabilities such as `tmux` and `codex` CLI availability are checked by `doctor` and `run`, not frozen into the install manifest. Claude Code skills pass explicit `--runtime claude-code` / `--lead-runtime claude-code` so they never depend on host auto-detection.
135
+ `src/lib/runtime-resolver.mjs` is the single reference point for runtime auto-detection. `okstra install` defaults to `--runtime auto`, records the request and any successful resolution in `installed-runtimes.json` schemaVersion 2, and still copies the shared runtime payload from the installed package `runtime/` tree even when host detection is unavailable. Skill targets always include the default Agent-compatible `~/.agents/skills` target, with `~/.claude/skills` also populated when `~/.claude` exists. Dynamic capabilities such as `tmux` and `codex` CLI availability are checked by `doctor` and `run`, not frozen into the install manifest. Claude Code skills pass explicit `--runtime claude-code` / `--lead-runtime claude-code` so they never depend on host auto-detection.
136
136
 
137
137
  ---
138
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.102.2",
3
+ "version": "0.102.4",
4
4
  "description": "Multi-agent cross-verification orchestrator runtime + Claude Code skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -16,7 +16,12 @@
16
16
  "bin/",
17
17
  "src/",
18
18
  "runtime/",
19
- "docs/",
19
+ "docs/contributor-change-matrix.md",
20
+ "docs/for-ai/",
21
+ "docs/kr/",
22
+ "docs/pr-template-usage.md",
23
+ "docs/project-structure-overview.md",
24
+ "docs/task-process/",
20
25
  "README.md",
21
26
  "README.kr.md"
22
27
  ],
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.102.2",
3
- "builtAt": "2026-06-24T14:47:45.768Z",
2
+ "package": "0.102.4",
3
+ "builtAt": "2026-06-25T17:22:51.416Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -189,6 +189,18 @@ autofill_from_manifest() {
189
189
  return 0
190
190
  fi
191
191
 
192
+ PYTHONPATH="$WORKSPACE_ROOT/scripts:${PYTHONPATH-}" python3 - "$manifest_project_root" "$manifest_task_root" <<'PY' || true
193
+ import sys
194
+ from pathlib import Path
195
+
196
+ from okstra_ctl.implementation_outcome import reconcile_implementation_outcome
197
+
198
+ try:
199
+ reconcile_implementation_outcome(Path(sys.argv[1]), Path(sys.argv[2]))
200
+ except Exception:
201
+ pass
202
+ PY
203
+
192
204
  local need_brief_val need_type_val
193
205
  need_brief_val="$([[ -z "$BRIEF_PATH" ]] && printf '1' || printf '0')"
194
206
  need_type_val="$([[ -z "$TASK_TYPE" ]] && printf '1' || printf '0')"
@@ -135,8 +135,7 @@ log_path="${prompt_path%.md}.log"
135
135
  # 2. Lead's redispatch policy distinguishes "wrapper never started"
136
136
  # from "CLI ran but produced no artifact" via `stage`/`started_ts`.
137
137
  # Writes are best-effort.
138
- status_path="${prompt_path%.md}.status.json"
139
- [[ "$status_path" == "$prompt_path" ]] && status_path="${prompt_path}.status.json"
138
+ status_path="${prompt_path}.status.json"
140
139
  started_ts=$(date +%s)
141
140
  script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
142
141
  # Trace-pane caller resolution helper (okstra_resolve_caller_pane). The lib dir
@@ -179,8 +179,7 @@ log_path="${prompt_path%.md}.log"
179
179
  # from "CLI ran but produced no artifact" via `stage`/`started_ts`.
180
180
  # Writes are best-effort; sidecar failures must NOT break the dispatch
181
181
  # (the underlying CLI run is the wrapper's primary job).
182
- status_path="${prompt_path%.md}.status.json"
183
- [[ "$status_path" == "$prompt_path" ]] && status_path="${prompt_path}.status.json"
182
+ status_path="${prompt_path}.status.json"
184
183
  started_ts=$(date +%s)
185
184
  script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
186
185
  # Trace-pane caller resolution helper (okstra_resolve_caller_pane). The lib dir
@@ -27,20 +27,13 @@ _HERE = Path(__file__).resolve().parent
27
27
  sys.path.insert(0, str(_HERE))
28
28
 
29
29
  from okstra_ctl.i18n import SUPPORTED_LANGS # noqa: E402
30
+ from okstra_ctl.final_report_paths import final_report_markdown_path # noqa: E402
30
31
  from okstra_ctl.render_final_report import ( # noqa: E402
31
32
  FinalReportRenderError,
32
33
  render_to_file,
33
34
  )
34
35
 
35
36
 
36
- def _derive_output_path(data_path: Path) -> Path:
37
- """``foo.data.json`` → ``foo.md``. Anything else gets ``.md`` appended."""
38
- name = data_path.name
39
- if name.endswith(".data.json"):
40
- return data_path.with_name(name[: -len(".data.json")] + ".md")
41
- return data_path.with_suffix(".md")
42
-
43
-
44
37
  def main(argv: list[str]) -> int:
45
38
  parser = argparse.ArgumentParser(
46
39
  description="Render a final-report markdown from its JSON SSOT.",
@@ -80,7 +73,7 @@ def main(argv: list[str]) -> int:
80
73
  )
81
74
  args = parser.parse_args(argv)
82
75
 
83
- output = args.output or _derive_output_path(args.data)
76
+ output = args.output or final_report_markdown_path(args.data)
84
77
 
85
78
  try:
86
79
  bytes_written = render_to_file(
@@ -50,6 +50,7 @@ from pathlib import Path
50
50
 
51
51
  sys.path.insert(0, str(Path(__file__).resolve().parent))
52
52
 
53
+ from okstra_ctl.final_report_paths import final_report_markdown_path # noqa: E402
53
54
  from okstra_project.dirs import tasks_root # noqa: E402
54
55
 
55
56
 
@@ -110,13 +111,10 @@ def _write_manifest(path: Path, payload: dict) -> None:
110
111
 
111
112
  def _data_to_report_path(data_path: Path) -> Path:
112
113
  """Derive the markdown sibling path used in spawned manifests for
113
- the `parentReportPath` field. Falls back to the data.json itself if
114
- the suffix is not recognised.
114
+ the `parentReportPath` field. Falls back to replacing the suffix with
115
+ ``.md`` when the conventional suffix is not recognised.
115
116
  """
116
- name = data_path.name
117
- if name.endswith(".data.json"):
118
- return data_path.with_name(name[: -len(".data.json")] + ".md")
119
- return data_path.with_suffix(".md")
117
+ return final_report_markdown_path(data_path)
120
118
 
121
119
 
122
120
  def _spawn_one(
@@ -128,6 +128,27 @@ _tag_in_scope() {
128
128
  [[ "$tag" == "$run_dir" ]]
129
129
  }
130
130
 
131
+ _title_in_okstra_scope() {
132
+ local title="$1"
133
+ case "$title" in
134
+ # Claude/FleetView teammate panes may carry the task title instead of the
135
+ # worker id. These glyph prefixes are the only stable tmux-side signal.
136
+ "✳ "*|"⠂ "*)
137
+ return 0 ;;
138
+ *claude-worker*|*claude-executor*|*claude-verifier*)
139
+ return 0 ;;
140
+ *codex-worker*|*codex-executor*|*codex-verifier*)
141
+ return 0 ;;
142
+ *agy-worker*|*agy-executor*|*agy-verifier*)
143
+ return 0 ;;
144
+ *antigravity-worker*|*antigravity-executor*|*antigravity-verifier*)
145
+ return 0 ;;
146
+ *report-writer-worker*|*report-writer*)
147
+ return 0 ;;
148
+ esac
149
+ return 1
150
+ }
151
+
131
152
  collect_okstra_panes() {
132
153
  local -a panes=()
133
154
  local pid trace_tag worker_tag status_tag title
@@ -166,10 +187,9 @@ collect_okstra_panes() {
166
187
  while IFS=$'\t' read -r pid title; do
167
188
  [[ -n "$pid" ]] || continue
168
189
  [[ "$pid" == "$lead_pane" ]] && continue
169
- case "$title" in
170
- *claude-worker*|*codex-worker*|*antigravity-worker*|*report-writer-worker*)
171
- panes+=("$pid") ;;
172
- esac
190
+ if _title_in_okstra_scope "$title"; then
191
+ panes+=("$pid")
192
+ fi
173
193
  done < <(tmux list-panes -s -t "$lead_pane" \
174
194
  -F '#{pane_id}'$'\t''#{pane_title}' 2>/dev/null || true)
175
195
  fi