okstra 0.75.0 → 0.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.kr.md +5 -3
  2. package/README.md +5 -3
  3. package/bin/okstra +10 -2
  4. package/docs/kr/architecture.md +1 -1
  5. package/docs/kr/cli.md +20 -4
  6. package/docs/pr-template-usage.md +3 -3
  7. package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +1 -1
  8. package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +358 -0
  9. package/package.json +1 -1
  10. package/runtime/BUILD.json +2 -2
  11. package/runtime/agents/workers/codex-worker.md +1 -1
  12. package/runtime/agents/workers/gemini-worker.md +1 -1
  13. package/runtime/bin/lib/okstra/cli.sh +5 -1
  14. package/runtime/bin/lib/okstra/globals.sh +1 -0
  15. package/runtime/bin/lib/okstra/usage.sh +6 -4
  16. package/runtime/bin/okstra.sh +1 -0
  17. package/runtime/prompts/launch.template.md +4 -13
  18. package/runtime/prompts/profiles/_coding-conventions-preflight.md +21 -0
  19. package/runtime/prompts/profiles/_implementation-executor.md +3 -6
  20. package/runtime/prompts/profiles/error-analysis.md +6 -0
  21. package/runtime/prompts/profiles/improvement-discovery.md +5 -0
  22. package/runtime/prompts/profiles/release-handoff.md +2 -2
  23. package/runtime/prompts/wizard/prompts.ko.json +12 -4
  24. package/runtime/python/okstra_ctl/analysis_packet.py +17 -0
  25. package/runtime/python/okstra_ctl/codex_dispatch.py +1484 -0
  26. package/runtime/python/okstra_ctl/lead_events.py +129 -0
  27. package/runtime/python/okstra_ctl/paths.py +3 -0
  28. package/runtime/python/okstra_ctl/pr_template.py +1 -1
  29. package/runtime/python/okstra_ctl/render.py +160 -29
  30. package/runtime/python/okstra_ctl/run.py +78 -15
  31. package/runtime/python/okstra_ctl/wizard.py +23 -9
  32. package/runtime/python/okstra_token_usage/codex.py +12 -7
  33. package/runtime/python/okstra_token_usage/collect.py +243 -54
  34. package/runtime/python/okstra_token_usage/gemini.py +12 -7
  35. package/runtime/skills/okstra-setup/SKILL.md +1 -1
  36. package/runtime/validators/validate-run.py +56 -22
  37. package/runtime/validators/validate_session_conformance.py +121 -4
  38. package/src/codex-dispatch.mjs +70 -0
  39. package/src/codex-run.mjs +68 -0
  40. package/src/doctor.mjs +40 -4
  41. package/src/install.mjs +122 -26
  42. package/src/paths.mjs +17 -3
  43. package/src/render-bundle.mjs +2 -0
  44. package/src/runtime-manifest.mjs +26 -0
  45. package/src/uninstall.mjs +26 -4
  46. /package/runtime/{skills/okstra-run/templates → templates/prd}/pr-body.template.md +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.75.0",
3
- "builtAt": "2026-06-11T19:32:02.652Z",
2
+ "package": "0.77.0",
3
+ "builtAt": "2026-06-12T18:41:28.107Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -135,7 +135,7 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Cod
135
135
  - Treat the prompt-history path as the canonical worker prompt history artifact for the current run, resolved to absolute against `Project Root` if given as relative.
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
- - **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` (transcribed by the lead from `prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") — the Codex CLI does not share the lead's context, so an untranscribed 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.
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
139
  - Include context (code, diff, file paths) if provided.
140
140
  - For long prompts, dispatch through the wrapper with literal absolute paths (plus the worktree path for implementation phase):
141
141
  ```bash
@@ -135,7 +135,7 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Gem
135
135
  - Treat the prompt-history path as the canonical worker prompt history artifact for the current run, resolved to absolute against `Project Root` if given as relative.
136
136
  - The assigned model execution value is canonical for CLI execution. Do not substitute a different Gemini model unless the task bundle explicitly changes it.
137
137
  - Pass the prompt received from Lead directly to gemini after persisting the exact prompt to the assigned path.
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` (transcribed by the lead from `prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") — the Gemini CLI does not share the lead's context, so an untranscribed gate never reaches the process that writes the code. If the heading is absent, return `GEMINI_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.
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 Gemini 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 `GEMINI_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
139
  - Include context (code, diff, file paths) if provided.
140
140
  - For long prompts, dispatch through the wrapper with literal absolute paths (plus the worktree path for implementation phase):
141
141
  ```bash
@@ -82,6 +82,10 @@ while [[ $# -gt 0 ]]; do
82
82
  REPORT_WRITER_MODEL_OVERRIDE="$(require_option_value --report-writer-model "${2-}")"
83
83
  shift 2
84
84
  ;;
85
+ --lead-runtime)
86
+ LEAD_RUNTIME="$(require_option_value --lead-runtime "${2-}")"
87
+ shift 2
88
+ ;;
85
89
  --executor)
86
90
  EXECUTOR_OVERRIDE="$(require_option_value --executor "${2-}")"
87
91
  shift 2
@@ -208,7 +212,7 @@ while [[ $# -gt 0 ]]; do
208
212
  printf ' hint: did you mean --task-id?\n' >&2
209
213
  ;;
210
214
  esac
211
- printf ' valid options: --render-only --resume-clarification --yes --workers --lead-model --claude-model --codex-model --gemini-model --report-writer-model --related-tasks --task-type --project-id --project-root --task-group --task-id --task-brief --directive --fix-cycle --clarification-response --approved-plan --approve --implementation-option --stage --qa-waiver --no-plan-verification -h|--help\n' >&2
215
+ printf ' valid options: --render-only --resume-clarification --yes --workers --lead-model --claude-model --codex-model --gemini-model --report-writer-model --lead-runtime --related-tasks --task-type --project-id --project-root --task-group --task-id --task-brief --directive --fix-cycle --clarification-response --approved-plan --approve --implementation-option --stage --qa-waiver --no-plan-verification -h|--help\n' >&2
212
216
  usage
213
217
  exit 1
214
218
  ;;
@@ -23,6 +23,7 @@ CLAUDE_MODEL_OVERRIDE=""
23
23
  CODEX_MODEL_OVERRIDE=""
24
24
  GEMINI_MODEL_OVERRIDE=""
25
25
  REPORT_WRITER_MODEL_OVERRIDE=""
26
+ LEAD_RUNTIME="claude-code"
26
27
  EXECUTOR_OVERRIDE=""
27
28
  CRITIC_CHOICE=""
28
29
  WORK_CATEGORY=""
@@ -3,7 +3,7 @@
3
3
  usage() {
4
4
  cat >&2 <<USAGE_EOF
5
5
  usage:
6
- $DISPLAY_COMMAND_NAME [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--executor claude|codex|gemini] [--critic off|claude|codex|gemini] [--related-tasks taskA,taskB] --project-id <project-id> [--project-root <path>] --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>] [--fix-cycle <yes|no>]
6
+ $DISPLAY_COMMAND_NAME [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--lead-runtime claude-code|codex] [--executor claude|codex|gemini] [--critic off|claude|codex|gemini] [--related-tasks taskA,taskB] --project-id <project-id> [--project-root <path>] --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>] [--fix-cycle <yes|no>]
7
7
 
8
8
  summary:
9
9
  $DISPLAY_TOOL_NAME prepares a task-keyed instruction bundle for Claude Code and launches an interactive Claude session by default.
@@ -27,7 +27,7 @@ required arguments:
27
27
  optional arguments:
28
28
  --project-root Absolute path to the target project root. Resolution order when omitted:
29
29
  (1) ancestor of cwd that contains .okstra/project.json,
30
- (2) `git rev-parse --show-toplevel` from cwd. Errors out if neither resolves.
30
+ (2) \`git rev-parse --show-toplevel\` from cwd. Errors out if neither resolves.
31
31
  --directive Free-form user-supplied directive carried into the run as a "## Directive" section
32
32
  inside instruction-set/analysis-material.md. Lead, workers, and skills (e.g. okstra-schedule)
33
33
  may treat this as a hard hint that overrides default heuristics. Use to express intent
@@ -87,13 +87,16 @@ options:
87
87
  exclusive with --clarification-response and --approved-plan.
88
88
  --yes Skip interactive prompting and confirmation. Requires all required arguments.
89
89
  --workers Comma-separated worker list for this run. Default: claude,codex,report-writer
90
- (Gemini worker is optional; add `gemini` explicitly, e.g. --workers claude,codex,gemini,report-writer)
90
+ (Gemini worker is optional; add \`gemini\` explicitly, e.g. --workers claude,codex,gemini,report-writer)
91
91
  --lead-model Model for Claude lead. Default: OKSTRA_DEFAULT_LEAD_MODEL or opus
92
92
  --claude-model Model for Claude worker. Default: OKSTRA_DEFAULT_CLAUDE_MODEL or opus
93
93
  --codex-model Model for Codex worker. Default: OKSTRA_DEFAULT_CODEX_MODEL or gpt-5.5
94
94
  --gemini-model Model for Gemini worker. Default: OKSTRA_DEFAULT_GEMINI_MODEL or auto
95
95
  --report-writer-model
96
96
  Model for report writer worker. Default: OKSTRA_DEFAULT_REPORT_WRITER_MODEL or lead model default
97
+ --lead-runtime Lead runtime adapter. Default: claude-code.
98
+ codex is currently render-only and records Codex adapter
99
+ metadata in prepared artifacts without dispatching workers.
97
100
  --executor Provider that performs the Executor role during --task-type=implementation.
98
101
  One of: claude | codex | gemini. Default: OKSTRA_DEFAULT_EXECUTOR or claude.
99
102
  The Executor is the only worker allowed to mutate project files; the other two
@@ -143,4 +146,3 @@ interactive behavior:
143
146
  If --yes is provided, $DISPLAY_TOOL_NAME skips prompting and confirmation and requires all required arguments up front.
144
147
  USAGE_EOF
145
148
  }
146
-
@@ -115,6 +115,7 @@ PY_ARGS=(
115
115
  [[ -n "${CODEX_MODEL_OVERRIDE-}" ]] && PY_ARGS+=(--codex-model "$CODEX_MODEL_OVERRIDE")
116
116
  [[ -n "${GEMINI_MODEL_OVERRIDE-}" ]] && PY_ARGS+=(--gemini-model "$GEMINI_MODEL_OVERRIDE")
117
117
  [[ -n "${REPORT_WRITER_MODEL_OVERRIDE-}" ]] && PY_ARGS+=(--report-writer-model "$REPORT_WRITER_MODEL_OVERRIDE")
118
+ [[ -n "${LEAD_RUNTIME-}" ]] && PY_ARGS+=(--lead-runtime "$LEAD_RUNTIME")
118
119
  [[ -n "${EXECUTOR_OVERRIDE-}" ]] && PY_ARGS+=(--executor "$EXECUTOR_OVERRIDE")
119
120
  [[ -n "${CRITIC_CHOICE-}" ]] && PY_ARGS+=(--critic "$CRITIC_CHOICE")
120
121
  [[ -n "${RELATED_TASKS_RAW-}" ]] && PY_ARGS+=(--related-tasks "$RELATED_TASKS_RAW")
@@ -1,7 +1,7 @@
1
1
  # okstra — {{TASK_KEY}}
2
2
 
3
- You are `Claude lead` for project `{{PROJECT_ID}}`.
4
- Invoke the `okstra` skill now. Read the manifests below for all task metadata, paths, model assignments, and worker roster.
3
+ {{LEAD_INTRO_LINE}}
4
+ {{LEAD_BOOTSTRAP_INSTRUCTION}}
5
5
 
6
6
  ## Progress reporting (BLOCKING)
7
7
 
@@ -28,13 +28,7 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
28
28
  - All other paths in this prompt are relative to this root unless they begin with `/`.
29
29
  - When dispatching workers, you MUST include this absolute root in every worker prompt header so that workers do not depend on inherited cwd to resolve relative paths.
30
30
 
31
- ## Worker Prompt Files (not pre-rendered)
32
-
33
- - The `runs/<phase>/prompts/<worker>-worker-prompt-*.md` files referenced in `task-manifest.json → artifacts.workerPromptPathByWorkerId` are **NOT** rendered by the okstra runtime. Those paths are the *assigned* locations where the prompt history MUST be written at dispatch time.
34
- - Therefore: at the start of every phase the prompts/ directory is normally empty (or contains only previously-dispatched workers' files). This is expected. Do NOT narrate it as "missing", "누락", or "not yet rendered" — it just means dispatch has not happened yet.
35
- - Before dispatching any required worker, **you (the lead) construct the worker prompt and persist it to the assigned absolute path using `Write`** (per `okstra-team-contract` rule 6). Only after persisting do you call the worker subagent (Agent tool / Codex / Gemini wrapper). The wrapper subagents will also re-write the same file on their end; the double-write is intentional and idempotent.
36
- - Do not "check if the file exists and skip dispatch" — file presence is not a signal to skip. Worker selection and skipping rules come from team-state, never from prompts/ directory contents.
37
- - **Worker Preamble Path (single anchor — replaces inlined `[Required reading]` and `[Error reporting]` blocks).** Every worker prompt you construct MUST include the anchor header `**Worker Preamble Path:** {{WORKER_PROMPT_PREAMBLE_PATH}}`. The file at that path is the canonical SSOT for Required Reading + Error Reporting + Output sections; workers Read it end-to-end before producing output. Do NOT re-inline those blocks into worker prompt bodies — that is the legacy ~80-line dispatch boilerplate that this anchor is designed to replace.
31
+ {{WORKER_DISPATCH_GUIDANCE}}
38
32
 
39
33
  ## Manifests
40
34
 
@@ -43,10 +37,7 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
43
37
  - Active run context: `{{ACTIVE_RUN_CONTEXT_RELATIVE_PATH}}`
44
38
  - Analysis packet: `{{ANALYSIS_PACKET_RELATIVE_PATH}}`
45
39
 
46
- ## Session
47
-
48
- - Session ID: `{{CLAUDE_SESSION_ID}}`
49
- - Resume: `{{CLAUDE_RESUME_COMMAND_RELATIVE_PATH}}`
40
+ {{LEAD_SESSION_BLOCK}}
50
41
 
51
42
  ## Run Paths
52
43
 
@@ -0,0 +1,21 @@
1
+ <!--
2
+ Single source for the executor's Coding-conventions preflight gate. Two delivery
3
+ paths converge here (see _implementation-executor.md "Pre-implementation context
4
+ exploration"):
5
+ - Claude executor reads this file directly before its first Edit / Write.
6
+ - codex / gemini executor cannot read this path (it sits outside the CLI
7
+ sandbox and the CLI only sees its stdin prompt), so the lead appends this
8
+ file's body into the persisted executor prompt at dispatch time.
9
+ The `Coding-conventions preflight` heading below is the literal string the CLI
10
+ wrapper's "Executor preflight forwarding check" greps for in the persisted
11
+ prompt (agents/workers/_cli-wrapper-template.md → Prompt Composition).
12
+ -->
13
+
14
+ # Coding-conventions preflight (BLOCKING — runs before the first `Edit` / `Write`, and binds the TDD loop)
15
+
16
+ Load the applicable coding conventions for every language the diff will touch, then state in ONE line which conventions apply (e.g. `Applying TS + hexagonal overlay; domain at src/domains/*/domain/`). Lint/test green is necessary but NOT sufficient — self-mocked tests, interaction-only assertions, and untruthful names all pass a green pipeline; this gate is what keeps them out of the diff.
17
+
18
+ - **Language-specific rules load per situation — never inline them here.** Detect each touched file's language (extension / project manifest) and load the matching reference by reading okstra's installed coding-conventions files directly at `~/.claude/skills/okstra-coding-preflight/` (placed there by `okstra install`): read `languages/<lang>.md` (mock/spy API, idioms, test framework) + `clean-code.md` + any `architecture/*` overlay via the Read tool by absolute path. The skill is `user-invocable: false`, so do NOT rely on Skill-tool auto-invocation — read the files directly. For a ports-and-adapters / NestJS-hex layout (`domain/` + `ports/` + `adapters/`, `*.port.*`), load the hexagonal overlay too. This per-language split is the skill's job — the executor does not carry a multi-language block in context.
19
+ - **Project review rule packs:** also look for project-local review skills in `<PROJECT_ROOT>/skills/*review*`, `<PROJECT_ROOT>/.claude/skills/*review*`, and up to two parent directories' `skills/*review*/SKILL.md`. Read the relevant `SKILL.md` plus referenced `references/*.md` files and apply their rules during implementation. This is a prevention pass, not a PR-comment generation workflow: do not dispatch reviewer subagents from the executor. For Fonts Ninja-style PR review packs, the executor must avoid newly introduced duplicate helper stacks, tautological tests that merely re-call the delegated helper, self-mocking, domain rules in adapters/ports, domain objects outside `domain/`, dead APIs, weak public names, and functions that fail the plain-English read.
20
+ - **Language-agnostic principles that ALWAYS bind (the TDD loop MUST satisfy them):** (1) no self-mocking of the SUT — stub/spy only injected collaborators, never the subject's own methods; (2) behavioral assertions on outcomes (return value, state, persisted rows, events, boundary calls) — never `toHaveBeenCalled*` on an internal helper as the only/primary assertion; (3) truthful names — a `get*` / `find*` that writes/inserts, or a name encoding the caller's use-case (`*ForInit`) or hiding a domain rule (`findValid*`), is a defect; (4) single-purpose functions ≤50 effective lines, plain-English readability.
21
+ - **Graceful degradation (codex / gemini executor runtimes, or any runtime where the `~/.claude/skills/okstra-coding-preflight/` files are absent or unreadable):** do NOT skip the gate — apply the agnostic principles above plus the project's own `CLAUDE.md` / `CONTRIBUTING` / formatter+lint config, and record `coding-conventions: skill-unavailable → applied <project rules + agnostic principles>` in the final report. Never claim a skill read that did not happen.
@@ -19,12 +19,9 @@ until Phase 5 ends, then drop from active context for Phase 6/7.
19
19
 
20
20
  ## Pre-implementation context exploration (executor before first edit)
21
21
 
22
- - **Coding-conventions preflight (BLOCKING — runs before the first `Edit` / `Write`, and binds the TDD loop below):** load the applicable coding conventions for every language the diff will touch, then state in ONE line which conventions apply (e.g. `Applying TS + hexagonal overlay; domain at src/domains/*/domain/`). Lint/test green is necessary but NOT sufficient — self-mocked tests, interaction-only assertions, and untruthful names all pass a green pipeline; this gate is what keeps them out of the diff.
23
- - **Language-specific rules load per situation — never inline them here.** Detect each touched file's language (extension / project manifest) and load the matching reference by reading okstra's installed coding-conventions files directly at `~/.claude/skills/okstra-coding-preflight/` (placed there by `okstra install`): read `languages/<lang>.md` (mock/spy API, idioms, test framework) + `clean-code.md` + any `architecture/*` overlay via the Read tool by absolute path. The skill is `user-invocable: false`, so do NOT rely on Skill-tool auto-invocation read the files directly. For a ports-and-adapters / NestJS-hex layout (`domain/` + `ports/` + `adapters/`, `*.port.*`), load the hexagonal overlay too. This per-language split is the skill's job — the executor does not carry a multi-language block in context.
24
- - **Project review rule packs:** also look for project-local review skills in `<PROJECT_ROOT>/skills/*review*`, `<PROJECT_ROOT>/.claude/skills/*review*`, and up to two parent directories' `skills/*review*/SKILL.md`. Read the relevant `SKILL.md` plus referenced `references/*.md` files and apply their rules during implementation. This is a prevention pass, not a PR-comment generation workflow: do not dispatch reviewer subagents from the executor. For Fonts Ninja-style PR review packs, the executor must avoid newly introduced duplicate helper stacks, tautological tests that merely re-call the delegated helper, self-mocking, domain rules in adapters/ports, domain objects outside `domain/`, dead APIs, weak public names, and functions that fail the plain-English read.
25
- - **Language-agnostic principles that ALWAYS bind (the TDD loop below MUST satisfy them):** (1) no self-mocking of the SUT — stub/spy only injected collaborators, never the subject's own methods; (2) behavioral assertions on outcomes (return value, state, persisted rows, events, boundary calls) — never `toHaveBeenCalled*` on an internal helper as the only/primary assertion; (3) truthful names — a `get*` / `find*` that writes/inserts, or a name encoding the caller's use-case (`*ForInit`) or hiding a domain rule (`findValid*`), is a defect; (4) single-purpose functions ≤50 effective lines, plain-English readability.
26
- - **Graceful degradation (codex / gemini executor runtimes, or any runtime where the `~/.claude/skills/okstra-coding-preflight/` files are absent or unreadable):** do NOT skip the gate — apply the agnostic principles above plus the project's own `CLAUDE.md` / `CONTRIBUTING` / formatter+lint config, and record `coding-conventions: skill-unavailable → applied <project rules + agnostic principles>` in the final report. Never claim a skill read that did not happen.
27
- - **CLI executor transcription (BLOCKING when the executor provider is `codex` or `gemini`):** the executor CLI process does NOT share the lead's context — a gate that stays in lead memory never reaches it. The lead MUST copy this entire "Coding-conventions preflight" bullet tree (file-read instructions, project review rule packs, agnostic principles, graceful degradation) verbatim into the dispatched executor prompt body. Enforcement: the CLI wrapper agents refuse an implementation-Executor dispatch whose persisted prompt lacks the literal heading `Coding-conventions preflight`, returning `<SENTINEL_PREFIX>_PREFLIGHT_MISSING` (see `agents/workers/_cli-wrapper-template.md` → Prompt Composition).
22
+ - **Coding-conventions preflight (BLOCKING — runs before the first `Edit` / `Write`, and binds the TDD loop below).** The gate body is a single source at `prompts/profiles/_coding-conventions-preflight.md` (sibling of this sidecar): skill-file pointers (`~/.claude/skills/okstra-coding-preflight/`), project review rule packs, the always-binding language-agnostic principles, and graceful degradation. Do NOT re-type that content from memory deliver it by file so it cannot drift or be dropped:
23
+ - **Claude executor:** Read `_coding-conventions-preflight.md` end-to-end before the first `Edit` / `Write`, then state in ONE line which conventions apply (e.g. `Applying TS + hexagonal overlay; domain at src/domains/*/domain/`).
24
+ - **CLI executor (BLOCKING when the executor provider is `codex` or `gemini`):** the executor CLI process does NOT share the lead's context, and it cannot Read this sidecar's directory that path sits outside the CLI sandbox and the CLI only sees its stdin prompt, so a file reference never reaches it. The lead MUST physically append the **body** of `_coding-conventions-preflight.md` into the persisted executor prompt at dispatch time: Read the file from the same absolute directory you read this sidecar from, then `Write`/`cat` its body into the persisted prompt. Never hand-retype it. Enforcement: the CLI wrapper agents refuse an implementation-Executor dispatch whose persisted prompt lacks the literal heading `Coding-conventions preflight`, returning `<SENTINEL_PREFIX>_PREFLIGHT_MISSING` (see `agents/workers/_cli-wrapper-template.md` → Prompt Composition).
28
25
  - **Stage discipline transcription (when a preceding stage is `done`):** the lead MUST transcribe the `Stage discipline` rule (from this run's rendered profile — the INCLUDEd `_stage-discipline.md` body) verbatim into the dispatched CLI executor prompt, so a codex/gemini executor honors the prior-stage behavior-freeze. Declaration-level — no wrapper sentinel.
29
26
  - **Non-interactive auto-execution (BLOCKING when the executor provider is `codex` or `gemini`).** A CLI executor runs head-less (`codex exec` / gemini equivalent) — there is no human at the keyboard. Skills loaded during the run (tdd, coding-preflight, and others) contain "get user approval", "state your plan to the user and wait", or "ask before proceeding" gates written for interactive sessions; in this run those gates are **already satisfied** by the upstream `implementation-planning` approval (the plan this stage executes was human-approved). The executor MUST NOT stop to request approval, MUST NOT end its turn after only producing a plan, and MUST carry the stage through end-to-end — RED → GREEN → refactor → per-step commits → `### Stage Carry Evidence`. The ONLY skill step to skip is the interactive user-approval prompt itself; every other skill rule (TDD discipline, conventions, real-IO isolation) still binds. The lead MUST transcribe this bullet verbatim into the dispatched CLI executor prompt (same reason as the preflight transcription rule above — the CLI process does not share lead context). Stopping early for approval in a head-less run is the observed empty-exit failure (exit 0, no diff): treat it as `contract-violated`.
30
27
  - **Mandatory TDD loop**: BEFORE the first `Edit` or `Write` call, the executor MUST apply a red-green-refactor loop for every code change in this run. This is required; skipping it is a `contract-violated` outcome. This governs HOW each step is executed (failing test first → minimal implementation → refactor); it does not override the approved plan's WHAT/file scope.
@@ -13,6 +13,12 @@
13
13
  - the reporter's symptom description in `Source Material` is the ground truth for what to reproduce. Do not paraphrase it when stating the symptom in the report; quote it.
14
14
  - any `intent-inference` augmentation that re-characterises the symptom (e.g. classifying "가끔 안 됨" as "intermittent failure on a specific code path") is a **hypothesis**, not a confirmed symptom. If `[CONFIRMED …]` appears on the matching `intent-check:` row, treat the confirmation as the symptom; otherwise, follow the precondition's `skipped` branch above and keep the inference labelled as hypothesis in the root-cause analysis.
15
15
  - `conversion-block:` rows mean the brief could not map a reporter statement to project vocabulary; never attempt to invent the missing mapping in this phase — the precondition above already handled them.
16
+ - Diagnosis loop:
17
+ - **Symptom lock:** state the reporter's symptom verbatim, then translate it into one observable failure condition. If the observable condition cannot be derived from the brief, make that the first blocker instead of guessing.
18
+ - **Reproduction status:** classify the run as `reproduced`, `not-reproduced`, or `blocked-before-repro`. Cite the command/log/file evidence used. If no command can be run safely in this phase, explain the read-only evidence path and the exact material needed next.
19
+ - **Falsifiable cause candidates:** every root-cause candidate must include supporting evidence, the strongest falsifying evidence checked, confidence, and the next diagnostic action that would disprove it. A candidate that cannot be falsified is too vague for this phase.
20
+ - **Sharp next diagnostic:** end with the single highest-value diagnostic command, log capture, or file inspection that should happen next, plus the expected signal that would confirm or reject the leading cause.
21
+ - **Fix-design boundary:** do not design the implementation fix beyond what is necessary to validate the cause. If the cause is credible, route to `implementation-planning` with the verified evidence; if the cause is still unclear, route to another `error-analysis` run with the next diagnostic.
16
22
  - Primary focus areas:
17
23
  - symptom and trigger clarification
18
24
  - root-cause candidates
@@ -20,6 +20,11 @@
20
20
  - per-candidate evidence (path:line) and scope mapping
21
21
  - per-candidate severity / effort / recommended-next-phase
22
22
  - convergence classification (full / partial / contested / worker-unique) across workers
23
+ - Worker diversity rule:
24
+ - every analyser inspects every priority lens, but each starts with a different primary pass so the run does not rely on model randomness for diversity. Order lenses exactly as they appear in the brief; `claude` starts at lens 1, `codex` at lens 2, and `gemini` at lens 3, wrapping around when fewer lenses are present.
25
+ - before broadening to the remaining lenses, each worker must either produce at least one candidate from its primary pass or record a no-candidate rationale with the highest-signal path:line evidence it inspected.
26
+ - two workers' candidates are the same candidate only when they cite the same underlying design/code problem and the same remediation direction. Shared evidence paths alone are not enough to merge; keep distinct failure modes distinct.
27
+ - when a candidate from one worker overlaps another worker's evidence, convergence must verify whether it is duplicate, broader/narrower, or conflicting. Do not collapse contested candidates just to meet the candidate cap.
23
28
  - Phase 1.5 — Lead reflect-back grilling (runs after Phase 1 context loading and before Phase 4 worker dispatch):
24
29
  - Lead inspects scan-scope paths via `ls` / `Grep` / `Read` to map modules, entry points, dependencies, approximate LOC, and recent commit patterns.
25
30
  - Lead emits a single reflect-back message covering: (a) understood scope per path (one-line summary), (b) understood meaning of each priority lens in this scope, (c) understood out-of-scope rationale, (d) ordered list of N open questions.
@@ -20,9 +20,9 @@
20
20
  - the lead MUST confirm `git log --oneline <base>..HEAD` contains at least one implementation commit. If it is empty, the run MUST end with status `blocked` and route back to `implementation`.
21
21
  - User interaction protocol (Claude lead — performed in order, using `AskUserQuestion` or the equivalent interactive prompt):
22
22
  1. **Action selection** — present three choices and capture exactly one:
23
- - `local only` — record the accepted, already-committed branch and end without push or PR.
23
+ - `local only` — complete the handoff as a local delivery record: record the accepted, already-committed branch and end without push or PR.
24
24
  - `push + PR` — push the feature branch, then open or reuse a pull request.
25
- - `skip` — record the verified state and end the run without any git command.
25
+ - `skip` — cancel delivery actions for now: record that release-handoff was intentionally skipped and end the run without any git command.
26
26
  If the user picks `skip`, route directly to the final-report self-review pass.
27
27
  - **stage-group mode order**: G1 base branch first (same options as Q2 — the dependency-closure check needs `origin/<base>`), then G2 stage confirmation, then assemble, then Q2b/Q3 as usual with the collector branch as the PR head.
28
28
  1g. **G2 — stage confirmation**: the stage selection already happened before the run (wizard `handoff_stage_pick`, or the CLI `--stages` flag) and is fixed in `HANDOFF_STAGES`. Display it as a one-line confirmation (`PR 대상 stage: <csv> — 진행합니다`) and proceed; do NOT re-ask the multi-select. Only if `HANDOFF_MODE` is `stage-group` but `HANDOFF_STAGES` is empty (defensive, should not happen) run `okstra handoff eligible --plan-run-root <plan-run-root> --approved-plan <approved plan path>` and ask the user to pick from the eligible stages.
@@ -196,6 +196,7 @@
196
196
  },
197
197
  "approved_plan_pick": {
198
198
  "label": "approved final-report 경로 (기본: {default})",
199
+ "label_final_verification": "검증 기준이 될 승인된 plan(approved final-report) 을 선택하세요 (기본: {default})",
199
200
  "echo_template": "approved-plan(pick): {value}",
200
201
  "options": {
201
202
  "__use_default__": "기본 경로 사용: {default}",
@@ -216,12 +217,17 @@
216
217
  "echo_template": "approved-plan: {value}"
217
218
  },
218
219
  "approve_plan_confirm": {
219
- "label": "이 플랜으로 진행할까요?\n {path}\n· 예 — 진행합니다. 플랜이 아직 승인 전이면 지금 data.json(정본) + 리포트를 함께 approved 로 처리한 뒤 진행합니다. (markdown 만 손으로 고치면 일관성 검증에서 거부되므로 이 경로로 승인하세요.)\n· 아니오 — 진행하지 않습니다.",
220
+ "label": "이 플랜으로 구현을 진행할까요?\n {path}\n· 예 — plan 대로 구현을 실행합니다. 플랜이 아직 승인 전이면 지금 data.json(정본) + 리포트를 함께 approved 로 처리한 뒤 진행합니다. (markdown 만 손으로 고치면 일관성 검증에서 거부되므로 이 경로로 승인하세요.)\n· 아니오 — 진행하지 않습니다.",
221
+ "label_final_verification": "이 plan 을 검증 기준으로 삼아 진행할까요?\n {path}\n· 예 — 선택한 stage 의 구현 결과를 위 plan 기준으로 검증합니다. (plan 이 아직 승인 전이면 data.json(정본) + 리포트를 함께 approved 로 처리한 뒤 검증합니다.)\n· 아니오 — 진행하지 않습니다.",
220
222
  "html_approval_note": "\nHTML 승인 기록 발견: {sidecar}\n 선택 옵션: {option}\n· 예(기록 적용) — 승인과 함께 위 옵션을 frontmatter 에 기록합니다.",
221
223
  "html_approval_note_default_option": "(추천 옵션 그대로)",
222
224
  "echo_template": "approve-plan: {value}",
223
225
  "options": {
224
- "yes": "예 — 승인하고 진행",
226
+ "yes": "예 — 승인하고 구현 진행",
227
+ "no": "아니오 — 진행하지 않음"
228
+ },
229
+ "options_final_verification": {
230
+ "yes": "예 — 이 plan 기준으로 검증 진행",
225
231
  "no": "아니오 — 진행하지 않음"
226
232
  },
227
233
  "options_html_approval": {
@@ -230,8 +236,10 @@
230
236
  "no": "아니오 — 진행하지 않음"
231
237
  },
232
238
  "echo_variants": {
233
- "selected": "plan 선택: {path} — 다음 단계에서 승인·진행 여부를 확인합니다",
234
- "approved": "approved-plan: {path} (승인·진행 확인됨)",
239
+ "selected": "plan 선택: {path} — 다음 단계에서 승인·구현 진행 여부를 확인합니다",
240
+ "selected_final_verification": "검증 기준 plan 선택: {path} 다음 단계에서 검증 진행 여부를 확인합니다",
241
+ "approved": "approved-plan: {path} (승인·구현 진행 확인됨)",
242
+ "approved_final_verification": "검증 기준 plan 확정: {path} (검증 진행 확인됨)",
235
243
  "approved_with_option": "approved-plan: {path} (승인 + 옵션 `{option}` 적용됨)"
236
244
  },
237
245
  "errors": {
@@ -27,12 +27,28 @@ PROFILE_SECTIONS = (
27
27
  "Clarification request policy",
28
28
  )
29
29
  PROFILE_SECTIONS_BY_TASK_TYPE = {
30
+ "requirements-discovery": (
31
+ "Fan-out",
32
+ "Decision-tree walk",
33
+ ),
34
+ "error-analysis": (
35
+ "Diagnosis loop",
36
+ ),
30
37
  "implementation-planning": (
31
38
  "Section heading contract",
32
39
  "Required deliverable shape",
33
40
  "No-placeholder rule",
34
41
  "Self-review pass before finalising the report",
35
42
  ),
43
+ "final-verification": (
44
+ "Required deliverable shape",
45
+ "Self-review pass before finalising the report",
46
+ ),
47
+ "improvement-discovery": (
48
+ "Phase 1.5 — Lead reflect-back grilling",
49
+ "Worker diversity rule",
50
+ "Decision-tree walk",
51
+ ),
36
52
  }
37
53
  CLARIFICATION_SECTIONS = (
38
54
  "Clarification Items",
@@ -261,6 +277,7 @@ def _top_level_bullet_heading(line: str) -> str:
261
277
  if not line.startswith("- ") or ":" not in line:
262
278
  return ""
263
279
  label = line[2:].split(":", 1)[0].strip().strip("*")
280
+ label = label.split(" (", 1)[0].strip()
264
281
  return label
265
282
 
266
283