okstra 0.104.0 → 0.106.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.
package/README.kr.md CHANGED
@@ -161,6 +161,7 @@ Claude Code 세션 안에서 사용하는 슬래시 커맨드:
161
161
  | `/okstra-run` | 새 task 시작 (또는 기존 task 의 다음 phase 이어가기) |
162
162
  | `/okstra-memory` | `~/.okstra/memory-book` 전역 대화 메모리 저장·검색·보관 |
163
163
  | `/okstra-inspect` | 통합 read-side 스킬. sub-command: `status` (phase / 상태, workStatus 설정), `history` (과거 task / re-run / resume), `report` (final-report 조회·읽기), `time` (소요 시간 breakdown), `logs` (wrapper log sidecar 조회·정리 제안), `cost` (task bundle 컨텍스트/읽기 비용), `errors` (run 에러 로그를 리포트로 집계), `error-zip` (cross-project 에러 로그를 익명화 zip 으로 수집·클러스터 요약), `recap` (run 간 전/후 요약 + task 의 `.okstra` 산출물 위 자유 Q&A) |
164
+ | `/okstra-rollup` | task-group(또는 프로젝트 전체)의 모든 task run 결과를 모아 task별 run수/소요시간/에러와 그룹 합계를 집계하고, report 들을 묶어 task 횡단 종합 요약 작성 |
164
165
  | `/okstra-schedule` | task-group 전체에 대한 작업 계획표 생성 |
165
166
  | `/okstra-container-build` | 검증 완료된 task 의 코드를 로컬 docker compose 그룹으로 배포하고 컨테이너별 로그를 감시 (sub-command: `up` / `status` / `logs` / `stop-watcher` / `down`) |
166
167
  | `/okstra-manager` | 여러 프로젝트에 걸친 okstra task 를 manager-owned plan, assignment, 단방향 project sync snapshot, status, child launch context packet 으로 조정 |
package/README.md CHANGED
@@ -43,7 +43,7 @@ okstra/ npm package = repo root
43
43
  ├── tools/build.mjs runtime/ sync script (invoked by prepack)
44
44
  ├── runtime/ gitignored install payload copied to ~/.okstra
45
45
  ├── scripts/ python + bash runtime sources
46
- ├── skills/ public skill markdown sources (8 user-facing skills)
46
+ ├── skills/ public skill markdown sources (9 user-facing skills)
47
47
  ├── agents/ worker agent markdown sources
48
48
  ├── prompts/, schemas/, templates/, validators/
49
49
  ├── tests/, tests-e2e/
@@ -159,6 +159,7 @@ User-facing slash commands inside a Claude Code session:
159
159
  | `/okstra-run` | Start a new task (or resume the next phase of an existing one) |
160
160
  | `/okstra-memory` | Store/search/archive global conversation memory in `~/.okstra/memory-book` |
161
161
  | `/okstra-inspect` | Unified read-side. Sub-commands: `status` (phase / state, workStatus update), `history` (past runs, re-run, resume), `report` (find/read final-report), `time` (elapsed-time breakdown), `logs` (wrapper log sidecar inventory + cleanup), `cost` (task bundle context/read cost), `errors` (aggregate run error logs into a report), `error-zip` (collect cross-project error logs into an anonymized zip and summarize clusters), `recap` (run-to-run before/after summary + free-form Q&A over a task's `.okstra` artifacts) |
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 |
162
163
  | `/okstra-schedule` | Generate a work schedule for an entire task-group |
163
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`) |
164
165
  | `/okstra-manager` | Coordinate cross-project okstra tasks through manager-owned plans, assignments, one-way project sync snapshots, status, and child launch context packets |
@@ -5,6 +5,9 @@ Use this matrix before changing high-risk repo contracts. Update the source file
5
5
  | Change | Must update | Tests |
6
6
  |---|---|---|
7
7
  | Add CLI flag | `src/`, `scripts/okstra_ctl/run.py`, `docs/kr/cli.md`, `prompts/wizard/` | JS CLI tests and pytest CLI contracts |
8
+ | Add Node subcommand | `src/cli-registry.mjs`, `src/commands/`, `docs/kr/cli.md`, `docs/project-structure-overview.md` | `tests-js/cli-registry.test.mjs` plus command-specific JS/Python tests |
9
+ | Add public skill | `src/lib/skill-catalog.mjs`, `.claude-plugin/plugin.json`, `skills/<name>/SKILL.md`, `docs/for-ai/README.md`, `docs/project-structure-overview.md`, `README*` | `tests-js/skill-catalog.test.mjs`, `tests/contract/test_docs_runtime_contract.py` |
10
+ | Change manager contract | `scripts/okstra_ctl/manager_*.py`, `src/commands/manager.mjs`, `skills/okstra-manager/SKILL.md`, `docs/for-ai/skills/okstra-manager.md`, `docs/kr/cli.md`, `docs/kr/architecture/storage-model.md` | `tests-js/manager.test.mjs`, `tests/test_okstra_manager_*.py` |
8
11
  | Add phase | `scripts/okstra_ctl/workflow.py`, `prompts/profiles/`, `validators/`, `tests/` | workflow and validation contract tests |
9
12
  | Change worker roster | `prompts/profiles/*.md`, `scripts/okstra_ctl/workers.py`, `tests/contract/test_repo_contracts.py` | worker roster contract tests |
10
13
  | Change report section | `schemas/final-report-v1.0.schema.json`, `templates/reports/final-report.template.md`, `scripts/okstra_ctl/render_final_report.py`, `validators/validate-run.py` | final-report schema, renderer, and validator tests |
@@ -19,7 +19,9 @@
19
19
  | 새 프로젝트나 새 머신에서 okstra 설치/초기화 | `okstra-setup` | [`skills/okstra-setup.md`](skills/okstra-setup.md) |
20
20
  | 요구사항, 티켓, 링크, 코드베이스 스캔, error-zip을 okstra 입력 brief로 변환 | `okstra-brief` | [`skills/okstra-brief.md`](skills/okstra-brief.md) |
21
21
  | 현재 Claude Code 세션에서 okstra run 시작 또는 다음 phase 실행 | `okstra-run` | [`skills/okstra-run.md`](skills/okstra-run.md) |
22
+ | 여러 프로젝트에 걸친 okstra task 묶음, 할당, sync snapshot, child launch packet 관리 | `okstra-manager` | [`skills/okstra-manager.md`](skills/okstra-manager.md) |
22
23
  | 상태, history, report, time, logs, cost, errors, error-zip, recap 확인 | `okstra-inspect` | [`skills/okstra-inspect.md`](skills/okstra-inspect.md) |
24
+ | task-group(또는 프로젝트 전체)의 여러 task run 결과를 모아 집계·종합 요약 | `okstra-rollup` | [`skills/okstra-rollup.md`](skills/okstra-rollup.md) |
23
25
  | task-group 전체의 클라이언트용 작업 일정 생성 | `okstra-schedule` | [`skills/okstra-schedule.md`](skills/okstra-schedule.md) |
24
26
  | 대화/결정/선호/요구사항을 전역 Memory Book에 저장 또는 검색 | `okstra-memory` | [`skills/okstra-memory.md`](skills/okstra-memory.md) |
25
27
  | implementation task worktree 기반 docker compose 사용자 테스트 환경 관리 | `okstra-container-build` | [`skills/okstra-container-build.md`](skills/okstra-container-build.md) |
@@ -43,12 +45,14 @@
43
45
 
44
46
  ## 공개 스킬 목록
45
47
 
46
- `src/lib/skill-catalog.mjs` 기준 공개 스킬은 다음 7개다.
48
+ `src/lib/skill-catalog.mjs` 기준 공개 스킬은 다음 9개다.
47
49
 
48
50
  - `okstra-setup`
49
51
  - `okstra-brief`
50
52
  - `okstra-run`
53
+ - `okstra-manager`
51
54
  - `okstra-memory`
52
55
  - `okstra-inspect`
56
+ - `okstra-rollup`
53
57
  - `okstra-schedule`
54
58
  - `okstra-container-build`
@@ -0,0 +1,62 @@
1
+ # okstra-manager
2
+
3
+ 여러 프로젝트에 걸친 okstra task 를 하나의 manager-owned context 로 묶을 때 사용한다. 원문 계약은 [`skills/okstra-manager/SKILL.md`](../../../skills/okstra-manager/SKILL.md), CLI 구현은 [`src/commands/manager.mjs`](../../../src/commands/manager.mjs) 와 [`scripts/okstra_ctl/manager_cli.py`](../../../scripts/okstra_ctl/manager_cli.py) 이다.
4
+
5
+ ## 언제 쓰나
6
+
7
+ - 사용자가 "여러 프로젝트", "cross-project", "okstra manager", "프로젝트 묶어서" 같은 의도를 말한다.
8
+ - manager 아래에 프로젝트를 등록하거나 후보 프로젝트를 찾는다.
9
+ - 공통 task-group/task-id 아래 child project task 를 계획하고 역할/지시를 배정한다.
10
+ - child project `.okstra` 상태를 manager snapshot 으로 동기화하거나 status 를 본다.
11
+ - 특정 child task 실행을 위한 launch packet 과 manager child context 를 준비한다.
12
+
13
+ ## 실행 규칙
14
+
15
+ 1. 모든 명령은 literal `okstra` 로 시작한다. 셸 변수, `$(...)`, `&&`, `eval`, 선행 env assignment 로 감싸지 않는다.
16
+ 2. JSON stdout 이 source of truth 다. manager 상태나 child launch args 를 문서/메모리에서 재구성하지 않는다.
17
+ 3. `--workspace-root` 는 Node wrapper 가 소유한다. 사용자가 넘기면 CLI 가 거부한다.
18
+ 4. `new project` 의 `--project-root` 는 이미 존재하는 디렉터리여야 한다. 그 안의 `.okstra/project.json` 이 없을 때만 setup-equivalent registration 을 수행한다.
19
+ 5. public child task identity 는 `project-id:task-group:task-id` 이다. `new task --task` 예시는 full key form 을 우선 보여준다.
20
+ 6. 같은 manager task id 아래 실제 child task id 가 다르면 `task assign` 과 `task run` 에 `--child-task-id <id>` 를 같이 넘긴다.
21
+
22
+ ## 명령 표면
23
+
24
+ ```bash
25
+ okstra manager init --manager-id <manager-id> --json
26
+ okstra manager discover-projects --json
27
+ okstra manager new project --manager-id <manager-id> --project-id <project-id> --project-root <abs-path> [--role <role>] [--tag <tag>] --json
28
+ okstra manager new task-group --manager-id <manager-id> --task-group <task-group> --json
29
+ okstra manager new task --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --task <project-id:task-group:task-id> --json
30
+ okstra manager task assign --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --project-id <project-id> [--child-task-id <child-task-id>] [--role <role>] [--tag <tag>] [--assignment <text>] --json
31
+ okstra manager task note --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --scope <shared|project> [--project-id <project-id>] --body <text> --json
32
+ okstra manager task sync --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --json
33
+ okstra manager task status --manager-id <manager-id> --task-group <task-group> --task-id <task-id> --json
34
+ okstra manager task run --manager-id <manager-id> --project-id <project-id> --task-group <task-group> --task-id <task-id> [--child-task-id <child-task-id>] --json
35
+ ```
36
+
37
+ ## 저장 모델
38
+
39
+ Manager state 는 `~/.okstra/managers/<manager-id>/` 아래에 저장된다.
40
+
41
+ - `manager.json`: manager id / schema / createdAt
42
+ - `projects.json`: 등록된 projectId, projectRoot, role, tags
43
+ - `task-groups/<safe-group>/<safe-task>/manifest.json`: manager task objective, common brief, progress mode
44
+ - `children.json`: child task plan, assignment, launch metadata
45
+ - `directives.jsonl`: shared/project directive rows
46
+ - `snapshots.json`: `task sync` 가 project-local `.okstra` 에서 읽어온 read-side snapshot
47
+ - `events.jsonl`: `task-created`, `child-launch-prepared` 같은 manager event
48
+ - `child-context/<safe-project>-<safe-task>.md`: `task run` 이 만든 child lead context
49
+
50
+ 비 ASCII task-group/task-id 처럼 slug 가 비는 segment 는 `u-<sha1-prefix>` path segment 를 사용하지만, manifest 와 child `taskKey` 는 원래 입력값을 보존한다.
51
+
52
+ ## Child launch
53
+
54
+ `task run` 은 child 작업을 직접 실행하지 않고 launch packet 을 준비한다. 반환 packet 의 핵심 필드는:
55
+
56
+ - `backend`: `$TMUX` 가 있으면 `tmux-child-lead`, 없으면 `subagent-child-lead`
57
+ - `workerDispatchBackend`: v1 에서는 항상 `subagent`
58
+ - `projectRoot`: child project root
59
+ - `contextPath`: manager child context markdown
60
+ - `runArgs`: host launcher 가 사용할 `okstra run ... --directive "Read manager child context: ..."` 인자
61
+
62
+ packet 생성이 성공하면 `children.json` 의 해당 child launch 상태가 `prepared` 로 갱신되고, `events.jsonl` 에 `child-launch-prepared` 가 append 된다. 실패해도 project-local task state 는 수정하지 않는다.
@@ -0,0 +1,113 @@
1
+ # okstra-rollup AI Manual
2
+
3
+ ## 원천
4
+
5
+ - 스킬 원문: [`skills/okstra-rollup/SKILL.md`](../../../skills/okstra-rollup/SKILL.md)
6
+ - 집계 코어(CLI): [`scripts/okstra_ctl/rollup.py`](../../../scripts/okstra_ctl/rollup.py)
7
+ - Node 래퍼: [`src/commands/inspect/rollup.mjs`](../../../src/commands/inspect/rollup.mjs)
8
+ - 재사용하는 단일-task 집계기: [`scripts/okstra_ctl/time_report.py`](../../../scripts/okstra_ctl/time_report.py), [`scripts/okstra_ctl/error_log_core.py`](../../../scripts/okstra_ctl/error_log_core.py)
9
+ - catalog 열거 헬퍼: [`scripts/okstra_project/state.py`](../../../scripts/okstra_project/state.py) (`list_project_tasks`)
10
+ - 단위 테스트: [`tests/inspect/test_okstra_rollup.py`](../../../tests/inspect/test_okstra_rollup.py)
11
+
12
+ ## 목적
13
+
14
+ `okstra-rollup`은 **여러 task의 run 결과를 한꺼번에 모아 요약**한다. 단일 task를 보는 `okstra-inspect`와 대비되는 task 횡단(cross-task) read-side 레이어다.
15
+
16
+ - 입력 범위: 한 task-group, 또는 `--task-group`을 생략하면 프로젝트 전체 catalog.
17
+ - deterministic 집계(개수·시간 합·에러 합·상태/카테고리/phase 분포)는 `okstra rollup` CLI가 전담한다. 스킬은 그 표를 렌더하고, 각 task의 report 본문을 읽어 **task 횡단 종합 요약(digest)**을 작성한다.
18
+ - 설계 원칙: 집계 손계산은 LLM이 틀리기 쉬우므로 CLI(SSOT)로 내리고, 자연어 종합만 LLM이 맡는다. `okstra-inspect time`이 "절대 손으로 시간을 재합산하지 말 것"이라 못 박는 것과 같은 분업이다.
19
+
20
+ 이 스킬은 read-only다. task 산출물을 mutate 하지 않는다.
21
+
22
+ ## 사용 조건
23
+
24
+ 사용한다:
25
+
26
+ - 사용자가 "롤업", "task-group 요약", "그룹 단위 리포트", "여러 task 결과 모아", "전체 task 현황 요약", "run 결과 한꺼번에 정리"를 요청한다.
27
+ - 한 task가 아니라 **여러 task**를 가로질러 보고 싶을 때.
28
+
29
+ 사용하지 않는다:
30
+
31
+ - 단일 task의 report/시간/에러/recap → `okstra-inspect` (report / time / errors / recap facet).
32
+ - 미래 작업 계획표(non-done task의 클라이언트용 일정) → `okstra-schedule`. rollup은 과거 run 결과를 모으는 **회고형**이고, schedule은 앞으로의 계획을 짜는 **전망형**이다.
33
+ - 실제 phase 실행 → `okstra-run`.
34
+
35
+ ## Preflight
36
+
37
+ 각각 별도 Bash 호출. 모두 리터럴 `okstra` 토큰으로 시작해 `Bash(okstra:*)` 자동 허용을 받는다. `if`/`eval`/`$(...)`/`VAR=`/`||`/`&&`/`npx` fallback으로 감싸지 않는다.
38
+
39
+ ```bash
40
+ okstra ensure-installed --runtime claude-code
41
+ okstra check-project --json
42
+ ```
43
+
44
+ `ensure-installed` 비정상 종료 → `/okstra-setup` 안내 후 멈춘다. `check-project`의 `ok:false` → `/okstra-setup` 안내 후 멈춘다. `ok:true`면 `projectRoot`를 리터럴 문자열로 들고 다음 단계로 간다.
45
+
46
+ ## scope 해석
47
+
48
+ - 사용자가 task-group을 지목("alpha 그룹 요약") → `--task-group <group>`.
49
+ - "전체 task"/"프로젝트 전체"/범위 미지정 → `--task-group` 생략(전체 catalog).
50
+ - 진짜 모호하면 한 번만 묻는다: 한 task-group인지 프로젝트 전체인지. 특정 그룹을 임의로 추측하지 않는다.
51
+
52
+ ## CLI 호출
53
+
54
+ ```bash
55
+ okstra rollup --task-group <group> --project-root <projectRoot> --json
56
+ ```
57
+
58
+ 전체 프로젝트면 `--task-group`을 뺀다. 출력은 항상 JSON이며 **모든 시간은 raw 밀리초**다.
59
+
60
+ ## 출력 해석
61
+
62
+ 최상위:
63
+
64
+ - `taskGroup` — 범위(`null`이면 프로젝트 전체), `taskCount` — task 수.
65
+ - `tasks[]` — task 1개당: `taskKey, taskGroup, taskId, taskType, workCategory, workStatus, currentPhase, currentPhaseState, nextRecommendedPhase, latestRunStatus, updatedAt, reportPath, runCount, cpuSumMs, wallClockMs, errorCount`.
66
+ - `totals` — `runs, cpuSumMs, wallClockMs, errors`, 그리고 `byWorkStatus` / `byWorkCategory` / `byCurrentPhase` / `byTaskType` (각각 `{값: 개수}` 맵).
67
+
68
+ 수치 의미(반드시 지킬 것):
69
+
70
+ - `runCount`는 timeline의 **전체 run 수**다. `cpuSumMs`/`wallClockMs`는 Phase 7 usage에 도달한 run만 반영하므로 `runCount > 0`이어도 `0`일 수 있다.
71
+ - `cpuSumMs`는 lead + worker가 겹쳐 도는 **CPU 합**이지 wall-clock이 아니다. 라벨을 "CPU"로 쓰고, wall-clock은 사용자가 명시적으로 물을 때만 `wallClockMs`로 보여준다.
72
+ - `reportPath`는 프로젝트 상대경로이며 비어 있을 수 있다(아직 report가 없는 task).
73
+ - `taskCount`가 `0`이면 해당 범위에 okstra task가 없다고 말하고 멈춘다.
74
+
75
+ ## 렌더
76
+
77
+ 모든 `*Ms`는 `HH:MM:SS`로 변환한다(zero-pad, raw ms 절대 노출 금지 — `okstra-inspect time`과 같은 규칙). task는 `updatedAt` 내림차순 정렬.
78
+
79
+ ```markdown
80
+ ## okstra Rollup — <task-group 또는 "whole project"> (<taskCount> tasks)
81
+
82
+ | Task | Category | workStatus | Phase | Runs | CPU | Errors | Report |
83
+ |------|----------|------------|-------|------|-----|--------|--------|
84
+ | DEV-1 | bugfix | done | final-verification | 2 | 00:25:00 | 2 | ✓ |
85
+ | DEV-2 | feature | in-progress | implementation | 1 | 00:00:00 | 0 | — |
86
+
87
+ **Totals:** 3 runs · CPU 00:25:00 · 2 errors
88
+ **workStatus:** done 1 · in-progress 1 **category:** bugfix 1 · feature 1
89
+ ```
90
+
91
+ - `Report` 열: `reportPath`가 있으면 `✓`, 없으면 `—`.
92
+ - 상태/카테고리/phase 줄은 `totals`의 tally 맵을 **그대로** 옮긴다. `tasks[]` 배열을 직접 세지 않는다(집계는 CLI가 SSOT).
93
+
94
+ ## digest 작성 (요약 — 스킬의 핵심 가치)
95
+
96
+ 사용자가 "요약"/"정리"/"summarize"/"digest"를 요청한 경우(일반적인 경우):
97
+
98
+ 1. `reportPath`가 비어 있지 않고 `<projectRoot>/<reportPath>` 파일이 실제로 존재하는 task마다 report를 읽고, **무엇을 달성했고 권장 다음 단계가 무엇인지** 1~2줄로 요약한다.
99
+ 2. per-task 줄 위에, 그룹 차원 종합 2~4문장을 쓴다: 그룹 전반에서 무엇이 산출됐는지, 미결 작업이 어디 있는지(`byWorkStatus`/`byCurrentPhase` 활용), 에러 핫스팟(높은 `errorCount` task)이 있는지.
100
+ 3. 각 per-task 주장은 report 경로(`<reportPath>`)로 인용해 독자가 바로 열어볼 수 있게 한다.
101
+
102
+ report가 없는 task는 요약을 지어내지 말고 현재 phase/workStatus를 대신 말한다. report 아닌 산출물을 읽어 빈칸을 메우지 않는다(artifact-home 규칙). report가 비었거나 없으면 그렇다고 말한다.
103
+
104
+ 단일 task의 깊은 drill-down(전체 report, worker별 시간, 에러 분해, run 간 recap)이 필요하면 `/okstra-inspect`로 안내한다.
105
+
106
+ ## 금지 패턴
107
+
108
+ - 집계 수치(합계, 분포)를 `tasks[]`에서 손으로 다시 세기. `totals`가 SSOT다.
109
+ - raw ms 노출. 항상 `HH:MM:SS`.
110
+ - `cpuSumMs`를 wall-clock인 양 표기.
111
+ - report가 없는 task에 대해 요약을 지어내기. 현재 phase/workStatus로 대체한다.
112
+ - okstra 산출물 밖(non-`.okstra`) 파일을 읽어 요약을 채우기.
113
+ - 단일 task 상세를 rollup에서 처리하기. `okstra-inspect`로 보낸다.
@@ -93,20 +93,13 @@ worker prompt history는 `/tmp`가 아니라 항상 현재 run의 `prompts/` 아
93
93
  같은 task-type으로 다시 실행하면 동일한 `runs/<task-type>/` 폴더를 재사용하지만, 유형별 하위 폴더 아래에서 run-level 파일명이 `-<task-type>-<seq>` suffix로 분리되므로 기존 산출물을 덮어쓰지 않습니다. `<seq>`는 카테고리 디렉토리(`manifests/`, `prompts/`, `reports/`, `status/`, `state/`, `sessions/`, `worker-results/`)별로 독립 스캔되므로 같은 run에서도 카테고리별 값이 다를 수 있습니다.
94
94
  이전 flat legacy artifact가 task-type run 폴더 최상위에 남아 있으면 다음 실행 시 해당 유형별 하위 폴더로 자동 정리합니다.
95
95
 
96
- ### 3. Project-level discovery and skill documents
96
+ ### 3. Project-level discovery and installed skill assets
97
97
  프로젝트 공용 discovery pointer는 아래 경로에 생성합니다.
98
98
 
99
99
  ```text
100
100
  <target-project>/.okstra/discovery/latest-task.json
101
101
  <target-project>/.okstra/discovery/task-catalog.json
102
102
  ```
103
- scripts/okstra.sh workflow가 사용하는 project-local Claude assets는 아래 경로들에 seed합니다.
104
-
105
- ```text
106
- <target-project>/.claude/skills/okstra/SKILL.md
107
- <target-project>/.claude/skills/<sub-skill>/SKILL.md
108
- <target-project>/.claude/agents/<agent>.md
109
- ```
110
103
 
111
104
  역할 구분:
112
105
 
@@ -123,6 +116,34 @@ scripts/okstra.sh workflow가 사용하는 project-local Claude assets는 아래
123
116
  - `.project-docs/ai/okstra/okstra-guide.md`
124
117
  - `.project-docs/ai/okstra/worker-catalog.md`
125
118
 
119
+ ### 4. Manager-owned cross-project state
120
+
121
+ `okstra manager` 는 project-local `.okstra` 정본을 대체하지 않고, 여러 project-local task 를 묶는 전역 manager state 를 사용자 홈에 저장합니다.
122
+
123
+ ```text
124
+ ~/.okstra/managers/<manager-id>/
125
+ ├── manager.json
126
+ ├── projects.json
127
+ └── task-groups/<safe-task-group>/<safe-task-id>/
128
+ ├── manifest.json
129
+ ├── children.json
130
+ ├── directives.jsonl
131
+ ├── snapshots.json
132
+ ├── events.jsonl
133
+ └── child-context/<safe-project-id>-<safe-child-task-id>.md
134
+ ```
135
+
136
+ 저장 권위:
137
+
138
+ - `manager.json`: manager identity 와 schema version.
139
+ - `projects.json`: manager 에 등록된 projectId / projectRoot / role / tags. `projectRoot` 는 이미 존재하는 디렉터리여야 하며, project-local `.okstra/project.json` 이 없을 때만 setup-equivalent registration 을 수행합니다.
140
+ - `manifest.json`, `children.json`, `directives.jsonl`: manager-owned plan, child assignment, shared/project directive.
141
+ - `snapshots.json`: `task sync` 가 child project `.okstra` 에서 읽어온 read-side snapshot. project state 의 source of truth 가 아닙니다.
142
+ - `events.jsonl`: `task-created`, `child-launch-prepared` 같은 manager event.
143
+ - `child-context/*.md`: `task run` 이 준비한 child lead context. sibling project report/snapshot 은 read-side source material 로만 전달합니다.
144
+
145
+ Path segment 는 slug 로 정규화합니다. 비 ASCII 값처럼 slug 가 비는 경우에는 `u-<sha1-prefix>` fallback segment 를 쓰지만, `manifest.json` 과 child `taskKey` 는 원래 입력값(`project-id:task-group:task-id`)을 보존합니다.
146
+
126
147
  ## Task manifest contract
127
148
 
128
149
  `task-manifest.json`은 Claude가 task continuity를 이해할 때 기준이 되는 canonical metadata 파일입니다.
@@ -77,7 +77,7 @@
77
77
 
78
78
  okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_task_bundle`](../../scripts/okstra_ctl/run.py) 에 모여 있습니다. 이 함수가 다음을 한 트랜잭션으로 수행합니다.
79
79
 
80
- - okstra 설치 자산(`~/.claude/skills/okstra/...`, `~/.claude/agents/...`, `~/.okstra/bin/...`) 존재 확인
80
+ - okstra 설치 자산(`~/.agents/skills/okstra-*`, optional `~/.claude/skills/okstra-*` / `~/.claude/agents/*-worker.md`, `~/.okstra/bin/...`) 존재 확인
81
81
  - `<PROJECT_ROOT>/.okstra/project.json` self-registration (또는 projectId 일치 검증)
82
82
  - task type → `prompts/profiles/<task-type>.md` 로드 + 권장 workers 추출
83
83
  - 사용자 worker/model 오버라이드 정규화 (Claude/Codex/Antigravity/Report-writer 각각 display ↔ execution-value 매핑)
@@ -122,6 +122,7 @@ okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_ta
122
122
  - [`okstra_ctl.session`](../../scripts/okstra_ctl/session.py) · [`okstra_ctl.seeding`](../../scripts/okstra_ctl/seeding.py) — Claude session id / resume command / 설치 검증 / runtime settings.
123
123
  - [`okstra_ctl.{ids,index,invocation,jsonl,project_meta,reconcile,resolver,sequence,batch,backfill,listing,locks,tmux}`](../../scripts/okstra_ctl/) — 중앙 인덱스 (`~/.okstra`) 의 기존 모듈군.
124
124
  - [`okstra_project.{resolver,state}`](../../scripts/okstra_project/) — PROJECT_ROOT 해석 + project.json upsert + task-catalog/manifest reader.
125
+ - [`okstra_ctl.manager_cli`](../../scripts/okstra_ctl/manager_cli.py), [`manager_store`](../../scripts/okstra_ctl/manager_store.py), [`manager_sync`](../../scripts/okstra_ctl/manager_sync.py), [`manager_launch`](../../scripts/okstra_ctl/manager_launch.py), [`manager_paths`](../../scripts/okstra_ctl/manager_paths.py) — `okstra manager` 의 cross-project manager state, one-way project snapshot sync, child launch packet/context 생성.
125
126
 
126
127
  ### Bash entry points (thin)
127
128
 
@@ -146,9 +147,9 @@ okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_ta
146
147
  - [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md) — main okstra lead contract. 런타임 리소스(`~/.okstra/prompts/lead/`)이며 agent skill 이 아닙니다.
147
148
  - [`skills/okstra-setup/SKILL.md`](../../skills/okstra-setup/SKILL.md) — **첫 실행 부트스트랩**. `okstra install` + `project.json` 생성.
148
149
  - [`skills/okstra-run/SKILL.md`](../../skills/okstra-run/SKILL.md) — **현재 claude 세션 안에서 okstra task 를 시작**하는 in-session 진입점. `prepare_task_bundle` 직접 호출.
149
- - 사용자 호출 가능 스킬은 `skills/okstra-setup/SKILL.md`, `skills/okstra-brief/SKILL.md`, `skills/okstra-run/SKILL.md`, `skills/okstra-memory/SKILL.md`, `skills/okstra-inspect/SKILL.md`, `skills/okstra-schedule/SKILL.md`, `skills/okstra-container-build/SKILL.md` 7종뿐이며, 이것만 agent skill home 으로 복사됩니다 — brief 작성, phase 진행, 전역 Memory Book 저장/검색, status/history/report/time/logs/cost/errors/recap read-side, schedule 보조, 그리고 `okstra-container-build` 는 검증 완료된 task 코드를 docker compose 그룹으로 배포하고 컨테이너별 watcher 로 감시하는 비선형(PHASE_SEQUENCE 외부) 컨테이너 배포/감시 스킬. `okstra-inspect` 의 read-side facet 은 `skills/okstra-inspect/SKILL.md` 의 sub-command 표가 정본인 8종입니다. `okstra-inspect logs` 는 codex/antigravity wrapper 가 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` 로 남기는 live-log sidecar 의 인벤토리·정리 안내(read-only), `okstra-inspect cost` 는 `okstra context-cost` 결과 요약, `okstra-inspect errors` 는 task 의 okstra-run 에러 로그를 타임스탬프 markdown error-report 로 모아 렌더하고 요약을 출력, `okstra-inspect recap` 은 task 의 run 간 phase 전·후 요약에 더해 `.okstra` 산출물에 대한 자유 Q&A 까지 답합니다.
150
+ - 사용자 호출 가능 스킬은 `skills/okstra-setup/SKILL.md`, `skills/okstra-brief/SKILL.md`, `skills/okstra-run/SKILL.md`, `skills/okstra-manager/SKILL.md`, `skills/okstra-memory/SKILL.md`, `skills/okstra-inspect/SKILL.md`, `skills/okstra-rollup/SKILL.md`, `skills/okstra-schedule/SKILL.md`, `skills/okstra-container-build/SKILL.md` 9종뿐이며, 이것만 agent skill home 으로 복사됩니다 — brief 작성, phase 진행, cross-project manager task 조정, 전역 Memory Book 저장/검색, status/history/report/time/logs/cost/errors/recap read-side, task-group 단위 run 결과 종합(rollup), schedule 보조, 그리고 `okstra-container-build` 는 검증 완료된 task 코드를 docker compose 그룹으로 배포하고 컨테이너별 watcher 로 감시하는 비선형(PHASE_SEQUENCE 외부) 컨테이너 배포/감시 스킬. `okstra-manager` 는 `okstra manager` CLI JSON/launch packet 을 source of truth 로 사용하며, manager-owned plan/assignment/directive/snapshot/event 는 `~/.okstra/managers/<manager-id>/` 아래에 저장합니다. `okstra-rollup` 은 단일 task 집계기(`okstra-inspect` 의 time/errors/recap)를 task-group(또는 프로젝트 전체 catalog)으로 fan-out 하는 read-side 레이어로, deterministic 집계는 `okstra rollup` CLI 가 맡고 report 본문 종합 요약만 스킬(LLM)이 작성합니다. `okstra-inspect` 의 read-side facet 은 `skills/okstra-inspect/SKILL.md` 의 sub-command 표가 정본입니다. `okstra-inspect logs` 는 codex/antigravity wrapper 가 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` 로 남기는 live-log sidecar 의 인벤토리·정리 안내(read-only), `okstra-inspect cost` 는 `okstra context-cost` 결과 요약, `okstra-inspect errors` 는 task 의 okstra-run 에러 로그를 타임스탬프 markdown error-report 로 모아 렌더하고 요약을 출력, `okstra-inspect recap` 은 task 의 run 간 phase 전·후 요약에 더해 `.okstra` 산출물에 대한 자유 Q&A 까지 답합니다.
150
151
  - 내부 운영 계약 — `context-loader` / `team-contract` / `convergence` / `report-writer` 와 lead 계약 — 은 `prompts/lead/*.md` 로, 구현/검증 워커의 언어별 coding preflight 는 `prompts/coding-preflight/*` (overview 라우터 + clean-code + languages/frameworks/architectures 3단계 선택) 로 이동했습니다. 모두 `~/.okstra/prompts/` 에 설치되는 런타임 리소스이며 skill discovery 대상이 아닙니다. generated launch prompt 가 lead 에게 절대 경로를 제공하고, 재설치 시 과거 `okstra-context-loader` / `okstra-team-contract` / `okstra-convergence` / `okstra-report-writer` / `okstra-coding-preflight` / `okstra` skill 디렉터리는 exact-name prune 됩니다.
151
- - 플러그인 매니페스트: [`../../.claude-plugin/plugin.json`](../../.claude-plugin/plugin.json) — `npx skills@latest add Devonshin/okstra` 보조 채널이 참조. 일반 셋업에는 `npx okstra@latest install` 을 사용한다. 플러그인 매니페스트는 사용자 진입점 7개(`okstra-setup`, `okstra-brief`, `okstra-run`, `okstra-memory`, `okstra-inspect`, `okstra-schedule`, `okstra-container-build`)만 노출한다.
152
+ - 플러그인 매니페스트: [`../../.claude-plugin/plugin.json`](../../.claude-plugin/plugin.json) — `npx skills@latest add Devonshin/okstra` 보조 채널이 참조. 일반 셋업에는 `npx okstra@latest install` 을 사용한다. 플러그인 매니페스트는 사용자 진입점 9개(`okstra-setup`, `okstra-brief`, `okstra-run`, `okstra-manager`, `okstra-memory`, `okstra-inspect`, `okstra-rollup`, `okstra-schedule`, `okstra-container-build`)만 노출한다.
152
153
  - 설치 위치: `~/.claude/skills/<name>/SKILL.md` 또는 `~/.agents/skills/<name>/SKILL.md`.
153
154
  - 릴리스 절차: [`../../RELEASING.md`](../../RELEASING.md) — npm publish 흐름과 release-please / manual fallback.
154
155
 
@@ -175,7 +176,7 @@ okstra 의 prepare 단계는 디스크 권위 + 단일 python 진입점 모델
175
176
  │ ┌────────────┴────────────────┐ │
176
177
  │ ▼ ▼ │
177
178
  │ on-disk authority ~/.okstra (central index) │
178
- │ <PROJECT_ROOT>/.project-docs/ per-task mutex + record_start │
179
+ │ <PROJECT_ROOT>/.okstra/ per-task mutex + record_start │
179
180
  └────────────────────────────────────────────────────────────────┘
180
181
  ```
181
182
 
package/docs/kr/cli.md CHANGED
@@ -620,7 +620,7 @@ chmod +x ~/.local/bin/okstra-ctl
620
620
 
621
621
  ### `okstra` Node CLI — admin / introspection subcommands
622
622
 
623
- `okstra` Node CLI (`bin/okstra`) 는 installer/admin 명령과 skill / agent 가 사용하는 introspection 명령을 함께 제공합니다. Python 런타임을 직접 호출하지 않고 Node wrapper를 통하므로 `PYTHONPATH` wiring은 `src/_python-helper.mjs`가 처리합니다.
623
+ `okstra` Node CLI (`bin/okstra`) 는 installer/admin 명령과 skill / agent 가 사용하는 introspection 명령을 함께 제공합니다. Python 런타임을 직접 호출하지 않고 Node wrapper를 통하므로 `PYTHONPATH` wiring은 `src/lib/python-helper.mjs`가 처리합니다.
624
624
 
625
625
  | 명령 | 용도 |
626
626
  |---|---|
@@ -633,7 +633,7 @@ chmod +x ~/.local/bin/okstra-ctl
633
633
  | `okstra check-project [--json]` | 현재 프로젝트가 등록되었는지 검증 |
634
634
  | `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | 영구 설정 관리 (예: `pr-template-path`). 원자적 JSON 쓰기 |
635
635
  | `okstra memory <add\|list\|search\|show\|archive>` | `~/.okstra/memory-book` 전역 대화 메모리 관리. 프로젝트 `.okstra/` 와 분리된 user-home 저장소이며, `okstra 에 정리해서 보관해` 자연어 스킬의 CLI 기반 |
636
- | `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 을 관리한다. child task key 는 공개 문서에서 `project-id:task-group:task-id` 전체 형식을 사용하며, `task run` 은 child launch context packet 을 JSON 으로 반환한다 |
636
+ | `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
637
  | `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 말까지 유지 후 제거 예정 |
638
638
  | `okstra task-list [--project-root <path>]` | `list_project_tasks` + `read_latest_task` 결과를 합쳐 task 카탈로그 + 최근 task 를 JSON 으로 반환 |
639
639
  | `okstra task-show <task-key> [--project-root <path>]` | task-manifest.json 의 workflow / phase / status 요약 |
@@ -647,7 +647,7 @@ chmod +x ~/.local/bin/okstra-ctl
647
647
  | `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)으로 진입합니다 |
648
648
  | `okstra token-usage ...` | 설치된 `okstra-token-usage.py` 를 감싸 run token usage 수집/치환을 수행. 세션 jsonl 은 기본적으로 `$OKSTRA_HOME/cache/token-usage/` 의 byte cursor 캐시로 증분 스캔하며, `--no-cache` 로 캐시를 우회해 전체 재스캔을 강제할 수 있음(정확성 폴백) |
649
649
 
650
- > 모든 subcommand 는 `bin/okstra` 가 spawn 하는 python 헬퍼 (`src/_python-helper.mjs`) 가 `PYTHONPATH` 와 `~/.okstra/lib/python` 을 wire 합니다. 직접 `python3 -m okstra_ctl.*` 으로 호출하면 `PYTHONPATH` 를 사용자가 직접 셋업해야 합니다.
650
+ > 모든 subcommand 는 `bin/okstra` 가 spawn 하는 python 헬퍼 (`src/lib/python-helper.mjs`) 가 `PYTHONPATH` 와 `~/.okstra/lib/python` 을 wire 합니다. 직접 `python3 -m okstra_ctl.*` 으로 호출하면 `PYTHONPATH` 를 사용자가 직접 셋업해야 합니다.
651
651
 
652
652
  ### Live-log sidecar
653
653
 
@@ -153,17 +153,29 @@ Runtime/install asset changes follow this checklist:
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
155
  | `config` | `src/commands/lifecycle/config.mjs` | Read/write project/global settings such as PR template path |
156
+ | `migrate` | `src/commands/lifecycle/migrate.mjs` | One-shot legacy `.project-docs/okstra` → `.okstra` migration helper |
157
+ | `git-reconcile` | `src/commands/execute/git-reconcile.mjs` | Reconcile stale stage SHAs after external git history changes |
158
+ | `handoff` | `src/commands/execute/handoff.mjs` | Stage-group release-handoff eligibility / assemble / record helpers |
159
+ | `integrate-stages` | `src/commands/execute/integrate-stages.mjs` | Merge verified stages into the task worktree and clean stage worktrees |
156
160
  | `task-list`, `task-show` | `src/commands/inspect/task-list.mjs`, `src/commands/inspect/task-show.mjs` | Task/run introspection for skills |
161
+ | `resolve-task-key` | `src/commands/inspect/resolve-task-key.mjs` | Resolve a bare task-id to candidate task-keys from the project catalog |
162
+ | `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.mjs` | Read-side task runtime, wrapper log, and error aggregation helpers |
157
163
  | `context-cost` | `src/commands/inspect/context-cost.mjs` | Estimate task bundle file/read context cost |
158
164
  | `worktree-lookup` | `src/commands/execute/worktree-lookup.mjs` | Look up a task-key's registered worktree |
159
165
  | `plan-validate` | `src/commands/execute/plan-validate.mjs` | Check approved-plan approval marker |
160
166
  | `render-bundle` | `src/commands/execute/render-bundle.mjs` | Preview `prepare_task_bundle(render_only=True)` |
167
+ | `run` | `src/commands/execute/run.mjs` | Host-aware execution front door (`auto` → Claude/Codex/external path selection) |
168
+ | `codex-run`, `codex-dispatch` | `src/commands/execute/codex-*.mjs` | Codex lead dry-run bundle preparation and CLI-backed worker dispatch |
169
+ | `team` | `src/commands/execute/team.mjs` | External lead tmux-pane worker dispatch / await / teardown |
161
170
  | `render-views` | `src/commands/report/render-views.mjs` | Generate slim MD + self-contained HTML report views |
171
+ | `render-final-report`, `inject-report-index` | `src/commands/report/*.mjs` | Render final-report Markdown from data.json and inject top-of-report index anchors |
162
172
  | `wizard` | `src/commands/execute/wizard.mjs` | Drive the `okstra-run` interactive state machine |
163
173
  | `token-usage` | `src/commands/execute/token-usage.mjs` | Wrap installed Python token usage CLI |
174
+ | `spawn-followups`, `error-log` | `src/commands/execute/*.mjs` | Follow-up task bundle creation and run error-log append helpers |
164
175
  | `memory` | `src/commands/memory/memory.mjs` | Store/find global conversation memory under `~/.okstra/memory-book` |
165
176
  | `recap` | `src/commands/inspect/recap.mjs` | `okstra recap <assemble\|record>` Node wrapper backing the okstra-inspect `recap` facet |
166
177
  | `container` | `src/commands/inspect/container.mjs` | `bin okstra container` thin shim into `scripts/okstra_ctl/container.py` for the okstra-container-build skill |
178
+ | `manager` | `src/commands/manager.mjs` | Thin shim into `scripts/okstra_ctl/manager_cli.py` for cross-project manager state and child launch packets |
167
179
 
168
180
  `src/lib/python-helper.mjs` centralizes Node → Python execution so command modules do not duplicate subprocess wiring.
169
181
 
@@ -176,7 +188,7 @@ Top-level scripts:
176
188
  | `okstra.sh` | Bash CLI wrapper around `prepare_task_bundle`, optionally launches `claude` |
177
189
  | `okstra-ctl.sh` | Bash control center for list/show/open/rerun/reconcile/project commands |
178
190
  | `okstra-central.sh` | Central run index writer / reconciler entrypoint |
179
- | `okstra-codex-exec.sh`, `okstra-antigravity-exec.sh` | Worker CLI wrappers with log/status sidecars |
191
+ | `okstra-claude-exec.sh`, `okstra-codex-exec.sh`, `okstra-antigravity-exec.sh` | Worker CLI wrappers with log/status sidecars |
180
192
  | `okstra-wrapper-status.py` | Heartbeat sidecar writer used by worker wrappers |
181
193
  | `okstra-token-usage.py` | Token usage CLI entrypoint |
182
194
  | `okstra-render-final-report.py` | Render final-report Markdown from data.json |
@@ -227,6 +239,11 @@ Important modules:
227
239
  | `container.py` | okstra-container-build 공개 스킬의 `okstra container` 수렴 entrypoint — `provision_container_group` + `up`/`status`/`logs`/`stop-watcher`/`down` 디스패치, env override 합성, compose argv 조립, 컨테이너별 watcher 기동 |
228
240
  | `container_registry.py` | flock-guarded 보조 인덱스 — 컨테이너 그룹별 tmux session/pane 및 watcher findings 추적 |
229
241
  | `plan_run_root.py` | `approved_plan_path` → `plan_run_root` 파생 + task-key 역추적 공유 헬퍼 |
242
+ | `manager_cli.py` | `okstra manager` Python entrypoint — manager init/discover/new/task subcommands and JSON output |
243
+ | `manager_paths.py` | Manager state path SSOT under `~/.okstra/managers/<manager-id>/`; slug fallback uses `u-<sha1-prefix>` when a safe segment would be empty |
244
+ | `manager_store.py` | Manager-owned state mutation — project membership, task planning, assignment, directives, event append |
245
+ | `manager_sync.py` | One-way child project `.okstra` snapshot reader; corrupt child state becomes row-level `error` so other children continue |
246
+ | `manager_launch.py` | Child launch packet and manager child context renderer; records `prepared` launch metadata/events without changing project-local task state |
230
247
 
231
248
  ### 4.4 `scripts/okstra_project/`
232
249
 
@@ -284,7 +301,7 @@ Token/cost accounting:
284
301
 
285
302
  ### 4.10 `skills/`
286
303
 
287
- 8 user-facing skills (the only skills `okstra install` copies):
304
+ 9 user-facing skills (the only skills `okstra install` copies):
288
305
 
289
306
  | Skill | User-invocable | Role |
290
307
  |---|---:|---|
@@ -292,6 +309,7 @@ Token/cost accounting:
292
309
  | `okstra-run` | yes | Start/resume okstra task in current Claude Code session |
293
310
  | `okstra-memory` | yes | Store/search/archive global conversation memory under `~/.okstra/memory-book` |
294
311
  | `okstra-inspect` | yes | Unified read-side — sub-commands `status` (lifecycle + workStatus), `history` (past runs / re-run / resume), `report` (find final-report), `time` (elapsed-time breakdown), `logs` (wrapper log inventory + cleanup), `cost` (task bundle context/read cost) |
312
+ | `okstra-rollup` | yes | Cross-task roll-up — aggregate runs/time/errors across a task-group (or whole project) and synthesize a digest from the report files |
295
313
  | `okstra-schedule` | yes | Generate task-group schedule |
296
314
  | `okstra-container-build` | yes | Non-linear deploy tool — deploy a verified task's code as a docker compose group and watch each container (sub-commands `up` / `status` / `logs` / `stop-watcher` / `down`) |
297
315
  | `okstra-manager` | yes | Coordinate cross-project okstra tasks through manager-owned plans, assignments, sync snapshots, status, and child launch context packets |
@@ -326,17 +344,17 @@ The lead operating contract moved out of `agents/` to `prompts/lead/okstra-lead-
326
344
  1. Resolve project root and verify/upsert `project.json`.
327
345
  2. Resolve profile, required workers, model assignments, executor provider.
328
346
  3. Compute task/run paths and persist run context under `runs/<task-type>/manifests/`.
329
- 4. Provision or reuse the task-key worktree.
347
+ 4. Provision or reuse the task-key worktree, or the selected implementation stage worktree for stage-isolated runs.
330
348
  5. Materialize `instruction-set/` files and lead prompt snapshot.
331
349
  6. Persist run inputs, team state, task manifest, task index, run manifest, timeline, discovery pointers.
332
350
  7. Record the run in `~/.okstra/{active,recent}.jsonl` and project index.
333
351
 
334
352
  ### 5.2 Worktree model
335
353
 
336
- One task-key owns one worktree:
354
+ Non-`implementation` phases share one task-key worktree:
337
355
 
338
356
  ```text
339
- ~/.okstra/worktrees/<project-id>/<task-group>/<task-id>/
357
+ ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/
340
358
  ```
341
359
 
342
360
  Branch name:
@@ -345,7 +363,16 @@ Branch name:
345
363
  <work-category-prefix>-<task-id-segment>
346
364
  ```
347
365
 
348
- The same worktree/branch is reused across all phases. `worktreeSyncDirs`, `worktreeSyncFiles`, and `worktreeSnapshotFiles` provide filesystem continuity only; they do not expand okstra's context/write boundary.
366
+ That task-key worktree is reused for `requirements-discovery` through `implementation-planning`, and by whole-task verification / handoff flows after implementation stages have been integrated. `worktreeSyncDirs`, `worktreeSyncFiles`, and `worktreeSnapshotFiles` provide filesystem continuity only; they do not expand okstra's context/write boundary.
367
+
368
+ `implementation` is stage-isolated: one run owns one `stage-<N>` worktree and branch, with stage-key reservation in `worktree_registry.py`.
369
+
370
+ ```text
371
+ ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/stage-<N>/
372
+ <work-category-prefix>-<task-id-segment>-s<N>
373
+ ```
374
+
375
+ Single-stage `final-verification --stage <N>` reuses the matching implementation stage worktree read-only, while run artifacts are isolated under `runs/final-verification/stage-<N>/`. Whole-task final-verification keeps the flat `runs/final-verification/` shape.
349
376
 
350
377
  ### 5.3 Final report model
351
378
 
@@ -368,13 +395,14 @@ The Markdown is derived, not the authoring source. The schema is the contract.
368
395
  ~/.okstra/
369
396
  ├── version
370
397
  ├── lib/python/{okstra_ctl,okstra_project,okstra_token_usage,okstra_vendor,lib/}
371
- ├── bin/{okstra.sh,okstra-codex-exec.sh,okstra-antigravity-exec.sh,...}
398
+ ├── bin/{okstra.sh,okstra-claude-exec.sh,okstra-codex-exec.sh,okstra-antigravity-exec.sh,...}
372
399
  ├── templates/
373
400
  ├── installed-skills.json
374
401
  ├── installed-agents.json
375
402
  ├── active.jsonl
376
403
  ├── recent.jsonl
377
404
  ├── projects/<project-id>/{meta.json,index.jsonl}
405
+ ├── managers/<manager-id>/{manager.json,projects.json,task-groups/...}
378
406
  ├── worktrees/{registry.json,registry.lock,<project>/<group>/<task>/}
379
407
  ├── archive/
380
408
  └── .locks/
@@ -481,4 +509,4 @@ Clarifications now live in the unified `## 1. Clarification Items` table. Deprec
481
509
 
482
510
  ---
483
511
 
484
- *Updated: 2026-06-05 · Source of truth checked against `package.json`, `bin/okstra`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
512
+ *Updated: 2026-06-27 · Source of truth checked against `package.json`, `bin/okstra`, `src/cli-registry.mjs`, `src/lib/skill-catalog.mjs`, `tools/build.mjs`, `scripts/`, `skills/`, `agents/`, `templates/`, `schemas/`, `validators/`, and tests.*
@@ -42,7 +42,7 @@ flowchart TD
42
42
  | `error-analysis` | [error-analysis.md](error-analysis.md) | 증상과 evidence로 원인 후보와 검증 경로를 찾는다. |
43
43
  | `implementation-planning` | [implementation-planning.md](implementation-planning.md) | 구현 옵션, 검증, rollback, approval gate가 있는 계획을 만든다. |
44
44
  | `implementation` | [implementation.md](implementation.md) | 승인된 계획을 executor가 구현하고 verifier가 독립 검증한다. |
45
- | `final-verification` | [final-verification.md](final-verification.md) | 구현 결과를 read-only로 acceptance 판단한다. |
45
+ | `final-verification` | [final-verification.md](final-verification.md) | 구현 결과의 whole-task 또는 single-stage acceptance 판정한다. |
46
46
  | `release-handoff` | [release-handoff.md](release-handoff.md) | accepted verdict 뒤 push/PR handoff를 lead-only로 수행한다. |
47
47
 
48
48
  ## 4. 핵심 코드 위치
@@ -52,10 +52,13 @@ flowchart TD
52
52
  | okstra-run skill 절차 | [`skills/okstra-run/SKILL.md`](../../skills/okstra-run/SKILL.md) |
53
53
  | wizard state machine | [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py) |
54
54
  | wizard prompt text | [`prompts/wizard/prompts.ko.json`](../../prompts/wizard/prompts.ko.json) |
55
- | render-bundle Node shim | [`src/render-bundle.mjs`](../../src/render-bundle.mjs) |
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
+ | 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) |
57
59
  | phase boundary | [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py) |
58
60
  | task worktree | [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py) |
61
+ | stage-group handoff | [`scripts/okstra_ctl/handoff.py`](../../scripts/okstra_ctl/handoff.py) |
59
62
  | worker roster parser | [`scripts/okstra_ctl/workers.py`](../../scripts/okstra_ctl/workers.py) |
60
63
  | lead operating contract | [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md) |
61
64
  | phase profiles | [`prompts/profiles/`](../../prompts/profiles/) |
@@ -68,7 +71,6 @@ flowchart TD
68
71
  | `requirements-discovery` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker analysis, convergence 1 round default | `pending-routing-decision` |
69
72
  | `error-analysis` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker analysis, convergence 2 rounds default | `implementation-planning` |
70
73
  | `implementation-planning` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker analysis + Phase 6 plan-body verification | `implementation` |
71
- | `implementation` | approved plan, stage, executor | approved marker, stage map, QA command deny-list | executor writes, verifiers read-only | `final-verification` |
72
- | `final-verification` | 공통 질문만 | profile/brief/base-ref 존재 | multi-worker read-only verification | `pending-release-handoff` |
73
- | `release-handoff` | PR template override/scope | PR template resolution, empty worker roster | single-lead, no TeamCreate, no workers | `done-or-follow-up` |
74
-
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` |
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` |
@@ -93,7 +93,7 @@ sequenceDiagram
93
93
  Skill->>FS: read claude-execution-prompt.md
94
94
  ```
95
95
 
96
- `render-bundle`은 `--workspace-root`와 `--render-only`를 직접 붙인다. 따라서 okstra-run 경로의 initial run status는 `prepared`, task status는 `instruction-set-generated`로 시작한다.
96
+ `render-bundle`의 Node shim은 [`src/commands/execute/render-bundle.mjs`](../../src/commands/execute/render-bundle.mjs)다. 이 shim이 `--workspace-root`, `--render-only`, runtime resolution 인자를 직접 붙인다. 따라서 okstra-run 경로의 initial run status는 `prepared`, task status는 `instruction-set-generated`로 시작한다.
97
97
 
98
98
  ## 5. Claude lead phase 1-7
99
99
 
@@ -131,8 +131,15 @@ flowchart TD
131
131
  Runs --> Reports[reports/final-report-*.md<br/>reports/*.data.json]
132
132
  Runs --> State[state/*.json]
133
133
  Runs --> Status[status/final-status-*.json]
134
+ Runs --> ImplStage[implementation/stage-N/...]
135
+ Runs --> FvStage[final-verification/stage-N/...]
136
+ Runs --> Carry[implementation/carry/stage-N.json]
137
+ Runs --> Consumers[implementation-planning/consumers.jsonl]
138
+ Root --> Handoff[release-handoff-input.md]
134
139
  ```
135
140
 
141
+ `implementation`과 단일-stage `final-verification`은 run 산출물을 `stage-<N>/` 아래에 격리한다. `implementation`의 carry sidecar와 `consumers.jsonl`은 stage 간 조율 ledger라 phase root에 남는다. `release-handoff`는 brief를 받지 않고 prepare가 `release-handoff-input.md`를 생성한다.
142
+
136
143
  `runtime/`은 build output이므로 이 흐름을 고칠 때는 source인 `scripts/`, `skills/`, `agents/`, `prompts/`, `templates/`, `validators/`를 수정하고 `npm run build`로 갱신한다.
137
144
 
138
145
  ## 7. 공통 분기 규칙
@@ -157,10 +164,12 @@ flowchart TD
157
164
 
158
165
  중요한 점은 `Use defaults`가 model 기본값을 뜻한다는 것이다. non-implementation task-type에서는 defaults를 골라도 worker roster 질문은 계속 나온다. 반대로 `implementation`은 worker override 질문이 없다. profile default roster와 executor binding을 사용한다.
159
166
 
167
+ Worktree 규칙은 phase별로 다르다. `requirements-discovery`부터 `implementation-planning`까지는 task-key worktree를 재사용한다. `implementation`은 task-key worktree를 anchor로 삼되 실제 실행은 stage-key(`stage-<N>`) worktree와 `runs/implementation/stage-<N>/` 산출물에서 한 stage씩 격리한다. `final-verification --stage N`은 해당 implementation stage worktree를 읽기 대상으로 재사용하고, whole-task 모드는 task-key worktree에 stage commit을 자동 통합한 뒤 검증 target을 만든다.
168
+
160
169
  ## 8. 주의할 불일치 지점
161
170
 
162
171
  - `okstra-run` wizard 경로는 implementation approved plan에 이미 approval marker가 있어야 통과한다. `scripts/okstra.sh`에는 `--approve`가 있어 checkbox를 CLI ack로 flip할 수 있지만, 현재 wizard `render_args()`에는 `approve` flag가 없다.
163
- - `release-handoff`도 task worktree provisioning 대상이다. 정상적인 handoff는 같은 task-key의 implementation/final-verification worktree재사용하는 흐름이 안전하다. 새 task로 시작하면 새 worktree가 만들어지고, profile"implementation commit이 있어야 함" entry gate에서 막힐 수 있다.
172
+ - `release-handoff`는 brief가 없다. prepare가 accepted final-verification report인용해 `release-handoff-input.md`를 만들고, wizard`handoff_stage_pick` 또는 CLI `--stages`가 whole-task/stage-group 범위를 고정한다.
173
+ - `release-handoff`도 task worktree provisioning 대상이다. 정상적인 handoff는 같은 task-key의 implementation/final-verification 결과를 재사용하는 흐름이 안전하다. 새 task로 시작하면 새 worktree가 만들어지고, profile의 "implementation commit이 있어야 함" entry gate에서 막힐 수 있다.
164
174
  - `release-handoff`는 profile에 `Required workers:` block이 없다. runtime도 worker roster를 강제로 empty로 만든다.
165
175
  - 모든 task-type은 한 run 안에서 다음 lifecycle phase를 시작하지 않는다. "다음 단계 진행해"는 현재 phase 산출을 마무리하라는 뜻으로만 해석한다.
166
-