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.
- package/README.kr.md +5 -5
- package/README.md +5 -5
- package/docs/kr/architecture/storage-model.md +8 -3
- package/docs/kr/architecture.md +12 -13
- package/docs/kr/cli.md +4 -4
- package/docs/kr/container.md +1 -1
- package/docs/kr/performance-improvement-plan-v2.md +2 -2
- package/docs/project-structure-overview.md +2 -2
- package/package.json +7 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/lib/okstra/interactive.sh +12 -0
- package/runtime/bin/okstra-antigravity-exec.sh +1 -2
- package/runtime/bin/okstra-codex-exec.sh +1 -2
- package/runtime/bin/okstra-render-final-report.py +2 -9
- package/runtime/bin/okstra-spawn-followups.py +4 -6
- package/runtime/bin/okstra-trace-cleanup.sh +24 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/report-writer.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +9 -11
- package/runtime/python/okstra_ctl/codex_dispatch.py +6 -13
- package/runtime/python/okstra_ctl/consumers.py +35 -0
- package/runtime/python/okstra_ctl/container.py +4 -6
- package/runtime/python/okstra_ctl/dispatch_core.py +8 -13
- package/runtime/python/okstra_ctl/final_report_paths.py +24 -0
- package/runtime/python/okstra_ctl/handoff.py +2 -1
- package/runtime/python/okstra_ctl/implementation_outcome.py +271 -0
- package/runtime/python/okstra_ctl/implementation_stage.py +7 -11
- package/runtime/python/okstra_ctl/path_hints.py +665 -0
- package/runtime/python/okstra_ctl/render.py +4 -3
- package/runtime/python/okstra_ctl/report_view_artifacts.py +14 -0
- package/runtime/python/okstra_ctl/report_views.py +7 -4
- package/runtime/python/okstra_ctl/run.py +3 -10
- package/runtime/python/okstra_ctl/run_context.py +4 -2
- package/runtime/python/okstra_ctl/stage_targets.py +18 -0
- package/runtime/python/okstra_ctl/wizard.py +37 -26
- package/runtime/python/okstra_ctl/wizard_stage_intent.py +54 -0
- package/runtime/python/okstra_project/state.py +40 -2
- package/runtime/python/okstra_token_usage/report.py +2 -5
- package/runtime/validators/validate-report-views.py +2 -1
- package/runtime/validators/validate-run.py +1 -11
- package/src/commands/lifecycle/install.mjs +5 -5
- package/src/commands/lifecycle/uninstall.mjs +4 -4
- package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
- package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
- package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
- package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
- package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
- package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
- package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
- package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
- package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
- package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
- package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
- package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
- package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
- package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
- package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
- package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
- package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
- package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
- package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
- package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
- package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
- package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
- package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
- package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
- package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
- package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
- package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
- package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
- package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
- package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
- package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
- package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
- package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
- package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
- package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
- package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
- package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
- package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
- package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
- package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
- package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
- package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
- package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
- package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
- package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
- package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
- package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
- package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
- package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
- package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
- package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
- package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
- package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
- package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
- package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
- package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
- package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
- package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
- package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
- package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
- package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
- package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
- package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
- package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
- package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
- package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
- package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
- package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
- package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
- package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
- package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
- package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
- package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
- package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
- package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
- package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
- package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
- package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
- package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
- package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
- package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
- package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
- package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
- package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
- package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
- package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
- package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
- package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
- package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
- package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
- package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
- package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
- package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
- package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
- package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
- package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
- package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
- package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
- package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
- package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
- package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
- package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
- package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
- package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
- package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
- package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
- package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
- package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
- 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 하므로 불필요).
|