okstra 0.102.2 → 0.102.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.kr.md +5 -5
  2. package/README.md +5 -5
  3. package/docs/kr/architecture/storage-model.md +8 -3
  4. package/docs/kr/architecture.md +12 -13
  5. package/docs/kr/cli.md +4 -4
  6. package/docs/kr/container.md +1 -1
  7. package/docs/kr/performance-improvement-plan-v2.md +2 -2
  8. package/docs/project-structure-overview.md +2 -2
  9. package/package.json +7 -2
  10. package/runtime/BUILD.json +2 -2
  11. package/runtime/bin/lib/okstra/interactive.sh +12 -0
  12. package/runtime/bin/okstra-antigravity-exec.sh +1 -2
  13. package/runtime/bin/okstra-codex-exec.sh +1 -2
  14. package/runtime/bin/okstra-render-final-report.py +2 -9
  15. package/runtime/bin/okstra-spawn-followups.py +4 -6
  16. package/runtime/bin/okstra-trace-cleanup.sh +24 -4
  17. package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
  18. package/runtime/prompts/lead/report-writer.md +1 -1
  19. package/runtime/prompts/profiles/_common-contract.md +9 -11
  20. package/runtime/python/okstra_ctl/codex_dispatch.py +6 -13
  21. package/runtime/python/okstra_ctl/consumers.py +35 -0
  22. package/runtime/python/okstra_ctl/container.py +4 -6
  23. package/runtime/python/okstra_ctl/dispatch_core.py +8 -13
  24. package/runtime/python/okstra_ctl/final_report_paths.py +24 -0
  25. package/runtime/python/okstra_ctl/handoff.py +2 -1
  26. package/runtime/python/okstra_ctl/implementation_outcome.py +271 -0
  27. package/runtime/python/okstra_ctl/implementation_stage.py +7 -11
  28. package/runtime/python/okstra_ctl/path_hints.py +665 -0
  29. package/runtime/python/okstra_ctl/render.py +4 -3
  30. package/runtime/python/okstra_ctl/report_view_artifacts.py +14 -0
  31. package/runtime/python/okstra_ctl/report_views.py +7 -4
  32. package/runtime/python/okstra_ctl/run.py +3 -10
  33. package/runtime/python/okstra_ctl/run_context.py +4 -2
  34. package/runtime/python/okstra_ctl/stage_targets.py +18 -0
  35. package/runtime/python/okstra_ctl/wizard.py +37 -26
  36. package/runtime/python/okstra_ctl/wizard_stage_intent.py +54 -0
  37. package/runtime/python/okstra_project/state.py +40 -2
  38. package/runtime/python/okstra_token_usage/report.py +2 -5
  39. package/runtime/validators/validate-report-views.py +2 -1
  40. package/runtime/validators/validate-run.py +1 -11
  41. package/src/commands/lifecycle/install.mjs +5 -5
  42. package/src/commands/lifecycle/uninstall.mjs +4 -4
  43. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
  44. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
  45. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
  46. package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
  47. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
  48. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
  49. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
  50. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
  51. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
  52. package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
  53. package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
  54. package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
  55. package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
  56. package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
  57. package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
  58. package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
  59. package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
  60. package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
  61. package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
  62. package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
  63. package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
  64. package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
  65. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
  66. package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
  67. package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
  68. package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
  69. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
  70. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
  71. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
  72. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
  73. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
  74. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
  75. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
  76. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
  77. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
  78. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
  79. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
  80. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
  81. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
  82. package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
  83. package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
  84. package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
  85. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
  86. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
  87. package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
  88. package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
  89. package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
  90. package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
  91. package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
  92. package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
  93. package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
  94. package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
  95. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
  96. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
  97. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
  98. package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
  99. package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
  100. package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
  101. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
  102. package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
  103. package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
  104. package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
  105. package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
  106. package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
  107. package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
  108. package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
  109. package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
  110. package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
  111. package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
  112. package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
  113. package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
  114. package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
  115. package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
  116. package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
  117. package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
  118. package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
  119. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
  120. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
  121. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
  122. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
  123. package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
  124. package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
  125. package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
  126. package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
  127. package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
  128. package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
  129. package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
  130. package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
  131. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
  132. package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
  133. package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
  134. package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
  135. package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
  136. package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
  137. package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
  138. package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
  139. package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
  140. package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
  141. package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
  142. package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
  143. package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
  144. package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
  145. package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
  146. package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
  147. package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
  148. package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
  149. package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
  150. package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
  151. package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
  152. package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
  153. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
  154. package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
  155. package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
  156. package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
  157. package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
  158. package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
  159. package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
  160. package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
  161. package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
  162. package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
  163. package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
  164. package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
  165. package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
  166. package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
  167. package/docs/superpowers/specs/2026-06-24-okstra-container-build-rename-design.md +0 -110
@@ -1,404 +0,0 @@
1
- # Host 기반 runtime auto-detection + auto-execution 설계
2
-
3
- - 날짜: 2026-06-14
4
- - 상태: 설계 초안
5
- - 대상: `okstra install`, `okstra doctor`, `okstra run`, lead runtime resolution, runtime manifest
6
- - 선행 문서:
7
- - [`2026-06-12-codex-lead-adapter-design.md`](2026-06-12-codex-lead-adapter-design.md)
8
- - [`2026-06-13-neutral-tmux-lead-adapter-design.md`](2026-06-13-neutral-tmux-lead-adapter-design.md)
9
-
10
- ## 1. 배경
11
-
12
- 현재 runtime 선택은 자동 감지가 아니다. `okstra install` 은 기본값 `claude-code` 를 사용하고, `installed-runtimes.json` 의 `codexAdapter` / `externalAdapter` 는 실제 adapter 실행 가능성이 아니라 install 인자 선택값만 반영한다.
13
-
14
- 확인된 현재 상태:
15
-
16
- - `installed-runtimes.json` 은 `runtime === "codex" || "all"` 일 때만 `codexAdapter:true`, `runtime === "external" || "all"` 일 때만 `externalAdapter:true` 를 쓴다([runtime-manifest.mjs:8](../../../src/runtime-manifest.mjs:8)).
17
- - `okstra install` 기본 runtime 은 `claude-code` 다([install.mjs:606](../../../src/install.mjs:606)).
18
- - `okstra doctor` 기본 runtime 도 `claude-code` 다([doctor.mjs:37](../../../src/doctor.mjs:37)).
19
- - Python prepare layer 는 `leadRuntime != "claude-code"` 이고 non-render 이면 막는다([run.py:2053](../../../scripts/okstra_ctl/run.py:2053)).
20
- - `--lead-runtime` 기본값도 `claude-code` 다([run.py:2416](../../../scripts/okstra_ctl/run.py:2416)).
21
- - `okstra team` 은 `leadRuntime=external` bundle 을 받아 tmux-pane worker dispatch/await/teardown 을 수행하는 Node→Python CLI 경계다([team.mjs:4](../../../src/team.mjs:4)).
22
-
23
- 사용자 결정:
24
-
25
- 1. 자동 감지 범위는 **실행까지 자동**이다.
26
- 2. runtime 우선순위는 **host 기반**이다.
27
- 3. fallback 은 **safe fallback** 이다. 의도와 다른 runtime 으로 조용히 넘어가지 않는다.
28
-
29
- ## 2. 문제
30
-
31
- 현재 이름과 동작이 서로 맞지 않는다.
32
-
33
- - `codexAdapter:false` / `externalAdapter:false` 는 adapter 미설치 또는 CLI 부재처럼 보이지만, 실제 의미는 "이번 install 선택값이 `claude-code`" 이다.
34
- - 공유 runtime 은 항상 `~/.okstra/bin` 으로 복사되므로 wrapper 파일 존재와 manifest flag 가 일치하지 않는다.
35
- - 사용자는 `okstra install` / `okstra run` 이 현재 host 를 이해한다고 기대하지만, 실제로는 `claude-code` 로 고정된다.
36
- - `external` 실행은 Python non-render gate 때문에 직접 full-run 으로 열 수 없고, Node driver 가 render-only prepare → team dispatch/await 를 orchestration 해야 한다.
37
-
38
- ## 3. 결정
39
-
40
- `auto` 를 runtime 값 자체가 아니라 **resolver 입력값**으로 도입한다.
41
-
42
- ```text
43
- explicit runtime: claude-code | codex | external | all
44
- auto request: host/context 를 감지해 위 runtime 중 하나로 resolve
45
- ```
46
-
47
- 새 단일 참조점:
48
-
49
- ```text
50
- src/runtime-resolver.mjs
51
- ```
52
-
53
- 역할:
54
-
55
- 1. host signal 수집
56
- 2. 설치 자산과 실행 capability 검사
57
- 3. command 별 허용 runtime 계산
58
- 4. safe fallback 적용
59
- 5. 최종 runtime, 이유, 경고를 구조화해서 반환
60
-
61
- 예상 API:
62
-
63
- ```js
64
- resolveRuntime({
65
- requestedRuntime: "auto" | "claude-code" | "codex" | "external" | "all",
66
- command: "install" | "ensure-installed" | "doctor" | "render" | "run" | "dispatch",
67
- env: process.env,
68
- paths,
69
- })
70
- ```
71
-
72
- 반환:
73
-
74
- ```json
75
- {
76
- "requestedRuntime": "auto",
77
- "resolvedRuntime": "external",
78
- "host": "generic-terminal",
79
- "confidence": "high",
80
- "reason": "No Claude Code or Codex host signal; tmux is available.",
81
- "fallbackFrom": null,
82
- "warnings": []
83
- }
84
- ```
85
-
86
- 핵심 규칙:
87
-
88
- - 명시 runtime 은 자동 override 하지 않는다.
89
- - `auto` 일 때만 감지한다.
90
- - resolver 결과는 install manifest, run manifest, doctor JSON, console output 에 남긴다.
91
- - `codexAdapter` / `externalAdapter` 는 새 manifest 에서 쓰지 않는다. v1 manifest read compatibility 에서만 해석한다.
92
-
93
- ## 4. 용어
94
-
95
- | 용어 | 의미 |
96
- |---|---|
97
- | install runtime | 어떤 asset set 을 설치/보장할지 결정하는 값 |
98
- | lead runtime | 이번 run 의 lead adapter 정체성: `claude-code`, `codex`, `external` |
99
- | host | 현재 `okstra` 를 실행 중인 환경: Claude Code session, Codex CLI/session, generic terminal |
100
- | dispatch backend | worker 를 어떻게 실행하는지: Claude Teams, CLI wrapper, tmux pane |
101
- | capability | 현재 시점에서 실행 가능한 조건: CLI binary, tmux, installed assets, phase support |
102
- | safe fallback | 같은 intent 를 보존할 수 있을 때만 fallback 하는 정책 |
103
-
104
- ## 5. Host 감지
105
-
106
- Resolver 는 allowlist 기반 signal 만 사용한다. 불명확한 signal 은 runtime 을 결정하지 않고 warning 으로 남긴다.
107
-
108
- 감지 우선순위:
109
-
110
- 1. **Explicit runtime**
111
- - CLI flag 또는 env override 가 `auto` 가 아니면 그대로 사용한다.
112
- - 예: `--lead-runtime external`, `OKSTRA_LEAD_RUNTIME=codex`.
113
- 2. **Explicit host override**
114
- - 새 env `OKSTRA_RUNTIME_HOST=claude-code|codex|external`.
115
- - 테스트와 wrapper 가 안정적으로 host 를 주입할 수 있는 public contract 다.
116
- 3. **Claude Code host**
117
- - Claude Code slash skill 또는 agent contract 가 `OKSTRA_RUNTIME_HOST=claude-code` 를 넘기는 방식이 primary signal 이다.
118
- - 환경 fingerprint 는 보조 signal 로만 사용한다.
119
- 4. **Codex host**
120
- - Codex wrapper/entrypoint 가 `OKSTRA_RUNTIME_HOST=codex` 를 넘기는 방식이 primary signal 이다.
121
- - `codex` executable 존재만으로 Codex host 라고 판단하지 않는다. binary availability 는 capability 일 뿐 host 가 아니다.
122
- 5. **External host**
123
- - 명시 host 가 없고, 일반 terminal 에서 `tmux` 가 사용 가능하면 `external`.
124
- 6. **Unknown**
125
- - host 와 capability 가 모두 부족하면 fail-fast.
126
-
127
- 이 설계는 "binary가 설치되어 있으니 그 runtime으로 실행" 을 피한다. host 기반 결정과 capability 검사를 분리해야 예측 가능하다.
128
-
129
- ## 6. Safe fallback matrix
130
-
131
- Fallback 은 `requestedRuntime:auto` 에서만 동작한다. 명시 runtime 은 실패를 사용자에게 보여주고 중단한다.
132
-
133
- | resolved candidate | 실행 불가 이유 | fallback |
134
- |---|---|---|
135
- | `claude-code` | Claude Code host signal 은 있으나 Claude assets 누락 | `ensure-installed --runtime claude-code` 로 보강 후 재시도 |
136
- | `claude-code` | Claude Code host 가 아닌 것으로 판정 | `external` if tmux 가능, 아니면 fail |
137
- | `codex` | Codex host signal 은 있으나 Codex CLI 없음 | fail. Claude/external 로 조용히 전환하지 않음 |
138
- | `codex` | requested roster 에 unsupported worker 포함 | fail with supported worker/report-writer opt-in 안내 |
139
- | `external` | tmux 없음 | prepare/render-only 까지는 가능, dispatch 는 fail |
140
- | `external` | `claude` worker 포함, Claude CLI wrapper 실행 불가 | 해당 worker dispatch fail. roster 를 몰래 줄이지 않음 |
141
- | unknown | host signal 없음 + tmux 없음 | fail with next-command suggestion |
142
-
143
- Fallback reason 은 run manifest 에 남긴다.
144
-
145
- ## 7. CLI UX
146
-
147
- ### 7.1 기본값
148
-
149
- 다음 command 의 기본 runtime 을 `auto` 로 바꾼다.
150
-
151
- ```bash
152
- okstra install
153
- okstra ensure-installed
154
- okstra doctor
155
- okstra render-bundle ...
156
- okstra run ...
157
- ```
158
-
159
- 명시 선택은 유지한다.
160
-
161
- ```bash
162
- okstra install --runtime claude-code
163
- okstra install --runtime codex
164
- okstra install --runtime external
165
- okstra install --runtime all
166
- okstra run --lead-runtime external ...
167
- ```
168
-
169
- `all` 은 감지값이 아니다. 모든 runtime asset set 을 명시 설치/검사하는 admin mode 로 유지한다.
170
-
171
- ### 7.2 Execution front doors
172
-
173
- Auto execution has two front doors because Claude Code native tools are not available to a plain Node process.
174
-
175
- | Front door | Host | Responsibility |
176
- |---|---|---|
177
- | `/okstra-run` skill | Claude Code | Uses resolver context, keeps the existing Claude Code interactive/team path |
178
- | `okstra run` Node CLI | Codex / generic terminal | Resolves runtime and orchestrates CLI-backed `codex` or `external` execution |
179
-
180
- New Node driver `okstra run` is still useful, but it must not pretend it can call Claude Code `TeamCreate` / `Agent(...)` from a terminal. If `okstra run` resolves `claude-code` without being invoked by a Claude Code skill handoff, it fails with an instruction to use `/okstra-run` or pass another explicit runtime.
181
-
182
- ```text
183
- okstra run ...
184
- → resolveRuntime(requestedRuntime=auto by default, command=run)
185
- → if resolvedRuntime=codex: codex-run → codex-dispatch
186
- → if resolvedRuntime=external: render-bundle → team dispatch → team await
187
- → if resolvedRuntime=claude-code outside skill handoff: fail with /okstra-run guidance
188
- ```
189
-
190
- `external` 은 Python `prepare_task_bundle()` 의 non-render gate 를 열지 않는다. Node `okstra run` 이 render-only prepare 이후 dispatch/await 를 소유한다.
191
-
192
- ### 7.3 기존 command 와의 관계
193
-
194
- - `okstra codex-run`: 유지. Codex lead prompt materialization 의 explicit low-level command.
195
- - `okstra codex-dispatch`: 유지. Prepared Codex run 의 explicit dispatch command.
196
- - `okstra team dispatch/await/teardown`: 유지. External/tmux backend 의 explicit low-level command.
197
- - `okstra render-bundle`: 유지. Preview/debug 목적의 low-level prepare command.
198
- - `okstra run`: 위 command 들을 host-aware 하게 묶는 high-level command.
199
-
200
- ## 8. Manifest 변경
201
-
202
- ### 8.1 installed-runtimes.json v2
203
-
204
- 현재 v1 의 `codexAdapter` / `externalAdapter` 는 쓰지 않는다. 새 manifest 는 설치 요청과 설치 자산을 분리한다.
205
-
206
- ```json
207
- {
208
- "schemaVersion": 2,
209
- "installedAt": "2026-06-14T00:00:00.000Z",
210
- "installRequest": "auto",
211
- "runtimeResolution": {
212
- "requestedRuntime": "auto",
213
- "resolvedRuntime": "external",
214
- "host": "generic-terminal",
215
- "reason": "No Claude Code or Codex host signal; tmux is available.",
216
- "fallbackFrom": null,
217
- "warnings": []
218
- },
219
- "installedRuntimes": ["external"],
220
- "installedAssets": {
221
- "sharedRuntime": true,
222
- "claudeSkills": false,
223
- "claudeAgents": false,
224
- "binWrappers": true,
225
- "templates": true,
226
- "schemas": true,
227
- "validators": true
228
- }
229
- }
230
- ```
231
-
232
- Dynamic capability 는 install manifest 에 고정하지 않는다. `tmux`, `codex`, `claude` CLI availability 는 시간이 지나면 바뀌므로 `doctor` 와 `run` 이 매번 검사한다.
233
-
234
- ### 8.2 run manifest additions
235
-
236
- Run manifest 에 runtime request/resolution 을 기록한다.
237
-
238
- ```json
239
- {
240
- "leadRuntimeRequest": "auto",
241
- "leadRuntime": "external",
242
- "runtimeResolution": {
243
- "requestedRuntime": "auto",
244
- "resolvedRuntime": "external",
245
- "host": "generic-terminal",
246
- "reason": "No Claude Code or Codex host signal; tmux is available.",
247
- "fallbackFrom": null,
248
- "warnings": []
249
- }
250
- }
251
- ```
252
-
253
- `leadRuntime` 은 기존 consumer 호환을 위해 최종 resolved runtime 을 유지한다.
254
-
255
- ## 9. Install / ensure / doctor 동작
256
-
257
- ### 9.1 install
258
-
259
- `okstra install` 기본값은 `--runtime auto` 와 같다.
260
-
261
- - Claude Code host → `claude-code` assets 설치: shared runtime + Claude skills/agents.
262
- - Codex host → `codex` assets 설치: shared runtime only.
263
- - Generic terminal + tmux → `external` assets 설치: shared runtime only.
264
- - `--runtime all` → shared runtime + Claude skills/agents + all installedRuntimes 기록.
265
-
266
- 공유 runtime 은 모든 install mode 에서 복사한다. 이 때문에 `bin/okstra-codex-exec.sh` 같은 wrapper 존재만으로 `codex` runtime 설치를 의미하지 않는다. v2 manifest 는 이 혼동을 `installedAssets` 와 `installedRuntimes` 로 나눠 제거한다.
267
-
268
- ### 9.2 ensure-installed
269
-
270
- `okstra ensure-installed` 기본값도 auto다.
271
-
272
- - 현재 host 에 필요한 asset 이 없으면 같은 host-resolved runtime 으로 install 을 수행한다.
273
- - generic terminal 에서 `external` 로 설치된 뒤 Claude Code 에서 `/okstra-run` 이 실행되면, Claude Code host signal 이 `claude-code` 로 resolve 되고 Claude assets 를 보강 설치한다.
274
- - v1 manifest 는 읽을 수 있어야 한다. v1 에서 `runtime:"claude-code"` 이면 `installedRuntimes:["claude-code"]` 로 해석한다.
275
-
276
- ### 9.3 doctor
277
-
278
- `okstra doctor --runtime auto` 는 현재 host 에 필요한 readiness 만 검사한다.
279
-
280
- `okstra doctor --runtime all` 은 admin check 로 다음을 모두 검사한다.
281
-
282
- - shared runtime files
283
- - Claude assets
284
- - Codex CLI availability
285
- - external/tmux availability
286
- - manifest v1/v2 해석
287
-
288
- JSON output 에 `runtimeResolution` 을 포함한다.
289
-
290
- ## 10. Execution flow
291
-
292
- ### 10.1 Claude Code host
293
-
294
- ```text
295
- /okstra-run
296
- → resolver context = claude-code
297
- → ensure-installed claude-code
298
- → existing Claude Code interactive/team path
299
- ```
300
-
301
- Bare `okstra run` must not claim Claude Code execution unless it is part of a Claude Code skill handoff. A Node process cannot invoke native `TeamCreate` / `Agent(...)` directly.
302
-
303
- 이 경로는 기존 slash skill UX 를 깨지 않는다.
304
-
305
- ### 10.2 Codex host
306
-
307
- ```text
308
- okstra run ...
309
- → resolveRuntime = codex
310
- → ensure-installed codex
311
- → okstra codex-run ...
312
- → okstra codex-dispatch ...
313
- ```
314
-
315
- Report-writer 는 기존 Codex opt-in 정책을 따른다. 필요한 phase 에서 report-writer 가 required 인데 opt-in 이 없으면 fail-fast 한다. Worker roster 를 몰래 줄이지 않는다.
316
-
317
- ### 10.3 External/generic terminal host
318
-
319
- ```text
320
- okstra run ...
321
- → resolveRuntime = external
322
- → ensure-installed external
323
- → okstra render-bundle ... --lead-runtime external
324
- → read produced run manifest
325
- → okstra team dispatch --run-manifest <path>
326
- → okstra team await --run-manifest <path>
327
- → post-processing / validation
328
- ```
329
-
330
- Python `prepare_task_bundle()` 의 non-render gate 는 유지한다. Full external execution 은 Node driver 가 orchestration 한다.
331
-
332
- ## 11. Error handling
333
-
334
- All resolver failures should be actionable.
335
-
336
- Examples:
337
-
338
- - `auto resolved codex but codex CLI is unavailable. Install Codex CLI or run with --lead-runtime external.`
339
- - `auto resolved external but tmux is unavailable. Run render-only or install tmux.`
340
- - `explicit --lead-runtime codex requested, but worker claude is unsupported by codex-dispatch. Choose supported workers or use claude-code/external.`
341
- - `host unknown. Set OKSTRA_RUNTIME_HOST=claude-code|codex|external or pass --lead-runtime explicitly.`
342
-
343
- No fallback may change worker roster, phase, task type, executor, or report-writer role without explicit user input.
344
-
345
- ## 12. Backward compatibility
346
-
347
- - Existing explicit flags keep working.
348
- - Existing `okstra codex-run`, `okstra codex-dispatch`, `okstra team *`, `okstra render-bundle` keep working.
349
- - v1 `installed-runtimes.json` remains readable.
350
- - New installs write v2.
351
- - Existing v1 `codexAdapter` / `externalAdapter` are interpreted only while reading old manifests.
352
- - `leadRuntime` in run manifest remains final resolved runtime, so validators that already read `leadRuntime` do not need a broad schema break.
353
-
354
- ## 13. Tests
355
-
356
- Required test groups:
357
-
358
- 1. `runtime-resolver` unit tests
359
- - explicit runtime bypasses auto
360
- - host override resolves each runtime
361
- - generic terminal + tmux resolves external
362
- - binary availability alone does not imply host
363
- - safe fallback matrix
364
- 2. install tests
365
- - default install writes v2 auto manifest
366
- - Claude host installs Claude assets
367
- - external host skips Claude assets
368
- - v1 manifest read compatibility
369
- 3. doctor tests
370
- - `--runtime auto` reports runtimeResolution
371
- - `--runtime all` checks all readiness categories
372
- 4. run driver tests
373
- - auto external builds render-only bundle and invokes team dispatch/await in dry-run/fake mode
374
- - auto codex invokes codex-run/codex-dispatch in dry-run/fake mode
375
- - bare `okstra run` resolving `claude-code` fails with `/okstra-run` guidance
376
- - unsupported Codex worker fails without roster shrink
377
- 5. docs contract tests
378
- - default runtime is auto
379
- - host-based priority documented
380
- - safe fallback documented
381
- - manifest v2 no longer documents `codexAdapter` / `externalAdapter` as live fields
382
-
383
- ## 14. Rollout plan
384
-
385
- Recommended implementation order:
386
-
387
- 1. Add `runtime-resolver.mjs` and tests.
388
- 2. Add v2 runtime manifest writer/reader while preserving v1 read path.
389
- 3. Switch install/ensure/doctor defaults from `claude-code` to `auto`.
390
- 4. Add `okstra run` high-level driver with dry-run/fake subprocess tests.
391
- 5. Wire external execution path through render-bundle → team dispatch → team await.
392
- 6. Wire codex execution path through codex-run → codex-dispatch.
393
- 7. Update docs and CLI help.
394
- 8. Keep explicit low-level commands unchanged.
395
-
396
- ## 15. Non-goals
397
-
398
- - Do not remove explicit runtime flags.
399
- - Do not remove Claude Code slash skill UX.
400
- - Do not make binary availability alone choose a host.
401
- - Do not open Python `prepare_task_bundle()` non-render for `external` in this change.
402
- - Do not silently shrink worker roster for fallback.
403
- - Do not implement non-tmux external dispatch backends.
404
- - Do not change phase profile/schema/validator contracts by provider fork.
@@ -1,123 +0,0 @@
1
- # okstra-run 에러 집계 리포트 (`okstra error-report` + inspect `errors` facet) 설계
2
-
3
- - 날짜: 2026-06-17
4
- - 상태: 설계 초안
5
- - 대상: 신규 `scripts/okstra_ctl/error_report.py`, 신규 `src/error-report.mjs`, `src/cli-registry.mjs`, `skills/okstra-inspect/SKILL.md`
6
- - 선행 문서:
7
- - [`2026-06-06-stage-worktree-isolation-design.md`](2026-06-06-stage-worktree-isolation-design.md) (stage-isolated run 경로)
8
-
9
- ## 1. 배경
10
-
11
- okstra-run 은 실행 중 발생한 에러를 이미 구조화된 형태로 적재하고 있다. 그러나 그 데이터를 **읽어서 사람에게 리포트로 보여주는 소비자가 없다.**
12
-
13
- 확인된 현재 상태:
14
-
15
- - 에러는 run 별 JSONL 로 적재된다: `runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl` ([paths.py:196](../../../scripts/okstra_ctl/paths.py:196)).
16
- - 단일 writer 헬퍼가 스키마를 강제한다. 레코드 필드는 `ts / recordedAt / taskKey / phase / agent / agentRole / model / source / errorType / command / commandKind / exitCode / durationMs / message / stderrExcerpt / context` ([okstra-error-log.py:122](../../../scripts/okstra-error-log.py:122)).
17
- - 두 경로로 수집된다: lead 가 직접 관측한 에러(`append-observed`)와 워커 사이드카(`worker-results/<id>-worker-errors-*.json`)에서 끌어온 에러(`append-from-worker`) ([okstra-error-log.py:96](../../../scripts/okstra-error-log.py:96), [okstra-error-log.py:144](../../../scripts/okstra-error-log.py:144)). `source` 는 각각 `lead-observed` / `worker-reported`.
18
- - `errorType` 화이트리스트: `tool-failure`, `cli-failure`, `contract-violation` ([okstra-error-log.py:17](../../../scripts/okstra-error-log.py:17)).
19
- - `_active_error_logs` 는 이 경로들을 **lead 에게 "여기 기록하라"고 알려주는 쓰기 타깃**으로만 노출한다 ([render.py:361](../../../scripts/okstra_ctl/render.py:361), [render.py:430](../../../scripts/okstra_ctl/render.py:430)). errors.jsonl 을 읽어 보고하는 코드는 없다(grep 확인).
20
- - okstra-inspect 는 현재 `latestRunStatus == error` 라는 **run 단위 거친 상태**만 노출할 뿐, 개별 에러 이벤트(어느 phase 에서 어느 워커가 무슨 command 로 exitCode 몇으로 실패했는지)는 어디서도 리포트하지 않는다 ([skills/okstra-inspect/SKILL.md:206](../../../skills/okstra-inspect/SKILL.md:206)).
21
-
22
- ## 2. 사용자 결정
23
-
24
- 브레인스토밍에서 4개 핵심을 확정했다.
25
-
26
- 1. **리포트 성격 = 파일 산출물.** 화면 출력에 그치지 않고 `.md` 파일로 저장한다.
27
- 2. **범위 = task 전체 집계.** 한 task 의 모든 run 에 걸친 errors.jsonl 을 합쳐 phase / worker / errorType 별로 집계한다.
28
- 3. **렌더링 주체 = 신규 CLI `okstra error-report`.** 여러 run 의 JSONL 집계는 결정론적이어야 정확하므로 Python 렌더러가 수행한다. inspect facet 은 이 CLI 를 호출하고 결과를 표시한다 — `cost` facet 이 `okstra context-cost` 를 호출하는 것과 동일한 패턴 ([skills/okstra-inspect/SKILL.md:528](../../../skills/okstra-inspect/SKILL.md:528)).
29
- 4. **저장 방식 = timestamp 누적.** 매 호출마다 새 파일을 만들어 이력을 파일로 보존한다 — schedule 산출물과 동일한 누적 패턴 ([skills/okstra-schedule/SKILL.md:160](../../../skills/okstra-schedule/SKILL.md:160)).
30
-
31
- ## 3. 아키텍처
32
-
33
- 4개 변경. 모두 기존 컴포넌트를 복제하므로 새 패턴을 만들지 않는다.
34
-
35
- | 컴포넌트 | 역할 | 복제 대상 |
36
- |---|---|---|
37
- | `scripts/okstra_ctl/error_report.py` (신규) | task-key → task_root resolve → errors.jsonl glob → 집계 → `.md` 렌더 + stdout JSON 요약 | [`context_cost.py`](../../../scripts/okstra_ctl/context_cost.py) |
38
- | `src/error-report.mjs` (신규) | Node CLI 래퍼. `runPythonModule({module: "okstra_ctl.error_report"})` | [`src/context-cost.mjs`](../../../src/context-cost.mjs) |
39
- | `src/cli-registry.mjs` | `error-report` 명령 등록 (`introspection` 카테고리) | [`cli-registry.mjs:100`](../../../src/cli-registry.mjs:100) (context-cost 항목) |
40
- | `skills/okstra-inspect/SKILL.md` | 신규 `errors` facet 섹션 + dispatch 테이블 1행 + 트리거 phrase | `cost` facet 섹션 |
41
-
42
- ### 단일 참조점 준수
43
-
44
- task-key → task_root 해석의 SSOT 는 공유 모듈 `okstra_project` 의 `find_task_root` / `resolve_project_root` 다 ([context_cost.py:16](../../../scripts/okstra_ctl/context_cost.py:16) 가 이를 `_resolve_task_root` 로 감싸 사용, [context_cost.py:92](../../../scripts/okstra_ctl/context_cost.py:92)). `error_report.py` 는 새 해석 경로를 만들지 않고 같은 공유 모듈을 직접 재사용한다 — `context_cost.py` 의 `_resolve_task_root`(target = task-root path / task-key + project-root / task-key + cwd 3형태)와 동일한 입력 계약을 따른다.
45
-
46
- ## 4. CLI 인터페이스
47
-
48
- ```
49
- okstra error-report <task-root>
50
- okstra error-report <task-key> --project-root <dir>
51
- okstra error-report <task-key> --cwd <dir>
52
- ```
53
-
54
- - 입력 형태는 `context-cost` 와 동일(task-root 직접 / task-key + project-root / task-key + cwd).
55
- - 동작: errors.jsonl 들을 모아 집계 → `.md` 파일을 쓰고 → **stdout 으로 요약 JSON** 을 낸다.
56
- - stdout JSON shape(초안):
57
- ```json
58
- {
59
- "taskKey": "<project-id>:<task-group>:<task-id>",
60
- "reportPath": "<project-root-relative .md path>",
61
- "totals": { "errorCount": 12, "runCount": 4, "byErrorType": {...}, "bySource": {...} },
62
- "byPhase": [ { "phase": "...", "count": N } ],
63
- "byAgent": [ { "agent": "...", "count": N } ]
64
- }
65
- ```
66
- - inspect `errors` facet 은 이 JSON 을 파싱해 생성 경로 + 요약 카운트만 화면에 표시한다(전체 본문은 `.md` 파일이 SSOT).
67
-
68
- ## 5. 산출물 위치 / 구조
69
-
70
- - 저장 경로: **`<task_root>/error-reports/error-report-<YYYY-MM-DD_HH-MM-SS>.md`**
71
- - task 레벨 집계 산출물이므로 task root 하위 전용 디렉터리(`error-reports/`)에 둔다. run 별 산출물(`runs/<type>/reports/`, [paths.py:148](../../../scripts/okstra_ctl/paths.py:148))과 레벨이 다르므로 디렉터리를 분리해 혼동을 막는다.
72
- - timestamp 형식은 schedule 과 동일한 `<YYYY-MM-DD_HH-MM-SS>`.
73
- - artifact-home 규칙 준수: 모든 산출물이 `<PROJECT_ROOT>/.okstra/` 하위에 있다.
74
- - 리포트 `.md` 섹션 구조:
75
- 1. **요약** — 총 에러 N건, 집계된 run 수, `errorType` 별 카운트, `source`(lead-observed / worker-reported) 별 카운트, 생성 시각.
76
- 2. **phase 별 집계** — `| Phase | Count |` (lifecycle phase 순).
77
- 3. **worker(agent) 별 집계** — `| Agent | Role | Count |`.
78
- 4. **run 별 분해** — `| Run (type/seq) | Errors | 최초 ts | 최종 ts |`.
79
- 5. **개별 에러 이벤트** — `ts / phase / agent / errorType / command / exitCode / message` 테이블 + `stderrExcerpt` 는 접힌 코드블록. `ts` 오름차순.
80
-
81
- ## 6. 데이터 흐름
82
-
83
- 1. task-key → task_root resolve (context_cost 와 동일).
84
- 2. errors.jsonl glob:
85
- - flat: `<task_root>/runs/*/logs/errors-*.jsonl`
86
- - stage-isolated: `<task_root>/runs/*/stage-*/logs/errors-*.jsonl` ([2026-06-06-stage-worktree-isolation-design.md](2026-06-06-stage-worktree-isolation-design.md) 의 stage 경로 규칙)
87
- 3. 각 파일을 줄 단위 JSON 으로 파싱. 깨진 줄은 건너뛰되 카운트해 리포트 말미에 `parse-skipped: N` 으로 surface(조용한 누락 금지).
88
- 4. 집계 → `.md` 렌더 + stdout JSON.
89
-
90
- ## 7. inspect 의 "두 번째 write" 경계
91
-
92
- 현재 SKILL 첫 줄은 "read-side inspection plus the one write-side mutation (`workStatus`)" ([SKILL.md:9](../../../skills/okstra-inspect/SKILL.md:9)).
93
-
94
- `errors` facet 은 `task-manifest.json` 같은 **okstra 상태를 mutate 하지 않는다.** CLI 를 호출해 **읽은 에러 데이터에서 파생한 산출물(.md)을 렌더**할 뿐이며, 이는 `cost` 가 추정치를 내는 것과 같은 read-derived 동작이다. 따라서 SKILL 의 정체성 문구를 다음으로 정정한다:
95
-
96
- > read-side okstra inspection + 상태 mutation 하나(`workStatus`) + read-derived 산출물 렌더(`errors` 리포트).
97
-
98
- 이로써 "유일한 write 는 workStatus" 라는 기존 불변식과 모순되지 않게 경계를 명시한다(상태 mutation 은 여전히 workStatus 하나뿐).
99
-
100
- ## 8. 엣지케이스
101
-
102
- - **glob 결과 0개** (errors.jsonl 자체가 없음): "이 task 에는 기록된 에러 로그가 없습니다" 를 facet 이 보고하고 `.md` 를 생성하지 않는다.
103
- - **파일은 있으나 레코드 0건**: 빈 결과와 구분해, "에러 0건" 을 명시한 리포트를 생성한다.
104
- - **깨진 JSONL 줄**: 건너뛰고 `parse-skipped` 카운트로 surface.
105
- - **stage-isolated + flat 혼재**: 둘 다 glob 해 합산.
106
-
107
- ## 9. 테스트 계획
108
-
109
- - `tests/test_okstra_error_report.py` (신규):
110
- - flat / stage-isolated / 혼재 fixture 에서 errorCount·byPhase·byAgent·bySource 집계 정확성.
111
- - errors.jsonl 0개 / 빈 파일 / 깨진 줄(parse-skipped) 처리.
112
- - 생성 `.md` 의 섹션 헤딩·테이블 컬럼 존재.
113
- - stdout JSON shape.
114
- - 기존 `tests/test_okstra_error_log.py` 와 충돌하지 않게 별도 모듈.
115
- - e2e: 기존 시나리오에 에러를 적재한 뒤 `okstra error-report` 를 돌려 `.md` 가 생성되는지 확인하는 시나리오를 선택적으로 추가(범위 밖일 수 있음 — plan 단계에서 판단).
116
-
117
- ## 10. 범위 밖 (YAGNI)
118
-
119
- - 단일 run 한정 모드 / `--all` 토글 — 이번엔 task 집계 단일 모드만.
120
- - task-group 단위 집계.
121
- - run 종료 훅에서의 자동 생성(on-demand 보고가 의도).
122
- - HTML / slim-AI 뷰 렌더.
123
- - errors.jsonl 의 timeline/catalog 경로 노출(facet 이 결정론적 glob 으로 resolve 하므로 불필요).