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,483 +0,0 @@
|
|
|
1
|
-
# Worker pane 완료-즉시 회수 + 내성 fallback 구현 계획
|
|
2
|
-
|
|
3
|
-
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
-
|
|
5
|
-
**Goal:** 외부 CLI worker(codex/antigravity)의 trace pane 을 완료 즉시 회수하고, pane 생성 실패 시 in-process 대체로 run 이 멈추지 않게 하여 tmux pane 한도 초과를 방지한다.
|
|
6
|
-
|
|
7
|
-
**Architecture:** wrapper 가 trace pane 에 자기 status 파일 경로를 태그(`@okstra_status`)로 단다 → `SubagentStop`/`TaskCompleted` 훅이 `active.jsonl` 의 활성 run 을 순회하며 `okstra-trace-cleanup.sh --reclaim-completed` 를 호출 → 그 모드는 status 가 `exited`(완료)인 trace pane 만 닫고 진행 중은 보존한다. 하니스가 만드는 teammate pane 은 okstra 가 태그할 수 없어 회수 대상에서 제외하고, lead 계약의 내성 fallback 으로 다룬다.
|
|
8
|
-
|
|
9
|
-
**Tech Stack:** Bash(wrapper/cleanup/hook 엔트리), Python(`okstra_ctl` — 완료 판정은 기존 `wrapper_status.read_wrapper_status` 재사용), tmux user-options(`@okstra_*`), Claude Code hooks.
|
|
10
|
-
|
|
11
|
-
## Global Constraints
|
|
12
|
-
|
|
13
|
-
- `runtime/` 는 빌드 산출물 — 직접 수정 금지. 소스는 `scripts/`, `templates/` 에 두고 `npm run build` 로 동기화([CLAUDE.md](../../../CLAUDE.md)).
|
|
14
|
-
- 사용자 영향 수정은 seed/template 에 — 훅은 [templates/reports/settings.template.json](../../../templates/reports/settings.template.json) 에 배선(개인 `.claude/` 아님).
|
|
15
|
-
- Bash 는 thin 엔트리/어댑터. 판정 로직은 Python 모듈 재사용 — Bash 에 비즈니스 로직 복제 금지.
|
|
16
|
-
- 새/대폭 수정 함수는 유효 50줄 이내.
|
|
17
|
-
- pre-1.0 — 하위호환 shim 없음.
|
|
18
|
-
- 문서/주석 한국어(코드 식별자·경로·CLI 인자는 영어).
|
|
19
|
-
- 완료 판정 SSOT: `wrapper_status.WrapperStatus.is_terminal`(`stage == "exited"`) — 새 판정 로직 만들지 말 것.
|
|
20
|
-
- "worktree" 용어는 실제 git worktree 에만 — stage 폴더 상위는 "상위 디렉터리".
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Task 0: 실측 게이트 — teammate pane title 확인 (코드 작성 전 1회)
|
|
25
|
-
|
|
26
|
-
설계의 단 하나 미검증 가정: **하니스가 teammate(subagent) pane title 을 `*-worker` 로 다는가.** 이 결과가 회수 범위를 정한다(trace pane 만 vs teammate pane 도). tmux 안에서 실측한다.
|
|
27
|
-
|
|
28
|
-
**Files:** 없음(조사).
|
|
29
|
-
|
|
30
|
-
- [ ] **Step 1: tmux 세션 안에서 okstra worker 1개를 띄운 직후 pane title 덤프**
|
|
31
|
-
|
|
32
|
-
tmux 안에서 `/okstra-run` 또는 직접 dispatch 로 worker 1개를 띄운 뒤:
|
|
33
|
-
|
|
34
|
-
Run: `tmux list-panes -a -F '#{pane_id}\t#{pane_title}\t#{@okstra_trace_run}\t#{@okstra_worker_run}'`
|
|
35
|
-
|
|
36
|
-
- [ ] **Step 2: 판정 기록**
|
|
37
|
-
|
|
38
|
-
- teammate pane title 이 `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker` 중 하나와 `*<title>*` 매칭되면 → **회수 가능**. 이 plan 의 Task 2 끝 "조건부 확장" 을 적용한다.
|
|
39
|
-
- 매칭 안 되거나(빈 title, 하니스 고유 라벨) 같은 title 이 여러 worker 에 중복돼 진행중/완료 구분이 불가하면 → **trace pane 만 회수**. teammate 누적은 Task 5 내성에 의존(설계대로). 이 경우 Task 2 "조건부 확장" 은 건너뛴다.
|
|
40
|
-
- 결과를 이 파일 Task 0 아래 한 줄로 적어 후속 task 가 참조하게 한다.
|
|
41
|
-
|
|
42
|
-
> 실측 불가 환경(현재 세션이 tmux 밖)이면: trace pane 만 회수하는 경로로 진행하고, teammate 회수는 미적용으로 둔다. 이는 안전한 기본값이다(없는 기능을 가정해 진행 중 pane 을 죽이는 것보다 낫다).
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Task 1: wrapper 가 trace pane 에 `@okstra_status` 태그 추가
|
|
47
|
-
|
|
48
|
-
trace pane 을 그 worker 의 status 파일과 연결한다. cleanup 이 이 태그로 완료 여부를 읽는다.
|
|
49
|
-
|
|
50
|
-
**Files:**
|
|
51
|
-
- Modify: `scripts/okstra-codex-exec.sh` (trace pane 태그 블록, 현재 `@okstra_trace_run` 설정부 근처 ~272-281)
|
|
52
|
-
- Modify: `scripts/okstra-antigravity-exec.sh` (동일 블록 ~214-220)
|
|
53
|
-
|
|
54
|
-
**Interfaces:**
|
|
55
|
-
- Consumes: 각 wrapper 가 이미 보유한 `$status_path`(`${prompt_path%.md}.status.json`, codex:182 / antigravity:138)와 `$trace_pane`(split 결과 pane id).
|
|
56
|
-
- Produces: trace pane 의 tmux user-option `@okstra_status=<status_path 절대경로>`.
|
|
57
|
-
|
|
58
|
-
- [ ] **Step 1: codex wrapper — `@okstra_trace_run` 설정 직후 status 태그 추가**
|
|
59
|
-
|
|
60
|
-
`scripts/okstra-codex-exec.sh` 의 `tmux set-option -p -t "$trace_pane" @okstra_trace_run "$run_dir"` 줄 **직후**에 추가:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
[[ -n "$status_path" ]] && tmux set-option -p -t "$trace_pane" @okstra_status "$status_path" 2>/dev/null || true
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
- [ ] **Step 2: antigravity wrapper — 동일 추가**
|
|
67
|
-
|
|
68
|
-
`scripts/okstra-antigravity-exec.sh` 의 동일한 `@okstra_trace_run` 설정 줄 직후에 같은 한 줄을 추가(변수명 `$status_path` / `$trace_pane` 동일).
|
|
69
|
-
|
|
70
|
-
- [ ] **Step 3: 태그 라인이 두 파일에 들어갔는지 확인**
|
|
71
|
-
|
|
72
|
-
Run: `grep -n '@okstra_status' scripts/okstra-codex-exec.sh scripts/okstra-antigravity-exec.sh`
|
|
73
|
-
Expected: 두 파일 각각 1줄.
|
|
74
|
-
|
|
75
|
-
- [ ] **Step 4: 커밋**
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
git add scripts/okstra-codex-exec.sh scripts/okstra-antigravity-exec.sh
|
|
79
|
-
git commit -m "feat(wrapper): trace pane 에 @okstra_status 태그를 달아 완료 회수 연결"
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## Task 2: `okstra-trace-cleanup.sh --reclaim-completed` 모드
|
|
85
|
-
|
|
86
|
-
완료된(`stage == "exited"`) worker 의 trace pane 만 닫고 진행 중은 보존하는 모드. 완료 판정은 Python SSOT 를 호출한다.
|
|
87
|
-
|
|
88
|
-
**Files:**
|
|
89
|
-
- Create: `scripts/okstra_ctl/pane_reclaim.py` (완료 판정 wrapper — 테스트 대상)
|
|
90
|
-
- Modify: `scripts/okstra-trace-cleanup.sh` (인자 파싱 + collect 에 완료 필터)
|
|
91
|
-
- Test: `tests/test_pane_reclaim.py`
|
|
92
|
-
|
|
93
|
-
**Interfaces:**
|
|
94
|
-
- Consumes: trace pane 의 `@okstra_status` 태그(Task 1), `@okstra_trace_run` 태그(기존).
|
|
95
|
-
- Produces: `pane_reclaim.is_completed_status(status_path: str) -> bool` (CLI: `python3 -m okstra_ctl.pane_reclaim <status_path>` → exit 0 완료 / 1 미완료·부재). `okstra-trace-cleanup.sh --reclaim-completed --run-dir <RUN_DIR>`.
|
|
96
|
-
|
|
97
|
-
- [ ] **Step 1: 완료 판정 테스트 작성 (실패)**
|
|
98
|
-
|
|
99
|
-
`tests/test_pane_reclaim.py`:
|
|
100
|
-
|
|
101
|
-
```python
|
|
102
|
-
from pathlib import Path
|
|
103
|
-
from okstra_ctl.pane_reclaim import is_completed_status
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def _write(p: Path, stage: str) -> Path:
|
|
107
|
-
p.write_text('{"stage": "%s", "exit_code": 0}' % stage, encoding="utf-8")
|
|
108
|
-
return p
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def test_exited_status_is_completed(tmp_path):
|
|
112
|
-
assert is_completed_status(str(_write(tmp_path / "w.status.json", "exited"))) is True
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def test_started_status_is_not_completed(tmp_path):
|
|
116
|
-
assert is_completed_status(str(_write(tmp_path / "w.status.json", "started"))) is False
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def test_missing_status_is_not_completed(tmp_path):
|
|
120
|
-
assert is_completed_status(str(tmp_path / "absent.status.json")) is False
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
- [ ] **Step 2: 테스트 실패 확인**
|
|
124
|
-
|
|
125
|
-
Run: `python3 -m pytest tests/test_pane_reclaim.py -v`
|
|
126
|
-
Expected: FAIL — `ModuleNotFoundError: okstra_ctl.pane_reclaim`
|
|
127
|
-
|
|
128
|
-
- [ ] **Step 3: `pane_reclaim.py` 구현 (기존 SSOT 재사용)**
|
|
129
|
-
|
|
130
|
-
`scripts/okstra_ctl/pane_reclaim.py`:
|
|
131
|
-
|
|
132
|
-
```python
|
|
133
|
-
"""완료(terminal) worker 판정 — pane 회수용. 판정 SSOT 는
|
|
134
|
-
wrapper_status.read_wrapper_status 이며 여기서 재사용한다."""
|
|
135
|
-
from __future__ import annotations
|
|
136
|
-
|
|
137
|
-
import sys
|
|
138
|
-
from pathlib import Path
|
|
139
|
-
|
|
140
|
-
from .wrapper_status import read_wrapper_status
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def is_completed_status(status_path: str) -> bool:
|
|
144
|
-
status = read_wrapper_status(Path(status_path))
|
|
145
|
-
return status is not None and status.is_terminal
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def main(argv: list[str]) -> int:
|
|
149
|
-
if len(argv) != 1:
|
|
150
|
-
return 1
|
|
151
|
-
return 0 if is_completed_status(argv[0]) else 1
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if __name__ == "__main__":
|
|
155
|
-
raise SystemExit(main(sys.argv[1:]))
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
- [ ] **Step 4: 테스트 통과 확인**
|
|
159
|
-
|
|
160
|
-
Run: `python3 -m pytest tests/test_pane_reclaim.py -v`
|
|
161
|
-
Expected: PASS (3 passed)
|
|
162
|
-
|
|
163
|
-
- [ ] **Step 5: `okstra-trace-cleanup.sh` 에 `--reclaim-completed` 인자 추가**
|
|
164
|
-
|
|
165
|
-
옵션 파싱(`while` 루프 `case`)에 추가:
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
--reclaim-completed) MODE="reclaim" ;;
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
`MODE` 초기값 주석에 `reclaim` 추가. `--reclaim-completed` 는 `--run-dir` 필수(기존 검증 재사용).
|
|
172
|
-
|
|
173
|
-
- [ ] **Step 6: collect 에 완료 필터 적용**
|
|
174
|
-
|
|
175
|
-
`collect_okstra_panes` 의 (1) 태그 스캔 루프에서, `MODE == "reclaim"` 일 때 trace pane 은 `@okstra_status` 가 완료일 때만 포함하도록 분기. tmux 수집 포맷에 `@okstra_status` 컬럼을 추가하고 판정을 끼운다:
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
while IFS=$'\t' read -r pid trace_tag worker_tag status_tag; do
|
|
179
|
-
[[ -n "$pid" ]] || continue
|
|
180
|
-
[[ "$pid" == "$lead_pane" ]] && continue
|
|
181
|
-
if _tag_in_scope "$trace_tag" || _tag_in_scope "$worker_tag"; then
|
|
182
|
-
if [[ "$MODE" == "reclaim" ]]; then
|
|
183
|
-
# reclaim 모드: 완료(stage=exited)된 worker 의 pane 만. status 태그가
|
|
184
|
-
# 없거나(teammate/비-wrapper pane) 미완료면 보존.
|
|
185
|
-
[[ -n "$status_tag" ]] || continue
|
|
186
|
-
python3 -m okstra_ctl.pane_reclaim "$status_tag" || continue
|
|
187
|
-
fi
|
|
188
|
-
panes+=("$pid")
|
|
189
|
-
fi
|
|
190
|
-
done < <(tmux list-panes -a \
|
|
191
|
-
-F '#{pane_id}'$'\t''#{@okstra_trace_run}'$'\t''#{@okstra_worker_run}'$'\t''#{@okstra_status}' \
|
|
192
|
-
2>/dev/null || true)
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
`MODE == "reclaim"` 에서는 (2) title-allowlist teammate 스캔을 **건너뛴다**(Task 0 미통과 기본값 — teammate pane 보존). `MODE` 가 `kill`/`list` 일 때는 기존 동작 유지. `kill` 분기는 `MODE in (kill, reclaim)` 가 동일 kill 경로를 타도록 마지막 실행부 조건을 `[[ "$MODE" != "list" ]]` 로 둔다.
|
|
196
|
-
|
|
197
|
-
> **Task 0 통과 시에만** — teammate pane 도 회수하려면, reclaim 모드에서 (2) title 스캔을 살리되 각 teammate pane 의 완료 판정을 추가해야 한다. 단 teammate pane 엔 `@okstra_status` 태그가 없으므로(okstra 가 못 닮) 완료를 디스크에서 역매핑할 수단이 필요하다. Task 0 결과가 "회수 가능"이면 그 매핑(title→worker→status_path)을 별도 스텝으로 설계해 추가하고, 아니면 이 박스는 무시한다.
|
|
198
|
-
|
|
199
|
-
- [ ] **Step 7: PYTHONPATH 확인 — cleanup 이 `okstra_ctl` 를 import 할 수 있는지**
|
|
200
|
-
|
|
201
|
-
`okstra-trace-cleanup.sh` 가 `python3 -m okstra_ctl.pane_reclaim` 를 호출하려면 `scripts/` 가 `sys.path` 에 있어야 한다. 스크립트 상단(기존 `_clean_script_dir` 도출 직후)에 추가:
|
|
202
|
-
|
|
203
|
-
```bash
|
|
204
|
-
export PYTHONPATH="$_clean_script_dir${PYTHONPATH:+:$PYTHONPATH}"
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
설치 레이아웃에서 `pane_reclaim.py`/`wrapper_status.py` 가 `$_clean_script_dir` 기준 어디에 놓이는지 [src/install.mjs](../../../src/install.mjs) 의 python 페이로드 경로와 대조해 PYTHONPATH 를 맞춘다(repo 는 `scripts/`, 설치본은 `~/.okstra/lib/python/`).
|
|
208
|
-
|
|
209
|
-
- [ ] **Step 8: e2e 시나리오 — 완료 pane 회수 / 진행 중 보존**
|
|
210
|
-
|
|
211
|
-
`tests-e2e/scenario-<id>-pane-reclaim.sh`: `mktemp -d` OKSTRA_HOME, tmux 가용할 때만 실행(없으면 skip). 모의 run-dir 에 두 worker prompt+status(`exited` 1개, `started` 1개)와 태그된 모의 pane 2개를 만들고, `--reclaim-completed --list` 가 `exited` pane 만 출력하는지 검증. `trap` 으로 OKSTRA_HOME 정리.
|
|
212
|
-
|
|
213
|
-
- [ ] **Step 9: 단위 테스트 통과 + 커밋**
|
|
214
|
-
|
|
215
|
-
Run: `python3 -m pytest tests/test_pane_reclaim.py -v && bash -n scripts/okstra-trace-cleanup.sh`
|
|
216
|
-
Expected: PASS + 문법 오류 없음
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
git add scripts/okstra_ctl/pane_reclaim.py scripts/okstra-trace-cleanup.sh tests/test_pane_reclaim.py tests-e2e/scenario-*-pane-reclaim.sh
|
|
220
|
-
git commit -m "feat(cleanup): --reclaim-completed 모드 — 완료된 trace pane 만 회수"
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
---
|
|
224
|
-
|
|
225
|
-
## Task 3: 훅 진입점 `okstra-subagent-reclaim.sh` — 활성 run 순회
|
|
226
|
-
|
|
227
|
-
`SubagentStop`/`TaskCompleted` 가 주는 stdin 은 run-dir 을 직접 주지 않고 `cwd` 도 run-dir 보장이 없다. session_id 매핑 대신 `active.jsonl` 의 활성 run 을 모두 순회한다 — 완료 판정(Task 2)이 cross-run 안전을 보장하므로 다른 run 의 진행 중 pane 을 건드리지 않는다.
|
|
228
|
-
|
|
229
|
-
**Files:**
|
|
230
|
-
- Create: `scripts/okstra-subagent-reclaim.sh`
|
|
231
|
-
- Test: `tests/test_subagent_reclaim_targets.py` (run-dir 추출 로직을 Python helper 로 분리해 테스트)
|
|
232
|
-
|
|
233
|
-
**Interfaces:**
|
|
234
|
-
- Consumes: stdin JSON(무시 가능 — 어느 worker 가 끝났든 활성 run 전체를 reclaim), `~/.okstra/active.jsonl`(`runDirRel`/`projectRoot`/`status`).
|
|
235
|
-
- Produces: `pane_reclaim.active_run_dirs(home: Path) -> list[Path]` (status 가 종료 상태가 아닌 run 들의 절대 run-dir).
|
|
236
|
-
|
|
237
|
-
- [ ] **Step 1: active run-dir 추출 테스트 작성 (실패)**
|
|
238
|
-
|
|
239
|
-
`tests/test_subagent_reclaim_targets.py`:
|
|
240
|
-
|
|
241
|
-
```python
|
|
242
|
-
import json
|
|
243
|
-
from pathlib import Path
|
|
244
|
-
from okstra_ctl.pane_reclaim import active_run_dirs
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
def test_active_run_dirs_resolves_absolute(tmp_path):
|
|
248
|
-
home = tmp_path
|
|
249
|
-
(home / "active.jsonl").write_text(
|
|
250
|
-
json.dumps({"status": "running", "runDirRel": "tasks/g/t/runs/x", "projectRoot": "/proj"}) + "\n",
|
|
251
|
-
encoding="utf-8",
|
|
252
|
-
)
|
|
253
|
-
dirs = active_run_dirs(home)
|
|
254
|
-
assert dirs == [home / "tasks/g/t/runs/x"]
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
def test_finished_runs_excluded(tmp_path):
|
|
258
|
-
home = tmp_path
|
|
259
|
-
(home / "active.jsonl").write_text(
|
|
260
|
-
json.dumps({"status": "done", "runDirRel": "tasks/g/t/runs/x", "projectRoot": "/proj"}) + "\n",
|
|
261
|
-
encoding="utf-8",
|
|
262
|
-
)
|
|
263
|
-
assert active_run_dirs(home) == []
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
> **구현 전 확인:** `runDirRel` 의 base 가 `home` 인지 `projectRoot` 인지 [index.py](../../../scripts/okstra_ctl/index.py) `reserve_active` 호출부에서 확정하고, 위 테스트의 기대 경로를 그에 맞춘다. `status` 의 "활성" 집합(`reserving`/`running`/...)도 같은 파일에서 확인해 제외 조건을 맞춘다.
|
|
267
|
-
|
|
268
|
-
- [ ] **Step 2: 테스트 실패 확인**
|
|
269
|
-
|
|
270
|
-
Run: `python3 -m pytest tests/test_subagent_reclaim_targets.py -v`
|
|
271
|
-
Expected: FAIL — `active_run_dirs` 없음
|
|
272
|
-
|
|
273
|
-
- [ ] **Step 3: `active_run_dirs` 를 `pane_reclaim.py` 에 추가**
|
|
274
|
-
|
|
275
|
-
```python
|
|
276
|
-
import json
|
|
277
|
-
|
|
278
|
-
_FINISHED = {"done", "complete", "error", "aborted"} # index.py 의 종료 status 와 대조해 확정
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def active_run_dirs(home: Path) -> list[Path]:
|
|
282
|
-
path = home / "active.jsonl"
|
|
283
|
-
if not path.is_file():
|
|
284
|
-
return []
|
|
285
|
-
dirs: list[Path] = []
|
|
286
|
-
for line in path.read_text(encoding="utf-8").splitlines():
|
|
287
|
-
line = line.strip()
|
|
288
|
-
if not line:
|
|
289
|
-
continue
|
|
290
|
-
try:
|
|
291
|
-
row = json.loads(line)
|
|
292
|
-
except json.JSONDecodeError:
|
|
293
|
-
continue
|
|
294
|
-
rel = row.get("runDirRel")
|
|
295
|
-
if not rel or row.get("status") in _FINISHED:
|
|
296
|
-
continue
|
|
297
|
-
dirs.append(home / rel)
|
|
298
|
-
return dirs
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
- [ ] **Step 4: 테스트 통과 확인**
|
|
302
|
-
|
|
303
|
-
Run: `python3 -m pytest tests/test_subagent_reclaim_targets.py -v`
|
|
304
|
-
Expected: PASS
|
|
305
|
-
|
|
306
|
-
- [ ] **Step 5: 훅 엔트리 스크립트 작성**
|
|
307
|
-
|
|
308
|
-
`scripts/okstra-subagent-reclaim.sh`:
|
|
309
|
-
|
|
310
|
-
```bash
|
|
311
|
-
#!/usr/bin/env bash
|
|
312
|
-
#
|
|
313
|
-
# okstra-subagent-reclaim.sh — SubagentStop / TaskCompleted 훅 엔트리.
|
|
314
|
-
# stdin(JSON)은 읽고 버린다(어느 worker 가 끝났든 활성 run 전체의 완료 pane 만
|
|
315
|
-
# 회수하므로). active.jsonl 의 각 활성 run 에 대해 cleanup --reclaim-completed.
|
|
316
|
-
# 모든 실패는 조용히 삼킨다 — 훅은 세션 진행을 절대 막지 않는다.
|
|
317
|
-
set -u
|
|
318
|
-
cat >/dev/null 2>&1 || true # drain stdin
|
|
319
|
-
|
|
320
|
-
_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
321
|
-
home="${OKSTRA_HOME:-$HOME/.okstra}"
|
|
322
|
-
export PYTHONPATH="$_dir${PYTHONPATH:+:$PYTHONPATH}"
|
|
323
|
-
|
|
324
|
-
while IFS= read -r run_dir; do
|
|
325
|
-
[[ -n "$run_dir" ]] || continue
|
|
326
|
-
"$_dir/okstra-trace-cleanup.sh" --reclaim-completed --run-dir "$run_dir" 2>/dev/null || true
|
|
327
|
-
done < <(python3 -m okstra_ctl.pane_reclaim --active-dirs "$home" 2>/dev/null || true)
|
|
328
|
-
|
|
329
|
-
exit 0
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
`pane_reclaim.main` 에 `--active-dirs <home>` 서브커맨드를 추가해 `active_run_dirs` 결과를 한 줄씩 출력하게 한다(기존 단일 status_path 판정과 분기).
|
|
333
|
-
|
|
334
|
-
- [ ] **Step 6: `pane_reclaim.main` 에 `--active-dirs` 분기 추가**
|
|
335
|
-
|
|
336
|
-
```python
|
|
337
|
-
def main(argv: list[str]) -> int:
|
|
338
|
-
if len(argv) == 2 and argv[0] == "--active-dirs":
|
|
339
|
-
for d in active_run_dirs(Path(argv[1])):
|
|
340
|
-
print(d)
|
|
341
|
-
return 0
|
|
342
|
-
if len(argv) == 1:
|
|
343
|
-
return 0 if is_completed_status(argv[0]) else 1
|
|
344
|
-
return 1
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
- [ ] **Step 7: 실행권한 + 문법 + 테스트**
|
|
348
|
-
|
|
349
|
-
Run: `chmod +x scripts/okstra-subagent-reclaim.sh && bash -n scripts/okstra-subagent-reclaim.sh && python3 -m pytest tests/test_subagent_reclaim_targets.py tests/test_pane_reclaim.py -v`
|
|
350
|
-
Expected: PASS
|
|
351
|
-
|
|
352
|
-
- [ ] **Step 8: 커밋**
|
|
353
|
-
|
|
354
|
-
```bash
|
|
355
|
-
git add scripts/okstra-subagent-reclaim.sh scripts/okstra_ctl/pane_reclaim.py tests/test_subagent_reclaim_targets.py
|
|
356
|
-
git commit -m "feat(hook): okstra-subagent-reclaim.sh — 활성 run 의 완료 pane 회수 엔트리"
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## Task 4: 훅 배선 — `settings.template.json`
|
|
362
|
-
|
|
363
|
-
완료 이벤트에 reclaim 엔트리를 배선한다. no-team(Agent) 경로는 `SubagentStop`, Teams 경로는 `TaskCompleted`.
|
|
364
|
-
|
|
365
|
-
**Files:**
|
|
366
|
-
- Modify: `templates/reports/settings.template.json` (`hooks` 객체)
|
|
367
|
-
|
|
368
|
-
- [ ] **Step 1: 두 이벤트 훅 추가**
|
|
369
|
-
|
|
370
|
-
`hooks` 객체에 추가(기존 `PreToolUse`, `SessionEnd` 유지):
|
|
371
|
-
|
|
372
|
-
```json
|
|
373
|
-
"SubagentStop": [
|
|
374
|
-
{
|
|
375
|
-
"hooks": [
|
|
376
|
-
{
|
|
377
|
-
"type": "command",
|
|
378
|
-
"command": "$HOME/.okstra/bin/okstra-subagent-reclaim.sh"
|
|
379
|
-
}
|
|
380
|
-
]
|
|
381
|
-
}
|
|
382
|
-
],
|
|
383
|
-
"TaskCompleted": [
|
|
384
|
-
{
|
|
385
|
-
"hooks": [
|
|
386
|
-
{
|
|
387
|
-
"type": "command",
|
|
388
|
-
"command": "$HOME/.okstra/bin/okstra-subagent-reclaim.sh"
|
|
389
|
-
}
|
|
390
|
-
]
|
|
391
|
-
}
|
|
392
|
-
]
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
- [ ] **Step 2: JSON 유효성 확인**
|
|
396
|
-
|
|
397
|
-
Run: `python3 -c "import json; json.load(open('templates/reports/settings.template.json'))"`
|
|
398
|
-
Expected: 오류 없음
|
|
399
|
-
|
|
400
|
-
- [ ] **Step 3: 설치 payload 에 새 스크립트가 포함되는지 확인**
|
|
401
|
-
|
|
402
|
-
[src/install.mjs](../../../src/install.mjs) 가 `scripts/okstra-*.sh` 를 `~/.okstra/bin/` 으로 복사하는 규칙에 `okstra-subagent-reclaim.sh` 가 자동 포함되는지(glob/명시 목록) 확인. 명시 목록이면 추가한다.
|
|
403
|
-
|
|
404
|
-
Run: `grep -n 'okstra-trace-cleanup\|okstra-.*\.sh\|bin/' src/install.mjs | head`
|
|
405
|
-
|
|
406
|
-
- [ ] **Step 4: 커밋**
|
|
407
|
-
|
|
408
|
-
```bash
|
|
409
|
-
git add templates/reports/settings.template.json src/install.mjs
|
|
410
|
-
git commit -m "feat(hook): SubagentStop/TaskCompleted 에 pane reclaim 배선"
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## Task 5: 내성 계약 — `_common-contract.md`
|
|
416
|
-
|
|
417
|
-
하니스 teammate pane 생성 실패는 okstra Python 이 못 보므로 코드 강제 불가. lead 행동 계약에 명시한다(declaration, prompt 지시임을 분명히).
|
|
418
|
-
|
|
419
|
-
**Files:**
|
|
420
|
-
- Modify: `prompts/profiles/_common-contract.md` (dispatch/convergence 절)
|
|
421
|
-
|
|
422
|
-
- [ ] **Step 1: pane-실패 fallback 문단 추가**
|
|
423
|
-
|
|
424
|
-
기존 dispatch 관련 절에 추가(한국어/영어는 그 파일의 기존 언어 관행에 맞춤):
|
|
425
|
-
|
|
426
|
-
> **Pane-budget fallback (tolerance).** worker dispatch 가 `no room for another tmux split`(또는 동등한 teammate pane 생성 실패)로 거부되면, 그 worker 를 `run_in_background` 없이 in-process 로 재시도하거나, 외부 CLI worker 였다면 in-process claude 분석으로 **대체**하고 그 사실(provider 불가)을 run 기록·convergence 노트에 남긴다. 완료된 외부 CLI worker 의 trace pane 은 `SubagentStop` 훅이 자동 회수하지만, 하니스가 만든 teammate pane 누적은 okstra 가 직접 회수할 수 없으므로 이 fallback 이 최후 방어선이다. (이는 코드 강제가 아닌 prompt 지시다.)
|
|
427
|
-
|
|
428
|
-
- [ ] **Step 2: declaration ≠ enforcement 규칙 준수 확인**
|
|
429
|
-
|
|
430
|
-
이 문단이 "MUST/BLOCKING" 같은 강제 용어를 enforcement 없이 쓰지 않는지 확인(글로벌 5.5). "최후 방어선"·"대체한다" 수준의 행동 지시로 유지하고, 코드 강제가 아님을 명시한 현재 문구를 지킨다.
|
|
431
|
-
|
|
432
|
-
- [ ] **Step 3: 커밋**
|
|
433
|
-
|
|
434
|
-
```bash
|
|
435
|
-
git add prompts/profiles/_common-contract.md
|
|
436
|
-
git commit -m "docs(contract): pane-budget fallback — pane 실패 시 in-process 대체"
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
## Task 6: 빌드 동기화 + 전체 검증
|
|
442
|
-
|
|
443
|
-
**Files:** 없음(빌드/검증).
|
|
444
|
-
|
|
445
|
-
- [ ] **Step 1: 빌드**
|
|
446
|
-
|
|
447
|
-
Run: `npm run build`
|
|
448
|
-
Expected: `done. NN/NN sources synced.`
|
|
449
|
-
|
|
450
|
-
- [ ] **Step 2: 전체 단위 + 워크플로 검증**
|
|
451
|
-
|
|
452
|
-
Run: `python3 -m pytest tests/ -q && bash validators/validate-workflow.sh`
|
|
453
|
-
Expected: 모두 통과
|
|
454
|
-
|
|
455
|
-
- [ ] **Step 3: CLI 스모크 + doctor**
|
|
456
|
-
|
|
457
|
-
Run: `node bin/okstra --version && node bin/okstra doctor`
|
|
458
|
-
Expected: 정상
|
|
459
|
-
|
|
460
|
-
- [ ] **Step 4: CHANGES.md 항목 추가 (사용자 영향)**
|
|
461
|
-
|
|
462
|
-
`CHANGES.md` 최상단 날짜 섹션에 항목 추가 — trace pane 완료-즉시 회수 + 내성 fallback 이 pane 한도 초과를 완화한다는 `사용자 영향:` 줄 포함. 한국어.
|
|
463
|
-
|
|
464
|
-
- [ ] **Step 5: 커밋**
|
|
465
|
-
|
|
466
|
-
```bash
|
|
467
|
-
git add CHANGES.md
|
|
468
|
-
git commit -m "docs(changes): worker trace pane 완료-회수 + 내성 fallback"
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
---
|
|
472
|
-
|
|
473
|
-
## 완료 기준
|
|
474
|
-
|
|
475
|
-
- 외부 CLI worker 완료 시 그 trace pane 이 `SubagentStop`/`TaskCompleted` 훅으로 자동 회수되고, 진행 중 worker 의 pane 은 보존된다(e2e 시나리오로 입증).
|
|
476
|
-
- pane 생성 실패 시 lead 가 in-process 대체로 진행하도록 계약에 명시된다.
|
|
477
|
-
- 전체 pytest + validate-workflow 통과, 빌드 동기화 완료.
|
|
478
|
-
- teammate pane 회수는 Task 0 실측 결과에 따라 적용/미적용이 명확히 기록된다.
|
|
479
|
-
|
|
480
|
-
## 알려진 한계 (spec §9 와 일치)
|
|
481
|
-
|
|
482
|
-
- 하니스 teammate pane 은 okstra 가 태그·식별을 보장할 수 없어, Task 0 미통과 시 회수 대상이 아니다 — 그 누적은 Task 5 내성에 의존하며, 내성은 코드 강제가 불가능한 prompt 계약이다.
|
|
483
|
-
- 한 세션 다중 동시 run 시 active.jsonl 순회가 모든 run 을 reclaim 하지만, 완료 판정이 진행 중 pane 을 보호하므로 안전하다.
|