okstra 0.109.0 → 0.111.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 +2 -1
- package/README.md +2 -1
- package/docs/for-ai/skills/okstra-run.md +7 -5
- package/docs/kr/architecture.md +11 -12
- package/docs/kr/cli.md +4 -4
- package/docs/project-structure-overview.md +12 -12
- package/docs/task-process/README.md +4 -4
- package/docs/task-process/common-flow.md +8 -5
- package/docs/task-process/implementation.md +4 -5
- package/docs/task-process/release-handoff.md +3 -3
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/antigravity-worker.md +1 -0
- package/runtime/agents/workers/codex-worker.md +1 -0
- package/runtime/prompts/lead/convergence.md +7 -7
- package/runtime/prompts/profiles/_common-contract.md +1 -1
- package/runtime/prompts/profiles/_implementation-diff-review.md +43 -0
- package/runtime/prompts/profiles/_implementation-executor.md +7 -9
- package/runtime/prompts/profiles/_implementation-self-check.md +11 -5
- package/runtime/python/okstra_ctl/codex_dispatch.py +3 -0
- package/runtime/python/okstra_ctl/consumers.py +4 -0
- package/runtime/python/okstra_ctl/handoff.py +5 -23
- package/runtime/python/okstra_ctl/implementation_stage.py +11 -11
- package/runtime/python/okstra_ctl/report_views.py +76 -26
- package/runtime/python/okstra_ctl/stage_targets.py +152 -0
- package/runtime/python/okstra_ctl/wizard.py +47 -0
- package/runtime/python/okstra_ctl/worktree.py +14 -13
- package/runtime/python/okstra_project/__init__.py +2 -0
- package/runtime/python/okstra_project/state.py +44 -2
- package/runtime/skills/okstra-run/SKILL.md +21 -17
- package/src/commands/execute/wizard.mjs +3 -1
- package/src/commands/inspect/task-show.mjs +11 -31
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
|
|
|
@@ -193,7 +194,7 @@ Claude Code 세션 밖에서 task 를 시작하려면:
|
|
|
193
194
|
|
|
194
195
|
0.8.0 이후 `main` 에 추가된 workflow 변경:
|
|
195
196
|
|
|
196
|
-
- **모든 task-type 격리 worktree 자동 provisioning** — prepare 단계에서 `okstra-ctl` 이 task-key 당 한 번 `git worktree add ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>` 를 수행해 격리된 working tree 와 브랜치 `<work-category-
|
|
197
|
+
- **모든 task-type 격리 worktree 자동 provisioning** — prepare 단계에서 `okstra-ctl` 이 task-key 당 한 번 `git worktree add ~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>` 를 수행해 격리된 working tree 와 브랜치 `<work-category-namespace>/<task-id-segment>` (예: `feature/dev-9436`, `fix/dev-7311`) 를 만듭니다. base ref 는 사용자가 `--base-ref` 로 지정 (release-handoff PR base picker 와 동일한 메뉴: `main` / `dev` / `staging` / `preprod` / `prod` / 직접 입력). 첫 phase 에서는 필수이며, okstra-run skill 이 `AskUserQuestion` 으로 수집합니다 — 비대화형 호출자는 `--base-ref` 플래그를 직접 전달해야 prepare 가 통과합니다. 같은 task-key 의 후속 **비-`implementation`** phase(`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`)는 같은 path/branch를 재사용합니다. 반면 `implementation` run 은 **stage 격리** 로 동작합니다 — 각 run 이 자신의 `.../<task>/stage-<N>/` worktree(브랜치 `<work-category-namespace>/<task>-s<N>`)에서 한 stage 만 실행하므로, 독립(`depends-on (none)`) stage 를 별도 run 으로 **동시에 병렬 구현** 할 수 있습니다(트리 공유 없음). registry 는 task-key 와 **stage-key** 를 함께 flock 예약합니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 됩니다(stage 격리도 평면 경로로 degrade). 수동 cleanup: `git worktree remove <path>` → `git branch -D <branch>` + registry 항목 release/remove. 상세: [`docs/kr/architecture.md`](docs/kr/architecture.md) *Task type* 섹션, [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
|
|
197
198
|
- **`release-handoff` lifecycle phase** — `final-verification` 이 `verdict=accepted` 를 반환한 직후에 실행되는 신규 phase. lead 가 Claude worker (drafter) 를 통해 commit message · PR body 후보를 만들고, `AskUserQuestion` 으로 사용자에게 (1) action (`commit only` / `commit + PR` / `skip`), (2) PR base branch (`staging` / `preprod` / `prod` / `main` / `dev` / 직접 입력), (3) message handling (`use as-is` / `edit then proceed` / `cancel`) 세 가지를 순서대로 묻습니다. 사용자가 메뉴로 선택한 git / gh 명령만 실행되고, force-push, base 브랜치 직접 push, hook bypass (`--no-verify`), release publish (`gh release`, `npm publish`, ...) 는 금지됩니다. 이 phase 에서는 소스 코드를 수정하지 않습니다. profile: [`prompts/profiles/release-handoff.md`](prompts/profiles/release-handoff.md).
|
|
198
199
|
- **PR 본문 템플릿 설정** (release-handoff) — PR 본문은 마크다운 템플릿에서 채워집니다. 해석 우선순위: 1회성 override (`--pr-template-path` 또는 okstra-run Step 6 prompt) → `<project_root>/.okstra/project.json` 의 `prTemplatePath` → `~/.okstra/config.json` 의 `prTemplatePath` → 스킬 디폴트 `~/.claude/skills/templates/prd/pr-body.template.md`. 템플릿 등록 명령: `okstra config set pr-template-path <path> [--scope project|global]` (project 스코프는 project root 기준 상대경로 허용, global 스코프는 절대경로 또는 `~/` 시작 경로만 허용). 현재 설정 확인: `okstra config get pr-template-path --scope all` 은 각 스코프 값 + 실제로 우승하는 경로(effective) 까지 보여줍니다. 디폴트 템플릿은 `## Summary` / `## Changes` / `## Test plan` / `## Linked issues` 4 섹션 + HTML 주석으로 lead 작성 가이드를 포함하며, PR 생성 직전에 lead 가 주석을 제거합니다.
|
|
199
200
|
- **프로파일 워커 로스터 검증** — `--workers <csv>` 와 okstra-run Step 6 의 워커 prompt 는 해당 프로파일의 `Required workers:` 블록에 선언된 워커 ID 만 허용합니다. 프로파일에 없는 워커 (예: `release-handoff` 에서 `codex` / `antigravity`) 를 요청하면 명확한 에러로 거절되고, 인터랙티브 prompt 도 프로파일이 실제로 받는 워커만 보여줍니다.
|
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
|
|
|
@@ -191,7 +192,7 @@ Notable flags added in 0.7.0 / 0.8.0:
|
|
|
191
192
|
|
|
192
193
|
Recent workflow additions (post-0.8.0, on `main`):
|
|
193
194
|
|
|
194
|
-
- **Isolated task worktree for every task-type** — prepare automatically runs `git worktree add ~/.okstra/worktrees/<project>/<group>/<task>/` on a fresh branch `<work-category-
|
|
195
|
+
- **Isolated task worktree for every task-type** — prepare automatically runs `git worktree add ~/.okstra/worktrees/<project>/<group>/<task>/` on a fresh branch `<work-category-namespace>/<task-id-segment>` (e.g. `feature/dev-9436`, `fix/dev-7311`) branched from the **user-chosen base ref** (`--base-ref`, mirroring the `release-handoff` PR-base picker: `main` / `dev` / `staging` / `preprod` / `prod` / any local ref) the first time a task-key is seen. `--base-ref` is required on first phase; the okstra-run skill collects it via `AskUserQuestion`, non-interactive callers must pass the flag explicitly. Every subsequent **non-`implementation`** phase of the same task-key (`requirements-discovery` → `error-analysis` → `implementation-planning` → `final-verification` → `release-handoff`) reuses the same path and branch, so phase N inherits the working-tree state phase N-1 left behind. `implementation` runs are **stage-isolated** instead — each run owns exactly one stage in its own `.../<task>/stage-<N>/` worktree on branch `<work-category-namespace>/<task>-s<N>`, so independent (`depends-on (none)`) stages can be implemented in parallel across simultaneous runs without sharing a tree. A global registry at `~/.okstra/worktrees/registry.json` (flock-guarded) reserves task-keys **and stage-keys** across concurrent runs; all path/branch segments are sanitised (`/`, `:`, etc. → `-`). The worktree is preserved after every run for follow-up phases, PR authoring, and rollback. Skip paths: when the caller is already inside another worktree or `project_root` is not a git repo, provisioning no-ops (stage isolation degrades to the flat path too). Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` plus releasing/removing the key from the registry. Details: [`docs/kr/architecture.md`](docs/kr/architecture.md) (*Task type* section) and [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
|
|
195
196
|
- **`release-handoff` lifecycle phase** — runs after `final-verification` returns `verdict=accepted`. The lead drafts a commit message and PR body via a Claude worker, then prompts the user with `AskUserQuestion` for three choices: action (`commit only` / `commit + PR` / `skip`), PR base branch (`staging` / `preprod` / `prod` / `main` / `dev` / free-form), and message handling (`use as-is` / `edit then proceed` / `cancel`). Only user-selected mutating git/gh commands run. Force-push, base-branch direct push, hook bypass (`--no-verify`), and release publishing (`gh release`, `npm publish`, ...) are forbidden. Source code is not edited in this phase. Profile: [`prompts/profiles/release-handoff.md`](prompts/profiles/release-handoff.md).
|
|
196
197
|
- **Configurable PR body template** (release-handoff) — the PR body is filled from a markdown template chosen in priority order: per-run override (`--pr-template-path` or the okstra-run Step 6 prompt) → `<project_root>/.okstra/project.json` `prTemplatePath` → `~/.okstra/config.json` `prTemplatePath` → bundled skill default at `~/.claude/skills/templates/prd/pr-body.template.md`. Register a template with `okstra config set pr-template-path <path> [--scope project|global]` (project scope accepts paths relative to the project root; global scope requires absolute or `~/`-prefixed). `okstra config get pr-template-path --scope all` reports every scope plus the effective winner. The bundled default ships `## Summary` / `## Changes` / `## Test plan` / `## Linked issues` with HTML comment guidance that the lead strips before opening the PR.
|
|
197
198
|
- **Profile-roster worker validation** — `--workers <csv>` (and the okstra-run Step 6 worker prompt) are now restricted to the worker IDs declared by the chosen profile's `Required workers:` block. Asking for `codex` / `antigravity` on a profile that does not list them (e.g. `release-handoff`) is rejected with a clear error, and the interactive prompt only offers workers the profile actually accepts.
|
|
@@ -124,15 +124,15 @@ okstra wizard confirmation --state-file /tmp/okstra-wizard/state.json
|
|
|
124
124
|
|
|
125
125
|
`text`를 사용자에게 보여준 뒤 Proceed/Edit/중단 picker를 렌더한다. `Edit`은 wizard가 이전 step으로 rewind한다.
|
|
126
126
|
|
|
127
|
-
##
|
|
127
|
+
## outcome과 render-bundle
|
|
128
128
|
|
|
129
129
|
`next.kind == "done"`이면:
|
|
130
130
|
|
|
131
131
|
```bash
|
|
132
|
-
okstra wizard
|
|
132
|
+
okstra wizard outcome --state-file /tmp/okstra-wizard/state.json
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
`
|
|
135
|
+
`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
136
|
|
|
137
137
|
```bash
|
|
138
138
|
okstra render-bundle \
|
|
@@ -207,14 +207,16 @@ anchor가 unresolvable이면 `--reset-anchor <ref>`는 사용자 확인 후 실
|
|
|
207
207
|
|
|
208
208
|
## PR template persistence
|
|
209
209
|
|
|
210
|
-
release-handoff에서 `pr-template-path
|
|
210
|
+
release-handoff에서 `outcome.persistActions[]`가 `config.set` / `pr-template-path` action을 반환하면 render-bundle 전에 config를 저장한다.
|
|
211
211
|
|
|
212
212
|
```bash
|
|
213
|
+
# action.scope == "project"
|
|
213
214
|
okstra config set pr-template-path "<path>" --scope project
|
|
215
|
+
# action.scope == "global"
|
|
214
216
|
okstra config set pr-template-path "<path>" --scope global
|
|
215
217
|
```
|
|
216
218
|
|
|
217
|
-
scope는 wizard state file
|
|
219
|
+
scope와 path는 wizard state file이 아니라 `okstra wizard outcome`의 persist action에서 읽는다. raw state file을 직접 읽지 않는다.
|
|
218
220
|
|
|
219
221
|
## Claude lead 전환
|
|
220
222
|
|
package/docs/kr/architecture.md
CHANGED
|
@@ -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 (
|
|
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)
|
|
@@ -347,8 +347,8 @@ okstra phase 는 PRD / issue file 을 직접 쓰지 않습니다. 동등한 결
|
|
|
347
347
|
공통 제약:
|
|
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
|
-
- **모든 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-
|
|
351
|
-
- **implementation stage 격리 worktree (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 의 모델입니다. `implementation` task 는 **stage 격리** 로 동작합니다 — **한 run = 한 stage**, 각 run 이 `.../<task-id-segment>/stage-<N>/` (브랜치 `<
|
|
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 예약하고, 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,12 +378,12 @@ 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 +
|
|
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` 의
|
|
386
|
-
- worktree registry 는 stage-group 점유를 `<task-key>#group-<id>` 키로 예약하고, 수집 브랜치 이름은 `<work-category-
|
|
385
|
+
- 자격 판정의 SSOT 는 Stage Lifecycle Snapshot 입니다. Snapshot 은 `consumers.jsonl` 의 `verified`(어떤 stage 가 단독-stage final-verification 에서 accepted 됨), `pr`(어떤 stage 들이 어느 PR 로 나갔는지), done rows 를 읽어 `verified` 인데 아직 `pr` 에 안 들어간 stage 를 후보로 계산합니다.
|
|
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
|
|
|
389
389
|
### improvement-discovery (sidetrack entry-point)
|
|
@@ -645,18 +645,17 @@ Claude가 작성하는 최종 보고서는 아래 구조를 우선 사용합니
|
|
|
645
645
|
차이점이 실질적으로 없으면 억지로 대비를 만들지 말고, 차이가 없음을 명시합니다.
|
|
646
646
|
저장 실패나 세션 제한에 대한 메타 설명 대신 실제 Markdown 보고서 본문을 파일에 작성해야 합니다.
|
|
647
647
|
|
|
648
|
-
## Final report views (
|
|
648
|
+
## Final report views (HTML)
|
|
649
649
|
|
|
650
|
-
Phase 7 step 1.5 가 final-report MD 한 본을 입력으로
|
|
650
|
+
Phase 7 step 1.5 가 final-report MD 한 본을 입력으로 self-contained HTML view 를 결정론적으로 자동 생성합니다.
|
|
651
651
|
|
|
652
|
-
- `reports/final-report-<task-type>-<seq>.
|
|
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` (`
|
|
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` —
|
|
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 생성으로 인해 수정되지 않습니다.
|
package/docs/kr/cli.md
CHANGED
|
@@ -398,8 +398,8 @@ fallback 기본값은 아래와 같습니다.
|
|
|
398
398
|
- Claude/Codex/Antigravity 세 verifier 는 executor provider 와 관계없이 항상 dispatch 됩니다. Executor 와 같은 provider 라도 별도 CLI 세션으로 verifier 가 호출되어 context 가 분리되므로 self-review 안전장치는 유지됩니다.
|
|
399
399
|
- 실제 파일 변경은 Codex/Antigravity 의 경우 각 CLI 의 auto-edit 모드 (예: `codex exec --sandbox workspace-write`) 를 통해 일어나며, Claude-side Edit/Write tool 을 거치지 않습니다. implementation phase 에서 worker 가 mutation 을 수행하는 위치는 다음 항목에서 설명하는 task worktree 이며, 양쪽 wrapper(`scripts/okstra-codex-exec.sh`, `scripts/okstra-antigravity-exec.sh`) 는 worktree 경로를 4번째 positional 인자로 받아 codex 는 `--add-dir`, antigravity 는 `--include-directories` 로 forward 합니다. 누락하면 codex `workspace-write` 샌드박스가 worktree 쓰기를 EPERM 으로 거부합니다.
|
|
400
400
|
- **Claude executor 의 cwd 처리**: Claude Bash tool 은 per-call cwd 인자를 받지 않고 lead session 의 cwd 를 상속하므로, cwd 에 민감한 toolchain (`cargo`, `npm`, `pnpm`, `bun`, `pytest`, `make`, `go` 등) 을 worktree 안에서 실행하려면 호출을 `cd {{EXECUTOR_WORKTREE_PATH}} && <cmd>` 로 prefix 해야 합니다. 단일 Bash 호출 안에서 `cd` 가 leading token 으로 남아야 Claude Code 의 permission auto-allow 가 정상 동작하므로 `bash -lc "..."` / `bash -c "..."` 로 감싸지 않습니다 (감싸면 `cd` 가 가려져 매 호출마다 permission prompt 가 발생). `git -C <path>`, `cargo --manifest-path`, `pytest --rootdir` 처럼 작업 디렉터리 플래그를 받는 도구는 `cd && ` chain 대신 해당 플래그를 우선 사용합니다. Edit/Write/Read tool 은 이미 절대경로를 사용하므로 별도 cwd 처리가 필요 없습니다. 이 규칙은 Claude executor 에만 적용되고 codex / antigravity executor 는 CLI wrapper 가 cwd 를 주입합니다.
|
|
401
|
-
- **Task worktree (모든 task-type 자동 격리)**: 모든 task-type 의 첫 번째 phase prepare 단계에서 `okstra-ctl` 이 `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` 에 `git worktree` 를 생성하고, 브랜치 `<work-category-
|
|
402
|
-
- **implementation stage 격리 (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 에만 해당합니다. `implementation` task 의 각 run 은 **stage 별 격리 worktree** (`~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/stage-<N>/`, 브랜치 `<work-category-
|
|
401
|
+
- **Task worktree (모든 task-type 자동 격리)**: 모든 task-type 의 첫 번째 phase prepare 단계에서 `okstra-ctl` 이 `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/` 에 `git worktree` 를 생성하고, 브랜치 `<work-category-namespace>/<task-id-segment>` (예: `feature/dev-9436`, `fix/dev-7311`) 를 main worktree `HEAD` 에서 분기합니다. 같은 task-key 의 이후 phase 는 동일한 path/branch 를 재사용하므로 status 가 `reused` 로 기록됩니다 (run-prep 시점에 새 `git worktree add` 가 일어나지 않음). 모든 segment 의 `/`·`:` 등 특수문자는 `-` 로 정규화되며, `~/.okstra/worktrees/registry.json` 가 task-key → path/branch 매핑을 전역 관리합니다 (flock-guarded). Executor 의 Edit/Write/build/test/commit, verifier 의 read 는 모두 이 worktree 안에서 수행됩니다. caller 가 이미 다른 worktree 안에 있거나 project_root 가 git repo 가 아니면 provisioning 은 skip 되고 status 가 `skipped-in-worktree` / `skipped-not-git` 로 기록됩니다. 경로·브랜치 충돌은 `PrepareError` 로 즉시 실패시키며, run 종료 후 worktree 는 자동 삭제하지 않습니다 (수동: `git worktree remove` → `git branch -D` + registry 항목 삭제). **단, 아래 implementation stage 격리는 예외입니다.**
|
|
402
|
+
- **implementation stage 격리 (동시 병렬)**: 위 task-key 단위 worktree 는 `requirements-discovery`~`implementation-planning` 에만 해당합니다. `implementation` task 의 각 run 은 **stage 별 격리 worktree** (`~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/stage-<N>/`, 브랜치 `<work-category-namespace>/<task-id-segment>-s<N>`)에서 실행됩니다. registry 가 stage-key (`<task-key>#stage-<N>`) 를 flock 으로 원자 예약하고, `_resolve_effective_stages` 가 `consumers.jsonl` 의 `started` 행 + registry 예약 stage 를 제외하며, stage 선택부터 worktree 생성·registry 예약까지가 task-key 단위 프로비저닝 mutex(`~/.okstra/.locks/worktree-provision/`) 한 임계구역 안에서 수행되므로, 두 `implementation` run 을 동시에 띄우면 서로 다른 ready stage 를 안전하게 잡습니다 (**한 run = 한 stage**). stage worktree 의 base 는 의존 종류로 결정됩니다 — 독립(`depends-on (none)`) = 공통 anchor(첫 stage 진입 시 task-key worktree HEAD 1회 고정), 단일 의존(`depends-on X`) = 선행 stage 의 done `head_commit`, 다중 의존(`depends-on X,Y…`) = 선행들이 모두 머지된 task worktree HEAD(`git merge-base --is-ancestor` 로 검증, 미머지 시 `PrepareError` 로 머지 안내). 실행할 stage 는 `--stage <auto|N>` (`okstra.sh`/`render-bundle` 공통) 또는 okstra-run wizard 의 `stage_pick` 단계로 지정합니다. `project_root` 가 git repo 가 아니거나 nested worktree 면 stage 격리도 평면 동작으로 degrade 합니다.
|
|
403
403
|
- **단일-stage final-verification 산출물 격리**: `--task-type final-verification --stage <N>` 은 해당 implementation stage worktree 를 registry 에서 read-only 로 재사용하면서, run 산출물은 `runs/final-verification/stage-<N>/` 하위에 stage 별로 격리하고 팀 이름에 `-fv-s<N>` 접미사를 붙입니다. 서로 다른 stage 의 final-verification 을 동시에 띄워도 state·worker-results·팀이 충돌하지 않습니다 (같은 stage 를 동시에 두 번 띄우는 것은 격리되지 않음 — TeamCreate 이름 충돌로 즉시 실패). 전체-task 검증(stage 빈 값)은 평면 `runs/final-verification/` 를 유지합니다.
|
|
404
404
|
|
|
405
405
|
예:
|
|
@@ -637,7 +637,7 @@ chmod +x ~/.local/bin/okstra-ctl
|
|
|
637
637
|
| `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
638
|
| `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
639
|
| `okstra task-list [--project-root <path>]` | `list_project_tasks` + `read_latest_task` 결과를 합쳐 task 카탈로그 + 최근 task 를 JSON 으로 반환 |
|
|
640
|
-
| `okstra task-show <task-key> [--project-root <path>]` |
|
|
640
|
+
| `okstra task-show <task-key> [--project-root <path>]` | Task Read-Side Snapshot 기반 workflow / phase / status / artifact 요약 |
|
|
641
641
|
| `okstra worktree-lookup <task-key>` | `worktree_registry.lookup` 결과 (예약된 path / branch / base ref / 현재 상태) |
|
|
642
642
|
| `okstra plan-validate <plan-path>` | `_validate_approved_plan` — frontmatter `approved` 인식 결과와 Blocks=approval 미해결 행 진단 |
|
|
643
643
|
| `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 문서를 자동 생성한다 |
|
|
@@ -645,7 +645,7 @@ chmod +x ~/.local/bin/okstra-ctl
|
|
|
645
645
|
| `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
646
|
| `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
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)으로 진입합니다 |
|
|
648
|
+
| `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
649
|
| `okstra token-usage ...` | 설치된 `okstra-token-usage.py` 를 감싸 run token usage 수집/치환을 수행. 세션 jsonl 은 기본적으로 `$OKSTRA_HOME/cache/token-usage/` 의 byte cursor 캐시로 증분 스캔하며, `--no-cache` 로 캐시를 우회해 전체 재스캔을 강제할 수 있음(정확성 폴백) |
|
|
650
650
|
|
|
651
651
|
> 모든 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 (
|
|
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
|
|
@@ -157,7 +157,7 @@ Runtime/install asset changes follow this checklist:
|
|
|
157
157
|
| `git-reconcile` | `src/commands/execute/git-reconcile.mjs` | Reconcile stale stage SHAs after external git history changes |
|
|
158
158
|
| `handoff` | `src/commands/execute/handoff.mjs` | Stage-group release-handoff eligibility / assemble / record helpers |
|
|
159
159
|
| `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 |
|
|
160
|
+
| `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
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
162
|
| `time-report`, `log-report`, `error-report`, `error-zip` | `src/commands/inspect/*.mjs` | Read-side task runtime, wrapper log, and error aggregation helpers |
|
|
163
163
|
| `context-cost` | `src/commands/inspect/context-cost.mjs` | Estimate task bundle file/read context cost |
|
|
@@ -169,7 +169,7 @@ Runtime/install asset changes follow this checklist:
|
|
|
169
169
|
| `team` | `src/commands/execute/team.mjs` | External lead tmux-pane worker dispatch / await / teardown |
|
|
170
170
|
| `render-views` | `src/commands/report/render-views.mjs` | Generate slim MD + self-contained HTML report views |
|
|
171
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 |
|
|
172
|
-
| `wizard` | `src/commands/execute/wizard.mjs` | Drive the `okstra-run` interactive state machine |
|
|
172
|
+
| `wizard` | `src/commands/execute/wizard.mjs` | Drive the `okstra-run` interactive state machine, including the final outcome envelope |
|
|
173
173
|
| `token-usage` | `src/commands/execute/token-usage.mjs` | Wrap installed Python token usage CLI |
|
|
174
174
|
| `spawn-followups`, `error-log` | `src/commands/execute/*.mjs` | Follow-up task bundle creation and run error-log append helpers |
|
|
175
175
|
| `memory` | `src/commands/memory/memory.mjs` | Store/find global conversation memory under `~/.okstra/memory-book` |
|
|
@@ -193,7 +193,7 @@ Top-level scripts:
|
|
|
193
193
|
| `okstra-wrapper-status.py` | Heartbeat sidecar writer used by worker wrappers |
|
|
194
194
|
| `okstra-token-usage.py` | Token usage CLI entrypoint |
|
|
195
195
|
| `okstra-render-final-report.py` | Render final-report Markdown from data.json |
|
|
196
|
-
| `okstra-render-report-views.py` | Render
|
|
196
|
+
| `okstra-render-report-views.py` | Render self-contained HTML views from final-report Markdown |
|
|
197
197
|
| `okstra-error-log.py` | Normalize worker/lead error sidecars |
|
|
198
198
|
| `okstra-spawn-followups.py` | Follow-up spawning helper |
|
|
199
199
|
| `okstra-trace-cleanup.sh` | tmux okstra pane cleanup (worker-agent + trace, lead pane 제외); `--reclaim-completed` 모드는 `@okstra_status` 가 종료(stage=exited)인 trace pane 만 회수하고 진행 중 pane 은 보존 |
|
|
@@ -206,8 +206,8 @@ Important modules:
|
|
|
206
206
|
| Module | Role |
|
|
207
207
|
|---|---|
|
|
208
208
|
| `run.py` | `prepare_task_bundle()` single authority and CLI parser |
|
|
209
|
-
| `implementation_stage.py` | `implementation` 단일-stage run 오케스트레이션 —
|
|
210
|
-
| `stage_targets.py` | Stage readiness/verification 정책 SSOT — 어떤 stage 가 실행 가능한지, 어느 commit 에서 분기하는지, final-verification 이 무엇을 검사하는지
|
|
209
|
+
| `implementation_stage.py` | `implementation` 단일-stage run 오케스트레이션 — Stage Lifecycle Snapshot 읽기 → 가용 Stage Map entry 선택 → 격리 stage worktree provision → 선택 stage 를 run context 로 발행 (`run.py` 에서 추출) |
|
|
210
|
+
| `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
211
|
| `stage_reconcile.py` | stage prepare 흐름 공용 best-effort git reconciliation (`git_reconcile.auto_reconcile` 위임; advisory — 실패는 stderr 보고만, dependency gate 가 권위 판정 유지) |
|
|
212
212
|
| `run_context.py` | Per-task mutex, run context and run-input persistence; `consumers_mutex` helper for atomic `consumers.jsonl` writes |
|
|
213
213
|
| `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 +224,7 @@ Important modules:
|
|
|
224
224
|
| `md_table.py` | Markdown pipe-table escape/split SSOT — `mdcell` 필터(`escape_pipes`)와 `\|` 인식 `split_pipe_row`; renderer·HTML view·validators 공용 |
|
|
225
225
|
| `qa_commands.py` | QA command deny-list validation for plans |
|
|
226
226
|
| `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 →
|
|
227
|
+
| `report_views.py`, `render_final_report.py`, `final_report_schema.py` | Final-report data.json → Markdown → Report View Model → self-contained HTML pipeline |
|
|
228
228
|
| `final_report_paths.py`, `report_view_artifacts.py` | Final-report markdown/data.json 쌍 및 생성 view artifact(HTML view, user-responses 디렉터리) 경로 helper SSOT |
|
|
229
229
|
| `wizard.py` | `okstra-run` prompt state machine; user-facing Korean strings live in `prompts/wizard/prompts.ko.json` |
|
|
230
230
|
| `wizard_stage_intent.py` | `okstra-run` wizard 출력의 stage 관련 intent projection — whole-task(`__whole_task__`) vs 단일/멀티 stage 선택을 render-args 로 정규화 (`resolve_wizard_stage_intent`) |
|
|
@@ -253,7 +253,7 @@ Important modules:
|
|
|
253
253
|
Project resolver and read-only state helpers:
|
|
254
254
|
|
|
255
255
|
- `resolver.py`: locate project root and upsert `project.json`
|
|
256
|
-
- `state.py`: read project metadata, task catalog, task manifest
|
|
256
|
+
- `state.py`: read project metadata, task catalog, task manifest, and curated task read-side snapshots
|
|
257
257
|
|
|
258
258
|
### 4.5 `scripts/okstra_token_usage/`
|
|
259
259
|
|
|
@@ -360,10 +360,10 @@ Non-`implementation` phases share one task-key worktree:
|
|
|
360
360
|
~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
-
Branch name:
|
|
363
|
+
Branch name (namespace by work_category — `feature`/`improvement` → `feature/`, `bugfix` → `fix/`, `refactor` → `refactor/`, `ops` → `ops/`, unset → `task/`):
|
|
364
364
|
|
|
365
365
|
```text
|
|
366
|
-
<work-category-
|
|
366
|
+
<work-category-namespace>/<task-id-segment>
|
|
367
367
|
```
|
|
368
368
|
|
|
369
369
|
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.
|
|
@@ -372,7 +372,7 @@ That task-key worktree is reused for `requirements-discovery` through `implement
|
|
|
372
372
|
|
|
373
373
|
```text
|
|
374
374
|
~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>/stage-<N>/
|
|
375
|
-
<work-category-
|
|
375
|
+
<work-category-namespace>/<task-id-segment>-s<N>
|
|
376
376
|
```
|
|
377
377
|
|
|
378
378
|
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.
|
|
@@ -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,
|
|
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 |
|
|
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` |
|
|
@@ -79,8 +79,11 @@ sequenceDiagram
|
|
|
79
79
|
participant FS as .okstra
|
|
80
80
|
participant Home as ~/.okstra
|
|
81
81
|
|
|
82
|
-
Skill->>Node: okstra wizard
|
|
83
|
-
Node-->>Skill: {
|
|
82
|
+
Skill->>Node: okstra wizard outcome
|
|
83
|
+
Node-->>Skill: { renderArgs: ..., persistActions: ... }
|
|
84
|
+
opt persistActions present
|
|
85
|
+
Skill->>Node: okstra config set ...
|
|
86
|
+
end
|
|
84
87
|
Skill->>Node: okstra render-bundle --... --render-only
|
|
85
88
|
Node->>Py: python3 -m okstra_ctl.run --render-only --...
|
|
86
89
|
Py->>Py: validate profile, brief, task-type gates
|
|
@@ -128,7 +131,7 @@ flowchart TD
|
|
|
128
131
|
Runs --> Man[manifests/run-manifest-*.json]
|
|
129
132
|
Runs --> Prompts[prompts/*-worker-prompt-*.md]
|
|
130
133
|
Runs --> Results[worker-results/*.md]
|
|
131
|
-
Runs --> Reports[reports/final-report-*.md<br/>reports/*.data.json]
|
|
134
|
+
Runs --> Reports[reports/final-report-*.md<br/>reports/*.data.json<br/>reports/final-report-*.html]
|
|
132
135
|
Runs --> State[state/*.json]
|
|
133
136
|
Runs --> Status[status/final-status-*.json]
|
|
134
137
|
Runs --> ImplStage[implementation/stage-N/...]
|
|
@@ -138,7 +141,7 @@ flowchart TD
|
|
|
138
141
|
Root --> Handoff[release-handoff-input.md]
|
|
139
142
|
```
|
|
140
143
|
|
|
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`를 생성한다.
|
|
144
|
+
`implementation`과 단일-stage `final-verification`은 run 산출물을 `stage-<N>/` 아래에 격리한다. `implementation`의 carry sidecar와 `consumers.jsonl`은 stage 간 조율 ledger라 phase root에 남는다. runtime은 이 ledger와 registry 예약을 Stage Lifecycle Snapshot으로 읽어 stage 선택과 handoff eligibility를 계산한다. `release-handoff`는 brief를 받지 않고 prepare가 `release-handoff-input.md`를 생성한다.
|
|
142
145
|
|
|
143
146
|
`runtime/`은 build output이므로 이 흐름을 고칠 때는 source인 `scripts/`, `skills/`, `agents/`, `prompts/`, `templates/`, `validators/`를 수정하고 `npm run build`로 갱신한다.
|
|
144
147
|
|
|
@@ -164,7 +167,7 @@ flowchart TD
|
|
|
164
167
|
|
|
165
168
|
중요한 점은 `Use defaults`가 model 기본값을 뜻한다는 것이다. non-implementation task-type에서는 defaults를 골라도 worker roster 질문은 계속 나온다. 반대로 `implementation`은 worker override 질문이 없다. profile default roster와 executor binding을 사용한다.
|
|
166
169
|
|
|
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을 만든다.
|
|
170
|
+
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을 만든다. Stage Lifecycle Snapshot은 이 저장 구조를 변경하지 않는 read-side view다.
|
|
168
171
|
|
|
169
172
|
## 8. 주의할 불일치 지점
|
|
170
173
|
|
|
@@ -58,7 +58,7 @@ sequenceDiagram
|
|
|
58
58
|
P->>Plan: file exists?
|
|
59
59
|
P->>Plan: approval marker regex matches?
|
|
60
60
|
P->>Plan: unresolved Blocks=approval rows?
|
|
61
|
-
P->>Stage:
|
|
61
|
+
P->>Stage: build Stage Lifecycle Snapshot
|
|
62
62
|
P->>Reg: read active stage-key reservations
|
|
63
63
|
P->>Stage: select exactly one ready stage
|
|
64
64
|
P->>WT: provision stage-N worktree + branch
|
|
@@ -94,9 +94,8 @@ Executor만 project file을 mutate할 수 있다. verifier는 같은 worktree에
|
|
|
94
94
|
```mermaid
|
|
95
95
|
flowchart LR
|
|
96
96
|
Plan[approved plan<br/>Stage Map] --> Parse[parse stage map]
|
|
97
|
-
Parse -->
|
|
98
|
-
|
|
99
|
-
Reserved --> Resolve{stage arg}
|
|
97
|
+
Parse --> Snapshot[Stage Lifecycle Snapshot<br/>carry + consumers + reservations]
|
|
98
|
+
Snapshot --> Resolve{stage arg}
|
|
100
99
|
Resolve -->|auto| Next[lowest ready<br/>not done/started/reserved]
|
|
101
100
|
Resolve -->|number| Forced[selected stage]
|
|
102
101
|
Next --> Base[resolve stage base commit]
|
|
@@ -106,7 +105,7 @@ flowchart LR
|
|
|
106
105
|
Started --> Run[implementation executes one selected stage]
|
|
107
106
|
```
|
|
108
107
|
|
|
109
|
-
stage 선택은 `auto` 또는 숫자다. 다른 task-type에서 `--stage`가 오면 `PrepareError`다. runtime은 `consumers.jsonl`의 `done`/`started
|
|
108
|
+
stage 선택은 `auto` 또는 숫자다. 다른 task-type에서 `--stage`가 오면 `PrepareError`다. runtime은 Stage Lifecycle Snapshot에서 `consumers.jsonl`의 `done`/`started`, carry sidecar backfill, registry의 active stage-key를 함께 읽고 점유 stage를 제외한다. Snapshot은 새 저장 파일이 아니라 `stage_targets.py`의 read-side view다.
|
|
110
109
|
|
|
111
110
|
stage worktree base는 dependency 형태로 정한다. 독립 stage는 첫 implementation 진입 때 고정한 task-key worktree HEAD를 anchor로 삼고, 단일 의존 stage는 선행 stage의 done `head_commit`에서 분기한다. 다중 의존 stage는 모든 선행 done commit이 task-key worktree HEAD의 ancestor인지 확인한 뒤 그 HEAD에서 분기한다.
|
|
112
111
|
|
|
@@ -39,7 +39,7 @@ flowchart TD
|
|
|
39
39
|
Confirm --> Render[render-bundle]
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
`release-handoff`는 worker roster prompt가 없다. wizard의 `
|
|
42
|
+
`release-handoff`는 worker roster prompt가 없다. wizard outcome의 `renderArgs`는 `pr-template-path`를 release-handoff일 때만 포함하고, runtime은 worker list를 강제로 empty로 만든다. scope 선택은 prepare 전에 끝나며, project/global 저장은 `outcome.persistActions[]`의 `config.set pr-template-path` action으로 `render-bundle` 전에 실행된다. whole-task는 accepted whole-task verification report가 있어야 하고, stage-group은 Stage Lifecycle Snapshot에서 accepted single-stage verification으로 `verified` 처리됐지만 아직 `pr`로 덮이지 않은 stage만 후보가 된다.
|
|
43
43
|
|
|
44
44
|
주의할 점은 이 phase도 task worktree provisioning 대상이라는 것이다. 정상 흐름은 같은 task-key의 implementation/final-verification 결과를 재사용한다. 새 task로 시작하면 새 branch가 만들어질 수 있고, entry gate의 "implementation commit exists" 조건에서 막힐 가능성이 높다.
|
|
45
45
|
|
|
@@ -54,7 +54,7 @@ sequenceDiagram
|
|
|
54
54
|
participant FS as task artifacts
|
|
55
55
|
|
|
56
56
|
W->>P: task-type=release-handoff, approved-plan, stages csv, optional pr-template-path
|
|
57
|
-
P->>P: enforce stage eligibility (
|
|
57
|
+
P->>P: enforce stage eligibility (Stage Lifecycle Snapshot)
|
|
58
58
|
P->>FS: generate release-handoff-input.md (cited verification reports)
|
|
59
59
|
P->>P: force workers=[]
|
|
60
60
|
P->>T: resolve PR template
|
|
@@ -90,7 +90,7 @@ lead는 사용자에게 push/PR 여부를 묻기 전에 다음을 확인한다.
|
|
|
90
90
|
|
|
91
91
|
- prepare 가 생성한 input 문서(`release-handoff-input.md`)의 `## Source Verification Report` 가 모드(`HANDOFF_MODE`)와 인용 보고서 표를 담고 있다. brief 는 entry phase 의 입력물이라 release-handoff 에는 없다 — 사용자의 stage 선택은 wizard `handoff_stage_pick` 또는 CLI `--stages` 로 prepare 전에 끝난다.
|
|
92
92
|
- whole-task mode에서는 인용 report가 `verificationScope=whole-task`이고 `Verdict Token = accepted`여야 한다.
|
|
93
|
-
- stage-group mode에서는 인용된 각 single-stage report가 `Verdict Token = accepted`여야 하며, prepare/`okstra handoff assemble`이 eligibility와 dependency closure를 다시 강제한다.
|
|
93
|
+
- stage-group mode에서는 인용된 각 single-stage report가 `Verdict Token = accepted`여야 하며, prepare/`okstra handoff assemble`이 Stage Lifecycle Snapshot 기반 eligibility와 dependency closure를 다시 강제한다.
|
|
94
94
|
- working tree가 clean이다.
|
|
95
95
|
- 현재 branch가 `main`, `master`, `prod`, `preprod`, `staging`, `dev` 같은 base branch가 아니다.
|
|
96
96
|
- `<base>..HEAD` commit range가 비어 있지 않다.
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -136,6 +136,7 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Ant
|
|
|
136
136
|
- The assigned model execution value is canonical for CLI execution. Do not substitute a different Antigravity model unless the task bundle explicitly changes it.
|
|
137
137
|
- Pass the prompt received from Lead directly to agy after persisting the exact prompt to the assigned path.
|
|
138
138
|
- **Executor preflight forwarding check (implementation runs only).** When the lead prompt assigns this dispatch the `Executor` role for an `implementation` run, the persisted prompt body MUST contain the literal heading `Coding-conventions preflight` (the lead appends the body of `prompts/profiles/_coding-conventions-preflight.md` into the dispatch prompt — see `prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") — the Antigravity CLI does not share the lead's context, so an unforwarded gate never reaches the process that writes the code. If the heading is absent, return `ANTIGRAVITY_PREFLIGHT_MISSING: executor dispatch prompt lacks the coding-conventions preflight block` instead of invoking the CLI; the lead is responsible for re-dispatching with the block included. This check does NOT apply to verifier or analysis dispatches.
|
|
139
|
+
- **Executor post-write gate forwarding check (implementation runs only).** For the same reason — the Antigravity CLI does not share the lead's context — an `implementation` `Executor` dispatch prompt MUST also carry the two post-write gate bodies the lead appends after the preflight (via `codex_dispatch.py` `_implementation_executor_tail`): the persisted prompt body MUST contain BOTH the literal heading `Pre-commit diff review sweep` (from `prompts/profiles/_implementation-diff-review.md`) and the literal heading `Implementation self-check` (from `prompts/profiles/_implementation-self-check.md`). If either heading is absent, return `ANTIGRAVITY_POSTWRITE_GATE_MISSING: executor dispatch prompt lacks the post-write diff-review / self-check gate block` instead of invoking the CLI; the lead re-dispatches with both blocks included. This check does NOT apply to verifier or analysis dispatches.
|
|
139
140
|
- Include context (code, diff, file paths) if provided.
|
|
140
141
|
- For long prompts, dispatch through the wrapper with literal absolute paths (plus the worktree path for implementation phase):
|
|
141
142
|
```bash
|
|
@@ -136,6 +136,7 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Cod
|
|
|
136
136
|
- The assigned model execution value is canonical for CLI execution. Do not substitute a different Codex model unless the task bundle explicitly changes it.
|
|
137
137
|
- Pass the prompt received from Lead directly to codex after persisting the exact prompt to the assigned path.
|
|
138
138
|
- **Executor preflight forwarding check (implementation runs only).** When the lead prompt assigns this dispatch the `Executor` role for an `implementation` run, the persisted prompt body MUST contain the literal heading `Coding-conventions preflight` (the lead appends the body of `prompts/profiles/_coding-conventions-preflight.md` into the dispatch prompt — see `prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") — the Codex CLI does not share the lead's context, so an unforwarded gate never reaches the process that writes the code. If the heading is absent, return `CODEX_PREFLIGHT_MISSING: executor dispatch prompt lacks the coding-conventions preflight block` instead of invoking the CLI; the lead is responsible for re-dispatching with the block included. This check does NOT apply to verifier or analysis dispatches.
|
|
139
|
+
- **Executor post-write gate forwarding check (implementation runs only).** For the same reason — the Codex CLI does not share the lead's context — an `implementation` `Executor` dispatch prompt MUST also carry the two post-write gate bodies the lead appends after the preflight (via `codex_dispatch.py` `_implementation_executor_tail`): the persisted prompt body MUST contain BOTH the literal heading `Pre-commit diff review sweep` (from `prompts/profiles/_implementation-diff-review.md`) and the literal heading `Implementation self-check` (from `prompts/profiles/_implementation-self-check.md`). If either heading is absent, return `CODEX_POSTWRITE_GATE_MISSING: executor dispatch prompt lacks the post-write diff-review / self-check gate block` instead of invoking the CLI; the lead re-dispatches with both blocks included. This check does NOT apply to verifier or analysis dispatches.
|
|
139
140
|
- Include context (code, diff, file paths) if provided.
|
|
140
141
|
- For long prompts, dispatch through the wrapper with literal absolute paths (plus the worktree path for implementation phase):
|
|
141
142
|
```bash
|
|
@@ -656,12 +656,12 @@ The verdict tokens `AGREE` / `DISAGREE` / `SUPPLEMENT` are reused, but their mea
|
|
|
656
656
|
|
|
657
657
|
- **AGREE**: the item is executable as written *and* internally consistent with other items in the plan.
|
|
658
658
|
- **DISAGREE(<kind>)**: the item is broken. `<kind>` MUST be one of:
|
|
659
|
-
- `a` — referenced file path / symbol
|
|
660
|
-
- `b` — command is not executable or is ambiguous
|
|
659
|
+
- `a` — a concrete referenced file path / symbol **contradicts** a different concrete path / symbol for the same artifact in another step or option's File Structure list (a genuine mismatch between two spelled-out references). An abbreviated / ellipsis (`…`) / under-specified path is NOT kind `a` — it contradicts nothing, it is merely imprecise notation; classify it as `b`.
|
|
660
|
+
- `b` — a command **or a referenced path** is not executable or is ambiguous — including an abbreviated, ellipsis, or under-specified path that does not resolve as written
|
|
661
661
|
- `c` — validation signal is not observable
|
|
662
662
|
- `d` — rollback violates commit / dependency order
|
|
663
663
|
- `e` — item contradicts the trade-off matrix
|
|
664
|
-
- `f` — requirement coverage row cites no concrete option / stage / step, cites a non-existent option / stage / step, or marks a requirement `covered` while the cited plan item does not satisfy the row's stated requirement
|
|
664
|
+
- `f` — requirement coverage row cites no concrete option / stage / step, cites a non-existent option / stage / step, or marks a requirement `covered` while the cited plan item does not satisfy the row's stated requirement. A row that cites an existing option / stage / step is concrete for this purpose even if that option's File Structure paths are abbreviated — path imprecision inside the cited option is kind `b` on that option's own item, not `f` on the coverage row.
|
|
665
665
|
- **SUPPLEMENT**: the item is sound but is missing a dependency / edge case / precondition.
|
|
666
666
|
|
|
667
667
|
Worker non-result handling (`timeout`, `error`, no result file, wrapper `cli-failure`) is identical to finding convergence: do NOT aggregate as DISAGREE, record `contract-violation`, and apply the round-level abort rule below.
|
|
@@ -679,7 +679,7 @@ When `config.adversarial == true` (the default for `implementation-planning`; se
|
|
|
679
679
|
- The burden of proof sits on the plan: an item earns `AGREE` only if the verifier actively tried to break it and could not.
|
|
680
680
|
- The verifier MUST open the file paths / symbols / commands the item cites and confirm they exist and are executable as written. This is the one allowed widening of the lightweight "judge from internal consistency and stated commands / paths" rule — confirming the existence of cited paths is not "re-analyzing the original requirements".
|
|
681
681
|
- If a cited path / command / validation signal cannot be confirmed, the verifier responds `DISAGREE(<kind>)` with the applicable breakage kind (a–e); uncertainty resolves toward DISAGREE, not AGREE.
|
|
682
|
-
- **Single-vote-blocking kinds.** A single `DISAGREE` is approval-blocking on its own — no majority needed — when the breakage kind is `a` (cited path/symbol mismatch) or `d` (rollback violates commit/dependency order) on *any* plan item, or `f` (requirement-coverage mismatch) on a `P-Req-*` item. These defects are concrete, safety-critical, and adversarially verifiable (the verifier confirmed the cited path / order / requirement), so one correct dissent must not be outvoted. Each creates a `majority-disagree` classification and MUST become a `Blocks=approval` clarification row. Kinds `b` / `c` / `e` still need a majority — `b` especially is prone to planning-vs-implementation environment false positives. **Enforced:** `validators/validate-run.py` `_classify_plan_item_gate` (`_SINGLE_VOTE_BLOCKING_KINDS = {a, d}` + the P-Req `f` rule).
|
|
682
|
+
- **Single-vote-blocking kinds.** A single `DISAGREE` is approval-blocking on its own — no majority needed — when the breakage kind is `a` (cited path/symbol mismatch) or `d` (rollback violates commit/dependency order) on *any* plan item, or `f` (requirement-coverage mismatch) on a `P-Req-*` item. These defects are concrete, safety-critical, and adversarially verifiable (the verifier confirmed the cited path / order / requirement), so one correct dissent must not be outvoted. Each creates a `majority-disagree` classification and MUST become a `Blocks=approval` clarification row. Kinds `b` / `c` / `e` still need a majority — `b` especially is prone to planning-vs-implementation environment false positives. Because `a` is reserved for a concrete contradiction between two spelled-out references (see §"Plan-body verdict semantics"), an abbreviated / ellipsis / under-specified path is raised as `b` (majority-gated), never `a` — a lone "this path is abbreviated" dissent must not single-vote-block on notation alone, and it is especially not blocking on a *rejected* option that will never be implemented. **Enforced:** `validators/validate-run.py` `_classify_plan_item_gate` (`_SINGLE_VOTE_BLOCKING_KINDS = {a, d}` + the P-Req `f` rule).
|
|
683
683
|
|
|
684
684
|
Plan-body verification stays **lightweight** even under this posture — the `verificationMode = "full-reanalysis"` forcing in §"Adversarial Verification Mode" applies to finding convergence only (see §"Mode constraint"); the adversarial posture here only changes verifier behaviour, not the mode. This raises verification *quality* (active refutation, plan-side burden). The gate *threshold* stays majority-based for the majority-gated kinds (`b`/`c`/`e`), with the single-vote-blocking exception above for the concrete, safety-critical kinds (`a`/`d`, and `f` on P-Req). A majority requires at least two participating (non-error) votes, so a lone surviving `DISAGREE` whose peer returned a non-result does NOT block on a majority-gated kind — a worker failure must not make the gate stricter than a healthy roster would.
|
|
685
685
|
|
|
@@ -767,12 +767,12 @@ verdict:
|
|
|
767
767
|
- **AGREE**: The item is executable as written and internally consistent with
|
|
768
768
|
other items in the plan.
|
|
769
769
|
- **DISAGREE(<kind>)**: The item is broken. Cite which kind:
|
|
770
|
-
(a) referenced file path / symbol
|
|
771
|
-
(b) command is not executable or is ambiguous,
|
|
770
|
+
(a) a concrete referenced file path / symbol contradicts a different concrete path / symbol for the same artifact elsewhere — a genuine mismatch; an abbreviated / ellipsis path is NOT (a), use (b),
|
|
771
|
+
(b) command or referenced path is not executable or is ambiguous — including an abbreviated / ellipsis / under-specified path that does not resolve as written,
|
|
772
772
|
(c) validation signal is not observable,
|
|
773
773
|
(d) rollback violates commit / dependency order,
|
|
774
774
|
(e) item contradicts the trade-off matrix,
|
|
775
|
-
(f) requirement coverage row does not
|
|
775
|
+
(f) requirement coverage row does not map the stated requirement to a concrete satisfying option / stage / step — citing an existing option counts as concrete even if that option's paths are abbreviated (that is (b) on the option's item, not (f)).
|
|
776
776
|
- **SUPPLEMENT**: The item is sound but a dependency / edge case / precondition
|
|
777
777
|
is missing.
|
|
778
778
|
|
|
@@ -104,7 +104,7 @@ profile document.
|
|
|
104
104
|
The labels `Ticket:` / `Kind:` / `Blocks:` / `Status:` stay English in every locale so the approval-gate parser (`clarification_items.parse_meta_cell`) reads them regardless of report language.
|
|
105
105
|
Profile-specific addenda may tighten cell content but MUST NOT add, remove, rename, or reorder columns, nor change the meta-cell field order. The `ID` is `C-NNN` (3-digit zero-padded), the `Status` ∈ `{open, answered, resolved, obsolete}`, and the `Kind` / `Blocks` legal values are listed below.
|
|
106
106
|
- section 1 is a **single unified table** per `final-report-template.md`. Every clarification item — whether the user must attach a file, choose between options, or supply a single number/path — is one row of that table. Do not split it into sub-sections (`1.1 추가 자료 요청` / `1.2 사용자 확인 질문` / `5.5.9 Open Questions` are removed and the validator fails reports that reintroduce them), do not create a parallel table elsewhere in the report, and do not duplicate the same item into an approval block or any other section.
|
|
107
|
-
- each row's `Kind` column picks one of `{material, decision, data-point}`: `material` for files / snapshots / logs / screenshots the user must attach (the `User input` cell will hold a path or URL); `decision` for choices and yes/no confirmations only the user can make; `data-point` for a single number, ID, date, or short string the user can answer inline. Items that mix "yes/no + file path if yes" are one row of `Kind=material` with the combined expectation written into `Expected form`.
|
|
107
|
+
- each row's `Kind` column picks one of `{material, decision, data-point}`: `material` for files / snapshots / logs / screenshots the user must attach (the `User input` cell will hold a path or URL); `decision` for choices and yes/no confirmations only the user can make; `data-point` for a single number, ID, date, or short string the user can answer inline. A `decision` alternative must be a terminal choice the user can pick as-is; if acting on an alternative still requires the user to supply a concrete value (a path, string, number, or file), that value is its own `data-point` / `material` row — never phrase a data-entry action (e.g. "경로 구체화", "값 입력") as a selectable `decision` option, because the rendered `<select>` cannot capture the value the option demands. Items that mix "yes/no + file path if yes" are one row of `Kind=material` with the combined expectation written into `Expected form`.
|
|
108
108
|
- each row's `Blocks` column picks one of `{approval, next-phase, none}`. `approval` is reserved for items that gate an approval action, especially the `implementation-planning` `approved:` frontmatter flip; outside `implementation-planning`, unresolved brief reporter-confirmation rows use `next-phase` instead. `next-phase` blocks the next run from starting cleanly. `none` is informational/audit-only.
|
|
109
109
|
- write every entry in full, descriptive sentences that a non-developer can act on without further context. Avoid abbreviations and internal jargon. The `Statement` cell must state *what* is needed, *why* the answer / attachment changes the next step, and (for `material`) *where* the user can find it and *where* to place it. The `Expected form` cell must state the answer shape (예/아니오, 보기 중 하나, 숫자/날짜, 파일 경로, 짧은 서술 등); supply concrete option choices when applicable.
|
|
110
110
|
- if a phase requires a recommended answer, alternatives, or an evidence-check note, encode it inside the existing 4-column schema: put evidence notes in `Statement` as `Evidence checked: <path:line>` or `Evidence checked: none — <human-only reason>`, and put recommendations/options in `Expected form` as `Recommended: <answer> — <rationale>; Alternatives: <options>`. When there is more than one alternative, enumerate them as `(a) … (b) …` so each renders as its own selectable option; a single alternative may be written plainly. Do **not** append a pick-one answer-space summary such as `(A / B 중 택1)` or `(… 중 택N)` to `<options>` — the rendered `<select>` already enforces single choice, and that annotation leaks verbatim into an option label. Do not add `Recommended`, `Evidence`, `Alternatives`, or `evidence-checked` columns, and do not break the merged record-meta cell back into separate columns.
|