okstra 0.110.0 → 0.112.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 (74) hide show
  1. package/README.kr.md +3 -2
  2. package/README.md +3 -2
  3. package/bin/okstra +7 -1
  4. package/docs/for-ai/README.md +2 -2
  5. package/docs/for-ai/skills/okstra-brief.md +2 -3
  6. package/docs/for-ai/skills/okstra-container-build.md +2 -3
  7. package/docs/for-ai/skills/okstra-inspect.md +5 -12
  8. package/docs/for-ai/skills/okstra-rollup.md +3 -4
  9. package/docs/for-ai/skills/okstra-run.md +10 -10
  10. package/docs/for-ai/skills/okstra-schedule.md +2 -7
  11. package/docs/for-ai/skills/okstra-setup.md +1 -1
  12. package/docs/kr/architecture/storage-model.md +1 -2
  13. package/docs/kr/architecture.md +11 -12
  14. package/docs/kr/cli.md +6 -4
  15. package/docs/project-structure-overview.md +14 -12
  16. package/docs/task-process/README.md +4 -4
  17. package/docs/task-process/common-flow.md +8 -5
  18. package/docs/task-process/implementation.md +4 -5
  19. package/docs/task-process/release-handoff.md +3 -3
  20. package/package.json +1 -1
  21. package/runtime/BUILD.json +2 -2
  22. package/runtime/agents/workers/antigravity-worker.md +1 -0
  23. package/runtime/agents/workers/codex-worker.md +1 -0
  24. package/runtime/prompts/coding-preflight/overview.md +3 -1
  25. package/runtime/prompts/launch.template.md +1 -5
  26. package/runtime/prompts/lead/context-loader.md +2 -4
  27. package/runtime/prompts/lead/convergence.md +11 -240
  28. package/runtime/prompts/lead/okstra-lead-contract.md +70 -34
  29. package/runtime/prompts/lead/plan-body-verification.md +240 -0
  30. package/runtime/prompts/lead/report-writer.md +7 -7
  31. package/runtime/prompts/lead/team-contract.md +15 -17
  32. package/runtime/prompts/profiles/_common-contract.md +2 -38
  33. package/runtime/prompts/profiles/_implementation-diff-review.md +43 -0
  34. package/runtime/prompts/profiles/_implementation-executor.md +9 -11
  35. package/runtime/prompts/profiles/_implementation-self-check.md +11 -5
  36. package/runtime/prompts/profiles/_implementation-verifier.md +1 -1
  37. package/runtime/prompts/profiles/final-verification.md +1 -1
  38. package/runtime/prompts/profiles/implementation-planning.md +2 -2
  39. package/runtime/prompts/profiles/implementation.md +1 -1
  40. package/runtime/python/okstra_ctl/codex_dispatch.py +3 -0
  41. package/runtime/python/okstra_ctl/consumers.py +4 -0
  42. package/runtime/python/okstra_ctl/handoff.py +5 -23
  43. package/runtime/python/okstra_ctl/implementation_stage.py +11 -11
  44. package/runtime/python/okstra_ctl/path_hints.py +1 -0
  45. package/runtime/python/okstra_ctl/paths.py +3 -0
  46. package/runtime/python/okstra_ctl/render.py +8 -0
  47. package/runtime/python/okstra_ctl/report_views.py +76 -26
  48. package/runtime/python/okstra_ctl/set_work_status.py +147 -0
  49. package/runtime/python/okstra_ctl/stage_targets.py +152 -0
  50. package/runtime/python/okstra_ctl/team_reconcile.py +1 -1
  51. package/runtime/python/okstra_ctl/wizard.py +47 -0
  52. package/runtime/python/okstra_project/__init__.py +2 -0
  53. package/runtime/python/okstra_project/state.py +44 -2
  54. package/runtime/skills/okstra-brief/SKILL.md +32 -176
  55. package/runtime/skills/okstra-brief/references/reporter-confirmations.md +71 -0
  56. package/runtime/skills/okstra-brief/references/tracker-recursion.md +90 -0
  57. package/runtime/skills/okstra-container-build/SKILL.md +7 -20
  58. package/runtime/skills/okstra-graphify/SKILL.md +8 -8
  59. package/runtime/skills/okstra-inspect/SKILL.md +27 -43
  60. package/runtime/skills/okstra-rollup/SKILL.md +6 -6
  61. package/runtime/skills/okstra-run/SKILL.md +27 -32
  62. package/runtime/skills/okstra-schedule/SKILL.md +64 -419
  63. package/runtime/skills/okstra-setup/SKILL.md +25 -223
  64. package/runtime/skills/okstra-setup/references/project-config.md +188 -0
  65. package/runtime/templates/reports/schedule.template.md +2 -2
  66. package/runtime/templates/worker-prompt-preamble.md +1 -1
  67. package/runtime/validators/validate-run.py +7 -7
  68. package/src/cli-registry.mjs +14 -0
  69. package/src/commands/execute/wizard.mjs +3 -1
  70. package/src/commands/inspect/set-work-status.mjs +31 -0
  71. package/src/commands/inspect/task-show.mjs +11 -31
  72. package/src/commands/lifecycle/check-project.mjs +68 -56
  73. package/src/commands/lifecycle/install.mjs +1 -0
  74. package/src/commands/lifecycle/preflight.mjs +82 -0
package/README.kr.md CHANGED
@@ -164,6 +164,7 @@ Claude Code 세션 안에서 사용하는 슬래시 커맨드:
164
164
  | `/okstra-rollup` | task-group(또는 프로젝트 전체)의 모든 task run 결과를 모아 task별 run수/소요시간/에러와 그룹 합계를 집계하고, report 들을 묶어 task 횡단 종합 요약 작성 |
165
165
  | `/okstra-schedule` | task-group 전체에 대한 작업 계획표 생성 |
166
166
  | `/okstra-container-build` | 검증 완료된 task 의 코드를 로컬 docker compose 그룹으로 배포하고 컨테이너별 로그를 감시 (sub-command: `up` / `status` / `logs` / `stop-watcher` / `down`) |
167
+ | `/okstra-graphify` | 프로젝트 자체 `.okstra/` 메모리(final report, `decisions/*.md`, `glossary.md`)를 지식그래프로 빌드·질의 (범위는 `.okstra/` 로 한정, 산출물은 `.okstra/graph/` 아래; sub-command: `build` / `query` / `path` / `explain` / `mcp` / `wiki`) |
167
168
  | `/okstra-manager` | 여러 프로젝트에 걸친 okstra task 를 manager-owned plan, assignment, 단방향 project sync snapshot, status, child launch context packet 으로 조정 |
168
169
  | `/okstra-setup` | 프로젝트별 부트스트랩 (§3.2) |
169
170
 
@@ -202,7 +203,7 @@ Claude Code 세션 밖에서 task 를 시작하려면:
202
203
  - **Phase 6 plan-body verification (implementation-planning 전용)** — Report writer worker 가 final-report draft 를 작성한 직후, 사용자 승인 gate 직전에 lead 가 1 라운드의 사후 검증을 추가로 돌립니다. 합성된 `## 5.5` implementation plan deliverables 본문에서 `P-Opt-*` / `P-Step-*` / `P-Dep-*` / `P-Val-*` / `P-Rb-*` plan-item 을 추출해 모든 analyser 워커에게 `AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT` 평결을 요청합니다. 집계된 gate 결과는 `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result` 중 하나입니다. frontmatter `approved` 필드는 항상 `false` 로 발행되며, blocking gate 결과는 이를 false 로 유지하고 `## 1. Clarification Items` row 로 변환합니다. 빠른 반복용 opt-out 은 `--no-plan-verification` 입니다. 세부 계약: [`prompts/lead/convergence.md`](prompts/lead/convergence.md) "Plan-body verification mode", [`docs/kr/cli.md#--no-plan-verification`](docs/kr/cli.md#--no-plan-verification).
203
204
  - **Brief = translation layer + Step 6.5 reporter batch confirmation** — `okstra-brief` 가 외부 입력 (이슈 ticket, 요구사항 문서, 사용자 메시지) 을 verbatim 으로 옮기되 okstra 가 추가한 부분은 labelled augmentation 으로 구분하는 translation layer 가 됐습니다. Step 6.5 가 brief 가 옮기는 과정에서 의미 변화가 발생했는지 사용자에게 일괄 확인받아 `Reporter Confirmations` 섹션에 기록하고, 모든 분석 profile 은 이 섹션의 존재를 phase 분석 진입 precondition 으로 강제합니다 (validator: `validators/validate-brief.py`).
204
205
  - **Artifact-home rule (`.okstra/`)** — okstra 의 project artifact root 는 `<project>/.okstra/` 하나뿐입니다. 이 root 밖은 okstra memory 가 아니며, Source Material 또는 Reporter Confirmations 가 명시적으로 cite 한 경우에만 read-only 로 읽습니다. 쓰기는 같은 explicit request path 를 요구합니다. okstra-internal 등가물: 용어집 `glossary.md`, 결정 기록 `decisions/<NNNN>-<slug>.md` (`implementation-planning` phase 에서 평가).
205
- - **Dual-format final-report views** — Phase 7 가 `final-report-<task-type>-<seq>.md` 를 쓰면 `okstra render-views` 가 같은 `reports/` 폴더에 두 view 를 자동 생성합니다: AI 다음-phase 입력용 슬림 markdown, 사람 reviewer 용 self-contained HTML (CSS/JS 인라인, 외부 URL 0). HTML 의 `Export user response` 버튼은 `## 1. Clarification Items` 입력을 `runs/<task-type>/user-responses/user-response-<task-type>-<seq>.md` 사이드카로 직렬화해 다음 phase 가 소비합니다. 원본 MD 는 어떤 경우에도 view 생성으로 인해 수정되지 않습니다.
206
+ - **Self-contained HTML final-report view** — Phase 7 가 `final-report-<task-type>-<seq>.md` 를 쓰면 `okstra render-views` 가 같은 `reports/` 폴더에 사람 reviewer 용 self-contained HTML view (CSS/JS 인라인, 외부 URL 0) 를 자동 생성합니다. HTML 의 `Export user response` 버튼은 `## 1. Clarification Items` 입력을 `runs/<task-type>/user-responses/user-response-<task-type>-<seq>.md` 사이드카로 직렬화해 다음 phase 가 소비합니다. 원본 MD 는 어떤 경우에도 view 생성으로 인해 수정되지 않습니다.
206
207
  - **`improvement-discovery` task-type (sidetrack entry-point)** — 코드베이스 범위 + 우선순위 lens 화이트리스트 안에서 multi-worker 합의 기반 개선 후보 N개 (기본 8, 절대 cap 12) 도출. `PHASE_SEQUENCE` 외부 sidetrack entry-point — 사용자가 후보를 골라 각각 새 task-id 로 `requirements-discovery` / `implementation-planning` / `error-analysis` 진입. lens enum SSOT: [`scripts/okstra_ctl/improvement_lenses.py`](scripts/okstra_ctl/improvement_lenses.py). 출력 섹션: `## 4.9 Improvement Candidates` (10-column 표). validator: [`validators/validate_improvement_report.py`](validators/validate_improvement_report.py).
207
208
 
208
209
  ### 3.5 운영 명령
@@ -217,7 +218,7 @@ Claude Code 세션 밖에서 task 를 시작하려면:
217
218
  | `npx -y okstra@latest config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | okstra 설정 읽기/쓰기. 현재 지원 키: `pr-template-path` (project.json 또는 `~/.okstra/config.json` 의 `prTemplatePath` 갱신) |
218
219
  | `npx -y okstra@latest memory <add\|list\|search\|show\|archive>` | `~/.okstra/memory-book` 전역 대화 메모리 저장·검색·보관 |
219
220
  | `npx -y okstra@latest context-cost <task-key\|task-root> [--project-root <path>]` | task bundle 의 lead/worker/report-writer 컨텍스트·읽기 비용 추정 |
220
- | `npx -y okstra@latest render-views <final-report.md>` | final-report MD 한 본을 입력으로 슬림 MD + HTML view 를 (재)생성 (Phase 7 step 1.5; 멱등) |
221
+ | `npx -y okstra@latest render-views <final-report.md>` | final-report MD 한 본을 입력으로 self-contained HTML view 를 (재)생성 (Phase 7 step 1.5; 멱등) |
221
222
  | `npx -y okstra@latest token-usage ...` | run token usage 수집/치환. 설치된 Python token usage CLI를 감싼 Node wrapper |
222
223
  | `npx -y okstra@latest uninstall` | 런타임 + 스킬 제거; 사용자 데이터(`recent.jsonl`, `projects/`, …)는 보존 |
223
224
  | `npx -y okstra@latest uninstall --purge -y` | 사용자 데이터까지 모두 제거 |
package/README.md CHANGED
@@ -162,6 +162,7 @@ User-facing slash commands inside a Claude Code session:
162
162
  | `/okstra-rollup` | Roll up run results across every task in a task-group (or the whole project) — per-task runs/time/errors plus group totals — and synthesize a cross-task digest from the report files |
163
163
  | `/okstra-schedule` | Generate a work schedule for an entire task-group |
164
164
  | `/okstra-container-build` | Deploy a verified task's code as a local docker compose group and watch each container's logs (sub-commands: `up` / `status` / `logs` / `stop-watcher` / `down`) |
165
+ | `/okstra-graphify` | Build and query a knowledge graph over the project's own `.okstra/` memory (final reports, `decisions/*.md`, `glossary.md`), scoped to `.okstra/` with outputs under `.okstra/graph/` (sub-commands: `build` / `query` / `path` / `explain` / `mcp` / `wiki`) |
165
166
  | `/okstra-manager` | Coordinate cross-project okstra tasks through manager-owned plans, assignments, one-way project sync snapshots, status, and child launch context packets |
166
167
  | `/okstra-setup` | Per-project bootstrap (§3.2) |
167
168
 
@@ -200,7 +201,7 @@ Recent workflow additions (post-0.8.0, on `main`):
200
201
  - **Phase 6 plan-body verification (implementation-planning only)** — after the Report writer worker authors the final-report draft and before the user approval gate, the lead runs one additional verification round: it extracts `P-Opt-*` / `P-Step-*` / `P-Dep-*` / `P-Val-*` / `P-Rb-*` items from the consolidated `## 5.5` implementation plan deliverables body and dispatches them to every analyser worker as `AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT`. The aggregated gate result is one of `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result`. The frontmatter `approved` flag is always emitted as `false`; blocking gate results keep it false and become `## 1. Clarification Items` rows. Details: [`prompts/lead/convergence.md`](prompts/lead/convergence.md) "Plan-body verification mode" and [`docs/kr/cli.md#--no-plan-verification`](docs/kr/cli.md#--no-plan-verification).
201
202
  - **Brief as translation layer + reporter batch confirmation (Step 6.5)** — `okstra-brief` now produces the brief as a translation layer that preserves external inputs (issue ticket, requirements doc, user message) verbatim while labelling okstra augmentations. A new Step 6.5 walks the user through a single batch confirmation of any rewordings, recorded in a `Reporter Confirmations` section. Every analysis profile blocks phase entry until this section exists (validator: `validators/validate-brief.py`).
202
203
  - **Artifact-home rule (`.okstra/`)** — okstra's project artifact root is only `<project>/.okstra/`. Anything outside that root is not okstra memory; it may be read only when explicitly cited as Source Material or Reporter Confirmations, and writes require the same explicit request path. okstra-internal equivalents: `glossary.md` for terminology and `decisions/<NNNN>-<slug>.md` for decision records (evaluated in `implementation-planning`).
203
- - **Dual-format final-report views** — after Phase 7 writes `final-report-<task-type>-<seq>.md`, `okstra render-views` automatically emits two sibling views in the same `reports/` directory: a slim Markdown for downstream AI input and a self-contained HTML (inline CSS/JS, no external URLs) for human review. The HTML lets a reviewer fill in `## 1. Clarification Items` decisions and export them to `runs/<task-type>/user-responses/user-response-<task-type>-<seq>.md`, which the next phase consumes as input. The original MD is never modified by view generation.
204
+ - **Self-contained HTML final-report view** — after Phase 7 writes `final-report-<task-type>-<seq>.md`, `okstra render-views` automatically emits a sibling self-contained HTML view (inline CSS/JS, no external URLs) in the same `reports/` directory for human review. The HTML lets a reviewer fill in `## 1. Clarification Items` decisions and export them to `runs/<task-type>/user-responses/user-response-<task-type>-<seq>.md`, which the next phase consumes as input. The original MD is never modified by view generation.
204
205
  - **`improvement-discovery` task-type (sidetrack entry-point)** — Discover ranked improvement candidates within a codebase scope and lens whitelist via multi-worker consensus (default top-8, hard cap 12). Outside `PHASE_SEQUENCE`; the user selects candidates and opens each as a new task with `requirements-discovery`, `implementation-planning`, or `error-analysis`. Lens enum SSOT: [`scripts/okstra_ctl/improvement_lenses.py`](scripts/okstra_ctl/improvement_lenses.py). Output section: `## 4.9 Improvement Candidates` (10-column table). Validator: [`validators/validate_improvement_report.py`](validators/validate_improvement_report.py).
205
206
 
206
207
  ### 3.5 Ops commands
@@ -215,7 +216,7 @@ Recent workflow additions (post-0.8.0, on `main`):
215
216
  | `npx -y okstra@latest config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | Read / write okstra settings; initial key `pr-template-path` (writes `prTemplatePath` to project.json or `~/.okstra/config.json`) |
216
217
  | `npx -y okstra@latest memory <add\|list\|search\|show\|archive>` | Store and find global conversation memory in `~/.okstra/memory-book` |
217
218
  | `npx -y okstra@latest context-cost <task-key\|task-root> [--project-root <path>]` | Estimate lead/worker/report-writer context and read cost for a task bundle |
218
- | `npx -y okstra@latest render-views <final-report.md>` | Regenerate the slim-MD + HTML sibling views from a final-report MD (Phase 7 step 1.5; idempotent) |
219
+ | `npx -y okstra@latest render-views <final-report.md>` | Regenerate the self-contained HTML sibling view from a final-report MD (Phase 7 step 1.5; idempotent) |
219
220
  | `npx -y okstra@latest token-usage ...` | Collect/substitute token usage for a run; wraps the installed Python token usage CLI |
220
221
  | `npx -y okstra@latest uninstall` | Remove runtime + skills; preserves user data (`recent.jsonl`, `projects/`, …) |
221
222
  | `npx -y okstra@latest uninstall --purge -y` | Remove everything including user data |
package/bin/okstra CHANGED
@@ -18,7 +18,13 @@ async function main(argv) {
18
18
  const [cmd, ...rest] = args;
19
19
  const loader = COMMANDS.get(cmd);
20
20
  if (!loader) {
21
- process.stderr.write(`unknown command: ${cmd}\n\n${USAGE}`);
21
+ process.stderr.write(
22
+ `unknown command: ${cmd}\n` +
23
+ "hint: this okstra binary may predate the skill calling it — update it " +
24
+ "with 'npm i -g okstra@latest' (or invoke via 'npx -y okstra@latest " +
25
+ `${cmd} ...').\n\n` +
26
+ USAGE,
27
+ );
22
28
  return 2;
23
29
  }
24
30
 
@@ -28,9 +28,9 @@
28
28
 
29
29
  ## 공통 실행 규칙
30
30
 
31
- 1. 명령은 스킬 원문이 요구하는 경우 각각 별도의 Bash 호출로 실행한다. 특히 `okstra ensure-installed`, `okstra check-project --json`, `okstra wizard ...`, `okstra container ...` 호출을 `&&`, `||`, `$(...)`, 선행 변수 할당, `eval`, `export`로 감싸지 않는다.
31
+ 1. 명령은 스킬 원문이 요구하는 경우 각각 별도의 Bash 호출로 실행한다. 특히 `okstra preflight --runtime claude-code --json`, `okstra wizard ...`, `okstra container ...` 호출을 `&&`, `||`, `$(...)`, 선행 변수 할당, `eval`, `export`로 감싸지 않는다.
32
32
  2. `okstra <subcmd>` 호출은 자체적으로 Python path를 부트스트랩한다. 스킬에서 명시하지 않는 한 `okstra paths --shell`이나 `export PYTHONPATH=...`를 만들지 않는다.
33
- 3. `okstra-setup`을 제외한 대부분의 스킬은 `npx` fallback을 쓰지 않는다. runtime이 없으면 사용자에게 `/okstra-setup`을 실행하라고 알리고 멈춘다.
33
+ 3. `okstra-setup`을 제외한 대부분의 스킬은 `npx` fallback을 쓰지 않는다. runtime이 없으면 사용자에게 `/okstra-setup`을 실행하라고 알리고 멈춘다. 단 `unknown command: <cmd>`로 실패하면 PATH의 `okstra` 바이너리가 스킬보다 오래된 것이다 — `/okstra-setup`이 아니라 `npm i -g okstra@latest`를 안내하고 멈춘다.
34
34
  4. 프로젝트 산출물은 기본적으로 `<PROJECT_ROOT>/.okstra/` 아래에 둔다. 예외는 `okstra-memory`이며, 이 스킬은 전역 사용자 메모리 `~/.okstra/memory-book/`을 사용한다.
35
35
  5. `runtime/`은 build output이다. 스킬 원문이나 템플릿을 고칠 때는 `skills/`, `templates/`, `validators/`, `scripts/`, `src/`의 source를 수정하고 build로 반영한다.
36
36
  6. tracker, URL, 파일, report, log, zip, template, validator 내용을 추측하지 않는다. 도구로 읽거나 실행해서 확인한 내용만 사용한다.
@@ -40,11 +40,10 @@
40
40
 
41
41
  ## Preflight
42
42
 
43
- 명령을 각각 별도 호출로 실행한다.
43
+ 단일 호출로 실행한다.
44
44
 
45
45
  ```bash
46
- okstra ensure-installed --runtime claude-code
47
- okstra check-project --json
46
+ okstra preflight --runtime claude-code --json
48
47
  ```
49
48
 
50
49
  runtime이나 project setup이 없으면 `/okstra-setup`을 안내하고 멈춘다. 이 스킬에서 `npx` fallback을 쓰지 않는다.
@@ -24,11 +24,10 @@
24
24
 
25
25
  ## Preflight
26
26
 
27
- 각각 별도 호출:
27
+ 단일 호출:
28
28
 
29
29
  ```bash
30
- okstra ensure-installed --runtime claude-code
31
- okstra check-project --json
30
+ okstra preflight --runtime claude-code --json
32
31
  ```
33
32
 
34
33
  project setup이 없으면 `/okstra-setup` 안내 후 멈춘다. Docker daemon이 필요하다. Docker connection error가 나오면 Docker Desktop/daemon을 시작하라고 안내하고, 직접 Docker를 시작하지 않는다.
@@ -36,11 +36,10 @@
36
36
  모든 sub-command 전에 한 번만 실행한다.
37
37
 
38
38
  ```bash
39
- okstra ensure-installed --runtime claude-code
40
- okstra check-project --json
39
+ okstra preflight --runtime claude-code --json
41
40
  ```
42
41
 
43
- `check-project`는 Bash 호출의 cwd만 본다. cwd가 아닌 프로젝트(형제 repo·monorepo 하위·요청에 명시된 프로젝트)에서 `ok:false`는 setup 부재가 아니라 false negative다 — 바로 멈추지 말고 `okstra check-project --cwd <that-dir> --json`으로 재시도한다(`--cwd`는 leading `cd` 없이 프로젝트를 지정하는 sanctioned 방식). 그것도 `ok:false`일 때만 `/okstra-setup` 안내 후 멈춘다. 이후 `projectRoot`를 literal 값으로 사용하고, 이를 받는 sub-command CLI(`recap`, `context-cost` 등)에는 `--cwd`/`--project-root <projectRoot>`로 전달한다.
42
+ 프로젝트 확인은 Bash 호출의 cwd만 본다. cwd가 아닌 프로젝트(형제 repo·monorepo 하위·요청에 명시된 프로젝트)에서 `ok:false`는 setup 부재가 아니라 false negative다 — 바로 멈추지 말고 `okstra preflight --runtime claude-code --cwd <that-dir> --json`으로 재시도한다(`--cwd`는 leading `cd` 없이 프로젝트를 지정하는 sanctioned 방식). 그것도 `ok:false`일 때만 `/okstra-setup` 안내 후 멈춘다. 이후 `projectRoot`를 literal 값으로 사용하고, 이를 받는 sub-command CLI(`recap`, `context-cost` 등)에는 `--cwd`/`--project-root <projectRoot>`로 전달한다.
44
43
 
45
44
  ## intent routing
46
45
 
@@ -115,13 +114,7 @@ task 하나의 detail은 catalog를 먼저 보고, 필요하면 `.okstra/tasks/<
115
114
  - `blocked`
116
115
  - `done`
117
116
 
118
- 절차:
119
-
120
- 1. status 값 검증.
121
- 2. `okstra resolve-task-key ... --json`으로 task 해석.
122
- 3. catalog entry의 `taskManifestPath` 또는 `taskGroupPathSegment`/`taskIdPathSegment`로 manifest path를 만든다.
123
- 4. `task-manifest.json` root의 `workStatus`, `workStatusUpdatedAt`, 선택적 `workStatusNote`만 targeted edit한다.
124
- 5. JSON 전체를 parse/stringify로 round-trip하지 않는다. key order, indentation, trailing newline을 보존한다.
117
+ 절차: `okstra set-work-status <token> <status> [--note <text>] --project-root <projectRoot> --json` 단일 호출로 갱신한다 — manifest 를 손으로 편집하지 않는다. `stage:"ambiguous"` 면 `matches[]` 로 되묻고, `stage:"not-found"` 면 못 찾았다고 답한다.
125
118
 
126
119
  읽기 표시에서 `workStatus`가 없으면 lifecycle state로 추론하되, 읽기만으로 back-fill하지 않는다.
127
120
 
@@ -134,9 +127,9 @@ task 하나의 detail은 catalog를 먼저 보고, 필요하면 `.okstra/tasks/<
134
127
 
135
128
  catalog가 없으면 `.okstra/tasks/*/*/task-manifest.json` glob으로 fallback한다. disk manifest가 source of truth다.
136
129
 
137
- Re-run은 source run-manifest에서 `projectId`, `taskGroup`, `taskId`, `taskType`, `taskBriefPath`, workers, relatedTasks, model overrides 등을 뽑아 command를 조립한다. `implementation`의 `--base-ref`는 run-manifest에 없고 worktree registry에 있으므로 상황에 따라 묻는다. migrated task(빈 `latestRunManifestPath`)는 바로 포기하지 않는다 — `runs/**/manifests/run-manifest-*.json`을 on-disk glob해 파일명 타임스탬프 최신을 고르고, glob도 비었을 때만 사용자에게 묻는다.
130
+ Re-run은 source run-manifest에서 `projectId`, `taskGroup`, `taskId`, `taskType`, `taskBriefPath`, workers, relatedTasks, model overrides 등을 뽑아 command를 조립한다. `implementation`의 `--base-ref`는 run-manifest에 없고 worktree registry에 있으므로 상황에 따라 묻는다.
138
131
 
139
- Resume은 `latestResumeCommandPath` 또는 timeline entry의 `resumeCommandPath`를 확인하고 파일이 있으면 `bash <resume-command-path>`를 안내/실행한다. catalog/timeline 경로가 비었거나 `.project-docs/okstra/...`를 가리키면 `runs/**/sessions/claude-resume-*.sh`를 glob해 타임스탬프 최신을 고른다. glob도 비었을 때만 "resume 없음"으로 선언한다.
132
+ Resume은 `latestResumeCommandPath` 또는 timeline entry의 `resumeCommandPath`를 확인하고 파일이 있으면 `bash <resume-command-path>`를 안내/실행한다. 경로가 비었거나 파일이 없으면 "resume 없음"으로 선언하고 history.3(re-run)을 안내한다.
140
133
 
141
134
  ## report
142
135
 
@@ -34,14 +34,13 @@
34
34
 
35
35
  ## Preflight
36
36
 
37
- 각각 별도 Bash 호출. 모두 리터럴 `okstra` 토큰으로 시작해 `Bash(okstra:*)` 자동 허용을 받는다. `if`/`eval`/`$(...)`/`VAR=`/`||`/`&&`/`npx` fallback으로 감싸지 않는다.
37
+ 리터럴 `okstra` 토큰으로 시작하는 단일 Bash 호출(`if`/`eval`/`$(...)`/`VAR=`/`||`/`&&`/`npx` fallback으로 감싸지 않는다):
38
38
 
39
39
  ```bash
40
- okstra ensure-installed --runtime claude-code
41
- okstra check-project --json
40
+ okstra preflight --runtime claude-code --json
42
41
  ```
43
42
 
44
- `ensure-installed` 비정상 종료 → `/okstra-setup` 안내 후 멈춘다. `check-project`의 `ok:false` → `/okstra-setup` 안내 후 멈춘다. `ok:true`면 `projectRoot`를 리터럴 문자열로 들고 다음 단계로 간다.
43
+ `ok:false` → `/okstra-setup` 안내 후 멈춘다. `ok:true`면 `projectRoot`를 리터럴 문자열로 들고 다음 단계로 간다.
45
44
 
46
45
  ## scope 해석
47
46
 
@@ -34,15 +34,13 @@
34
34
 
35
35
  ## Preflight
36
36
 
37
- 각각 별도 Bash 호출:
37
+ 단일 Bash 호출:
38
38
 
39
39
  ```bash
40
- okstra ensure-installed --runtime claude-code
41
- okstra paths --json
42
- okstra check-project --json
40
+ okstra preflight --runtime claude-code --json
43
41
  ```
44
42
 
45
- `paths --json`은 diagnostic context로만 읽는다. `export PYTHONPATH`를 만들지 않는다. runtime이나 project setup이 없으면 `/okstra-setup`을 안내하고 멈춘다.
43
+ runtime이나 project setup이 없으면(`ok:false`) `/okstra-setup`을 안내하고 멈춘다. `export PYTHONPATH`를 만들지 않는다.
46
44
 
47
45
  ## Bash 호출 규칙
48
46
 
@@ -124,15 +122,15 @@ okstra wizard confirmation --state-file /tmp/okstra-wizard/state.json
124
122
 
125
123
  `text`를 사용자에게 보여준 뒤 Proceed/Edit/중단 picker를 렌더한다. `Edit`은 wizard가 이전 step으로 rewind한다.
126
124
 
127
- ## render-args와 render-bundle
125
+ ## outcome과 render-bundle
128
126
 
129
127
  `next.kind == "done"`이면:
130
128
 
131
129
  ```bash
132
- okstra wizard render-args --state-file /tmp/okstra-wizard/state.json
130
+ okstra wizard outcome --state-file /tmp/okstra-wizard/state.json
133
131
  ```
134
132
 
135
- `args` object의 key를 `okstra render-bundle` flag로 전달한다. 빈 string 값도 명시적으로 전달한다. 예외: `chain-stages` key는 render-bundle flag가 아니다 — Step 7 무인 연쇄 루프를 구동하는 값이라 flag로 넘기지 않는다(`run.py`는 `--stage`/`--stages`만 받는다). render-bundle block의 `--stage`는 implementation·final-verification 전용, `--stages`는 release-handoff 전용(빈 값 = whole-task)이다.
133
+ `outcome.persistActions[]`를 먼저 실행한 뒤 `outcome.renderArgs` object의 key를 `okstra render-bundle` flag로 전달한다. 빈 string 값도 명시적으로 전달한다. 예외: `chain-stages` key는 render-bundle flag가 아니다 — Step 7 무인 연쇄 루프를 구동하는 값이라 flag로 넘기지 않는다(`run.py`는 `--stage`/`--stages`만 받는다). render-bundle block의 `--stage`는 implementation·final-verification 전용, `--stages`는 release-handoff 전용(빈 값 = whole-task)이다.
136
134
 
137
135
  ```bash
138
136
  okstra render-bundle \
@@ -207,14 +205,16 @@ anchor가 unresolvable이면 `--reset-anchor <ref>`는 사용자 확인 후 실
207
205
 
208
206
  ## PR template persistence
209
207
 
210
- release-handoff에서 `pr-template-path`와 scope가 있으면 render-bundle 전에 config를 저장한다.
208
+ release-handoff에서 `outcome.persistActions[]`가 `config.set` / `pr-template-path` action을 반환하면 render-bundle 전에 config를 저장한다.
211
209
 
212
210
  ```bash
211
+ # action.scope == "project"
213
212
  okstra config set pr-template-path "<path>" --scope project
213
+ # action.scope == "global"
214
214
  okstra config set pr-template-path "<path>" --scope global
215
215
  ```
216
216
 
217
- scope는 wizard state file `pr_template_scope`에 있다. 현재 별도 subcommand가 없으므로 raw state file을 Read tool로 읽는다. shell로 `jq`나 `python3 -c`를 호출하지 않는다.
217
+ scope와 path는 wizard state file 아니라 `okstra wizard outcome`의 persist action에서 읽는다. raw state file을 직접 읽지 않는다.
218
218
 
219
219
  ## Claude lead 전환
220
220
 
@@ -32,19 +32,14 @@
32
32
 
33
33
  ## Preflight
34
34
 
35
- 각각 별도 Bash 호출:
35
+ 단일 Bash 호출:
36
36
 
37
37
  ```bash
38
- okstra ensure-installed --runtime claude-code
39
- okstra check-project --json
38
+ okstra preflight --runtime claude-code --json
40
39
  ```
41
40
 
42
41
  runtime이나 project setup이 없으면 `/okstra-setup` 안내 후 멈춘다.
43
42
 
44
- ## model gate
45
-
46
- 스킬 frontmatter는 `model: opus`다. 활성 모델이 Opus-class 또는 Fable-class가 아니면 사용자에게 전환을 권한다. 사용자가 lower model로 진행하겠다고 명시하면 진행하되, 생성 schedule 상단에 verbatim warning 한 줄을 넣는다: `> ⚠️ Generated with <model> (not Opus). Cross-task synthesis quality may be reduced.`
47
-
48
43
  ## task-group 해석
49
44
 
50
45
  1. `.okstra/discovery/task-catalog.json`을 읽는다.
@@ -93,7 +93,7 @@ okstra setup --yes --project-root /abs/project --project-id my-project
93
93
 
94
94
  ## 선택 설정
95
95
 
96
- 원문상 Step 4.5-4.9는 사용자가 명시적으로 원할 때만 수행하는 선택 설정이다. 기본값으로 충분하면 건너뛰고 doctor로 간다.
96
+ 원문상 Step 3.5 는 사용자가 명시적으로 원할 때만 수행하는 선택 설정이다 — 상세 절차는 스킬 디렉터리의 `references/project-config.md` 를 읽는다. 기본값으로 충분하면 건너뛰고 doctor로 간다.
97
97
 
98
98
  선택 설정:
99
99
 
@@ -74,7 +74,6 @@ task manifest, task index, instruction-set, runs, history가 이 루트 아래
74
74
  그리고 `--render-only`가 아니면 handoff된 Claude session이 보통 아래 결과 파일을 현재 run에 추가합니다.
75
75
  - `sessions/claude-resume-<task-type>-<seq>.sh`
76
76
  - `reports/final-report-<task-type>-<seq>.md`
77
- - `reports/final-report-<task-type>-<seq>.slim.md` *(Phase 7 결정론적 후처리: AI 다음-phase 입력용 슬림 markdown)*
78
77
  - `reports/final-report-<task-type>-<seq>.html` *(Phase 7 결정론적 후처리: 사람 reviewer 용 self-contained HTML, CSS/JS 인라인)*
79
78
  - `user-responses/user-response-<task-type>-<seq>.md` *(HTML 의 `Export user response` 버튼이 같은 이름으로 다운로드해 주는 사이드카; 여기 저장해 두면 `--resume-clarification` 이 instruction-set 의 `clarification-response.md` 에 자동 첨부한다 — `clarification_items.clarification_response_with_sidecars`)*
80
79
  - `worker-results/<worker>-audit-<task-type>-<seq>.md` *(워커별 Reading Confirmation 사이드카; 본문이 아니라 audit 용)*
@@ -83,7 +82,7 @@ task manifest, task index, instruction-set, runs, history가 이 루트 아래
83
82
  - `consumers.jsonl` *(implementation-planning 전용: 이 plan 의 각 stage 를 소비한 impl-run 역링크; append-only)*
84
83
  최종 결과 파일 (`final-report` MD / status) 은 `okstra`가 stdout을 저장해서 만드는 파일이 아닙니다.
85
84
  `okstra`가 준비한 task bundle을 바탕으로 Claude가 현재 run 안에 직접 작성하는 결과물입니다.
86
- slim MD / HTML view 는 `okstra render-views <final-report.md>` (Phase 7 step 1.5) 가 final-report MD 한 본을 입력으로 결정론적으로 생성합니다. 원본 MD 는 view 생성으로 인해 수정되지 않습니다.
85
+ self-contained HTML view 는 `okstra render-views <final-report.md>` (Phase 7 step 1.5) 가 final-report MD 한 본을 입력으로 결정론적으로 생성합니다. 원본 MD 는 view 생성으로 인해 수정되지 않습니다.
87
86
  반면 `sessions/claude-resume-<task-type>-<seq>.sh`는 `okstra`가 Claude launch 전에 미리 생성하는 interruption recovery helper입니다.
88
87
 
89
88
  run directory는 task-type 단위로 task 실행 이력을 모으고, 내부를 `manifests/`, `state/`, `prompts/`, `reports/`, `status/`, `sessions/`, `worker-results/`처럼 유형별 하위 폴더로 나눈 뒤 각 run-level artifact와 result 파일을 `-<task-type>-<seq>` suffix(per-category 3-digit zero-padded counter, 예: `001`, `002`)로 구분합니다.
@@ -20,7 +20,7 @@
20
20
  - **Required team contract**: 각 phase profile의 `Required workers:` 블록이 roster의 권위입니다. 일반 분석 phase는 Claude/Codex analyser + report-writer를 기본으로 하고, Antigravity는 profile과 `--workers`가 허용할 때만 포함됩니다. `release-handoff`처럼 lead-only에 가까운 phase는 별도 roster를 가집니다.
21
21
  - **User-home install + project-local task bundles**: `npx okstra@latest install` 한 명령이 런타임(`~/.okstra/{lib/python, bin, templates, prompts}`)을 설치하고, public skill 을 `~/.agents/skills/` 에 기본 설치합니다. `~/.claude` 가 있으면 Claude skills + worker agent 4종(`~/.claude/agents/*-worker.md`)도 함께 설치합니다. 사용자 진입점 스킬만 목록에 노출되고 lead/support 운영 계약은 `~/.okstra/prompts/` 아래 runtime resource 로 설치되어 skill discovery 대상이 아닙니다. 전역 대화 메모리는 프로젝트와 분리된 `~/.okstra/memory-book/` 에 저장됩니다. 대상 프로젝트에는 task bundle 과 discovery metadata 가 `.okstra/` 아래 저장되고, **추가로 `<PROJECT_ROOT>/.claude/settings.local.json` 이 `~/.okstra/templates/settings.local.json` 을 가리키는 symlink 로 provisioning** 됩니다 (`okstra setup` 또는 `okstra-ctl` prepare 가 idempotent 하게 관리; 기존에 일반 파일이 있었다면 `.bak.<timestamp>` 로 보존 후 교체).
22
22
  - **Resume and clarification**: `--task-key`, `--resume-clarification`, `--clarification-response`로 같은 task 재개와 lead의 추가 질문 응답 흐름을 지원합니다.
23
- - **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을 제공합니다.
23
+ - **Derived views and telemetry**: final-report data.json → Markdown → Report View Model 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
 
@@ -58,7 +58,7 @@
58
58
  - [9. 같은 task 재개](#9-같은-task-재개)
59
59
  - [Lifecycle status and resume](#lifecycle-status-and-resume)
60
60
  - [Final report structure](#final-report-structure)
61
- - [Final report views (slim MD + HTML)](#final-report-views-slim-md--html)
61
+ - [Final report views (HTML)](#final-report-views-html)
62
62
  - [Worker error collection (optional sidecar)](#worker-error-collection-optional-sidecar)
63
63
  - [Token usage and cost accounting](#token-usage-and-cost-accounting)
64
64
  - [Validators](#validators)
@@ -348,7 +348,7 @@ okstra phase 는 PRD / issue file 을 직접 쓰지 않습니다. 동등한 결
348
348
 
349
349
  - `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는 여전히 금지됩니다.
350
350
  - **모든 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-namespace>/<task-id-segment>` (예: `feature/dev-9436`, `fix/dev-7311`) 입니다. 네임스페이스는 work_category 로 결정됩니다(`feature`·`improvement`→`feature/`, `bugfix`→`fix/`, `refactor`→`refactor/`, `ops`→`ops/`, 미지정→`task/`). base ref 는 첫 phase prepare 시점의 main worktree `HEAD`. `~/.okstra/worktrees/registry.json` (flock-guarded) 가 task-key → path/branch 매핑을 전역 관리해 동시 실행 시 path·branch 충돌을 방지합니다. configured sync dirs 는 main worktree 에서 symlink 로 연결되어 task checkout 사이의 filesystem continuity 를 제공합니다 (sync 대상 목록은 `project.json` 의 `worktreeSyncDirs` 또는 `OKSTRA_WORKTREE_SYNC_DIRS` 환경변수로 override 가능; 빈 배열이면 sync 비활성화). 이 sync 는 okstra context/write boundary 를 확장하지 않습니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 되고 executor 는 project_root 에서 그대로 작업합니다. worktree 는 run 종료 후 자동 삭제되지 않으며 후속 phase·PR 작성·rollback 검증의 권위 artefact 입니다. 수동 cleanup: `git -C <main-worktree> worktree remove <path>` → `git -C <main-worktree> branch -D <branch>` + registry 항목 삭제. 자세한 동작은 `prompts/profiles/implementation.md` 의 *Task worktree* 블록과 `prompts/lead/okstra-lead-contract.md` 의 *Task worktree (BLOCKING for every task-type)* 섹션 참고.
351
- - **implementation stage 격리 worktree (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 의 모델입니다. `implementation` task 는 **stage 격리** 로 동작합니다 — **한 run = 한 stage**, 각 run 이 `.../<task-id-segment>/stage-<N>/` (브랜치 `<work-category-namespace>/<task-id-segment>-s<N>`) 격리 worktree 를 발급받습니다. registry 가 task-key 와 **stage-key** (`<task-key>#stage-<N>`) 를 함께 flock 예약하고, `_resolve_effective_stages` `consumers.jsonl` 의 `started` + registry 예약 stage 를 ready 집합에서 제외하므로(점유 SSOT = registry), 사용자가 두 `implementation` run 을 동시에 띄우면 서로 다른 독립 stage 를 충돌 없이 진행합니다. base 결정: 독립 = 공통 anchor(첫 stage 진입 HEAD 고정), 단일 의존 = 선행 done commit, 다중 의존 = 선행이 모두 ancestor 인 task worktree HEAD(`git merge-base --is-ancestor`; 미머지 시 `PrepareError`). cost-aware-design 의 ready-set batch 는 stage 마다 격리 branch 가 필요해 의미를 잃으므로(같은 branch 에 두 stage-key reserve 시 branch-uniqueness 충돌) 폐기되었고, 순차 진행은 stage done 후 다음 run, 동시 진행은 별도 run 으로 — cost 등가. `--stage <auto|N>` 또는 wizard `stage_pick` 으로 stage 를 선택합니다. wizard `stage_pick` 은 각 stage 의 상태(`[완료]`/`[진행중]`/`[준비됨]`/`[대기]`)를 라벨에 표시하는 멀티선택이며, 선택분의 의존성 closure 를 Kahn 위상정렬(`stage_targets.order_stage_closure`)해 render-args 의 `chain-stages` CSV 로 내보냅니다. `okstra-run` SKILL 이 이 큐를 받아 의존성 순서대로 단일-stage run 을 N 회 순차 실행(무인 연쇄)하되, 각 stage 의 Phase 6 `done` 행을 확인한 뒤 다음으로 넘어갑니다. 이는 오케스트레이션 계층일 뿐이며 wizard·prepare 의 **한 run = 한 stage** 격리 불변은 그대로입니다. worktree 뿐 아니라 **run 산출물(report·state·worker-results·manifest)도 `runs/implementation/stage-<N>/` 로 stage 별 격리**되므로 동시 실행하는 두 stage 의 보고서·상태가 섞이지 않습니다. 반면 `consumers.jsonl` 과 worktree registry 는 stage 간 공유되는 조율 SSOT 라 task-type 루트(`runs/implementation/`)에 그대로 둡니다.
351
+ - **implementation stage 격리 worktree (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 의 모델입니다. `implementation` task 는 **stage 격리** 로 동작합니다 — **한 run = 한 stage**, 각 run 이 `.../<task-id-segment>/stage-<N>/` (브랜치 `<work-category-namespace>/<task-id-segment>-s<N>`) 격리 worktree 를 발급받습니다. registry 가 task-key 와 **stage-key** (`<task-key>#stage-<N>`) 를 함께 flock 예약하고, Stage Lifecycle Snapshot 이 `consumers.jsonl` 의 `done`/`started`, carry sidecar backfill, registry 예약 stage 를 함께 읽어 ready 집합에서 제외하므로(점유 SSOT = registry), 사용자가 두 `implementation` run 을 동시에 띄우면 서로 다른 독립 stage 를 충돌 없이 진행합니다. base 결정: 독립 = 공통 anchor(첫 stage 진입 HEAD 고정), 단일 의존 = 선행 done commit, 다중 의존 = 선행이 모두 ancestor 인 task worktree HEAD(`git merge-base --is-ancestor`; 미머지 시 `PrepareError`). cost-aware-design 의 ready-set batch 는 stage 마다 격리 branch 가 필요해 의미를 잃으므로(같은 branch 에 두 stage-key reserve 시 branch-uniqueness 충돌) 폐기되었고, 순차 진행은 stage done 후 다음 run, 동시 진행은 별도 run 으로 — cost 등가. `--stage <auto|N>` 또는 wizard `stage_pick` 으로 stage 를 선택합니다. wizard `stage_pick` 은 각 stage 의 상태(`[완료]`/`[진행중]`/`[준비됨]`/`[대기]`)를 라벨에 표시하는 멀티선택이며, 선택분의 의존성 closure 를 Kahn 위상정렬(`stage_targets.order_stage_closure`)해 render-args 의 `chain-stages` CSV 로 내보냅니다. `okstra-run` SKILL 이 이 큐를 받아 의존성 순서대로 단일-stage run 을 N 회 순차 실행(무인 연쇄)하되, 각 stage 의 Phase 6 `done` 행을 확인한 뒤 다음으로 넘어갑니다. 이는 오케스트레이션 계층일 뿐이며 wizard·prepare 의 **한 run = 한 stage** 격리 불변은 그대로입니다. worktree 뿐 아니라 **run 산출물(report·state·worker-results·manifest)도 `runs/implementation/stage-<N>/` 로 stage 별 격리**되므로 동시 실행하는 두 stage 의 보고서·상태가 섞이지 않습니다. 반면 `consumers.jsonl` 과 worktree registry 는 stage 간 공유되는 조율 SSOT 라 task-type 루트(`runs/implementation/`)에 그대로 둡니다.
352
352
  - **단일-stage final-verification 의 run 산출물 격리 (동시 병렬)**: 단독-stage `final-verification`(`--stage <N>`)도 implementation 과 동일하게 run 산출물을 `runs/final-verification/stage-<N>/` 하위에 격리하고(seq 도 stage 별 독립), 팀 이름에 `-fv-s<N>` 접미사를 붙입니다 — `-fv-` 구분자로 같은 stage 의 implementation 팀(`-s<N>`)과도, 전체-task 검증의 기본 이름과도 충돌하지 않습니다. 따라서 여러 stage 의 final-verification 을 동시에 띄워도 state·worker-results·보고서·팀이 섞이지 않습니다. worktree 는 새로 만들지 않고 해당 implementation stage worktree 를 registry 에서 read-only 로 재사용하며, 그래서 registry stage-key 예약도 하지 않습니다. `teamName` 라벨에 `-fv-s<N>` 접미사를 붙이는 것은 audit/표시용 구분일 뿐이며, 실제 팀은 세션별 implicit team(`session-<leadSid>`)이라 v2.1.178 이전의 `TeamCreate` 이름 충돌 hard-fail 은 더 이상 발생하지 않습니다. 전체-task 검증(stage 빈 값)은 기존 평면 `runs/final-verification/` 구조를 유지합니다.
353
353
  - `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 는 여전히 금지).
354
354
  - 사용자가 "다음 단계 진행해" 같은 표현을 보내도, 그 발화만으로 다음 phase가 자동 시작되지 않습니다. 다음 phase는 새 `okstra.sh` 실행으로만 시작합니다.
@@ -378,11 +378,11 @@ release-handoff 까지 완료된 task 의 산출물에서 버그가 발견되면
378
378
  - **whole-task (기본)**: task 전체를 1개 PR 로 내보냅니다. 기존 동작입니다.
379
379
  - **stage-group**: 단독-stage final-verification 에서 `accepted` 를 받은 stage 들 중 일부를 골라, 수집(collector) 브랜치로 묶어 1개 PR 로 내보냅니다. task 전체가 끝나기를 기다리지 않고 검증 완료된 stage 묶음 단위로 PR 을 낼 수 있습니다.
380
380
 
381
- 진입은 brief 없이 **task-id 기반**입니다 — brief 는 entry phase 의 입력물이고, release-handoff 는 prepare 가 approved plan 의 Stage Map + `consumers.jsonl` 자격을 판정한 뒤 검증 보고서를 인용하는 input 문서(`<task_root>/release-handoff-input.md`)를 자동 생성합니다. stage 선택은 okstra-run wizard 의 `handoff_stage_pick` 멀티선택(eligible stage 묶음 / accepted whole-task 보고서가 있으면 전체 task) 또는 CLI `--stages <csv>` 로 들어오고, run-context 의 `HANDOFF_MODE` / `HANDOFF_STAGES` 로 lead 에 노출됩니다.
381
+ 진입은 brief 없이 **task-id 기반**입니다 — brief 는 entry phase 의 입력물이고, release-handoff 는 prepare 가 approved plan 의 Stage Map + Stage Lifecycle Snapshot 으로 자격을 판정한 뒤 검증 보고서를 인용하는 input 문서(`<task_root>/release-handoff-input.md`)를 자동 생성합니다. stage 선택은 okstra-run wizard 의 `handoff_stage_pick` 멀티선택(eligible stage 묶음 / accepted whole-task 보고서가 있으면 전체 task) 또는 CLI `--stages <csv>` 로 들어오고, run-context 의 `HANDOFF_MODE` / `HANDOFF_STAGES` 로 lead 에 노출됩니다.
382
382
 
383
383
  stage-group 의 상호작용 순서: **G1 base 선택 → G2 stage 확인(선택은 prepare 전에 끝남 — 재질문 없음) → assemble(수집 브랜치 생성 + 선택 stage 머지) → 충돌 프로브 → PR 초안 → push/PR**.
384
384
 
385
- - 자격 판정의 SSOT 는 `consumers.jsonl` 의 두 행입니다 — `verified`(어떤 stage 가 단독-stage final-verification 에서 accepted 됨), `pr`(어떤 stage 들이 어느 PR 로 나갔는지). `verified` 인데 아직 `pr` 에 안 들어간 stage 자격 후보입니다.
385
+ - 자격 판정의 SSOT 는 Stage Lifecycle Snapshot 입니다. Snapshot 은 `consumers.jsonl` 의 `verified`(어떤 stage 가 단독-stage final-verification 에서 accepted 됨), `pr`(어떤 stage 들이 어느 PR 로 나갔는지), done rows 를 읽어 `verified` 인데 아직 `pr` 에 안 들어간 stage 후보로 계산합니다.
386
386
  - worktree registry 는 stage-group 점유를 `<task-key>#group-<id>` 키로 예약하고, 수집 브랜치 이름은 `<work-category-namespace>/<task-id-segment>-g2-3` (예: 선택한 stage 가 2·3 이면 `-g2-3`) 형태입니다.
387
387
  - 강제 지점은 선언이 아니라 Python 모듈 `okstra_ctl.handoff` 입니다 (`okstra handoff <subcommand>`). 서브커맨드 4종: `eligible`(자격 stage 조회) / `assemble`(수집 브랜치 생성·머지) / `record-verified`(`verified` 행 기록) / `record-pr`(`pr` 행 기록). 수집 단계의 머지는 isolation spec 의 "okstra 자동 머지 없음" 비목표에 대한 명시적 예외입니다.
388
388
 
@@ -645,18 +645,17 @@ Claude가 작성하는 최종 보고서는 아래 구조를 우선 사용합니
645
645
  차이점이 실질적으로 없으면 억지로 대비를 만들지 말고, 차이가 없음을 명시합니다.
646
646
  저장 실패나 세션 제한에 대한 메타 설명 대신 실제 Markdown 보고서 본문을 파일에 작성해야 합니다.
647
647
 
648
- ## Final report views (slim MD + HTML)
648
+ ## Final report views (HTML)
649
649
 
650
- Phase 7 step 1.5 가 final-report MD 한 본을 입력으로 view 를 결정론적으로 자동 생성합니다.
650
+ Phase 7 step 1.5 가 final-report MD 한 본을 입력으로 self-contained HTML view 를 결정론적으로 자동 생성합니다.
651
651
 
652
- - `reports/final-report-<task-type>-<seq>.slim.md` — AI 다음-phase 입력용. 장식·캡션·sentinel 셀을 제거한 토큰-경제 버전. `validate-run.py` phase substring 검사를 byte-identical 통과합니다.
653
- - `reports/final-report-<task-type>-<seq>.html` — 사람 reviewer 용 self-contained HTML. CSS / JS 인라인 임베드 (외부 URL 0), system color 다크모드, sticky header, 인쇄 대응. §5 `C-*` 행의 의사결정 입력 (체크박스 / 셀렉트 / textarea) 을 화면에서 채우고 `Export user response` 버튼으로 사이드카 markdown 을 생성합니다.
652
+ - `reports/final-report-<task-type>-<seq>.html` — 사람 reviewer self-contained HTML. CSS / JS 인라인 임베드 (외부 URL 0), system color 다크모드, sticky header, 인쇄 대응. §1 `C-*` 행의 의사결정 입력 (체크박스 / 셀렉트 / textarea) 을 화면에서 채우고 `Export user response` 버튼으로 사이드카 markdown 생성합니다.
654
653
 
655
654
  진입점:
656
655
 
657
- - Python 단일 reference: `scripts/okstra_ctl/report_views.py` (`slim_markdown(...)`, `render_html(..., css, js)`, `serialize_user_response(...)`). HTML 내 JS `buildUserResponseMarkdown` 은 Python `serialize_user_response` 와 **byte-identical** (Node `vm.runInThisContext` 단위 테스트로 자동 검증).
656
+ - Python 단일 reference: `scripts/okstra_ctl/report_views.py` (`build_report_view_model(...)`, `render_report_view_model(..., css, js)`, `render_html(..., css, js)`, `serialize_user_response(...)`). HTML 내 JS `buildUserResponseMarkdown` 은 Python `serialize_user_response` 와 **byte-identical** (Node `vm.runInThisContext` 단위 테스트로 자동 검증).
658
657
  - CLI: `scripts/okstra-render-report-views.py <final-report.md>` 또는 Node 위임 wrapper `bin/okstra render-views <md>`.
659
- - 검증: `validators/validate-report-views.py` — slim 의 phase substring 보존, HTML 내 form control 위치, 외부 URL 부재, Response ID parity (`C-*` ↔ HTML), 모듈 substring 상수 drift 모두 검사.
658
+ - 검증: `validators/validate-report-views.py` — HTML 내 form control 위치, 외부 URL 부재, stale source digest, Response ID parity (`C-*` ↔ HTML) 검사.
660
659
  - 사용자 응답 사이드카 스키마 SSOT: `templates/reports/user-response.template.md`.
661
660
 
662
661
  원본 final-report MD 는 어떤 경우에도 view 생성으로 인해 수정되지 않습니다.
@@ -713,7 +712,7 @@ phase 산출물의 출고 가능 여부를 강제하는 진입점:
713
712
 
714
713
  - `validators/validate-workflow.sh` — phase contract 통합 검증.
715
714
  - `validators/validate-run.py` — run-level final-report 본문 contract (Verdict Card 존재, `rationale` 4개 필드의 증거-앵커 강제(`_validate_rationale_evidence`), deprecated §6.1/§6.2/§5.5.8/§5.5.9 Open Questions 부재, Plan Body Verification gate × Approval 마커 cross-check, Token Usage sentinel/zero 차단, 워커-결과 audit 사이드카 존재).
716
- - `validators/validate-report-views.py` — slim MD / HTML view 의 phase substring 보존 form-control 영역 검사.
715
+ - `validators/validate-report-views.py` — self-contained HTML view 의 form-control 위치, 외부 URL 부재, stale source digest, Response ID parity(`C-*` ↔ HTML) 검사.
717
716
  - `validators/validate-brief.py` — brief schema (front-matter, `Reporter Confirmations` 섹션 존재, root parent-id self 규칙, slug 컨벤션 등) 강제. `bash validators/validate-brief.sh <brief.md>` 가 thin wrapper.
718
717
 
719
718
  각 validator 는 contract 위반 시 `contract-violated` exit code 로 phase 를 차단합니다. 위반은 다음 phase 실행 시점에 적용되므로 이전 산출물은 그대로 둡니다.
package/docs/kr/cli.md CHANGED
@@ -610,7 +610,7 @@ chmod +x ~/.local/bin/okstra-ctl
610
610
  | 진행 중 run 보기 | `okstra-ctl tail active` |
611
611
  | 단일 run 결과 메타 | `okstra-ctl show <runId-or-prefix>` |
612
612
  | 결과 보고서 경로 | `okstra-ctl open <runId-or-prefix>` |
613
- | final-report view 재생성 | `okstra render-views <final-report.md>` |
613
+ | final-report HTML view 재생성 | `okstra render-views <final-report.md>` |
614
614
  | 단일 재실행 | `okstra-ctl rerun <runId-or-prefix> --yes` |
615
615
  | 다중 재실행 | `okstra-ctl rerun --filter --project X --status failed --yes` |
616
616
  | 가장 최근 재실행 | `okstra-ctl rerun last --project X --task-group Y --yes` |
@@ -631,21 +631,23 @@ chmod +x ~/.local/bin/okstra-ctl
631
631
  | `okstra doctor [--runtime claude-code\|codex\|external\|all] [--phase <phase>] [--json]` | runtime + Python import + skill/agent 설치 진단. `codex` / `external` runtime 은 Claude skill checks 를 제외한다. `--phase` 는 `implementation`, `final-verification`, `release-handoff`, `improvement-discovery` 실행 전 readiness 체크를 추가한다 |
632
632
  | `okstra setup --project-id <id>` | 현재 프로젝트의 `.okstra/project.json` 생성/갱신 |
633
633
  | `okstra check-project [--json]` | 현재 프로젝트가 등록되었는지 검증 |
634
+ | `okstra preflight [--runtime <name>] [--cwd <dir>] [--json]` | 스킬 preflight 단일 호출: `ensure-installed`(stale 시 조용히 재설치) + `check-project` 를 합쳐 JSON 하나로 반환. 모든 프로젝트 스코프 스킬의 Step 0 이 이 명령 1회로 수렴한다 |
634
635
  | `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | 영구 설정 관리 (예: `pr-template-path`). 원자적 JSON 쓰기 |
635
636
  | `okstra memory <add\|list\|search\|show\|archive>` | `~/.okstra/memory-book` 전역 대화 메모리 관리. 프로젝트 `.okstra/` 와 분리된 user-home 저장소이며, `okstra 에 정리해서 보관해` 자연어 스킬의 CLI 기반 |
636
637
  | `okstra manager <init\|discover-projects\|new\|task>` | 여러 프로젝트의 okstra task 를 manager-owned context 로 묶는 공개 CLI. `new project`, `new task-group`, `new task` 로 manager 계획을 만들고, `task assign` / `task note` / `task sync` / `task status` / `task run` 으로 프로젝트별 할당과 snapshot 을 관리한다. `new project --project-root` 는 이미 존재하는 디렉터리만 받으며, 그 안의 `.okstra/project.json` 이 없을 때만 setup-equivalent registration 을 수행한다. child task key 는 공개 문서에서 `project-id:task-group:task-id` 전체 형식을 사용하고, 같은 manager task 안에서 child task id 가 다르면 `--child-task-id` 로 exact child 를 지정한다. `task run` 은 child lead 를 직접 실행하지 않고 `prepared` launch metadata/event 와 child launch context packet 을 JSON 으로 반환한다 |
637
638
  | `okstra rollup [--task-group <group>] [--project-root <dir>] [--cwd <dir>]` | okstra-rollup 스킬의 read-only 백엔드. catalog 의 모든 task(또는 한 task-group)에 대해 task 별 run 수·소요 시간(raw ms)·에러 수·최신 report 경로와 group 차원 합계 및 상태/카테고리/phase 분포를 JSON 으로 출력한다. `--task-group` 생략 시 프로젝트 전체 catalog 를 대상으로 한다. 시간은 raw ms 이며 HH:MM:SS 포맷·report 본문 종합은 호출자(skill)에 위임한다. 단일 task drill-down 은 `okstra inspect` 계열을 쓴다 |
638
639
  | `okstra migrate [--apply] [--cwd <dir>] [--quiet]` | 한 번만 실행: 프로젝트 산출물 루트를 `.project-docs/okstra/` → `.okstra/` 로 이동. 기본 dry-run, `--apply` 로 실제 실행. `git mv` (git worktree) + 빈 `.project-docs/` 제거 + `<PROJECT>/CLAUDE.md` import 라인 + `.gitignore` + `~/.okstra/{recent,active}.jsonl` + `~/.okstra/worktrees/registry.json` 의 해당 프로젝트 row 동기화. 이미 `.okstra/` 가 존재하거나 레거시 디렉토리가 없으면 exit 1 로 거부. v0.x 말까지 유지 후 제거 예정 |
639
640
  | `okstra task-list [--project-root <path>]` | `list_project_tasks` + `read_latest_task` 결과를 합쳐 task 카탈로그 + 최근 task 를 JSON 으로 반환 |
640
- | `okstra task-show <task-key> [--project-root <path>]` | task-manifest.json workflow / phase / status 요약 |
641
+ | `okstra task-show <task-key> [--project-root <path>]` | Task Read-Side Snapshot 기반 workflow / phase / status / artifact 요약 |
642
+ | `okstra set-work-status <token> <todo\|in-progress\|blocked\|done> [--note <text>] [--task-group <g>] [--project-root <dir>]` | task-manifest.json 의 사용자 관리 `workStatus`(+`workStatusUpdatedAt`, `--note` 시 `workStatusNote`) 갱신. `<token>` 은 전체 task-key 또는 bare task-id. manifest 렌더러와 동일한 직렬화 규칙으로 기록하며, 모호하면 `stage:"ambiguous"` + `matches[]` 로 반환한다 |
641
643
  | `okstra worktree-lookup <task-key>` | `worktree_registry.lookup` 결과 (예약된 path / branch / base ref / 현재 상태) |
642
644
  | `okstra plan-validate <plan-path>` | `_validate_approved_plan` — frontmatter `approved` 인식 결과와 Blocks=approval 미해결 행 진단 |
643
645
  | `okstra render-bundle <args…> [--stage <auto\|N>] [--stages <csv>]` | `prepare_task_bundle(render_only=True)` 의 thin shim — `python3 -m okstra_ctl.run --render-only` 와 동일 시그니처. `--stage` 는 `implementation` / `final-verification` 전용: 실행(검증)할 Stage Map 항목 지정. `implementation` 은 `auto` (기본값) = 의존성이 만족된 가장 빠른 미완료 stage, `<N>` = 강제 지정. `final-verification` 은 `<N>` = 해당 stage 단독 검증(산출물이 `runs/final-verification/stage-<N>/` 에 격리되고 팀 이름에 `-fv-s<N>` 접미사), 빈 값 = 전체-task 검증(평면 구조 유지). `--stages <csv>` 는 `release-handoff` 전용(별개 채널): PR 로 묶을 stage 번호들(stage-group 모드), 빈 값 = whole-task 모드. prepare 가 eligibility(`done`+`verified` accepted+미-`pr`)를 강제하고 검증 보고서 인용 input 문서를 자동 생성한다 |
644
646
  | `okstra codex-run <args…>` | Codex lead adapter dry-run entrypoint. `render-bundle` 과 같은 인자를 받되 `--render-only --lead-runtime codex` 를 wrapper 가 소유한다. task bundle 을 준비하고 Codex lead 가 읽을 prompt 를 출력하지만 worker dispatch 는 하지 않는다 |
645
647
  | `okstra codex-dispatch --project-root <dir> --run-manifest <path> [--workers codex,antigravity,report-writer]` | `codex-run` 이 준비한 run manifest 를 읽어 Codex-side 지원 worker subset 을 실행한다. `--workers` 생략 시 `claude` 같은 미지원 roster 항목은 건너뛰고, 명시 요청하면 실패한다. report-writer 는 `--enable-codex-report-writer --report-writer-codex-model <model>` opt-in 이 필요하며, 성공 시 token-usage substitution, HTML view 렌더, follow-up task stub 생성, run validation 을 자동 실행한다 |
646
648
  | `okstra team dispatch --project-root <dir> --run-manifest <path> [--workers <csv>] [--jobs-file <path>] [--dry-run]` / `okstra team await --project-root <dir> --run-manifest <path> [--json]` / `okstra team teardown --project-root <dir> --run-manifest <path> [--dry-run] [--json]` | `leadRuntime=external` run manifest 를 읽어 tmux-pane worker dispatch / wait / teardown 을 수행한다. tmux pane 을 만들 수 없으면 CLI wrapper 로 graceful degrade 하고 `workerDispatches[].degradedFrom` 에 기록한다 |
647
- | `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 를 검사 |
648
- | `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` 으로 넘어갑니다. brief 단계는 entry task-type(requirements-discovery / error-analysis / improvement-discovery)에서만 나오며, downstream 은 manifest 의 brief 를 자동 carry-in 하고(미등록 시 `brief_carry` 3-옵션 fallback), `release-handoff` 는 brief 없이 `handoff_stage_pick` 멀티선택(eligible stage 묶음 / 전체 task)으로 진입합니다 |
649
+ | `okstra render-views <final-report.md>` | Phase 7 step 1.5 — 토큰 치환된 final-report MD 한 본을 입력으로 sibling `*.html` (사람용 self-contained) view 를 결정론적으로 생성. 원본 MD 는 수정하지 않음. Node 위임 wrapper는 `scripts/okstra-render-report-views.py` 를 호출. `validators/validate-report-views.py` 가 form-control 위치 / 외부 URL 부재 / stale source digest / Response ID parity 를 검사 |
650
+ | `okstra wizard <init\|step\|render-args\|confirmation\|outcome> --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 블록을 반환. `outcome` 은 완료된 wizard 에서 `renderArgs`, `persistActions`, `confirmationText` 를 한 번에 반환하며, release-handoff 의 project/global PR template 저장은 `persistActions[].command == "config.set"` 로 노출된다. `implementation` task type 에서는 `approved_plan_pick` 직후 `stage_pick` 단계가 추가되어 실행할 stage 를 선택하고, `executor_pick` 으로 넘어갑니다. brief 단계는 entry task-type(requirements-discovery / error-analysis / improvement-discovery)에서만 나오며, downstream 은 manifest 의 brief 를 자동 carry-in 하고(미등록 시 `brief_carry` 3-옵션 fallback), `release-handoff` 는 brief 없이 `handoff_stage_pick` 멀티선택(eligible stage 묶음 / 전체 task)으로 진입합니다 |
649
651
  | `okstra token-usage ...` | 설치된 `okstra-token-usage.py` 를 감싸 run token usage 수집/치환을 수행. 세션 jsonl 은 기본적으로 `$OKSTRA_HOME/cache/token-usage/` 의 byte cursor 캐시로 증분 스캔하며, `--no-cache` 로 캐시를 우회해 전체 재스캔을 강제할 수 있음(정확성 폴백) |
650
652
 
651
653
  > 모든 subcommand 는 `bin/okstra` 가 spawn 하는 python 헬퍼 (`src/lib/python-helper.mjs`) 가 `PYTHONPATH` 와 `~/.okstra/lib/python` 을 wire 합니다. 직접 `python3 -m okstra_ctl.*` 으로 호출하면 `PYTHONPATH` 를 사용자가 직접 셋업해야 합니다.
@@ -51,10 +51,10 @@ okstra/
51
51
  │ ├── okstra_ctl/ orchestration core
52
52
  │ ├── okstra_project/ project root / project.json resolver
53
53
  │ ├── okstra_token_usage/ token usage + cost accounting
54
- │ ├── okstra_vendor/ vendored Jinja2 / MarkupSafe
54
+ │ ├── okstra_vendor/ vendored Jinja2 / MarkupSafe + graphify / networkx (okstra-graphify skill)
55
55
  │ ├── lib/okstra/ Bash helpers for okstra.sh
56
56
  │ └── lib/okstra-ctl/ Bash control-center subcommands
57
- ├── skills/ Claude Code skills (8)
57
+ ├── skills/ Claude Code skills (10)
58
58
  ├── agents/ lead SKILL.md + worker agent specs
59
59
  ├── prompts/ launch template, phase profiles, wizard prompt JSON
60
60
  ├── schemas/ JSON schema for final-report data.json
@@ -152,13 +152,15 @@ Runtime/install asset changes follow this checklist:
152
152
  | `doctor` | `src/commands/lifecycle/doctor.mjs` | Diagnose runtime and Python imports |
153
153
  | `setup` | `src/commands/lifecycle/setup.mjs` | Create/update `<PROJECT_ROOT>/.okstra/project.json` |
154
154
  | `check-project` | `src/commands/lifecycle/check-project.mjs` | Verify project registration |
155
+ | `preflight` | `src/commands/lifecycle/preflight.mjs` | One-call skill preflight: ensure-installed + check-project (single JSON) |
155
156
  | `config` | `src/commands/lifecycle/config.mjs` | Read/write project/global settings such as PR template path |
156
157
  | `migrate` | `src/commands/lifecycle/migrate.mjs` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
157
158
  | `git-reconcile` | `src/commands/execute/git-reconcile.mjs` | Reconcile stale stage SHAs after external git history changes |
158
159
  | `handoff` | `src/commands/execute/handoff.mjs` | Stage-group release-handoff eligibility / assemble / record helpers |
159
160
  | `integrate-stages` | `src/commands/execute/integrate-stages.mjs` | Merge verified stages into the task worktree and clean stage worktrees |
160
- | `task-list`, `task-show` | `src/commands/inspect/task-list.mjs`, `src/commands/inspect/task-show.mjs` | Task/run introspection for skills |
161
+ | `task-list`, `task-show` | `src/commands/inspect/task-list.mjs`, `src/commands/inspect/task-show.mjs` | Task/run introspection for skills; `task-show` consumes the Python task read-side snapshot |
161
162
  | `resolve-task-key` | `src/commands/inspect/resolve-task-key.mjs` | Resolve a bare task-id to candidate task-keys from the project catalog |
163
+ | `set-work-status` | `src/commands/inspect/set-work-status.mjs` | Set a task's user-managed `workStatus` in task-manifest.json (Python: `okstra_ctl.set_work_status`) |
162
164
  | `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.mjs` | Read-side task runtime, wrapper log, and error aggregation helpers |
163
165
  | `context-cost` | `src/commands/inspect/context-cost.mjs` | Estimate task bundle file/read context cost |
164
166
  | `worktree-lookup` | `src/commands/execute/worktree-lookup.mjs` | Look up a task-key's registered worktree |
@@ -167,9 +169,9 @@ Runtime/install asset changes follow this checklist:
167
169
  | `run` | `src/commands/execute/run.mjs` | Host-aware execution front door (`auto` → Claude/Codex/external path selection) |
168
170
  | `codex-run`, `codex-dispatch` | `src/commands/execute/codex-*.mjs` | Codex lead dry-run bundle preparation and CLI-backed worker dispatch |
169
171
  | `team` | `src/commands/execute/team.mjs` | External lead tmux-pane worker dispatch / await / teardown |
170
- | `render-views` | `src/commands/report/render-views.mjs` | Generate slim MD + self-contained HTML report views |
172
+ | `render-views` | `src/commands/report/render-views.mjs` | Generate the self-contained HTML report view |
171
173
  | `render-final-report`, `inject-report-index` | `src/commands/report/*.mjs` | Render final-report Markdown from data.json and inject top-of-report index anchors |
172
- | `wizard` | `src/commands/execute/wizard.mjs` | Drive the `okstra-run` interactive state machine |
174
+ | `wizard` | `src/commands/execute/wizard.mjs` | Drive the `okstra-run` interactive state machine, including the final outcome envelope |
173
175
  | `token-usage` | `src/commands/execute/token-usage.mjs` | Wrap installed Python token usage CLI |
174
176
  | `spawn-followups`, `error-log` | `src/commands/execute/*.mjs` | Follow-up task bundle creation and run error-log append helpers |
175
177
  | `memory` | `src/commands/memory/memory.mjs` | Store/find global conversation memory under `~/.okstra/memory-book` |
@@ -193,7 +195,7 @@ Top-level scripts:
193
195
  | `okstra-wrapper-status.py` | Heartbeat sidecar writer used by worker wrappers |
194
196
  | `okstra-token-usage.py` | Token usage CLI entrypoint |
195
197
  | `okstra-render-final-report.py` | Render final-report Markdown from data.json |
196
- | `okstra-render-report-views.py` | Render slim MD + HTML views from final-report Markdown |
198
+ | `okstra-render-report-views.py` | Render self-contained HTML views from final-report Markdown |
197
199
  | `okstra-error-log.py` | Normalize worker/lead error sidecars |
198
200
  | `okstra-spawn-followups.py` | Follow-up spawning helper |
199
201
  | `okstra-trace-cleanup.sh` | tmux okstra pane cleanup (worker-agent + trace, lead pane 제외); `--reclaim-completed` 모드는 `@okstra_status` 가 종료(stage=exited)인 trace pane 만 회수하고 진행 중 pane 은 보존 |
@@ -206,8 +208,8 @@ Important modules:
206
208
  | Module | Role |
207
209
  |---|---|
208
210
  | `run.py` | `prepare_task_bundle()` single authority and CLI parser |
209
- | `implementation_stage.py` | `implementation` 단일-stage run 오케스트레이션 — consumer 상태 복구 → 가용 Stage Map entry 선택 → 격리 stage worktree provision → 선택 stage 를 run context 로 발행 (`run.py` 에서 추출) |
210
- | `stage_targets.py` | Stage readiness/verification 정책 SSOT — 어떤 stage 가 실행 가능한지, 어느 commit 에서 분기하는지, final-verification 이 무엇을 검사하는지 결정 (`consumers.jsonl` 행과 git ancestry 검사를 단일 인터페이스 뒤로 캡슐화). `order_stage_closure` 는 wizard 멀티선택 stage 집합의 의존성 closure 를 Kahn 위상정렬해 `chain-stages` 무인 연쇄 순서를 산출 |
211
+ | `implementation_stage.py` | `implementation` 단일-stage run 오케스트레이션 — Stage Lifecycle Snapshot 읽기 → 가용 Stage Map entry 선택 → 격리 stage worktree provision → 선택 stage 를 run context 로 발행 (`run.py` 에서 추출) |
212
+ | `stage_targets.py` | Stage readiness/verification 정책 SSOT — Stage Lifecycle Snapshot(`consumers.jsonl` ledger + carry sidecar backfill + active registry reservation)으로 어떤 stage 가 실행 가능한지, 어느 commit 에서 분기하는지, final-verification 이 무엇을 검사하는지 결정. `order_stage_closure` 는 wizard 멀티선택 stage 집합의 의존성 closure 를 Kahn 위상정렬해 `chain-stages` 무인 연쇄 순서를 산출 |
211
213
  | `stage_reconcile.py` | stage prepare 흐름 공용 best-effort git reconciliation (`git_reconcile.auto_reconcile` 위임; advisory — 실패는 stderr 보고만, dependency gate 가 권위 판정 유지) |
212
214
  | `run_context.py` | Per-task mutex, run context and run-input persistence; `consumers_mutex` helper for atomic `consumers.jsonl` writes |
213
215
  | `path_hints.py` | Compact path-hint persistence + legacy context hydration — `run-context` / `active-run-context` 를 schemaVersion `2.0` 의 `identity` + `pathHints` compact schema 로 저장하고, host-side reader 가 읽는 순간 기존 flat path key(`RUN_MANIFEST_RELATIVE_PATH`, `TEAM_STATE_PATH` 등)를 메모리에서 hydrate |
@@ -224,7 +226,7 @@ Important modules:
224
226
  | `md_table.py` | Markdown pipe-table escape/split SSOT — `mdcell` 필터(`escape_pipes`)와 `\|` 인식 `split_pipe_row`; renderer·HTML view·validators 공용 |
225
227
  | `qa_commands.py` | QA command deny-list validation for plans |
226
228
  | `pr_template.py` | PR body template resolution for release-handoff |
227
- | `report_views.py`, `render_final_report.py`, `final_report_schema.py` | Final-report data.json → Markdown → slim/HTML pipeline |
229
+ | `report_views.py`, `render_final_report.py`, `final_report_schema.py` | Final-report data.json → Markdown → Report View Model → self-contained HTML pipeline |
228
230
  | `final_report_paths.py`, `report_view_artifacts.py` | Final-report markdown/data.json 쌍 및 생성 view artifact(HTML view, user-responses 디렉터리) 경로 helper SSOT |
229
231
  | `wizard.py` | `okstra-run` prompt state machine; user-facing Korean strings live in `prompts/wizard/prompts.ko.json` |
230
232
  | `wizard_stage_intent.py` | `okstra-run` wizard 출력의 stage 관련 intent projection — whole-task(`__whole_task__`) vs 단일/멀티 stage 선택을 render-args 로 정규화 (`resolve_wizard_stage_intent`) |
@@ -253,7 +255,7 @@ Important modules:
253
255
  Project resolver and read-only state helpers:
254
256
 
255
257
  - `resolver.py`: locate project root and upsert `project.json`
256
- - `state.py`: read project metadata, task catalog, task manifest
258
+ - `state.py`: read project metadata, task catalog, task manifest, and curated task read-side snapshots
257
259
 
258
260
  ### 4.5 `scripts/okstra_token_usage/`
259
261
 
@@ -295,7 +297,7 @@ Token/cost accounting:
295
297
  |---|---|
296
298
  | `validate-run.py` | Run/final-report contract validation |
297
299
  | `validate-brief.py`, `validate-brief.sh` | Brief frontmatter/body contract validation |
298
- | `validate-report-views.py` | Slim/HTML view validation |
300
+ | `validate-report-views.py` | HTML view validation (form-control 위치 / 외부 URL 부재 / stale source digest / Response ID parity) |
299
301
  | `validate-schedule.py` | Schedule section/order/code validation |
300
302
  | `validate-implementation-plan-stages.py` | Stage Map 구조 강제 — S1–S8 규칙 검사 (`## 5.5 Stage Map` + `## 5.5.<i> Stage <i>` 섹션, stage 당 step ≤ 8 등) |
301
303
  | `validate_improvement_report.py` | improvement-discovery final-report 의 11항목 contract 강제. `validate-run.py` 가 `task_type == "improvement-discovery"` 일 때 자동 호출 |
@@ -386,7 +388,7 @@ Current report pipeline:
386
388
  3. Report-writer worker writes `reports/final-report-<task-type>-<seq>.data.json`.
387
389
  4. `scripts/okstra-render-final-report.py` renders Markdown.
388
390
  5. Token usage substitution fills usage/cost cells.
389
- 6. `scripts/okstra-render-report-views.py` emits `.slim.md` and `.html`.
391
+ 6. `scripts/okstra-render-report-views.py` emits the self-contained `.html` view.
390
392
 
391
393
  The Markdown is derived, not the authoring source. The schema is the contract.
392
394
 
@@ -55,14 +55,14 @@ flowchart TD
55
55
  | render-bundle Node shim | [`src/commands/execute/render-bundle.mjs`](../../src/commands/execute/render-bundle.mjs) |
56
56
  | bundle 생성 단일 진입점 | [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py) |
57
57
  | implementation stage 선택/provision | [`scripts/okstra_ctl/implementation_stage.py`](../../scripts/okstra_ctl/implementation_stage.py) |
58
- | stage target/base/verification 정책 | [`scripts/okstra_ctl/stage_targets.py`](../../scripts/okstra_ctl/stage_targets.py) |
58
+ | Stage Lifecycle Snapshot + stage target/base/verification 정책 | [`scripts/okstra_ctl/stage_targets.py`](../../scripts/okstra_ctl/stage_targets.py) |
59
59
  | phase boundary | [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py) |
60
60
  | task worktree | [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py) |
61
61
  | stage-group handoff | [`scripts/okstra_ctl/handoff.py`](../../scripts/okstra_ctl/handoff.py) |
62
62
  | worker roster parser | [`scripts/okstra_ctl/workers.py`](../../scripts/okstra_ctl/workers.py) |
63
63
  | lead operating contract | [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md) |
64
64
  | phase profiles | [`prompts/profiles/`](../../prompts/profiles/) |
65
- | final report shape | [`templates/reports/final-report.template.md`](../../templates/reports/final-report.template.md) |
65
+ | final report shape / HTML view | [`templates/reports/final-report.template.md`](../../templates/reports/final-report.template.md), [`scripts/okstra_ctl/report_views.py`](../../scripts/okstra_ctl/report_views.py) |
66
66
 
67
67
  ## 5. 빠른 비교표
68
68
 
@@ -71,6 +71,6 @@ flowchart TD
71
71
  | `requirements-discovery` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker analysis, convergence 1 round default | `pending-routing-decision` |
72
72
  | `error-analysis` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker analysis, convergence 2 rounds default | `implementation-planning` |
73
73
  | `implementation-planning` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker analysis + Phase 6 plan-body verification | `implementation` |
74
- | `implementation` | approved plan, stage multi-pick, executor | approved marker, stage map, stage-key reservation, QA command deny-list | one run = one stage; executor writes in isolated stage worktree, verifiers read-only | `final-verification` |
74
+ | `implementation` | approved plan, stage multi-pick, executor | approved marker, Stage Lifecycle Snapshot, stage-key reservation, QA command deny-list | one run = one stage; executor writes in isolated stage worktree, verifiers read-only | `final-verification` |
75
75
  | `final-verification` | approved plan, stage pick(whole-task or single-stage) | `VERIFICATION_TARGET` 해소; whole-task 자동 통합/teardown 또는 single-stage worktree reuse | whole-task may integrate stages first; analyser verification itself is read-only | `pending-release-handoff` |
76
- | `release-handoff` | handoff scope(stage-group or whole-task), PR template override/scope | accepted verification eligibility, generated `release-handoff-input.md`, empty worker roster | single-lead; whole-task PR or stage-group collector branch/PR | `done-or-follow-up` |
76
+ | `release-handoff` | handoff scope(stage-group or whole-task), PR template override/scope | Stage Lifecycle Snapshot eligibility, generated `release-handoff-input.md`, empty worker roster | single-lead; whole-task PR or stage-group collector branch/PR | `done-or-follow-up` |