okstra 0.34.0 → 0.36.0

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 (101) hide show
  1. package/README.kr.md +26 -16
  2. package/README.md +26 -16
  3. package/docs/kr/architecture.md +59 -45
  4. package/docs/kr/cli.md +61 -18
  5. package/docs/pr-template-usage.md +65 -0
  6. package/docs/project-structure-overview.md +358 -354
  7. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +1 -1
  8. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +1 -1
  9. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +1 -1
  10. package/docs/superpowers/plans/2026-05-20-final-report-language.md +1501 -0
  11. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +1267 -0
  12. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +1007 -0
  13. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +720 -0
  14. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +681 -0
  15. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +1691 -0
  16. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +383 -0
  17. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +320 -0
  18. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +299 -0
  19. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +335 -0
  20. package/docs/task-process/README.md +74 -0
  21. package/docs/task-process/common-flow.md +166 -0
  22. package/docs/task-process/error-analysis.md +101 -0
  23. package/docs/task-process/final-verification.md +167 -0
  24. package/docs/task-process/implementation-planning.md +128 -0
  25. package/docs/task-process/implementation.md +149 -0
  26. package/docs/task-process/release-handoff.md +206 -0
  27. package/docs/task-process/requirements-discovery.md +115 -0
  28. package/package.json +1 -1
  29. package/runtime/BUILD.json +2 -2
  30. package/runtime/agents/SKILL.md +29 -13
  31. package/runtime/agents/workers/claude-worker.md +26 -0
  32. package/runtime/agents/workers/codex-worker.md +27 -1
  33. package/runtime/agents/workers/gemini-worker.md +27 -1
  34. package/runtime/agents/workers/report-writer-worker.md +8 -1
  35. package/runtime/bin/okstra-central.sh +6 -6
  36. package/runtime/bin/okstra-codex-exec.sh +49 -28
  37. package/runtime/bin/okstra-gemini-exec.sh +39 -21
  38. package/runtime/bin/okstra-render-final-report.py +13 -2
  39. package/runtime/bin/okstra-wrapper-status.py +155 -0
  40. package/runtime/bin/okstra.sh +2 -2
  41. package/runtime/prompts/profiles/_common-contract.md +11 -6
  42. package/runtime/prompts/profiles/error-analysis.md +3 -7
  43. package/runtime/prompts/profiles/implementation-planning.md +22 -21
  44. package/runtime/prompts/profiles/implementation.md +28 -11
  45. package/runtime/prompts/profiles/improvement-discovery.md +42 -0
  46. package/runtime/prompts/profiles/kr/_common-contract.md +92 -0
  47. package/runtime/prompts/profiles/kr/error-analysis.md +36 -0
  48. package/runtime/prompts/profiles/kr/final-verification.md +48 -0
  49. package/runtime/prompts/profiles/kr/implementation-planning.md +90 -0
  50. package/runtime/prompts/profiles/kr/implementation.md +144 -0
  51. package/runtime/prompts/profiles/kr/improvement-discovery.md +42 -0
  52. package/runtime/prompts/profiles/kr/release-handoff.md +104 -0
  53. package/runtime/prompts/profiles/kr/requirements-discovery.md +42 -0
  54. package/runtime/prompts/profiles/release-handoff.md +1 -1
  55. package/runtime/prompts/profiles/requirements-discovery.md +8 -12
  56. package/runtime/prompts/wizard/prompts.ko.json +230 -0
  57. package/runtime/python/lib/okstra/cli.sh +2 -49
  58. package/runtime/python/lib/okstra/globals.sh +21 -21
  59. package/runtime/python/lib/okstra/interactive.sh +7 -7
  60. package/runtime/python/okstra_ctl/clarification_items.py +3 -9
  61. package/runtime/python/okstra_ctl/consumers.py +53 -0
  62. package/runtime/python/okstra_ctl/final_report_schema.py +0 -7
  63. package/runtime/python/okstra_ctl/i18n.py +73 -0
  64. package/runtime/python/okstra_ctl/improvement_lenses.py +44 -0
  65. package/runtime/python/okstra_ctl/index.py +1 -1
  66. package/runtime/python/okstra_ctl/paths.py +23 -20
  67. package/runtime/python/okstra_ctl/render.py +147 -202
  68. package/runtime/python/okstra_ctl/render_final_report.py +53 -10
  69. package/runtime/python/okstra_ctl/run.py +292 -107
  70. package/runtime/python/okstra_ctl/run_context.py +22 -0
  71. package/runtime/python/okstra_ctl/seeding.py +186 -0
  72. package/runtime/python/okstra_ctl/wizard.py +348 -127
  73. package/runtime/python/okstra_ctl/workflow.py +21 -2
  74. package/runtime/python/okstra_ctl/worktree.py +54 -1
  75. package/runtime/python/okstra_project/resolver.py +4 -3
  76. package/runtime/python/okstra_token_usage/report.py +2 -2
  77. package/runtime/schemas/final-report-v1.0.schema.json +22 -16
  78. package/runtime/skills/okstra-brief/SKILL.md +124 -31
  79. package/runtime/skills/okstra-convergence/SKILL.md +2 -3
  80. package/runtime/skills/okstra-report-writer/SKILL.md +35 -15
  81. package/runtime/skills/okstra-run/SKILL.md +5 -4
  82. package/runtime/skills/okstra-schedule/SKILL.md +4 -4
  83. package/runtime/skills/okstra-setup/SKILL.md +27 -0
  84. package/runtime/skills/okstra-team-contract/SKILL.md +1 -1
  85. package/runtime/templates/okstra.CLAUDE.md +104 -0
  86. package/runtime/templates/reports/final-report.template.md +93 -98
  87. package/runtime/templates/reports/i18n/en.json +135 -0
  88. package/runtime/templates/reports/i18n/ko.json +135 -0
  89. package/runtime/templates/reports/implementation-planning-input.template.md +18 -0
  90. package/runtime/templates/reports/improvement-discovery-input.template.md +78 -0
  91. package/runtime/templates/reports/task-brief.template.md +2 -2
  92. package/runtime/validators/lib/fixtures.sh +30 -0
  93. package/runtime/validators/lib/runners.sh +1 -1
  94. package/runtime/validators/validate-implementation-plan-stages.py +211 -0
  95. package/runtime/validators/validate-run.py +121 -26
  96. package/runtime/validators/validate-workflow.sh +2 -2
  97. package/runtime/validators/validate_improvement_report.py +275 -0
  98. package/src/config.mjs +18 -0
  99. package/src/install.mjs +41 -14
  100. package/src/setup.mjs +133 -1
  101. package/src/uninstall.mjs +21 -1
@@ -14,13 +14,13 @@
14
14
 
15
15
  - **Task identity**: `<project-id>/<task-group>/<task-id>` 기반 stable task key로 task root를 생성하거나 재사용하고, manifest · index · timeline을 일관되게 갱신합니다.
16
16
  - **Task type별 profile**: `requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`, `final-verification`, `release-handoff` 등 표준 task type 프로파일을 로드해 instruction-set을 렌더링합니다.
17
- - **Run lifecycle**: 매 실행마다 per-run 디렉터리(`runs/<timestamp>/`)에 prompt snapshot, sessions/, expected-state, final report 템플릿, run manifest, timeline 이벤트를 저장합니다.
18
- - **Single python authority**: 모든 prepare wiring(profile/workers/model 해소, path 계산, 9개 render, central record_start)이 [`okstra_ctl.run.prepare_task_bundle()`](scripts/okstra_ctl/run.py) 한 함수에 모여 있습니다. `okstra.sh` 와 `okstra-run` skill 은 같은 함수를 호출하는 thin caller 이며, 환경 변수로 상태를 전달하지 않습니다 — task 정체성·경로·workflow 상태는 모두 디스크 권위 파일에서 매번 계산됩니다.
17
+ - **Run lifecycle**: 매 실행마다 `runs/<task-type>/` 아래에 manifests, prompts, state, reports, sessions, worker-results, logs를 누적하고, 파일명 suffix `-<task-type>-<seq>`로 같은 phase의 재실행을 분리합니다.
18
+ - **Single python authority**: 모든 prepare wiring(profile/workers/model 해소, path 계산, render, central record_start)이 [`okstra_ctl.run.prepare_task_bundle()`](../../scripts/okstra_ctl/run.py) 한 함수에 모여 있습니다. `okstra.sh` 와 `okstra-run` skill 은 같은 함수를 호출하는 thin caller 이며, 환경 변수로 상태를 전달하지 않습니다 — task 정체성·경로·workflow 상태는 모두 디스크 권위 파일에서 매번 계산됩니다.
19
19
  - **Claude handoff (두 모드)**: (a) `okstra.sh` 가 새 `claude` 프로세스를 띄우는 전통 방식, (b) `okstra-run` skill 이 현재 claude 세션 안에서 prepare 후 lead 역할을 그대로 인계받는 in-session 모드. 둘 다 `prepare_task_bundle` 의 산출물(instruction-set 등)을 그대로 사용합니다.
20
- - **Required team contract**: `Claude lead` + 기본 worker `Claude worker` · `Codex worker` · `Report writer worker` Agent Teams 우선 시도를 강제합니다. `Gemini worker` 옵션 워커로, `--workers` 또는 프로필의 `- Workers:` 섹션에 명시할 때만 포함됩니다.
21
- - **User-home install + project-local task bundles**: `npx okstra@latest install` 한 명령이 런타임(`~/.okstra/{lib/python, bin, templates}`) + 스킬 마크다운(`~/.claude/skills/<name>/SKILL.md`) 을 모두 깐다. 대상 프로젝트에는 task bundle 과 discovery metadata 가 `.project-docs/okstra/` 아래 저장되고, **추가로 `<PROJECT_ROOT>/.claude/settings.local.json` 이 `~/.okstra/templates/settings.local.json` 을 가리키는 symlink 로 provisioning** 됩니다 (`okstra setup` 또는 `okstra-ctl` prepare 가 idempotent 하게 관리; 기존에 일반 파일이 있었다면 `.bak.<timestamp>` 로 백업 후 교체). 이 symlink 가 host Claude Code 세션에 자동 로드되어 codex/gemini worker wrapper 호출 권한을 부여하므로, 사용자의 글로벌 `~/.claude/settings.json` 은 건드리지 않으며 별도 `--settings` CLI 주입도 필요 없습니다. (개발용으로는 `okstra-install.sh` `--link` 모드 symlink 설치를 제공합니다.)
20
+ - **Required team contract**: phase profile의 `Required workers:` 블록이 roster의 권위입니다. 일반 분석 phase는 Claude/Codex analyser + report-writer를 기본으로 하고, Gemini는 profile과 `--workers`가 허용할 때만 포함됩니다. `release-handoff`처럼 lead-only에 가까운 phase는 별도 roster를 가집니다.
21
+ - **User-home install + project-local task bundles**: `npx okstra@latest install` 한 명령이 런타임(`~/.okstra/{lib/python, bin, templates}`), 스킬 13종(`~/.claude/skills/<name>/SKILL.md`), worker agent 4종(`~/.claude/agents/*-worker.md`)설치합니다. 대상 프로젝트에는 task bundle 과 discovery metadata 가 `.project-docs/okstra/` 아래 저장되고, **추가로 `<PROJECT_ROOT>/.claude/settings.local.json` 이 `~/.okstra/templates/settings.local.json` 을 가리키는 symlink 로 provisioning** 됩니다 (`okstra setup` 또는 `okstra-ctl` prepare 가 idempotent 하게 관리; 기존에 일반 파일이 있었다면 `.bak.<timestamp>` 로 백업 후 교체). 이 symlink 가 host Claude Code 세션에 자동 로드되어 codex/gemini worker wrapper 호출 권한을 부여하므로, 사용자의 글로벌 `~/.claude/settings.json` 은 건드리지 않습니다. 개발용 `okstra install --link <repo>` 설치 파일을 repo source로 symlink합니다.
22
22
  - **Resume and clarification**: `--task-key`, `--resume-clarification`, `--clarification-response`로 같은 task 재개와 lead의 추가 질문 응답 흐름을 지원합니다.
23
- - **Optional integrations**: worker error sidecar, token usage / cost accounting을 옵션으로 제공합니다.
23
+ - **Derived views and telemetry**: final-report data.json → Markdown → slim MD / self-contained HTML view, worker error sidecar, wrapper log sidecar, token usage / cost accounting을 제공합니다.
24
24
 
25
25
  판단 정책과 worker orchestration은 Claude lead가 담당하고, `okstra`는 Claude가 잘 일할 수 있는 정형화된 입력 묶음과 출력 골격을 준비하는 역할에 집중합니다.
26
26
 
@@ -81,7 +81,7 @@
81
81
 
82
82
  ## What okstra does
83
83
 
84
- okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_task_bundle`](scripts/okstra_ctl/run.py) 에 모여 있습니다. 이 함수가 다음을 한 트랜잭션으로 수행합니다.
84
+ okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_task_bundle`](../../scripts/okstra_ctl/run.py) 에 모여 있습니다. 이 함수가 다음을 한 트랜잭션으로 수행합니다.
85
85
 
86
86
  - okstra 설치 자산(`~/.claude/skills/okstra/...`, `~/.claude/agents/...`, `~/.okstra/bin/...`) 존재 확인
87
87
  - `<PROJECT_ROOT>/.project-docs/okstra/project.json` self-registration (또는 projectId 일치 검증)
@@ -118,22 +118,22 @@ okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_ta
118
118
  >
119
119
  > 위 두 줄을 생략하면 `ModuleNotFoundError: No module named 'okstra_ctl'` 로 즉시 실패합니다 (실제 implementation phase 워커가 docs 만 보고 직접 호출하다가 자주 겪는 패턴). 일반 사용자/워커는 모듈을 직접 부르지 말고 `scripts/okstra.sh` 또는 `/okstra-run` 진입점을 사용하세요 — 그 wrapper 들이 PYTHONPATH 세팅을 자동으로 해 줍니다.
120
120
 
121
- - [`okstra_ctl.run`](scripts/okstra_ctl/run.py) — `prepare_task_bundle()` orchestrator + argparse CLI (`python3 -m okstra_ctl.run --workspace-root ... --project-root ... ...`, **PYTHONPATH 세팅 필요 — 위 호출 규약 참조**).
122
- - [`okstra_ctl.paths`](scripts/okstra_ctl/paths.py) — `compute_run_paths()` pure path/seq 계산.
123
- - [`okstra_ctl.run_context`](scripts/okstra_ctl/run_context.py) — `compute_and_write_run_context()`, `write_run_inputs()`, per-task mutex.
124
- - [`okstra_ctl.render`](scripts/okstra_ctl/render.py) — task-manifest / run-manifest / timeline / task-index / team-state / launch.template / reference-expectations / discovery 9개 render 함수 + `python3 -m okstra_ctl.render <subcommand>` dispatcher (**PYTHONPATH 세팅 필요 — 위 호출 규약 참조**).
125
- - [`okstra_ctl.workers`](scripts/okstra_ctl/workers.py) · [`okstra_ctl.models`](scripts/okstra_ctl/models.py) — worker / model 해소.
126
- - [`okstra_ctl.workflow`](scripts/okstra_ctl/workflow.py) — phase rules (PHASE_ALLOWED_OUTPUTS / PHASE_FORBIDDEN_ACTIONS).
127
- - [`okstra_ctl.material`](scripts/okstra_ctl/material.py) — `analysis-material.md` 본문 + related-tasks 빌더.
128
- - [`okstra_ctl.session`](scripts/okstra_ctl/session.py) · [`okstra_ctl.seeding`](scripts/okstra_ctl/seeding.py) — Claude session id / resume command / 설치 검증 / runtime settings.
129
- - [`okstra_ctl.{ids,index,invocation,jsonl,project_meta,reconcile,resolver,sequence,batch,backfill,listing,locks,tmux}`](scripts/okstra_ctl/) — 중앙 인덱스 (`~/.okstra`) 의 기존 모듈군.
130
- - [`okstra_project.{resolver,state}`](scripts/okstra_project/) — PROJECT_ROOT 해석 + project.json upsert + task-catalog/manifest reader.
121
+ - [`okstra_ctl.run`](../../scripts/okstra_ctl/run.py) — `prepare_task_bundle()` orchestrator + argparse CLI (`python3 -m okstra_ctl.run --workspace-root ... --project-root ... ...`, **PYTHONPATH 세팅 필요 — 위 호출 규약 참조**).
122
+ - [`okstra_ctl.paths`](../../scripts/okstra_ctl/paths.py) — `compute_run_paths()` pure path/seq 계산.
123
+ - [`okstra_ctl.run_context`](../../scripts/okstra_ctl/run_context.py) — `compute_and_write_run_context()`, `write_run_inputs()`, per-task mutex.
124
+ - [`okstra_ctl.render`](../../scripts/okstra_ctl/render.py) — task-manifest / run-manifest / timeline / task-index / team-state / launch.template / reference-expectations / discovery render 함수 + `python3 -m okstra_ctl.render <subcommand>` dispatcher (**PYTHONPATH 세팅 필요 — 위 호출 규약 참조**).
125
+ - [`okstra_ctl.workers`](../../scripts/okstra_ctl/workers.py) · [`okstra_ctl.models`](../../scripts/okstra_ctl/models.py) — worker / model 해소.
126
+ - [`okstra_ctl.workflow`](../../scripts/okstra_ctl/workflow.py) — phase rules (PHASE_ALLOWED_OUTPUTS / PHASE_FORBIDDEN_ACTIONS).
127
+ - [`okstra_ctl.material`](../../scripts/okstra_ctl/material.py) — `analysis-material.md` 본문 + related-tasks 빌더.
128
+ - [`okstra_ctl.session`](../../scripts/okstra_ctl/session.py) · [`okstra_ctl.seeding`](../../scripts/okstra_ctl/seeding.py) — Claude session id / resume command / 설치 검증 / runtime settings.
129
+ - [`okstra_ctl.{ids,index,invocation,jsonl,project_meta,reconcile,resolver,sequence,batch,backfill,listing,locks,tmux}`](../../scripts/okstra_ctl/) — 중앙 인덱스 (`~/.okstra`) 의 기존 모듈군.
130
+ - [`okstra_project.{resolver,state}`](../../scripts/okstra_project/) — PROJECT_ROOT 해석 + project.json upsert + task-catalog/manifest reader.
131
131
 
132
132
  ### Bash entry points (thin)
133
133
 
134
- - [`scripts/okstra.sh`](scripts/okstra.sh) ~160 줄. CLI 파싱 / interactive prompt / confirm-execution-plan / `prepare_task_bundle` 호출 / `exec claude`.
135
- - [`scripts/lib/okstra/{cli,globals,interactive,project-resolver,usage}.sh`](scripts/lib/okstra/) — CLI/인터랙티브 보조만. 산출물 생성 로직 보유 없음.
136
- - [`scripts/okstra-ctl.sh`](scripts/okstra-ctl.sh) + [`scripts/lib/okstra-ctl/`](scripts/lib/okstra-ctl/) — 중앙 컨트롤 센터 CLI (list / show / open / rerun / reconcile / 등).
134
+ - [`scripts/okstra.sh`](../../scripts/okstra.sh) CLI 파싱 / interactive prompt / confirm-execution-plan / `prepare_task_bundle` 호출 / `exec claude`.
135
+ - [`scripts/lib/okstra/{cli,globals,interactive,project-resolver,usage}.sh`](../../scripts/lib/okstra/) — CLI/인터랙티브 보조만. 산출물 생성 로직 보유 없음.
136
+ - [`scripts/okstra-ctl.sh`](../../scripts/okstra-ctl.sh) + [`scripts/lib/okstra-ctl/`](../../scripts/lib/okstra-ctl/) — 중앙 컨트롤 센터 CLI (list / show / open / rerun / reconcile / 등).
137
137
 
138
138
  ### Claude assets (templates + skills)
139
139
 
@@ -149,13 +149,13 @@ okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_ta
149
149
 
150
150
  ### Skills (`skills/`, `agents/`)
151
151
 
152
- - [`agents/SKILL.md`](agents/SKILL.md) — main okstra skill (cross-verify 트리거).
153
- - [`skills/okstra-setup/SKILL.md`](skills/okstra-setup/SKILL.md) — **첫 실행 부트스트랩**. `okstra install` + `project.json` 생성.
154
- - [`skills/okstra-run/SKILL.md`](skills/okstra-run/SKILL.md) — **현재 claude 세션 안에서 okstra task 를 시작**하는 in-session 진입점. `prepare_task_bundle` 직접 호출.
155
- - `skills/okstra-{status,history,convergence,schedule,context-loader,team-contract,report-finder,report-writer,time-summary,logs}/SKILL.md` — phase 진행·status·history 보조 skill. `okstra-logs` 는 codex/gemini wrapper 가 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` 로 남기는 live-log sidecar 의 인벤토리·정리 안내 (read-only, find-delete cleanup 명령 제안만 함).
156
- - 플러그인 매니페스트: [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json) — `npx skills@latest add Devonshin/okstra` 보조 채널이 참조. 0.3.0 부터는 `npx okstra install` 명령이 동일 결과를 보장하므로 일반 셋업에는 이 채널이 필요 없다.
152
+ - [`agents/SKILL.md`](../../agents/SKILL.md) — main okstra lead contract.
153
+ - [`skills/okstra-setup/SKILL.md`](../../skills/okstra-setup/SKILL.md) — **첫 실행 부트스트랩**. `okstra install` + `project.json` 생성.
154
+ - [`skills/okstra-run/SKILL.md`](../../skills/okstra-run/SKILL.md) — **현재 claude 세션 안에서 okstra task 를 시작**하는 in-session 진입점. `prepare_task_bundle` 직접 호출.
155
+ - `skills/okstra-{brief,status,history,convergence,schedule,context-loader,team-contract,report-finder,report-writer,time-summary,logs}/SKILL.md` — brief 작성, phase 진행, status/history, report/time/log 보조 skill. `okstra-logs` 는 codex/gemini wrapper 가 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` 로 남기는 live-log sidecar 의 인벤토리·정리 안내 (read-only, find-delete cleanup 명령 제안만 함).
156
+ - 플러그인 매니페스트: [`../../.claude-plugin/plugin.json`](../../.claude-plugin/plugin.json) — `npx skills@latest add Devonshin/okstra` 보조 채널이 참조. 일반 셋업에는 `npx okstra@latest install` 사용한다.
157
157
  - 설치 위치: `~/.claude/skills/<name>/SKILL.md` (`okstra-install.sh` dev 설치, 또는 위 npx 채널).
158
- - 릴리스 절차: [`RELEASING.md`](RELEASING.md) — npm publish 흐름과 GitHub Actions 워크플로(`v*.*.*` tag → 자동 publish), 자동화 토큰 셋업, 검증/롤백.
158
+ - 릴리스 절차: [`../../RELEASING.md`](../../RELEASING.md) — npm publish 흐름과 release-please / manual fallback.
159
159
 
160
160
  ## Architecture: python authority + thin callers
161
161
 
@@ -306,20 +306,20 @@ Claude launch prompt 본문은 항상 `prompts/launch.template.md` 템플릿에
306
306
 
307
307
  처음 실행이면 위 4-필드(`projectId`, `projectRoot`, `createdAt`, `updatedAt`)를 새로 작성합니다. 이미 존재하면 `--project-id` 인자값과 저장된 `projectId` 가 일치하는지 검증한 뒤 `projectRoot`/`updatedAt` 만 갱신하고, 사용자가 추가한 알 수 없는 필드(`worktreeSyncDirs`, 향후 `mcpServers` 등)는 upsert 과정에서 보존됩니다. 불일치 시 즉시 종료해 동일 디렉토리에서 두 개의 ID 가 혼용되는 것을 막습니다.
308
308
 
309
- `worktreeSyncDirs` (선택) 는 task worktree 로 symlink 할 project-root-relative 디렉토리 목록을 per-project 로 override 합니다. 해석 우선순위는 `OKSTRA_WORKTREE_SYNC_DIRS` 환경변수 → `project.json` → built-in default (`.project-docs`, `.scratch`, `graphify-out`, `.claude`). 빈 배열을 지정하면 sync 자체를 비활성화합니다.
309
+ `worktreeSyncDirs` (선택) 는 task worktree 로 symlink 할 project-root-relative 디렉토리 목록을 per-project 로 override 합니다. 해석 우선순위는 `OKSTRA_WORKTREE_SYNC_DIRS` 환경변수 → `project.json` → built-in default (`.project-docs`, `.scratch`, `graphify-out`, `.claude`). 빈 배열을 지정하면 sync 자체를 비활성화합니다. sync 는 filesystem continuity 용도일 뿐이며, okstra context/write boundary 는 계속 `<PROJECT_ROOT>/.project-docs/okstra/**` 입니다.
310
310
 
311
311
  `okstra-ctl` 의 reindex/backfill 도 신규 모델에서 권위 소스를 변경했습니다. 과거에는 `examples/projects/*.conf.sh` 를 source 했지만, 지금은 `~/.okstra/projects/<projectId>/meta.json` (record_start 가 위 project.json 정보를 mirror 한 결과) 을 스캔하여 (projectId, projectRoot) 매핑을 복원합니다. `OKSTRA_PROJECT_DEFINITION_DIR_OVERRIDE` 환경변수도 함께 폐기되었습니다.
312
312
 
313
313
  ## Artifact-home rule
314
314
 
315
- okstra 사용자 프로젝트에 생성·수정·삭제하는 모든 파일은 `<PROJECT_ROOT>/.project-docs/okstra/` subtree 안에만 위치합니다. 외부 경로 (예: `<PROJECT_ROOT>/CONTEXT.md`, `<PROJECT_ROOT>/docs/adr/`, `<PROJECT_ROOT>/.scratch/`, 소스 코드) **read-only reference** 입니다. okstra phase 파일들이 존재하면 읽을 있지만 부재해도 정상 상태로 간주하며, 자체 판단으로 외부 경로에 쓰지 않습니다.
315
+ okstra project artifact root `<PROJECT_ROOT>/.project-docs/okstra/` 하나뿐입니다. root 밖은 okstra memory 아닙니다. brief `Source Material` 또는 `Reporter Confirmations` 명시적으로 cite 경우에만 read-only source material 읽고, 자체 판단으로 root 밖에 쓰지 않습니다.
316
316
 
317
- 유일한 예외: brief 의 `Source Material` 또는 `Reporter Confirmations` 섹션에서 사용자가 **verbatim** 으로 특정 외부 파일 편집을 요청한 경우. 해당 편집을 수행하는 phase 는 자신의 final-report 에 사용자 원문 인용을 함께 남겨야 합니다.
317
+ 유일한 예외: brief 의 `Source Material` 또는 `Reporter Confirmations` 섹션에서 사용자가 **verbatim** 으로 특정 non-okstra 파일 편집을 요청한 경우. 해당 편집을 수행하는 phase 는 자신의 final-report 에 사용자 원문 인용을 함께 남겨야 합니다.
318
318
 
319
319
  okstra 는 자기 subtree 안에 자체 institutional memory 를 유지합니다.
320
320
 
321
- - `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` — run 을 가로지르며 누적되는 okstra 용어집. 외부 `CONTEXT.md` 류 skill 의 기능을 흡수합니다.
322
- - `<PROJECT_ROOT>/.project-docs/okstra/decisions/<NNNN>-<slug>.md` — okstra 의 결정 기록. 외부 ADR 시스템의 기능을 흡수합니다. 평가 시점은 `implementation-planning` phase 이며 `okstra-brief` 단계에서는 후보만 표시합니다.
321
+ - `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` — run 을 가로지르며 누적되는 okstra 용어집.
322
+ - `<PROJECT_ROOT>/.project-docs/okstra/decisions/<NNNN>-<slug>.md` — okstra 의 결정 기록. 평가 시점은 `implementation-planning` phase 이며 `okstra-brief` 단계에서는 후보만 표시합니다.
323
323
 
324
324
  okstra phase 는 PRD / issue file 을 직접 쓰지 않습니다. 동등한 결정 산출물은 `requirements-discovery` 와 `implementation-planning` 이 `.project-docs/okstra/` 내부에 만듭니다.
325
325
 
@@ -342,18 +342,18 @@ okstra phase 는 PRD / issue file 을 직접 쓰지 않습니다. 동등한 결
342
342
  |---|---|---|---|---|
343
343
  | `requirements-discovery` | 요청을 bugfix/feature/refactor/ops/improvement 중 하나로 분류하고 안전한 다음 phase로 라우팅 | work category, routing decision, missing-input list, clarification requests | `pending-routing-decision` (사용자 답변 후 결정) | 금지 |
344
344
  | `error-analysis` | 보고된 에러/사고의 증상·원인·재현 갭을 증거 기반으로 분석 | symptom/trigger 정리, root-cause 가설, reproduction gap, validation 경로 | `implementation-planning` | 금지 |
345
- | `implementation-planning` | 코딩 시작 전 안전한 구현 방향과 옵션을 평가 | 최소 2개 구현 옵션, 영향 파일 목록, trade-off, 단계별 실행 순서, validation/rollback, **User Approval Request** 블록, **§4.5.9 Plan Body Verification** (Phase 6 워커 사후 검증 라운드 — 합성된 plan 의 내적 일관성을 워커가 `AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT` 로 cross-verify; gate 결과가 `passed` / `passed-with-dissent` 일 때만 Approval 마커 렌더, `blocked-by-disagreement` / `aborted-non-result` 일 때는 majority DISAGREE 항목이 `## 5. Clarification Items` 의 `Blocks=approval` row 로 변환됨) | `implementation` (사용자 승인 후) | 금지 |
346
- | `implementation` | 승인된 `implementation-planning` final report의 단계대로 소스 코드를 수정 | commit list, diff summary, out-of-plan edits 블록, validation/TDD evidence, rollback 검증, verifier 결과(Gemini/Codex/Claude) | `final-verification` | 허용 (승인된 plan의 파일 목록 한정, `git push`/publish/deploy/실제 migration 금지) |
345
+ | `implementation-planning` | 코딩 시작 전 안전한 구현 방향과 옵션을 평가 | 최소 2개 구현 옵션, 영향 파일 목록, trade-off, 단계별 실행 순서, validation/rollback, **User Approval Request** 블록, **§4.5.9 Plan Body Verification** (Phase 6 워커 사후 검증 라운드 — 합성된 plan 의 내적 일관성을 워커가 `AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT` 로 cross-verify; gate 결과가 `passed` / `passed-with-dissent` 일 때만 Approval 마커 렌더, `blocked-by-disagreement` / `aborted-non-result` 일 때는 majority DISAGREE 항목이 `## 5. Clarification Items` 의 `Blocks=approval` row 로 변환됨). **산출 구조**: 항상 `## 4.5 Stage Map` + N 개의 `## 4.5.<i> Stage <i>` 섹션. 각 stage 의 effective step ≤ 6. `depends-on (none)` 인 stage 들은 별도 `implementation` run 으로 병렬 실행 가능 | `implementation` (사용자 승인 후) | 금지 |
346
+ | `implementation` | 승인된 `implementation-planning` final report의 단계대로 소스 코드를 수정. **한 run 에 한 stage 만 실행** (`--stage <auto\|N>` 인수로 stage 선택) | commit list, diff summary, out-of-plan edits 블록, validation/TDD evidence, rollback 검증, verifier 결과(Gemini/Codex/Claude), `carry/stage-<N>.json` evidence sidecar | `final-verification` | 허용 (승인된 plan의 파일 목록 한정, `git push`/publish/deploy/실제 migration 금지) |
347
347
  | `final-verification` | 완료된 작업의 잔존 결함·회귀 위험을 점검하고 release 판단 | acceptance verdict, residual risk, follow-up 라우팅(`error-analysis`/`implementation-planning`/`release-handoff`) | `pending-release-handoff` (verdict 가 `accepted` 일 때만 `release-handoff` 로 진입; 그 외에는 `error-analysis` 또는 `implementation-planning` 으로 리라우팅) | 금지 (read-only 테스트만 허용) |
348
348
  | `release-handoff` | `accepted` 받은 변경을 사용자가 선택한 방식대로 커밋·푸시·PR 로 전달 | 사용자 메뉴 응답(H1 action / H2 PR base / H3 message handling) 기록, 실행한 git/gh 명령 로그, commit SHA 목록, PR URL | `done-or-follow-up` | 허용 — 단 **사용자가 메뉴로 선택한 mutating 명령만** 실행. `git push --force*`, base 브랜치 직접 push, `--no-verify`, `gh release`, publish/deploy 는 금지. source code 자체는 수정 금지(이전 `implementation` 의 diff 를 그대로 패키징). |
349
349
 
350
350
  공통 제약:
351
351
 
352
352
  - `implementation`을 제외한 모든 phase는 source code edit, build, migration, deployment, 그 밖의 state-mutating 명령을 금지합니다(`final-verification`은 read-only 테스트 명령만 허용). `implementation`은 승인된 plan의 파일 목록 안에서만 edit/commit이 허용되며, `git push`·publish·deploy·실제 migration·third-party write API는 여전히 금지됩니다.
353
- - **모든 task-type 격리 worktree (BLOCKING)**: 모든 task-type 의 첫 번째 phase prepare 단계에서 `okstra-ctl` 이 자동으로 task-key 단위 `git worktree` 를 생성하고, 같은 task-key 의 이후 phase (`requirements-discovery` → `error-analysis` → `implementation-planning` → `implementation`) 는 동일한 worktree·브랜치를 재사용합니다. 위치는 `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` (segment 의 `/`·`:` 등 특수문자는 `-` 로 정규화) 이고, 브랜치 이름은 `<work-category-prefix>-<task-id-segment>` (예: `feat-dev-9436`, `fix-dev-7311`) 입니다. base ref 는 첫 phase prepare 시점의 main worktree `HEAD`. `~/.okstra/worktrees/registry.json` (flock-guarded) 가 task-key → path/branch 매핑을 전역 관리해 동시 실행 시 path·branch 충돌을 방지합니다. `.project-docs/`, `.scratch/`, `graphify-out/`, `.claude/` 는 main worktree 에서 symlink 로 연결되어 모든 task 동일한 shared state봅니다 (sync 대상 목록은 `project.json` 의 `worktreeSyncDirs` 또는 `OKSTRA_WORKTREE_SYNC_DIRS` 환경변수로 override 가능; 빈 배열이면 sync 비활성화). caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 되고 executor 는 project_root 에서 그대로 작업합니다. worktree 는 run 종료 후 자동 삭제되지 않으며 후속 phase·PR 작성·rollback 검증의 권위 artefact 입니다. 수동 cleanup: `git -C <main-worktree> worktree remove <path>` → `git -C <main-worktree> branch -D <branch>` + registry 항목 삭제. 자세한 동작은 `prompts/profiles/implementation.md` 의 *Task worktree* 블록과 `agents/SKILL.md` 의 *Task worktree (BLOCKING for every task-type)* 섹션 참고.
353
+ - **모든 task-type 격리 worktree (BLOCKING)**: 모든 task-type 의 첫 번째 phase prepare 단계에서 `okstra-ctl` 이 자동으로 task-key 단위 `git worktree` 를 생성하고, 같은 task-key 의 이후 phase (`requirements-discovery` → `error-analysis` → `implementation-planning` → `implementation`) 는 동일한 worktree·브랜치를 재사용합니다. 위치는 `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` (segment 의 `/`·`:` 등 특수문자는 `-` 로 정규화) 이고, 브랜치 이름은 `<work-category-prefix>-<task-id-segment>` (예: `feat-dev-9436`, `fix-dev-7311`) 입니다. base ref 는 첫 phase prepare 시점의 main worktree `HEAD`. `~/.okstra/worktrees/registry.json` (flock-guarded) 가 task-key → path/branch 매핑을 전역 관리해 동시 실행 시 path·branch 충돌을 방지합니다. configured sync dirs 는 main worktree 에서 symlink 로 연결되어 task checkout 사이의 filesystem continuity제공합니다 (sync 대상 목록은 `project.json` 의 `worktreeSyncDirs` 또는 `OKSTRA_WORKTREE_SYNC_DIRS` 환경변수로 override 가능; 빈 배열이면 sync 비활성화). 이 sync 는 okstra context/write boundary 를 확장하지 않습니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 되고 executor 는 project_root 에서 그대로 작업합니다. worktree 는 run 종료 후 자동 삭제되지 않으며 후속 phase·PR 작성·rollback 검증의 권위 artefact 입니다. 수동 cleanup: `git -C <main-worktree> worktree remove <path>` → `git -C <main-worktree> branch -D <branch>` + registry 항목 삭제. 자세한 동작은 `prompts/profiles/implementation.md` 의 *Task worktree* 블록과 `agents/SKILL.md` 의 *Task worktree (BLOCKING for every task-type)* 섹션 참고.
354
354
  - `implementation` 과 `release-handoff` 를 제외한 모든 phase 는 source code edit, build, migration, deployment, 그 밖의 state-mutating 명령을 금지합니다 (`final-verification` 은 read-only 테스트 명령만 허용). `implementation` 은 승인된 plan 의 파일 목록 안에서만 edit/commit 이 허용되며, `git push`·publish·deploy·실제 migration·third-party write API 는 여전히 금지됩니다. `release-handoff` 는 source code 자체는 수정하지 않고, 사용자가 메뉴로 선택한 commit / push / PR 명령만 실행합니다 (force push, base 브랜치 직접 push, hook bypass, release publish 는 여전히 금지).
355
355
  - 사용자가 "다음 단계 진행해" 같은 표현을 보내도, 그 발화만으로 다음 phase가 자동 시작되지 않습니다. 다음 phase는 새 `okstra.sh` 실행으로만 시작합니다.
356
- - **Authority & permissions assumption (HARD RULE — 모든 task-type 및 `okstra-schedule` 공통)**: 사용자(및 팀)는 예상되는 모든 작업에 대해 완전한 권한·승인 권한을 보유한다고 가정합니다. 외부 승인, 서드파티 액세스, 역할/IAM 권한, 조직적 sign-off, 법무·보안 검토, 벤더 협의, "권한 보유 여부 확인" 같은 항목을 routing 결정·missing inputs·clarification questions·risk·dependency·open questions·effort/day 추정에 포함하지 않습니다. okstra 내부 phase 핸드오프(`User Approval Request` 등)는 사용자 본인이 즉시 승인 가능한 내부 게이트이므로 영향 없으며, `implementation`의 forbidden actions(`git push`, prod deploy, shared-DB migration 등)도 권한 사유가 아닌 **안전 사유**로 계속 적용됩니다.
356
+ - **Authority & permissions assumption (모든 task-type 및 `okstra-schedule` 공통)**: 사용자(및 팀)는 예상되는 모든 작업에 대해 완전한 권한·승인 권한을 보유한다고 가정합니다. 외부 승인, 서드파티 액세스, 역할/IAM 권한, 조직적 sign-off, 법무·보안 검토, 벤더 협의, "권한 보유 여부 확인" 같은 항목을 routing 결정·missing inputs·clarification questions·risk·dependency·open questions·effort/day 추정에 포함하지 않습니다. okstra 내부 phase 핸드오프(`User Approval Request` 등)는 사용자 본인이 즉시 승인 가능한 내부 게이트이므로 영향 없으며, `implementation`의 forbidden actions(`git push`, prod deploy, shared-DB migration 등)도 권한 사유가 아닌 **안전 사유**로 계속 적용됩니다.
357
357
  - Phase별 상세 규칙은 `prompts/profiles/<task-type>.md`에 정의되어 있고, 그 본문이 그대로 `instruction-set/analysis-profile.md`로 렌더링됩니다.
358
358
 
359
359
  ### Phase 간 정보 전달
@@ -361,7 +361,20 @@ okstra phase 는 PRD / issue file 을 직접 쓰지 않습니다. 동등한 결
361
361
  - `requirements-discovery` 또는 `error-analysis`가 남긴 final report의 `## 5. Clarification Requests for the Next Run` 섹션에 사용자가 답변을 채운 뒤, 다음 run에서 `--clarification-response <previous-final-report.md>`로 그 파일을 carry-in합니다.
362
362
  - carry-in된 파일은 현재 run의 `instruction-set/clarification-response.md`로 복사되고, lead가 Section 0에서 prior `Q*` 행의 `Status`(`resolved` / `obsolete`)를 갱신한 뒤 진행합니다.
363
363
  - 답변 편집과 재실행을 한 번에 처리하려면 `--resume-clarification` 모드를 사용합니다. 자세한 동작은 `### --resume-clarification` 섹션을 참고합니다.
364
+ - **Stage carry-in (`implementation` → 다음 stage)**: 각 `implementation` run 은 `runs/implementation/carry/stage-<N>.json` evidence sidecar 를 남깁니다. 다음 stage 가 실행될 때 이 파일을 자동으로 carry-in 합니다. 어떤 `implementation` run 이 어떤 stage 를 소비했는지는 `runs/implementation-planning/consumers.jsonl` 에 역링크로 누적됩니다.
364
365
 
366
+ ### improvement-discovery (sidetrack entry-point)
367
+
368
+ ````
369
+ [brief: scope=codebase + priority-lenses]
370
+ ↓ okstra-run --task-type improvement-discovery
371
+ [improvement-discovery]
372
+ ↓ final-report (## 4.9 Improvement Candidates 후보 N개)
373
+ ↓ (사용자가 후보 K개 선택, 각각 새 brief 작성)
374
+ [requirements-discovery | implementation-planning | error-analysis] (선택된 후보별로 새 task-id 로)
375
+ ````
376
+
377
+ `PHASE_SEQUENCE` 의 정식 멤버에 들어가지 않는 sidetrack entry-point. 단방향 라이프사이클을 깨지 않으면서 코드베이스 발견 시나리오를 흡수한다. lens 화이트리스트와 candidate-cap 은 `scripts/okstra_ctl/improvement_lenses.py` SSOT 1개에서 통일된다. final-report 의 `## 4.9 Improvement Candidates` 표 (10 column) 는 `validators/validate_improvement_report.py` 의 11항목 contract 가 강제한다. 양방향 grilling 두 지점 (`okstra-brief` Step 4 강화 budget 8 + lead 의 Phase 1.5 reflect-back budget 12) 으로 사용자와 AI 의 이해도를 일치시킨다.
365
378
 
366
379
 
367
380
  ---
@@ -438,6 +451,8 @@ task manifest, task index, instruction-set, runs, history가 이 루트 아래
438
451
  - `user-responses/user-response-<task-type>-<seq>.md` *(HTML 의 `Export user response` 버튼이 생성하는 사이드카; 사용자가 채워 저장하면 다음 phase 가 입력으로 소비)*
439
452
  - `worker-results/<worker>-audit-<task-type>-<seq>.md` *(워커별 Reading Confirmation 사이드카; 본문이 아니라 audit 용)*
440
453
  - `status/final-<task-type>-<seq>.status`
454
+ - `carry/stage-<N>.json` *(implementation 전용: stage N 실행 evidence sidecar; 다음 stage 가 자동 carry-in)*
455
+ - `consumers.jsonl` *(implementation-planning 전용: 이 plan 의 각 stage 를 소비한 impl-run 역링크; append-only)*
441
456
  최종 결과 파일 (`final-report` MD / status) 은 `okstra`가 stdout을 저장해서 만드는 파일이 아닙니다.
442
457
  `okstra`가 준비한 task bundle을 바탕으로 Claude가 현재 run 안에 직접 작성하는 결과물입니다.
443
458
  slim MD / HTML 두 view 는 `okstra render-views <final-report.md>` (Phase 7 step 1.5) 가 final-report MD 한 본을 입력으로 결정론적으로 생성합니다. 원본 MD 는 view 생성으로 인해 수정되지 않습니다.
@@ -716,7 +731,7 @@ skill 흐름:
716
731
  2. 사용자의 입력으로 `okstra_ctl.run.prepare_task_bundle(render_only=True)` 를 호출합니다 — `okstra.sh` 를 거치지 않고 같은 python 함수를 직접 호출합니다.
717
732
  3. 같은 instruction-set 산출물이 디스크에 만들어지면 현재 claude 가 그 prompt 를 읽어 lead 역할로 진입합니다.
718
733
 
719
- 자세한 절차는 [`skills/okstra-run/SKILL.md`](skills/okstra-run/SKILL.md) 참조.
734
+ 자세한 절차는 [`skills/okstra-run/SKILL.md`](../../skills/okstra-run/SKILL.md) 참조.
720
735
 
721
736
  ### 5. 필요 시 에러 분석
722
737
 
@@ -754,15 +769,14 @@ scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --workers claud
754
769
 
755
770
  ### 7. 승인된 plan 기반 구현
756
771
 
757
- `implementation-planning` final report의 `User Approval Request` 블록에 사용자 승인이 기록된 뒤에만 실행합니다. 승인된 plan 경로를 `--approved-plan`으로 carry-in해야 하며, plan이 없거나 승인 마커가 없으면 run은 `contract-violated`로 거부됩니다.
772
+ `implementation-planning` final report YAML frontmatter `approved` field `true` 때에만 실행합니다. 승인된 plan 경로를 `--approved-plan`으로 carry-in해야 하며, plan 이 없거나 frontmatter `approved: true` 가 아니면 run 은 `contract-violated` 거부됩니다.
758
773
 
759
- 승인 마커는 line-anchored, case-insensitive로 다음 중 하나와 일치해야 합니다(코드 진실: `scripts/okstra.sh`).
774
+ 승인 형식 (코드 진실: `scripts/okstra_ctl/run.py` 의 `APPROVED_FRONTMATTER_PATTERN`):
760
775
 
761
- - `APPROVED` (라인 시작에 단독, 또는 뒤에 공백/콜론)
762
- - `[x] Approved`
763
- - `User Approval: APPROVED` / `User Approval: granted` / `User Approval: yes`
776
+ - final-report leading `---` YAML 펜스 안에 정확히 한 줄: `approved: true` 또는 `approved: false`
777
+ - 대소문자 무관. report-writer 는 항상 `approved: false` 로 발행하고, 사용자가 `true` 로 toggle 하면 implementation 진입 가능
764
778
 
765
- 승인 마커를 직접 편집하지 않고 CLI 호출 자체를 승인 행위로 처리하려면 `--approve` 플래그를 함께 줍니다. okstra 는 `--approved-plan` 파일의 `User Approval Request` 블록을 `- [x] Approved` 로 toggle 하고 audit 라인을 append 한 뒤 implementation phase 를 이어 실행합니다 (이전 `--ack-approved` alias 는 0.8.0 에서 제거됨). 자세한 동작은 [`docs/kr/cli.md`](cli.md#--approve) 참고.
779
+ 승인 라인을 직접 편집하지 않고 CLI 호출 자체를 승인 행위로 처리하려면 `--approve` 플래그를 함께 줍니다. okstra 는 `--approved-plan` 파일의 frontmatter `approved` `true` 로 toggle 하고 audit 라인을 append 한 뒤 implementation phase 를 이어 실행합니다 (이전 `--ack-approved` alias 는 0.8.0 에서 제거됨). 자세한 동작은 [`docs/kr/cli.md`](cli.md#--approve) 참고.
766
780
 
767
781
  ```bash
768
782
  scripts/okstra.sh --task-type implementation --workers claude,codex,gemini --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> --approved-plan <runs/implementation-planning/.../reports/final-report.md>
@@ -880,7 +894,7 @@ Phase 7 step 1.5 가 final-report MD 한 본을 입력으로 두 view 를 결정
880
894
  ### Live-log mirror (codex / gemini wrapper)
881
895
 
882
896
  - `scripts/okstra-codex-exec.sh`, `scripts/okstra-gemini-exec.sh` 는 dispatch 마다 prompt path 옆에 `<prompt>.log` sidecar 를 만들고 stdout 을 거기로 mirror 합니다 (`tee`, `PIPESTATUS[0]` 로 종료코드 보존). stderr 은 같은 파일에 append (subagent stderr 캡처 contract 보존), 매 dispatch 시 truncate. 호출 subagent 의 `BashOutput` 폴링은 60s 간격이라 long-running run (analysis 의 large-codebase scan, implementation 의 cargo / pytest) 동안 사용자가 stalled state 를 탐지할 수 없는 문제를 해소합니다.
883
- - `$TMUX` 가 셋팅된 lead 환경이면 wrapper 가 sibling pane 을 자동 분할해 `tail -F <log-path>` 를 띄웁니다. trace pane title 은 `<cli>-<role>-<pid>-trace` (e.g. `codex-worker-93421-trace`, `gemini-executor-93422-trace`); 동일 시점에 caller (worker) pane title 도 `<cli>-<role>-<pid>` 로 셋팅돼 worker ↔ trace 쌍을 한 눈에 매칭할 수 있습니다. `<pid>` 는 wrapper 자기 자신의 PID 라서 동일 role 의 worker 가 둘 이상 동시에 spawn 돼도 서로 구분됩니다. role 은 wrapper 의 5번째 optional positional 인자이며, 누락 시 기본값 `worker` 로 떨어집니다. caller 가 다른 라벨(예: `executor`)을 원하면 5번째 인자로 명시해야 합니다. wrapper 진입 직전의 caller pane title 은 capture 해두고 EXIT trap 에서 복원하므로, dispatch 사이의 stale title 이 남지 않습니다. focus 는 caller pane 으로 복귀하고, CLI 종료 후 pane 은 유지돼 스크롤백 가능. `$TMUX` 미설정, split 실패, 구버전 tmux 등 모든 경로는 silent degrade.
897
+ - `$TMUX` 가 셋팅된 lead 환경이면 wrapper 가 sibling pane 을 자동 분할해 `tail -F <log-path>` 를 띄웁니다. trace pane title 은 `<cli>-<role>-<pid>-trace[from=<caller-pane-id>]` (e.g. `codex-worker-93421-trace[from=%5]`, `gemini-executor-93422-trace[from=%5]`); 동일 시점에 caller (worker) pane title 도 `<cli>-<role>-<pid>` 로 셋팅됩니다. `<pid>` 는 wrapper 자기 자신의 PID 라서 동일 role 의 worker 가 둘 이상 동시에 spawn 돼도 서로 구분되며, trace title 에 박힌 caller pane id 덕분에 worker pane title 이 외부에서 덮어써져도 (Claude Code TUI 가 OSC 2 escape 로 자기 pane title 을 지속 emit) trace ↔ worker 매핑이 깨지지 않습니다. caller pane id 는 우선 `$TMUX_PANE` 에서, 비어 있으면 `tmux display-message -p '#{pane_id}'` (active pane) 으로 fallback — Claude Code Bash tool 환경처럼 `$TMUX_PANE` 가 stripping 돼도 caller pane 을 정확히 잡습니다. trace pane split 도 caller pane 을 `-t` 로 명시 anchor 합니다. role 은 wrapper 의 5번째 optional positional 인자이며, 누락 시 기본값 `worker` 로 떨어집니다. caller 가 다른 라벨(예: `executor`)을 원하면 5번째 인자로 명시해야 합니다. wrapper 진입 직전의 caller pane title 은 capture 해두고 EXIT trap 에서 복원하므로, dispatch 사이의 stale title 이 남지 않습니다. focus 는 caller pane 으로 복귀하고, CLI 종료 후 pane 은 유지돼 스크롤백 가능. `$TMUX` 미설정, split 실패, 구버전 tmux 등 모든 경로는 silent degrade.
884
898
  - **Claude `/exit` 시 자동 정리**: trace pane 의 `tail -F` 는 tmux 셸의 자식이라 Claude 가 종료돼도 살아남는 문제를 막기 위해, wrapper 는 spawn 한 pane id 를 caller `$TMUX_PANE` 으로 키된 registry (`${TMPDIR:-/tmp}/okstra-trace-panes/<caller-pane>.list`) 에 append 합니다. `templates/reports/settings.template.json` 의 `hooks.SessionEnd` 가 `$HOME/.okstra/bin/okstra-trace-cleanup.sh` 를 호출해 자신의 caller pane registry 만 읽어 `tmux kill-pane` 합니다. caller pane 단위로 scope 가 잡혀 있어 같은 tmux 세션에 Claude 인스턴스가 여러 개 떠 있어도 서로의 trace pane 을 죽이지 않습니다. tmux 가 없거나 stale pane id 인 경우 silent degrade.
885
899
  - **Phase 종료 시 사용자 확인**: 매 phase 의 마지막 단계로 lead 가 `okstra-trace-cleanup.sh --list` 로 등록된 pane 목록을 출력한 뒤 사용자에게 "모두 닫기 / 그대로 두기" 양자택일을 묻고 응답대로 처리합니다 (`prompts/profiles/_common-contract.md` 의 *Phase wrap-up* 항목). `$TMUX_PANE` 미설정 환경에서는 단계 자체가 silent-skip. `--list` 모드는 pane 을 죽이지 않고 `<pane_id>\t<pane_title>` 만 출력하므로 사용자가 무엇이 닫힐지 시각적으로 확인할 수 있습니다.
886
900
  - 디스크 누적은 `okstra-logs` skill 이 read-only 로 인벤토리 + cleanup 명령을 제안합니다 (실행은 사용자 copy-paste).
@@ -939,10 +953,10 @@ phase 산출물의 출고 가능 여부를 강제하는 진입점:
939
953
  - 최종 판단은 스크립트가 아니라 Claude가 수행합니다.
940
954
  - stable task key를 유지해야 이후 bug 추적, 재수정, 재검증이 가능합니다.
941
955
  - 워커 에러는 옵션 sidecar `runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl`로 수집되며 lead가 단독 writer입니다. 진입점 helper는 `scripts/okstra-error-log.py`입니다.
942
- - 토큰 사용 및 비용 집계는 `scripts/okstra-token-usage.py`가 담당하며.
956
+ - 토큰 사용 및 비용 집계는 `scripts/okstra-token-usage.py`와 Node wrapper `okstra token-usage`가 담당합니다.
943
957
  - `okstra.sh`는 worker CLI 호출 anchoring을 위해 절대 projectRoot를 강제합니다.
944
958
  - `okstra wizard step` 은 `--answer <val>` 을 **필수** 로 받습니다. 응답을 줄 차례가 아니라 다음 prompt 만 미리 보고 싶다면 `--no-submit` 으로 peek 합니다.
945
- - `okstra history` manifest fallback / 페이지네이션 / 필터를 지원하며, `--base-ref` 워크트리 registry 에서 해석합니다.
959
+ - `/okstra-history`는 task manifest fallback / 페이지네이션 / 필터를 지원하고, `--base-ref`는 워크트리 registry에서 해석합니다.
946
960
  - 사용자 프로젝트에 대한 모든 쓰기는 `<PROJECT_ROOT>/.project-docs/okstra/` 안에만 발생합니다 (Artifact-home rule 참조).
947
961
 
948
962
  ## Related documents
@@ -980,7 +994,7 @@ phase 산출물의 출고 가능 여부를 강제하는 진입점:
980
994
 
981
995
  호출 순서는 항상 `task lock` → `central lock` (ctl rerun) 또는 `central lock` 단독(record_start, reconcile). 역순 보유는 발생하지 않는다.
982
996
 
983
- `task_lock_filename` 은 각 세그먼트를 fs-safe 슬러그로 정규화한 뒤 `-` 를 `--` 로 escape 해 `-` 로 join 하므로, `('p','feature-8','email','x')` 와 `('p','feature','8-email','x')` 가 같은 파일명으로 충돌해 mutex 가 공유되는 문제를 방지한다 ([scripts/okstra_ctl/locks.py](scripts/okstra_ctl/locks.py)).
997
+ `task_lock_filename` 은 각 세그먼트를 fs-safe 슬러그로 정규화한 뒤 `-` 를 `--` 로 escape 해 `-` 로 join 하므로, `('p','feature-8','email','x')` 와 `('p','feature','8-email','x')` 가 같은 파일명으로 충돌해 mutex 가 공유되는 문제를 방지한다 ([scripts/okstra_ctl/locks.py](../../scripts/okstra_ctl/locks.py)).
984
998
 
985
999
  ### 환경변수
986
1000
 
package/docs/kr/cli.md CHANGED
@@ -30,6 +30,7 @@
30
30
  - [`--approved-plan`](#--approved-plan)
31
31
  - [`--approve`](#--approve)
32
32
  - [`--work-category`](#--work-category)
33
+ - [`--base-ref`](#--base-ref)
33
34
  - [`--related-tasks`](#--related-tasks)
34
35
  - [`--render-only`](#--render-only)
35
36
  - [`--no-plan-verification`](#--no-plan-verification)
@@ -49,7 +50,7 @@
49
50
  기본 명령(첫 진입 / full args):
50
51
 
51
52
  ```bash
52
- scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--executor claude|codex|gemini] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--clarification-response <previous-final-report>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>]
53
+ scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--executor claude|codex|gemini] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--base-ref <branch|tag|sha>] [--clarification-response <previous-final-report>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>]
53
54
  ```
54
55
 
55
56
  후속 phase 단축 형식(기존 task-manifest.json이 존재할 때):
@@ -108,6 +109,23 @@ interactive terminal에서 실행하면 다음 규칙이 추가로 적용됩니
108
109
  이번 run의 목적과 profile 선택, run directory 세그먼트, lifecycle phase 라우팅을 결정하는 단일 입력값입니다.
109
110
  표준 값과 phase별 책임은 위 [Task type](#task-type) 섹션을 참고합니다.
110
111
 
112
+ #### `--task-type improvement-discovery`
113
+
114
+ `improvement-discovery` 는 `PHASE_SEQUENCE` 외부 sidetrack entry-point 입니다. 코드베이스 스코프와 lens 화이트리스트 안에서 multi-worker 합의로 개선 후보를 도출합니다.
115
+
116
+ - 입력: frontmatter `scope: codebase` 마커가 있는 brief.
117
+ - `priority-lenses`: 1–4개. lens 화이트리스트는 `scripts/okstra_ctl/improvement_lenses.py` 의 `LENSES` 상수.
118
+ - `scan-scope`: 1개 이상의 경로.
119
+ - `out-of-scope`: 선택.
120
+ - `candidate-cap`: 1–12, 기본 8.
121
+ - 출력: `## 4.9 Improvement Candidates` 표 (10 column: Cand ID / Lens / Title / Scope / Severity / Effort / Consensus / Source workers / Recommended next-phase / Evidence).
122
+ - Verdict Token: `candidates-ready` / `no-candidates` / `blocked`.
123
+ - 라우팅: 자동 spin-off 없음. 사용자가 후보를 골라 새 task-id 로 `requirements-discovery` / `implementation-planning` / `error-analysis` 진입.
124
+ - 워커: claude + codex + gemini + report-writer 모두 필수.
125
+ - 양방향 grilling 두 지점: `okstra-brief` Step 4 강화 (budget 8) + lead 의 Phase 1.5 reflect-back (budget 12).
126
+ - Validator: `validators/validate_improvement_report.py` 가 `improvement-discovery` final-report 의 11항목 contract 를 강제.
127
+ - `improvement-discovery` run 은 `PHASE_SEQUENCE` 에 포함되지 않으므로 `--task-key` 단축 경로의 `nextRecommendedPhase` 자동 채움 대상이 아닙니다.
128
+
111
129
  ### `--task-brief`
112
130
 
113
131
  분석의 기준이 되는 task brief 문서 경로입니다.
@@ -349,22 +367,24 @@ scripts/okstra.sh --task-type implementation \
349
367
 
350
368
  ### `--approved-plan`
351
369
 
352
- `--task-type implementation` 의 입력으로, 이전 `implementation-planning` run 의 final report 경로를 받습니다. 이 파일에는 사용자 승인 마커가 기록되어 있어야 합니다. 마커는 line-anchored, case-insensitive 다음 중 하나와 일치해야 합니다.
370
+ `--task-type implementation` 의 입력으로, 이전 `implementation-planning` run 의 final report 경로를 받습니다. 이 파일의 YAML frontmatter 에는 `approved` field 있어야 하며 값이 `true` 여야 합니다.
371
+
372
+ 승인 형식:
353
373
 
354
- - `APPROVED` (라인 시작에 단독, 또는 뒤에 공백/콜론)
355
- - `[x] Approved`
356
- - `User Approval: APPROVED` / `User Approval: granted` / `User Approval: yes`
374
+ - final-report leading `---` YAML 펜스 안에 정확히 한 줄: `approved: true` 또는 `approved: false`
375
+ - 대소문자 무관 (`True` / `TRUE` 도 허용)
376
+ - report-writer 는 항상 `approved: false` 발행하고, 사용자가 `true` toggle 하면 implementation 진입 가능
357
377
 
358
- 승인 마커가 없으면 run 은 `contract-violated` 로 거부됩니다. 직접 파일을 편집하는 대신 `--approve` 플래그로 CLI 호출 자체를 승인 행위로 처리할 수도 있습니다.
378
+ frontmatter `approved: true` 가 아니면 run 은 `contract-violated` 로 거부됩니다. 직접 파일을 편집하는 대신 `--approve` 플래그로 CLI 호출 자체를 승인 행위로 처리할 수도 있습니다.
359
379
 
360
380
  ### `--approve`
361
381
 
362
382
  `--approved-plan` 과 `--task-type implementation` 과 함께 쓰는 플래그로, **CLI 호출 자체를 plan 승인 신호로 간주**합니다. 동작:
363
383
 
364
- - 지정된 `--approved-plan` 파일의 최상단 `User Approval Request` 블록을 갱신합니다.
365
- - `- [ ] Approved` `- [x] Approved` 로 toggle 하고, audit 라인 (`승인 일시: <ISO8601> — recorded by \`okstra --approve\``) 을 append 합니다.
366
- - 이미 승인 마커가 있는 파일이면 audit 라인만 보강합니다.
367
- - 파일에 `User Approval Request` 블록이 전혀 없으면 즉시 에러로 종료합니다 (잘못된 plan 파일을 가리키고 있을 가능성).
384
+ - 지정된 `--approved-plan` 파일의 YAML frontmatter 에서 `approved: false` 라인을 `approved: true` 로 toggle 합니다.
385
+ - 파일 끝에 audit 라인 (`- 승인 일시 (CLI ack): <ISO8601> — recorded by \`okstra --approve\``) 을 append 합니다.
386
+ - 이미 `approved: true` 파일이면 frontmatter 는 그대로 두고 audit 라인만 (한 번도 기록 안된 경우) 보강합니다.
387
+ - 파일에 YAML frontmatter 가 없거나 `approved:` 라인이 없으면 즉시 에러로 종료합니다 (잘못된 plan 파일을 가리키고 있을 가능성).
368
388
 
369
389
  `--approve` 는 `--task-type implementation` 이 아닌 곳에서는 의미가 없으며 에러로 종료합니다. CI/스크립트 환경 또는 한 줄로 "승인 + 다음 phase 실행" 을 함께 처리하고 싶을 때 사용합니다. (이전에 존재하던 `--ack-approved` alias 는 0.8.0 에서 제거되었습니다.)
370
390
 
@@ -400,6 +420,23 @@ scripts/okstra.sh --task-type implementation-planning \
400
420
  --task-brief .project-docs/tasks/8852/PLAN.md
401
421
  ```
402
422
 
423
+ ### `--base-ref`
424
+
425
+ task-key에 대한 격리 worktree를 처음 만들 때 기준으로 삼을 git ref입니다. 브랜치 이름, 태그, commit SHA를 받을 수 있습니다.
426
+
427
+ - 첫 phase prepare에서는 필수입니다. `okstra-run` skill은 PR base picker와 같은 메뉴(`main`, `dev`, `staging`, `preprod`, `prod`, 직접 입력)로 값을 수집합니다.
428
+ - 같은 task-key의 후속 phase에서는 registry에 저장된 worktree path / branch / base ref를 재사용하므로 새 값은 무시됩니다.
429
+ - `project_root`가 git repo가 아니거나 이미 non-main worktree 안이면 provisioning이 skip되고 이 값도 사용되지 않습니다.
430
+
431
+ 예:
432
+
433
+ ```bash
434
+ scripts/okstra.sh --task-type requirements-discovery \
435
+ --base-ref main \
436
+ --project-id jobs --task-group tasks --task-id 8852 \
437
+ --task-brief .project-docs/tasks/8852/BRIEF.md
438
+ ```
439
+
403
440
  ### `--related-tasks`
404
441
 
405
442
  간단한 연관 task 식별자 목록을 쉼표로 전달합니다.
@@ -526,25 +563,31 @@ chmod +x ~/.local/bin/okstra-ctl
526
563
  | 활성 run 재조정 | `okstra-ctl reconcile [--project <id|all>]` |
527
564
  | 배치 진행 | `okstra-ctl batch status <batch-id>` |
528
565
 
529
- ### `okstra` Node CLI — introspection subcommands
566
+ ### `okstra` Node CLI — admin / introspection subcommands
530
567
 
531
- `okstra` Node CLI (`bin/okstra`) skill / agent 에서 사용하는 read-only introspection subcommand 제공합니다. 모두 JSON stdout 으로 emit 합니다. 별도 python heredoc 대신 단일 allowlisted command 로 호출 가능 — Claude Code 가 매 호출마다 permission prompt 띄우지 않습니다 (`Bash(okstra:*)` runtime settings template 의 allow 룰에 포함).
568
+ `okstra` Node CLI (`bin/okstra`) installer/admin 명령과 skill / agent 사용하는 introspection 명령을 함께 제공합니다. Python 런타임을 직접 호출하지 않고 Node wrapper통하므로 `PYTHONPATH` wiring은 `src/_python-helper.mjs`가 처리합니다.
532
569
 
533
570
  | 명령 | 용도 |
534
571
  |---|---|
572
+ | `okstra paths [--field <name>\|--shell]` | package/runtime/home/bin/pythonpath/version 경로 출력 |
573
+ | `okstra install [--refresh\|--dry-run\|--link <repo>]` | runtime, templates, skills, agents 설치/갱신 |
574
+ | `okstra ensure-installed [-q]` | 설치 상태 확인, stale이면 재설치 |
575
+ | `okstra uninstall [--purge -y]` | 설치 자산 제거. 기본값은 사용자 데이터 보존 |
576
+ | `okstra doctor` | runtime + Python import + skill/agent 설치 진단 |
577
+ | `okstra setup --project-id <id>` | 현재 프로젝트의 `.project-docs/okstra/project.json` 생성/갱신 |
578
+ | `okstra check-project [--json]` | 현재 프로젝트가 등록되었는지 검증 |
579
+ | `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | 영구 설정 관리 (예: `pr-template-path`). 원자적 JSON 쓰기 |
535
580
  | `okstra task-list [--project-root <path>]` | `list_project_tasks` + `read_latest_task` 결과를 합쳐 task 카탈로그 + 최근 task 를 JSON 으로 반환 |
536
581
  | `okstra task-show <task-key> [--project-root <path>]` | task-manifest.json 의 workflow / phase / status 요약 |
537
582
  | `okstra worktree-lookup <task-key>` | `worktree_registry.lookup` 결과 (예약된 path / branch / base ref / 현재 상태) |
538
- | `okstra plan-validate <plan-path>` | `_validate_approved_plan` — approval marker 인식 결과와 sanitization diff |
539
- | `okstra render-bundle <args…>` | `prepare_task_bundle(render_only=True)` 의 thin shim — `python3 -m okstra_ctl.run --render-only` 와 동일 시그니처 |
583
+ | `okstra plan-validate <plan-path>` | `_validate_approved_plan` — frontmatter `approved` 인식 결과와 Blocks=approval 미해결 진단 |
584
+ | `okstra render-bundle <args…> [--stage <auto\|N>]` | `prepare_task_bundle(render_only=True)` 의 thin shim — `python3 -m okstra_ctl.run --render-only` 와 동일 시그니처. `--stage` 는 `implementation` task 전용: 실행할 Stage Map 항목 지정. `auto` (기본값) = 의존성이 만족된 가장 빠른 미완료 stage, `<N>` = 강제 지정 |
540
585
  | `okstra render-views <final-report.md>` | Phase 7 step 1.5 — 토큰 치환된 final-report MD 한 본을 입력으로 sibling `*.slim.md` (AI 입력용) + `*.html` (사람용 self-contained) 두 view 를 결정론적으로 생성. 원본 MD 는 수정하지 않음. Node 위임 wrapper는 `scripts/okstra-render-report-views.py` 를 호출. `validators/validate-report-views.py` 가 substring 보존 / form-control 위치 / Response ID parity 를 검사 |
541
- | `okstra wizard <init\|step\|render-args\|confirmation> --state-file <path>` | okstra-run 인터랙티브 입력 상태머신 (`okstra_ctl.wizard`). `init` 으로 state file 을 시드한 뒤 skill 이 `step --answer <val>` 을 반복 호출하면 다음 `Prompt` JSON 을 받음. `--answer` 는 **필수**. 응답을 주지 않고 다음 prompt 만 미리 보고 싶다면 `--no-submit` 으로 peek. `render-args` 는 최종 `render-bundle` 인자 맵, `confirmation` 은 사용자 echo 블록을 반환 |
542
- | `okstra history [--limit N] [--offset M] [--project <id>] [--status <enum>]` | run history 페이지네이션 / 필터 조회. 중앙 인덱스가 비어 있으면 프로젝트별 task-manifest 들을 스캔해 fallback 으로 채움. `--base-ref` 워크트리 registry 에서 해석 |
543
- | `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | 영구 설정 관리 (예: `pr-template-path`). 원자적 JSON 쓰기. global scope 의 상대경로는 거절 |
586
+ | `okstra wizard <init\|step\|render-args\|confirmation> --state-file <path>` | okstra-run 인터랙티브 입력 상태머신 (`okstra_ctl.wizard`). `init` 으로 state file 을 시드한 뒤 skill 이 `step --answer <val>` 을 반복 호출하면 다음 `Prompt` JSON 을 받음. `--answer` 는 **필수**. 응답을 주지 않고 다음 prompt 만 미리 보고 싶다면 `--no-submit` 으로 peek. `render-args` 는 최종 `render-bundle` 인자 맵, `confirmation` 은 사용자 echo 블록을 반환. `implementation` task type 에서는 `approved_plan_pick` 직후 `stage_pick` 단계가 추가되어 실행할 stage 를 선택하고, `executor_pick` 으로 넘어갑니다 |
587
+ | `okstra token-usage ...` | 설치된 `okstra-token-usage.py` 감싸 run token usage 수집/치환을 수행 |
544
588
 
545
589
  > 모든 subcommand 는 `bin/okstra` 가 spawn 하는 python 헬퍼 (`src/_python-helper.mjs`) 가 `PYTHONPATH` 와 `~/.okstra/lib/python` 을 wire 합니다. 직접 `python3 -m okstra_ctl.*` 으로 호출하면 `PYTHONPATH` 를 사용자가 직접 셋업해야 합니다.
546
590
 
547
591
  ### Live-log sidecar
548
592
 
549
593
  codex / gemini wrapper 는 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` sidecar 를 만들고 stdout / stderr 를 mirror 합니다. tmux 안에서 lead 를 띄우면 wrapper 가 자동으로 `tail -F` pane 을 분할합니다 (trace pane title: `<cli>-<role>-<pid>-trace`, caller (worker) pane title: `<cli>-<role>-<pid>` — wrapper PID 가 동일 role 의 동시 dispatch 를 구분합니다). 분할된 trace pane 은 caller `$TMUX_PANE` 으로 키된 registry 에 등록돼, Claude `/exit` 시 `SessionEnd` 훅이 `okstra-trace-cleanup.sh` 로 자동 정리합니다. 사용량 인벤토리와 `find … -delete` cleanup 명령은 `okstra-logs` skill 이 read-only 로 제안합니다. 자세한 와이어링은 [`docs/kr/architecture.md`](architecture.md) 의 *Live-log mirror* 절 참고.
550
-
@@ -0,0 +1,65 @@
1
+ # PR template 사용 가이드
2
+
3
+ `release-handoff` 단계에서 `Claude lead` 가 PR 본문을 작성할 때 사용하는 마크다운 템플릿의 해석 규칙·저장 위치·설정 방법을 정리한다.
4
+
5
+ 해석 로직의 권위 출처: [`scripts/okstra_ctl/pr_template.py`](../scripts/okstra_ctl/pr_template.py).
6
+
7
+ ## 1. 4 단계 lookup 우선순위
8
+
9
+ 높은 우선순위가 먼저 매치된다. 상위 단계가 매치되면 하위 단계는 조회하지 않는다.
10
+
11
+ | # | source | 위치 | 비고 |
12
+ |---|--------|------|------|
13
+ | 1 | **per-run override** | `okstra render-bundle --pr-template-path <path>` 또는 wizard 의 한 번성 입력 | 상대경로는 호출자 cwd 기준 (override) 또는 `project_root` 기준 (project scope 와 동일 함수 사용). |
14
+ | 2 | **project scope** | `<project_root>/.project-docs/okstra/project.json` 의 `prTemplatePath` 필드 | 상대경로는 `project_root` 기준으로 해석. |
15
+ | 3 | **global scope** | `~/.okstra/config.json` 의 `prTemplatePath` 필드 | **절대경로 또는 `~/` 시작 경로만** 허용. 상대경로는 모호하므로 거절. |
16
+ | 4 | **default (skill bundle)** | 후보 경로 중 먼저 존재하는 파일 (아래 §2) | `npx okstra install` 직후의 폴백 경로. |
17
+
18
+ 위 4 단계 중 어느 하나에서 명시된 파일이 존재하지 않으면 `PrTemplateError` 로 즉시 실패한다 (silent fallback 없음).
19
+
20
+ ## 2. default 후보 경로
21
+
22
+ 1. `$OKSTRA_SKILLS_DIR/okstra-run/templates/pr-body.template.md` — 환경변수 `OKSTRA_SKILLS_DIR` 가 설정돼 있을 때만.
23
+ 2. `~/.claude/skills/okstra-run/templates/pr-body.template.md` — `npx okstra install` 이 깔아두는 표준 위치.
24
+
25
+ 후보들은 우선순위 순서대로 시도되며, 모두 부재 시 다음과 같이 명시적인 에러로 끝난다.
26
+
27
+ > `no PR template available: default skill template not found. Reinstall okstra (npx okstra install) or set prTemplatePath in project.json / ~/.okstra/config.json.`
28
+
29
+ ## 3. 소스 리포지토리 안 원본
30
+
31
+ - [`skills/okstra-run/templates/pr-body.template.md`](../skills/okstra-run/templates/pr-body.template.md) — `npx okstra install` 이 §2 의 default 위치로 복사하는 원본. 카피를 바꾸고 싶으면 이 파일을 수정한 뒤 다시 install 한다.
32
+
33
+ ## 4. 설정 명령 — 영속화
34
+
35
+ per-run override 보다 길게 유지하려면 wizard 가 자동 호출하거나 직접 다음 명령으로 기록한다.
36
+
37
+ ```bash
38
+ # project scope: <project_root>/.project-docs/okstra/project.json 의 prTemplatePath 갱신
39
+ okstra config set pr-template-path "<path>" --scope project
40
+
41
+ # global scope: ~/.okstra/config.json 의 prTemplatePath 갱신 (절대경로 필수)
42
+ okstra config set pr-template-path "<absolute-path>" --scope global
43
+ ```
44
+
45
+ wizard 흐름에서는 `pr_template_pick` 단계에서 `한 번만 / 프로젝트에 저장 / 전역 저장` 중 선택한다. `프로젝트` 또는 `전역` 을 고르면 위 명령과 동일한 효과로 `prTemplatePath` 가 영속화된다.
46
+
47
+ ## 5. 소스 추적
48
+
49
+ 매 run 의 prepare 단계에서 실제로 채택된 단계가 ctx 에 기록되어 final report 등에서 추적할 수 있다.
50
+
51
+ | ctx key | 값 |
52
+ |---------|-----|
53
+ | `PR_TEMPLATE_PATH` | 실제 해석된 절대경로 |
54
+ | `PR_TEMPLATE_SOURCE` | `"override" \| "project" \| "global" \| "default"` 중 하나 |
55
+
56
+ `PR_TEMPLATE_SOURCE` 가 `default` 인데 프로젝트 컨벤션상 별도 PR 본문이 필요하다면, §4 의 영속화 명령으로 `prTemplatePath` 를 등록한다.
57
+
58
+ ## 6. 트러블슈팅
59
+
60
+ | 증상 | 원인 | 조치 |
61
+ |------|------|------|
62
+ | `override PR template not found: <path>` | per-run override 로 지정한 경로가 없음 | 경로 오타 점검 또는 영속화된 설정을 사용. |
63
+ | `project.json prTemplatePath points to missing file: <path>` | `project.json` 의 `prTemplatePath` 가 가리키는 파일 부재 | 해당 파일을 복원하거나 `okstra config set pr-template-path <path> --scope project` 로 재설정. |
64
+ | `global config prTemplatePath must be absolute or start with '~/'` | `~/.okstra/config.json` 에 상대경로가 들어감 | 절대경로 또는 `~/` 접두 경로로 갱신. |
65
+ | `no PR template available` | install 누락 또는 default 파일까지 모두 부재 | `npx okstra install` 재실행 또는 §4 명령으로 명시 설정. |