okstra 0.88.0 → 0.88.1

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
@@ -21,7 +21,7 @@
21
21
 
22
22
  ## 1. 용도
23
23
 
24
- `okstra` 는 **Claude Code 안에서 lead + worker 모델로 작업을 cross-verify 하기 위한 정형화된 task 실행 러너**입니다. Claude lead 가 phase 진행을 주도하고, 독립된 분석 worker — **기본 Claude · Codex** (Gemini 는 옵션으로 명시할 때만 추가) — 와 최종 보고서 작성을 전담하는 report-writer 를 dispatch 합니다.
24
+ `okstra` 는 **Claude Code 안에서 lead + worker 모델로 작업을 cross-verify 하기 위한 정형화된 task 실행 러너**입니다. Claude lead 가 phase 진행을 주도하고, 독립된 분석 worker — **기본 Claude · Codex** (Antigravity 는 옵션으로 명시할 때만 추가) — 와 최종 보고서 작성을 전담하는 report-writer 를 dispatch 합니다.
25
25
 
26
26
  설계의 세 가지 원칙:
27
27
 
@@ -61,7 +61,7 @@ okstra/ npm 패키지 = repo 루트
61
61
  ~/.okstra/ 런타임 홈, `okstra install` 이 생성
62
62
  ├── version 패키지 버전 stamp
63
63
  ├── lib/python/ okstra_project/, okstra_ctl/, okstra_token_usage/, lib/
64
- ├── bin/ okstra.sh, codex-exec, gemini-exec, ...
64
+ ├── bin/ okstra.sh, codex-exec, antigravity-exec, ...
65
65
  ├── templates/ report asset, settings template
66
66
  ├── prompts/ lead 운영 계약(prompts/lead/*) + coding-preflight 리소스 팩
67
67
  ├── installed-runtimes.json 설치된 runtime adapter 매니페스트
@@ -81,7 +81,7 @@ okstra/ npm 패키지 = repo 루트
81
81
  └── okstra-*/SKILL.md 사용자 노출 스킬 6종만 (setup/brief/run/memory/inspect/schedule)
82
82
 
83
83
  ~/.claude/agents/ Claude Code 가 자동 인식 (`~/.claude` 가 있을 때)
84
- └── {claude,codex,gemini,report-writer}-worker.md worker subagent 정의
84
+ └── {claude,codex,antigravity,report-writer}-worker.md worker subagent 정의
85
85
  (Claude Code multi-agent dispatch 필수)
86
86
 
87
87
  <프로젝트 루트>/.okstra/
@@ -185,7 +185,7 @@ Claude Code 세션 밖에서 task 를 시작하려면:
185
185
 
186
186
  0.7.0 / 0.8.0 에서 추가된 주요 플래그:
187
187
 
188
- - `--executor claude|codex|gemini` — `--task-type implementation` 에서 파일을 mutate 할 provider 를 선택합니다. 나머지 두 provider 는 같은 run 에서 strict read-only verifier 로 dispatch 됩니다 ([`docs/kr/cli.md`](docs/kr/cli.md#--executor)).
188
+ - `--executor claude|codex|antigravity` — `--task-type implementation` 에서 파일을 mutate 할 provider 를 선택합니다. 나머지 두 provider 는 같은 run 에서 strict read-only verifier 로 dispatch 됩니다 ([`docs/kr/cli.md`](docs/kr/cli.md#--executor)).
189
189
  - `--work-category bugfix|feature|refactor|ops|improvement` — `requirements-discovery` phase 를 건너뛰는 경우 작업 분류를 직접 지정합니다.
190
190
  - `--approve` — `--approved-plan` 과 함께 사용하면 plan 의 YAML frontmatter `approved` field 를 `false` → `true` 로 toggle 합니다 (제거된 `--ack-approved` alias 와 구 `[ ] Approved` 체크박스 마커 대체).
191
191
 
@@ -194,8 +194,8 @@ Claude Code 세션 밖에서 task 를 시작하려면:
194
194
  - **모든 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-prefix>-<task-id-segment>` (예: `feat-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(브랜치 `<prefix>-<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/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md`](docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md), [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
195
195
  - **`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).
196
196
  - **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 가 주석을 제거합니다.
197
- - **프로파일 워커 로스터 검증** — `--workers <csv>` 와 okstra-run Step 6 의 워커 prompt 는 해당 프로파일의 `Required workers:` 블록에 선언된 워커 ID 만 허용합니다. 프로파일에 없는 워커 (예: `release-handoff` 에서 `codex` / `gemini`) 를 요청하면 명확한 에러로 거절되고, 인터랙티브 prompt 도 프로파일이 실제로 받는 워커만 보여줍니다.
198
- - **실험적 Codex lead adapter** — `okstra codex-run <render-bundle args...>` 가 Claude Code 를 띄우지 않고 `leadRuntime=codex` task bundle 을 준비합니다. 이어서 `okstra codex-dispatch --project-root <dir> --run-manifest <path>` 로 roster 중 Codex-side 지원 subset 을 실행합니다(Codex/Gemini CLI worker 기본, Codex report-writer 는 `--enable-codex-report-writer --report-writer-codex-model <model>` opt-in 필요). 성공한 Codex report-writer dispatch 는 token/cost substitution, HTML view 렌더, follow-up stub 생성, run validation 을 순서대로 자동 실행합니다. Claude lead 경로와 같은 manifest/schema 를 공유하며, 프로젝트를 Codex 전용 fork 로 복제하지 않습니다.
197
+ - **프로파일 워커 로스터 검증** — `--workers <csv>` 와 okstra-run Step 6 의 워커 prompt 는 해당 프로파일의 `Required workers:` 블록에 선언된 워커 ID 만 허용합니다. 프로파일에 없는 워커 (예: `release-handoff` 에서 `codex` / `antigravity`) 를 요청하면 명확한 에러로 거절되고, 인터랙티브 prompt 도 프로파일이 실제로 받는 워커만 보여줍니다.
198
+ - **실험적 Codex lead adapter** — `okstra codex-run <render-bundle args...>` 가 Claude Code 를 띄우지 않고 `leadRuntime=codex` task bundle 을 준비합니다. 이어서 `okstra codex-dispatch --project-root <dir> --run-manifest <path>` 로 roster 중 Codex-side 지원 subset 을 실행합니다(Codex/Antigravity CLI worker 기본, Codex report-writer 는 `--enable-codex-report-writer --report-writer-codex-model <model>` opt-in 필요). 성공한 Codex report-writer dispatch 는 token/cost substitution, HTML view 렌더, follow-up stub 생성, run validation 을 순서대로 자동 실행합니다. Claude lead 경로와 같은 manifest/schema 를 공유하며, 프로젝트를 Codex 전용 fork 로 복제하지 않습니다.
199
199
  - **다단계 `implementation-planning` / `implementation`** — `implementation-planning` 은 항상 Stage Map + N 개 stage 섹션으로 산출합니다. 각 stage 의 step 은 ≤ 6 이며 `depends-on (none)` 인 stage 들은 별도 `implementation` run 으로 병렬 실행할 수 있습니다. 각 `implementation` 호출은 한 stage 만 실행하고 (`--stage <auto|N>`), 자동 생성되는 evidence sidecar (`carry/stage-<N>.json`) 가 다음 stage 의 carry-in 으로 흡수됩니다. `implementation-planning` run 디렉터리에 `consumers.jsonl` 역링크가 누적되어 어느 run 이 어느 stage 를 소비했는지 추적됩니다.
200
200
  - **Phase 6 plan-body verification (implementation-planning 전용)** — Report writer worker 가 final-report draft 를 작성한 직후, 사용자 승인 gate 직전에 lead 가 1 라운드의 사후 검증을 추가로 돌립니다. 합성된 `## 5.5` implementation plan deliverables 본문에서 `P-Opt-*` / `P-Step-*` / `P-Dep-*` / `P-Val-*` / `P-Rb-*` plan-item 을 추출해 모든 analyser 워커에게 `AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT` 평결을 요청합니다. 집계된 gate 결과는 `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result` 중 하나입니다. frontmatter `approved` 필드는 항상 `false` 로 발행되며, blocking gate 결과는 이를 false 로 유지하고 `## 1. Clarification Items` row 로 변환합니다. 빠른 반복용 opt-out 은 `--no-plan-verification` 입니다. 세부 계약: [`prompts/lead/convergence.md`](prompts/lead/convergence.md) "Plan-body verification mode", [`docs/kr/cli.md#--no-plan-verification`](docs/kr/cli.md#--no-plan-verification).
201
201
  - **Brief = translation layer + Step 6.5 reporter batch confirmation** — `okstra-brief` 가 외부 입력 (이슈 ticket, 요구사항 문서, 사용자 메시지) 을 verbatim 으로 옮기되 okstra 가 추가한 부분은 labelled augmentation 으로 구분하는 translation layer 가 됐습니다. Step 6.5 가 brief 가 옮기는 과정에서 의미 변화가 발생했는지 사용자에게 일괄 확인받아 `Reporter Confirmations` 섹션에 기록하고, 모든 분석 profile 은 이 섹션의 존재를 phase 분석 진입 precondition 으로 강제합니다 (validator: `validators/validate-brief.py`).
package/README.md CHANGED
@@ -21,7 +21,7 @@
21
21
 
22
22
  ## 1. Purpose
23
23
 
24
- `okstra` is a **structured task-execution runner for Claude Code that cross-verifies work with a lead + worker model**. The Claude lead drives phase progression and dispatches independent analysis workers — **Claude and Codex by default** (with **Gemini** available as an opt-in extra) — plus a dedicated report-writer for the final synthesis.
24
+ `okstra` is a **structured task-execution runner for Claude Code that cross-verifies work with a lead + worker model**. The Claude lead drives phase progression and dispatches independent analysis workers — **Claude and Codex by default** (with **Antigravity** available as an opt-in extra) — plus a dedicated report-writer for the final synthesis.
25
25
 
26
26
  The design rests on three principles:
27
27
 
@@ -60,7 +60,7 @@ okstra/ npm package = repo root
60
60
  ~/.okstra/ runtime home, populated by `okstra install`
61
61
  ├── version package version stamp
62
62
  ├── lib/python/ okstra_project/, okstra_ctl/, okstra_token_usage/, lib/
63
- ├── bin/ okstra.sh, codex-exec, gemini-exec, ...
63
+ ├── bin/ okstra.sh, codex-exec, antigravity-exec, ...
64
64
  ├── templates/ report assets, settings template
65
65
  ├── installed-runtimes.json manifest of installed runtime adapters
66
66
  ├── installed-skills.json manifest of installed skills (used by uninstall)
@@ -79,7 +79,7 @@ okstra/ npm package = repo root
79
79
  └── okstra-*/SKILL.md user-facing skills only (setup/brief/run/memory/inspect/schedule)
80
80
 
81
81
  ~/.claude/agents/ discovered automatically by Claude Code (if ~/.claude exists)
82
- └── {claude,codex,gemini,report-writer}-worker.md subagent definitions
82
+ └── {claude,codex,antigravity,report-writer}-worker.md subagent definitions
83
83
  (required for Claude Code multi-agent dispatch)
84
84
 
85
85
  <project-root>/.okstra/
@@ -183,7 +183,7 @@ Spawns a fresh `claude` process and hands it the lead role. Full argument list:
183
183
 
184
184
  Notable flags added in 0.7.0 / 0.8.0:
185
185
 
186
- - `--executor claude|codex|gemini` — pick the provider that mutates files during `--task-type implementation`. The other two providers are still dispatched as read-only verifiers (see [`docs/kr/cli.md`](docs/kr/cli.md#--executor)).
186
+ - `--executor claude|codex|antigravity` — pick the provider that mutates files during `--task-type implementation`. The other two providers are still dispatched as read-only verifiers (see [`docs/kr/cli.md`](docs/kr/cli.md#--executor)).
187
187
  - `--work-category bugfix|feature|refactor|ops|improvement` — classify a task when the lifecycle skips `requirements-discovery`.
188
188
  - `--approve` — combined with `--approved-plan`, flips the plan's YAML frontmatter `approved` field from `false` to `true` (replaces the removed `--ack-approved` alias and the older `[ ] Approved` checkbox marker).
189
189
 
@@ -192,8 +192,8 @@ Recent workflow additions (post-0.8.0, on `main`):
192
192
  - **Isolated task worktree for every task-type** — prepare automatically runs `git worktree add ~/.okstra/worktrees/<project>/<group>/<task>/` on a fresh branch `<work-category-prefix>-<task-id-segment>` 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 `<prefix>-<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), [`docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md`](docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md), and [`docs/kr/cli.md#--executor`](docs/kr/cli.md#--executor).
193
193
  - **`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).
194
194
  - **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.
195
- - **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` / `gemini` 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.
196
- - **Experimental Codex lead adapter** — `okstra codex-run <render-bundle args...>` prepares a `leadRuntime=codex` task bundle without launching Claude Code. `okstra codex-dispatch --project-root <dir> --run-manifest <path>` can then run the supported Codex-side subset of the roster (Codex/Gemini CLI workers by default; Codex report-writer only with `--enable-codex-report-writer --report-writer-codex-model <model>`). Successful Codex report-writer dispatch runs token/cost substitution, HTML view rendering, follow-up stub generation, and run validation in order. This shares the same manifests/schemas as the Claude lead path; it does not clone the project into a separate Codex-specific fork.
195
+ - **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.
196
+ - **Experimental Codex lead adapter** — `okstra codex-run <render-bundle args...>` prepares a `leadRuntime=codex` task bundle without launching Claude Code. `okstra codex-dispatch --project-root <dir> --run-manifest <path>` can then run the supported Codex-side subset of the roster (Codex/Antigravity CLI workers by default; Codex report-writer only with `--enable-codex-report-writer --report-writer-codex-model <model>`). Successful Codex report-writer dispatch runs token/cost substitution, HTML view rendering, follow-up stub generation, and run validation in order. This shares the same manifests/schemas as the Claude lead path; it does not clone the project into a separate Codex-specific fork.
197
197
  - **Multi-stage `implementation-planning` / `implementation`** — `implementation-planning` always produces a Stage Map plus N stage sections; each stage has ≤6 steps and stages whose `depends-on (none)` can be executed in parallel by separate `implementation` runs. Each `implementation` invocation picks one stage (via `--stage <auto|N>`) and emits an evidence sidecar (`carry/stage-<N>.json`) that the next stage automatically inherits. The `implementation-planning` run directory accumulates a `consumers.jsonl` reverse-link showing which `implementation` runs consumed which stage.
198
198
  - **Phase 6 plan-body verification (implementation-planning only)** — after the Report writer worker authors the final-report draft and before the user approval gate, the lead runs one additional verification round: it extracts `P-Opt-*` / `P-Step-*` / `P-Dep-*` / `P-Val-*` / `P-Rb-*` items from the consolidated `## 5.5` implementation plan deliverables body and dispatches them to every analyser worker as `AGREE` / `DISAGREE(a-e)` / `SUPPLEMENT`. The aggregated gate result is one of `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result`. The frontmatter `approved` flag is always emitted as `false`; blocking gate results keep it false and become `## 1. Clarification Items` rows. Details: [`prompts/lead/convergence.md`](prompts/lead/convergence.md) "Plan-body verification mode" and [`docs/kr/cli.md#--no-plan-verification`](docs/kr/cli.md#--no-plan-verification).
199
199
  - **Brief as translation layer + reporter batch confirmation (Step 6.5)** — `okstra-brief` now produces the brief as a translation layer that preserves external inputs (issue ticket, requirements doc, user message) verbatim while labelling okstra augmentations. A new Step 6.5 walks the user through a single batch confirmation of any rewordings, recorded in a `Reporter Confirmations` section. Every analysis profile blocks phase entry until this section exists (validator: `validators/validate-brief.py`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.88.0",
3
+ "version": "0.88.1",
4
4
  "description": "Multi-agent cross-verification orchestrator runtime + Claude Code skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.88.0",
3
- "builtAt": "2026-06-16T20:19:47.032Z",
2
+ "package": "0.88.1",
3
+ "builtAt": "2026-06-17T05:43:28.195Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -14,6 +14,7 @@ are collected and convergence finished. Phase 1-5 do not need it.
14
14
  - **Commit list**: each commit's SHA (or short SHA), message, and the plan step it satisfies
15
15
  - **Diff summary**: `git diff --stat <base>..HEAD` output, plus a per-file one-line summary of changes
16
16
  - **Out-of-plan edits block**: every file edited that was not in the approved plan's file list, with rationale (empty block is acceptable and preferred)
17
+ - **Clarification answers carried in**: when `instruction-set/clarification-response.md` exists, it holds the user's answers to the approved plan's `## 1. Clarification Items` rows (the `# Attached User Responses` the planning HTML form exported as `user-responses/` sidecars). The report MUST render the `## 0. Clarification Response Carried In From Previous Run` section (set `clarificationCarryIn.sourceFile` to that path) and, for every carried-over `## 1.` row whose answer appears there, fold the answer into the row (record it in the `User input` cell and flip `Status` to `resolved`). A row left `open`/`answered` despite a matching user answer is a contract violation; an answer that materially changes scope beyond the approved plan is routed to a new `implementation-planning` run, not silently executed.
17
18
  - **Stage sidecar evidence**: the JSON payload of `runs/<impl-task-key>/carry/stage-<N>.json` is embedded verbatim in a fenced ```json``` block, AND the `consumers.jsonl` rows this run appended are quoted line-by-line, so reviewers can audit the carry surface without grepping artifact directories.
18
19
  - **Validation evidence**: actual command output (stdout/stderr) for every `pre / mid / post` validation command from the plan. Truncated output is acceptable but the command line and exit code MUST be exact. No paraphrasing of test results.
19
20
  - **TDD evidence (when applicable)**: for steps that should be TDD-ordered, show the failing-test output BEFORE the implementation commit and the passing-test output AFTER, with commit SHAs framing the transition.
@@ -33,6 +33,7 @@ until Phase 5 ends, then drop from active context for Phase 6/7.
33
33
  - re-read the approved plan end-to-end and parse the `## 5.5 Stage Map`. Read the **Stage** injected in the launch prompt (`Stage for this implementation run`): the single stage number this run owns. The runtime already selected and reserved this stage (one run = one stage) — do NOT recompute the start stage from `consumers.jsonl`.
34
34
  - load every `runs/<plan-key>/carry/stage-<i>.json` for `i ∈ depends-on(this stage)` and inject them into the executor's working context as "runtime carry-in". For a `depends-on (none)` stage, no sidecar load — task-brief only.
35
35
  - this stage's `depends-on` are all already `status:done`. Its file list, step order, Stage Validation commands, Stage Exit Contract, and rollback path are the authoritative scope.
36
+ - **Clarification answers carried in (read before the first edit):** when `instruction-set/clarification-response.md` exists, it carries the user's answers to the approved plan's `## 1. Clarification Items` rows (the planning HTML form's `# Attached User Responses`). Treat each answer as an authoritative refinement of the plan's scope for the matching row; an answer that contradicts or expands the approved scope beyond the plan is a re-plan trigger (route to a new `implementation-planning` run), not a silent in-run change. **CLI executor (codex/antigravity):** that file sits outside the CLI sandbox, so the lead MUST transcribe its body into the dispatched executor prompt at dispatch time (same rule as the preflight / stage-discipline transcription above) — a path reference never reaches the CLI process.
36
37
  - inspect the current state of every file the plan names; if any file has changed materially since the plan was written, stop and route to a new `implementation-planning` run instead of editing speculatively
37
38
  - "materially changed" means: the function, class, section, or behaviour the plan targets has been edited, renamed, moved, removed, or otherwise altered in a way that invalidates the plan's reasoning. Cosmetic edits (whitespace, comment-only changes, unrelated function modifications elsewhere in the same file) do NOT trigger a re-plan; cite the diff (`git log --oneline <plan-created-at>..HEAD -- <file>`) in the final report and proceed.
38
39
  - distinguish the two file-scope rules (they are not in conflict):
@@ -302,20 +302,35 @@ def user_response_sidecars(source: Path) -> list[Path]:
302
302
  )
303
303
 
304
304
 
305
- def clarification_response_with_sidecars(source: Path) -> str:
306
- """clarification-response 원문 뒤에 `user-responses/` 사이드카를 덧붙인 본문.
307
-
308
- 사이드카 부재 시 원문 그대로 — 호출자는 항상 이 함수를 거쳐 instruction-set
309
- 사본을 쓰면 된다.
305
+ def attached_user_responses_section(source: Path) -> str:
306
+ """`source` 형제 `user-responses/` 사이드카만 모은 `# Attached User Responses`
307
+ 섹션 본문. 사이드카 부재 시 빈 문자열.
308
+
309
+ plan 본문이 이미 별도 경로(`--approved-plan`)로 참조되는 implementation
310
+ carry-in 에서, 원문을 중복 복사하지 않고 사용자 답변만 instruction-set 에
311
+ 첨부할 때 쓴다. `clarification_response_with_sidecars` 와 같은 직렬화 포맷을
312
+ 한 곳에서 만들어 두 carry-in 경로가 갈라지지 않게 한다.
310
313
  """
311
- text = source.read_text(encoding="utf-8")
312
314
  sidecars = user_response_sidecars(source)
313
315
  if not sidecars:
314
- return text
315
- parts = [text.rstrip("\n"), "\n\n---\n\n# Attached User Responses\n"]
316
+ return ""
317
+ parts = ["# Attached User Responses\n"]
316
318
  for sidecar in sidecars:
317
319
  parts.append(
318
320
  f"\n## {sidecar.name}\n\n"
319
321
  f"{sidecar.read_text(encoding='utf-8').strip()}\n"
320
322
  )
321
323
  return "".join(parts)
324
+
325
+
326
+ def clarification_response_with_sidecars(source: Path) -> str:
327
+ """clarification-response 원문 뒤에 `user-responses/` 사이드카를 덧붙인 본문.
328
+
329
+ 사이드카 부재 시 원문 그대로 — 호출자는 항상 이 함수를 거쳐 instruction-set
330
+ 사본을 쓰면 된다.
331
+ """
332
+ text = source.read_text(encoding="utf-8")
333
+ section = attached_user_responses_section(source)
334
+ if not section:
335
+ return text
336
+ return text.rstrip("\n") + "\n\n---\n\n" + section
@@ -73,7 +73,10 @@ from .md_table import is_separator_row as _is_separator_row
73
73
  _BLANK_PATTERN = re.compile(r"^\s*$")
74
74
 
75
75
  _HEADING_PATTERN = re.compile(r"^(#{1,6})\s+(.*?)\s*$")
76
- _CODEFENCE_PATTERN = re.compile(r"^```(.*)$")
76
+ # Leading whitespace is captured so fences nested in a list item (e.g.
77
+ # §5.7.5's carry sidecar JSON, indented 2 spaces) are recognised and the
78
+ # code lines can be dedented before rendering.
79
+ _CODEFENCE_PATTERN = re.compile(r"^(\s*)```(.*)$")
77
80
  _LIST_BULLET_PATTERN = re.compile(r"^(\s*)[-*]\s+(.*)$")
78
81
  _LIST_NUMBERED_PATTERN = re.compile(r"^(\s*)(\d+)\.\s+(.*)$")
79
82
  _INLINE_CODE_PATTERN = re.compile(r"`([^`]+)`")
@@ -198,11 +201,15 @@ def _markdown_to_html(
198
201
 
199
202
  m_code = _CODEFENCE_PATTERN.match(line)
200
203
  if m_code:
201
- lang = m_code.group(1).strip()
204
+ indent = m_code.group(1)
205
+ lang = m_code.group(2).strip()
202
206
  code_lines: list[str] = []
203
207
  i += 1
204
208
  while i < n and not _CODEFENCE_PATTERN.match(lines[i]):
205
- code_lines.append(lines[i])
209
+ raw = lines[i]
210
+ if indent and raw.startswith(indent):
211
+ raw = raw[len(indent):]
212
+ code_lines.append(raw)
206
213
  i += 1
207
214
  if i < n:
208
215
  i += 1
@@ -30,7 +30,11 @@ from okstra_project import project_json_path, upsert_project_json
30
30
  from okstra_project.state import slugify
31
31
  from . import fix_cycles
32
32
  from .analysis_packet import build_analysis_packet
33
- from .clarification_items import clarification_response_with_sidecars, scan_approval_gate
33
+ from .clarification_items import (
34
+ attached_user_responses_section,
35
+ clarification_response_with_sidecars,
36
+ scan_approval_gate,
37
+ )
34
38
  from .qa_commands import format_errors as _format_qa_errors, validate_qa_commands
35
39
  from .material import (
36
40
  build_analysis_material,
@@ -1823,6 +1827,16 @@ def _write_instruction_set_sources(
1823
1827
  clarification_response_with_sidecars(Path(inp.clarification_response_path)),
1824
1828
  encoding="utf-8",
1825
1829
  )
1830
+ elif inp.task_type == "implementation" and inp.approved_plan_path:
1831
+ # implementation carry-in: the approved plan reaches this run by path
1832
+ # (executor re-reads it), so attach ONLY the planning HTML form answers
1833
+ # (`runs/implementation-planning/.../user-responses/`) — without these
1834
+ # the user's clarification answers never reach the implementation run.
1835
+ plan_responses = attached_user_responses_section(Path(inp.approved_plan_path))
1836
+ if plan_responses:
1837
+ (instruction_set / "clarification-response.md").write_text(
1838
+ plan_responses, encoding="utf-8",
1839
+ )
1826
1840
  if inp.directive:
1827
1841
  (instruction_set / "directive.txt").write_text(inp.directive + "\n", encoding="utf-8")
1828
1842
  render_reference_expectations(
@@ -1836,7 +1850,7 @@ def _write_instruction_set_sources(
1836
1850
  reference_expectations_path=instruction_set / "reference-expectations.md",
1837
1851
  clarification_response_path=(
1838
1852
  instruction_set / "clarification-response.md"
1839
- if inp.clarification_response_path else None
1853
+ if (instruction_set / "clarification-response.md").is_file() else None
1840
1854
  ),
1841
1855
  directive=inp.directive,
1842
1856
  instruction_set_relative_path=ctx["INSTRUCTION_SET_RELATIVE_PATH"],