okstra 0.86.0 → 0.87.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 (101) hide show
  1. package/docs/kr/architecture.md +27 -27
  2. package/docs/kr/cli.md +21 -21
  3. package/docs/kr/performance-improvement-plan-v2.md +4 -4
  4. package/docs/kr/performance-improvement-plan.md +3 -3
  5. package/docs/project-structure-overview.md +6 -6
  6. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +724 -0
  7. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +123 -0
  8. package/docs/task-process/error-analysis.md +1 -1
  9. package/docs/task-process/final-verification.md +4 -4
  10. package/docs/task-process/implementation-planning.md +2 -2
  11. package/docs/task-process/implementation.md +3 -3
  12. package/docs/task-process/requirements-discovery.md +2 -2
  13. package/package.json +1 -1
  14. package/runtime/BUILD.json +2 -2
  15. package/runtime/agents/workers/{gemini-worker.md → antigravity-worker.md} +56 -56
  16. package/runtime/agents/workers/claude-worker.md +2 -2
  17. package/runtime/agents/workers/codex-worker.md +1 -1
  18. package/runtime/agents/workers/report-writer-worker.md +2 -2
  19. package/runtime/bin/lib/okstra/cli.sh +3 -3
  20. package/runtime/bin/lib/okstra/globals.sh +8 -8
  21. package/runtime/bin/lib/okstra/interactive.sh +1 -1
  22. package/runtime/bin/lib/okstra/usage.sh +7 -7
  23. package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +5 -3
  24. package/runtime/bin/lib/okstra-ctl/prepare.sh +4 -2
  25. package/runtime/bin/{okstra-gemini-exec.sh → okstra-antigravity-exec.sh} +67 -60
  26. package/runtime/bin/okstra-error-log.py +2 -1
  27. package/runtime/bin/okstra-token-usage.py +3 -4
  28. package/runtime/bin/okstra-trace-cleanup.sh +4 -4
  29. package/runtime/bin/okstra-wrapper-status.py +3 -3
  30. package/runtime/bin/okstra.sh +1 -1
  31. package/runtime/prompts/launch.template.md +3 -3
  32. package/runtime/prompts/lead/context-loader.md +1 -1
  33. package/runtime/prompts/lead/convergence.md +8 -8
  34. package/runtime/prompts/lead/okstra-lead-contract.md +15 -15
  35. package/runtime/prompts/lead/report-writer.md +6 -6
  36. package/runtime/prompts/lead/team-contract.md +31 -31
  37. package/runtime/prompts/profiles/_coding-conventions-preflight.md +2 -2
  38. package/runtime/prompts/profiles/_common-contract.md +7 -7
  39. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  40. package/runtime/prompts/profiles/_implementation-executor.md +6 -6
  41. package/runtime/prompts/profiles/_implementation-verifier.md +4 -4
  42. package/runtime/prompts/profiles/_stage-discipline.md +1 -1
  43. package/runtime/prompts/profiles/error-analysis.md +1 -1
  44. package/runtime/prompts/profiles/final-verification.md +1 -1
  45. package/runtime/prompts/profiles/forbidden-actions.json +2 -2
  46. package/runtime/prompts/profiles/implementation-planning.md +1 -1
  47. package/runtime/prompts/profiles/implementation.md +3 -3
  48. package/runtime/prompts/profiles/improvement-discovery.md +3 -3
  49. package/runtime/prompts/profiles/requirements-discovery.md +1 -1
  50. package/runtime/prompts/wizard/prompts.ko.json +9 -5
  51. package/runtime/python/okstra_ctl/__init__.py +2 -0
  52. package/runtime/python/okstra_ctl/analysis_packet.py +1 -1
  53. package/runtime/python/okstra_ctl/clarification_items.py +17 -7
  54. package/runtime/python/okstra_ctl/codex_dispatch.py +2 -2
  55. package/runtime/python/okstra_ctl/context_cost.py +10 -44
  56. package/runtime/python/okstra_ctl/doctor.py +1 -1
  57. package/runtime/python/okstra_ctl/error_report.py +185 -0
  58. package/runtime/python/okstra_ctl/improvement_lenses.py +1 -1
  59. package/runtime/python/okstra_ctl/models.py +10 -10
  60. package/runtime/python/okstra_ctl/paths.py +9 -9
  61. package/runtime/python/okstra_ctl/reconcile.py +74 -11
  62. package/runtime/python/okstra_ctl/render.py +21 -21
  63. package/runtime/python/okstra_ctl/run.py +16 -16
  64. package/runtime/python/okstra_ctl/run_context.py +1 -1
  65. package/runtime/python/okstra_ctl/seeding.py +1 -1
  66. package/runtime/python/okstra_ctl/task_target.py +44 -0
  67. package/runtime/python/okstra_ctl/team.py +1 -1
  68. package/runtime/python/okstra_ctl/wizard.py +55 -30
  69. package/runtime/python/okstra_ctl/workers.py +3 -3
  70. package/runtime/python/okstra_ctl/workflow.py +1 -1
  71. package/runtime/python/okstra_ctl/worktree.py +1 -1
  72. package/runtime/python/okstra_token_usage/__init__.py +2 -3
  73. package/runtime/python/okstra_token_usage/antigravity.py +26 -0
  74. package/runtime/python/okstra_token_usage/blocks.py +4 -0
  75. package/runtime/python/okstra_token_usage/collect.py +20 -15
  76. package/runtime/python/okstra_token_usage/paths.py +0 -1
  77. package/runtime/python/okstra_token_usage/pricing.py +6 -3
  78. package/runtime/schemas/final-report-v1.0.schema.json +1 -1
  79. package/runtime/skills/okstra-brief/SKILL.md +1 -1
  80. package/runtime/skills/okstra-inspect/SKILL.md +85 -21
  81. package/runtime/skills/okstra-run/SKILL.md +3 -3
  82. package/runtime/skills/okstra-setup/SKILL.md +2 -2
  83. package/runtime/templates/prd/brief.template.md +2 -2
  84. package/runtime/templates/reports/i18n/en.json +1 -1
  85. package/runtime/templates/reports/i18n/ko.json +1 -1
  86. package/runtime/templates/reports/settings.template.json +2 -2
  87. package/runtime/templates/reports/task-brief.template.md +2 -2
  88. package/runtime/templates/worker-prompt-preamble.md +7 -7
  89. package/runtime/validators/forbidden_actions.py +1 -1
  90. package/runtime/validators/lib/fixtures.sh +3 -3
  91. package/runtime/validators/lib/validate-assets.sh +1 -1
  92. package/runtime/validators/validate-run.py +8 -8
  93. package/src/cli-registry.mjs +7 -0
  94. package/src/codex-dispatch.mjs +3 -3
  95. package/src/codex-run.mjs +2 -2
  96. package/src/doctor.mjs +1 -1
  97. package/src/error-report.mjs +27 -0
  98. package/src/install.mjs +1 -1
  99. package/src/render-bundle.mjs +1 -1
  100. package/src/uninstall.mjs +2 -2
  101. package/runtime/python/okstra_token_usage/gemini.py +0 -82
@@ -11,19 +11,19 @@ until Phase 5 ends, then drop from active context for Phase 6/7.
11
11
 
12
12
  ## Executor role binding (carried over from the thin core)
13
13
 
14
- - **Executor dispatch labelling.** When Lead dispatches the Executor it MUST set the Agent `name` to `<provider>-executor` (e.g. `codex-executor`, `claude-executor`) — NOT the generic `<provider>-worker` — so the FleetView teammate pill names the job; see `prompts/lead/okstra-lead-contract.md` Phase 4 "Agent `name` on dispatch". For a `codex` / `gemini` Executor, Lead MUST additionally inject a `**Pane role:** executor` line into the dispatched prompt body so the CLI wrapper titles its tmux trace pane `<cli>-executor-<pid>` (the wrapper reads that line per `agents/workers/_cli-wrapper-template.md`). Token attribution is unaffected — the collector matches any `agentName` beginning `<provider>-`.
15
- - The `Executor` (bound in `implementation.md` thin core) is the **only worker permitted to use Edit / Write / state-mutating Bash commands** on project files. All other workers run read-only. When the executor provider is `codex` or `gemini`, the actual file mutation happens inside the executor CLI's own auto-edit mode (e.g. `codex exec --sandbox workspace-write`, gemini's equivalent) — not through Claude-side Edit/Write tools — but the safety rules in this sidecar still apply identically.
14
+ - **Executor dispatch labelling.** When Lead dispatches the Executor it MUST set the Agent `name` to `<provider>-executor` (e.g. `codex-executor`, `claude-executor`) — NOT the generic `<provider>-worker` — so the FleetView teammate pill names the job; see `prompts/lead/okstra-lead-contract.md` Phase 4 "Agent `name` on dispatch". For a `codex` / `antigravity` Executor, Lead MUST additionally inject a `**Pane role:** executor` line into the dispatched prompt body so the CLI wrapper titles its tmux trace pane `<cli>-executor-<pid>` (the wrapper reads that line per `agents/workers/_cli-wrapper-template.md`). Token attribution is unaffected — the collector matches any `agentName` beginning `<provider>-`.
15
+ - The `Executor` (bound in `implementation.md` thin core) is the **only worker permitted to use Edit / Write / state-mutating Bash commands** on project files. All other workers run read-only. When the executor provider is `codex` or `antigravity`, the actual file mutation happens inside the executor CLI's own auto-edit mode (e.g. `codex exec --sandbox workspace-write`, antigravity's equivalent) — not through Claude-side Edit/Write tools — but the safety rules in this sidecar still apply identically.
16
16
  - Worktree cwd handling — when the thin core's Task worktree block resolves status to `created` or `reused`, the Executor MUST run every Edit / Write / build / test / commit command with the worktree path as cwd. Treat it as `project_root` for the duration of this run. Do NOT mutate the caller's original checkout. Do NOT `cd` out of the worktree to reach files; if a file outside the worktree is needed, the dependency is a planning gap — record it in `Out-of-plan edits` and continue.
17
- - **How to set cwd per Bash call**: the Claude Bash tool inherits its cwd from the lead session, which is NOT the worktree. To put cwd-sensitive toolchains (`cargo`, `npm`, `pnpm`, `bun`, `pytest`, `make`, `go`) into the worktree, prefix the command with `cd {{EXECUTOR_WORKTREE_PATH}} && ` inside the same Bash invocation — e.g. `cd {{EXECUTOR_WORKTREE_PATH}} && cargo test -p foo`. **Never wrap in `bash -lc "..."` or `bash -c "..."`** — the wrapper hides the leading `cd` token from Claude Code's permission auto-allow layer (causing prompts on every call) without any safety benefit. For tools that accept an explicit working-directory flag (`git -C <path>`, `cargo --manifest-path`, `pytest --rootdir`), prefer that form over the `cd && ` chain. Edit / Write / Read tool calls already use absolute paths and need no cwd handling. The codex / gemini executor CLI wrappers (`okstra-codex-exec.sh -C`, `okstra-gemini-exec.sh --include-directories`) already inject worktree cwd at the CLI layer, so this rule applies primarily to the Claude executor.
17
+ - **How to set cwd per Bash call**: the Claude Bash tool inherits its cwd from the lead session, which is NOT the worktree. To put cwd-sensitive toolchains (`cargo`, `npm`, `pnpm`, `bun`, `pytest`, `make`, `go`) into the worktree, prefix the command with `cd {{EXECUTOR_WORKTREE_PATH}} && ` inside the same Bash invocation — e.g. `cd {{EXECUTOR_WORKTREE_PATH}} && cargo test -p foo`. **Never wrap in `bash -lc "..."` or `bash -c "..."`** — the wrapper hides the leading `cd` token from Claude Code's permission auto-allow layer (causing prompts on every call) without any safety benefit. For tools that accept an explicit working-directory flag (`git -C <path>`, `cargo --manifest-path`, `pytest --rootdir`), prefer that form over the `cd && ` chain. Edit / Write / Read tool calls already use absolute paths and need no cwd handling. The codex / antigravity executor CLI wrappers (`okstra-codex-exec.sh -C`, `okstra-antigravity-exec.sh --include-directories`) already inject worktree cwd at the CLI layer, so this rule applies primarily to the Claude executor.
18
18
  - **Synced okstra state directory.** At provision time `okstra-ctl` may symlink `.project-docs/` from the repo's **main worktree** into the task worktree. This is NOT an independent copy — writes through it land in the main worktree. Inside this run the executor MUST confine okstra artifact writes to its own task scope (i.e. `.okstra/tasks/<this-task-id>/...`). Other synced directories, if present due to local configuration, are not implicit okstra context; read them only when the brief explicitly cites them as source material.
19
19
 
20
20
  ## Pre-implementation context exploration (executor before first edit)
21
21
 
22
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): resolved `Coding preflight pack:` runtime-resource path usage, 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
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).
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.
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`.
24
+ - **CLI executor (BLOCKING when the executor provider is `codex` or `antigravity`):** 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).
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/antigravity executor honors the prior-stage behavior-freeze. Declaration-level — no wrapper sentinel.
26
+ - **Non-interactive auto-execution (BLOCKING when the executor provider is `codex` or `antigravity`).** A CLI executor runs head-less (`codex exec` / antigravity 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`.
27
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.
28
28
  - Order of operations per plan step: (1) write/extend the test that captures the step's acceptance criterion and confirm it fails for the right reason, (2) commit the failing test (`test(<scope>): ...`), (3) implement the minimum change to make it pass, (4) commit the implementation (`feat|fix(<scope>): ...`), (5) refactor without changing behaviour and commit separately if any cleanup is made (`refactor(<scope>): ...`). The failing-then-passing transition between steps (2) and (4) is the `TDD evidence` required by the final report.
29
29
  - Doc-only / config-only / pure-rename steps that have no observable runtime behaviour are exempt from the failing-test requirement, but the executor MUST cite the exemption per step in the final report (`TDD exemption: <reason>`).
@@ -9,10 +9,10 @@ at Phase 5, BEFORE constructing the verifier worker dispatch prompts.
9
9
 
10
10
  ## Verifier roles (resolved at run-prep time)
11
11
 
12
- - **Verifier dispatch labelling.** When Lead dispatches a verifier (here, and identically in `final-verification`) it MUST set the Agent `name` to `<provider>-verifier` (e.g. `claude-verifier`, `codex-verifier`) — NOT the generic `<provider>-worker` — so the FleetView teammate pill names the job; see `prompts/lead/okstra-lead-contract.md` Phase 4 "Agent `name` on dispatch". For a `codex` / `gemini` verifier, Lead MUST additionally inject a `**Pane role:** verifier` line into the dispatched prompt body so the CLI wrapper titles its tmux trace pane `<cli>-verifier-<pid>` (the wrapper reads that line per `agents/workers/_cli-wrapper-template.md`). Token attribution is unaffected — the collector matches any `agentName` beginning `<provider>-`.
13
- - The verifier slots are `Claude verifier` and `Codex verifier`, plus `Gemini verifier` **only when `gemini` is in the resolved `--workers` roster**. Every verifier in the resolved roster is dispatched regardless of which provider holds the executor role; the executor's own provider is run *separately* as a verifier (a fresh CLI session with no shared context) so that no verdict is produced from the same session that wrote the diff. Verifiers MUST NOT call Edit, Write, or any Bash command that mutates files outside the run's artifact directories. If a verifier wants a fix, it records the recommendation in its worker result; it does not apply the fix itself.
12
+ - **Verifier dispatch labelling.** When Lead dispatches a verifier (here, and identically in `final-verification`) it MUST set the Agent `name` to `<provider>-verifier` (e.g. `claude-verifier`, `codex-verifier`) — NOT the generic `<provider>-worker` — so the FleetView teammate pill names the job; see `prompts/lead/okstra-lead-contract.md` Phase 4 "Agent `name` on dispatch". For a `codex` / `antigravity` verifier, Lead MUST additionally inject a `**Pane role:** verifier` line into the dispatched prompt body so the CLI wrapper titles its tmux trace pane `<cli>-verifier-<pid>` (the wrapper reads that line per `agents/workers/_cli-wrapper-template.md`). Token attribution is unaffected — the collector matches any `agentName` beginning `<provider>-`.
13
+ - The verifier slots are `Claude verifier` and `Codex verifier`, plus `Antigravity verifier` **only when `antigravity` is in the resolved `--workers` roster**. Every verifier in the resolved roster is dispatched regardless of which provider holds the executor role; the executor's own provider is run *separately* as a verifier (a fresh CLI session with no shared context) so that no verdict is produced from the same session that wrote the diff. Verifiers MUST NOT call Edit, Write, or any Bash command that mutates files outside the run's artifact directories. If a verifier wants a fix, it records the recommendation in its worker result; it does not apply the fix itself.
14
14
  - Session isolation — not model-variant divergence — is the primary self-review safeguard: each verifier is a separate CLI invocation with its own context window, so reusing the same model variant for executor and same-provider verifier is acceptable. Different model variants (e.g. executor=opus / Claude verifier=sonnet) remain recommended when available.
15
- - Phase-specific model defaults override the shared defaults: `Claude verifier`=`opus`, `Codex verifier`=`gpt-5.5`, `Gemini verifier`=`auto` (only when present in the roster). The `Executor`'s model is taken from the provider-specific worker model corresponding to `--executor`: claude→`--claude-model` (default `opus`), codex→`--codex-model` (default `gpt-5.5`), gemini→`--gemini-model` (default `auto`).
15
+ - Phase-specific model defaults override the shared defaults: `Claude verifier`=`opus`, `Codex verifier`=`gpt-5.5`, `Antigravity verifier`=`auto` (only when present in the roster). The `Executor`'s model is taken from the provider-specific worker model corresponding to `--executor`: claude→`--claude-model` (default `opus`), codex→`--codex-model` (default `gpt-5.5`), antigravity→`--antigravity-model` (default `auto`).
16
16
  - Verifiers read from the SAME working tree path the Executor used so they observe the exact diff the Executor produced. Verifiers remain strictly read-only there.
17
17
 
18
18
  ## Verifier QA duties (independent re-run mandate)
@@ -114,7 +114,7 @@ A mocked unit test cannot observe the SQL a query builder actually emits — `co
114
114
 
115
115
  ## All-verifier-failure policy
116
116
 
117
- If every verifier present in the resolved roster (`Claude verifier`, `Codex verifier`, and `Gemini verifier` when opted in) ends with a non-result terminal status (`timeout`, `error`, `not-run`) — i.e. zero independent verdicts were produced — the run MUST end with status `blocked` and route to a follow-up `error-analysis` run. `Claude lead` MUST NOT substitute its own verdict in place of the missing verifier outputs; synthesis requires at least one independent verifier's verdict. If one or more verifiers fail but at least one returns a verdict, the run proceeds with the surviving verdict(s) and the final report MUST explicitly notate which verifiers were unavailable, with the captured error / timeout evidence per failed verifier.
117
+ If every verifier present in the resolved roster (`Claude verifier`, `Codex verifier`, and `Antigravity verifier` when opted in) ends with a non-result terminal status (`timeout`, `error`, `not-run`) — i.e. zero independent verdicts were produced — the run MUST end with status `blocked` and route to a follow-up `error-analysis` run. `Claude lead` MUST NOT substitute its own verdict in place of the missing verifier outputs; synthesis requires at least one independent verifier's verdict. If one or more verifiers fail but at least one returns a verdict, the run proceeds with the surviving verdict(s) and the final report MUST explicitly notate which verifiers were unavailable, with the captured error / timeout evidence per failed verifier.
118
118
 
119
119
  ## Verifier-specific forbidden actions (any occurrence → terminal status `contract-violated`)
120
120
 
@@ -2,7 +2,7 @@
2
2
  Shared stage-discipline rule. INCLUDEd by implementation-planning.md (binds the
3
3
  planner) and implementation.md (binds the lead). The implementation executor
4
4
  sidecar instructs the lead to transcribe this rule into a CLI executor prompt,
5
- since codex/gemini executors do not share lead context.
5
+ since codex/antigravity executors do not share lead context.
6
6
 
7
7
  Do NOT write the literal include directive token in this file's body — the
8
8
  resolver matches it anywhere and would recurse on this file itself.
@@ -6,7 +6,7 @@
6
6
  - codex
7
7
  - report-writer
8
8
  - Optional workers (opt-in via `--workers`):
9
- - gemini — when added to the roster it joins the analyser set; omitted by default
9
+ - antigravity — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
11
  - Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
12
12
  - Apply the shared reporter-confirmation precondition exactly as written. In this phase, unresolved `intent-check:` / `conversion-block:` rows use `Blocks=next-phase`; any unconfirmed inference may be used as a labelled hypothesis only.
@@ -6,7 +6,7 @@
6
6
  - codex
7
7
  - report-writer
8
8
  - Optional workers (opt-in via `--workers`):
9
- - gemini — when added to the roster it joins the analyser set; omitted by default
9
+ - antigravity — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
11
  - Primary focus areas (each maps to a deliverable section below):
12
12
  - Acceptance-gating — a failure here pushes the verdict toward `blocked` / `conditional-accept`:
@@ -35,11 +35,11 @@
35
35
  "real database migrations, schema changes against shared environments, or writes to non-local datastores",
36
36
  "production credentials, deploy commands, infra mutation (`terraform apply`, `kubectl apply` against non-local cluster, etc.)",
37
37
  "external API write calls (POST/PUT/PATCH/DELETE) to third-party services other than localhost test fixtures",
38
- "source edits or Bash mutations performed by any verifier role (`Gemini verifier`, `Codex verifier`, `Claude verifier` are read-only — recommend, do not apply)",
38
+ "source edits or Bash mutations performed by any verifier role (`Antigravity verifier`, `Codex verifier`, `Claude verifier` are read-only — recommend, do not apply)",
39
39
  "dispatching parallel sub-agents beyond the required worker roster",
40
40
  "silent scope expansion: every file edited outside the approved plan list MUST appear in the `Out-of-plan edits` block with rationale",
41
41
  "leaving placeholders such as TBD / TODO / \"implement later\" / \"handle edge cases\" in newly-added lines of this run (check via `git diff <base>..HEAD | grep -E '^\\+[^+].*\\b(TBD|TODO|FIXME|XXX|implement later|handle edge cases|similar to|placeholder)\\b'`; pre-existing strings in untouched regions are out of scope)",
42
- "lead substituting its own verdict when every required verifier (`Gemini verifier`, `Codex verifier`, `Claude verifier`) returned a non-result terminal status (`timeout`/`error`/`not-run`); in that case the run MUST end as `blocked` with routing recommendation back to `error-analysis`, never with a lead-only verdict",
42
+ "lead substituting its own verdict when every required verifier (`Antigravity verifier`, `Codex verifier`, `Claude verifier`) returned a non-result terminal status (`timeout`/`error`/`not-run`); in that case the run MUST end as `blocked` with routing recommendation back to `error-analysis`, never with a lead-only verdict",
43
43
  "claiming rollback verification on a schema migration, config-format change, or any persisted-state mutation without a recorded dry-run of the rollback step and its captured exit code",
44
44
  "declaring overall task acceptance — that is `final-verification` ownership; this phase reports only \"ready for final-verification\" or \"needs new planning loop\"",
45
45
  "delegating the self-review pass to a generic subagent — `Claude lead` must run it"
@@ -6,7 +6,7 @@
6
6
  - codex
7
7
  - report-writer
8
8
  - Optional workers (opt-in via `--workers`):
9
- - gemini — when added to the roster it joins the analyser set; omitted by default
9
+ - antigravity — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
11
  {{INCLUDE:_stage-discipline.md}}
12
12
  - Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
@@ -7,13 +7,13 @@
7
7
  - codex
8
8
  - report-writer
9
9
  - Optional workers (opt-in via `--workers`):
10
- - gemini — when added to the roster it joins the verifier set; when omitted only the Claude+Codex verifiers participate (`--executor gemini` is therefore not selectable without explicitly listing `gemini` in `--workers`)
10
+ - antigravity — when added to the roster it joins the verifier set; when omitted only the Claude+Codex verifiers participate (`--executor antigravity` is therefore not selectable without explicitly listing `antigravity` in `--workers`)
11
11
  - **Executor binding (resolved at run-prep time, fixed for this run):**
12
12
  - Executor display name: `{{EXECUTOR_DISPLAY_NAME}}`
13
- - Executor provider: `{{EXECUTOR_PROVIDER}}` (one of: `claude` | `codex` | `gemini`; chosen via `--executor` or `OKSTRA_DEFAULT_EXECUTOR`, default `claude`)
13
+ - Executor provider: `{{EXECUTOR_PROVIDER}}` (one of: `claude` | `codex` | `antigravity`; chosen via `--executor` or `OKSTRA_DEFAULT_EXECUTOR`, default `claude`)
14
14
  - Executor subagent for dispatch: `{{EXECUTOR_WORKER_AGENT}}`
15
15
  - Executor model: `{{EXECUTOR_MODEL_DISPLAY}}` (launch value: `{{EXECUTOR_MODEL_EXECUTION_VALUE}}`)
16
- - Wherever this profile mentions the `Executor`, it refers to the role bound above. The other two providers in the roster (`claude` / `codex` / `gemini` minus the executor) are dispatched as **verifiers only** for this run and remain strictly read-only.
16
+ - Wherever this profile mentions the `Executor`, it refers to the role bound above. The other two providers in the roster (`claude` / `codex` / `antigravity` minus the executor) are dispatched as **verifiers only** for this run and remain strictly read-only.
17
17
  {{INCLUDE:_common-contract.md}}
18
18
  {{INCLUDE:_stage-discipline.md}}
19
19
  - Pre-implementation gate (mandatory — refuse to start if any item fails):
@@ -4,7 +4,7 @@
4
4
  - Required workers:
5
5
  - claude
6
6
  - codex
7
- - gemini
7
+ - antigravity
8
8
  - report-writer
9
9
  - Optional workers (opt-in via `--workers`):
10
10
  - none — every required worker stays required because lens diversity is the load-bearing value of this phase
@@ -21,7 +21,7 @@
21
21
  - per-candidate severity / effort / recommended-next-phase
22
22
  - convergence classification (full / partial / contested / worker-unique) across workers
23
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.
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 `antigravity` at lens 3, wrapping around when fewer lenses are present.
25
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
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
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.
@@ -34,7 +34,7 @@
34
34
  - Decision-tree walk (bounded):
35
35
  - When candidates branch on a structural question (e.g. "is module X meant to own this responsibility?"), resolve via `Read` / `Grep` first. Only escalate to the user inside the Phase 1.5 budget.
36
36
  - Expected output emphasis:
37
- - the `## 5.9 Improvement Candidates` table populated with rows that obey the 10-column schema from `validators/validate-improvement-report.py` (Cand ID `I-NNN`, Lens from whitelist, Title, Scope ⊆ scan-scope, Severity, Effort, Consensus, Source workers `<worker>:<id>` from {claude, codex, gemini}, Recommended next-phase ∈ {requirements-discovery, implementation-planning, error-analysis}, Evidence as path:line list)
37
+ - the `## 5.9 Improvement Candidates` table populated with rows that obey the 10-column schema from `validators/validate-improvement-report.py` (Cand ID `I-NNN`, Lens from whitelist, Title, Scope ⊆ scan-scope, Severity, Effort, Consensus, Source workers `<worker>:<id>` from {claude, codex, antigravity}, Recommended next-phase ∈ {requirements-discovery, implementation-planning, error-analysis}, Evidence as path:line list)
38
38
  - `Consensus` cells in `## 5.9 Improvement Candidates` use the table enum exactly: `full`, `partial`, `contested`, `worker-unique`. Map convergence's `full-consensus` / `partial-consensus` labels to `full` / `partial` before writing the table.
39
39
  - `## 7. Final Verdict` Verdict Token ∈ {`candidates-ready`, `no-candidates`, `blocked`}; Direction `routing`; Next Step "사용자에게 후보 K개 선택 의뢰 (## 5.9 표 참조)"
40
40
  - `## 3. Recommended Next Steps` first entry summarises per-candidate routing and proposes new task-key names of the form `<task-group>/imp-<Cand-ID>`
@@ -6,7 +6,7 @@
6
6
  - codex
7
7
  - report-writer
8
8
  - Optional workers (opt-in via `--workers`):
9
- - gemini — when added to the roster it joins the analyser set; omitted by default
9
+ - antigravity — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
11
  - Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
12
12
  - Apply the shared reporter-confirmation precondition exactly as written. In this phase, unresolved `intent-check:` / `conversion-block:` rows use `Blocks=next-phase`.
@@ -290,7 +290,7 @@
290
290
  }
291
291
  },
292
292
  "clarification_pick": {
293
- "label": "clarification-response 파일 경로가 있나요? (follow-up 시에만)",
293
+ "label": "clarification-response 넘길까요? (follow-up 시에만 — final-report 선택 시 user-responses/ 폴더의 답변도 함께 첨부됩니다)",
294
294
  "echo_template": "clarification(pick): {value}",
295
295
  "options": {
296
296
  "__skip__": "없음 (건너뛰기)",
@@ -299,6 +299,10 @@
299
299
  "labels": {
300
300
  "latest_report": "최근 final-report 사용: {snippet}"
301
301
  },
302
+ "sidecar_note": {
303
+ "attached": " + user-responses 답변 {count}개 함께 첨부",
304
+ "empty": " (user-responses 폴더 비어 있음 — final-report 만 첨부)"
305
+ },
302
306
  "echo_suffixes": {
303
307
  "skip": "clarification: (none)",
304
308
  "latest_report": "clarification: {value} (재사용)"
@@ -354,7 +358,7 @@
354
358
  }
355
359
  },
356
360
  "defaults_or_custom": {
357
- "label": "역할별 모델·실행 옵션 단계입니다 (참여 워커 구성을 바꾸는 게 아닙니다).\n이번 run 의 워커: {workers}\n· 기본값으로 진행 — 모든 역할을 추천 모델로 둡니다. 추천 기본값: lead·report-writer=opus, claude=opus, codex=gpt-5.5, gemini=auto (실제 값은 runtime 기본값으로 해소). directive·관련 task 없이 바로 진행.\n· 커스터마이즈 — 역할별 모델을 직접 고르고, 추가 directive·관련 task 도 지정합니다.",
361
+ "label": "역할별 모델·실행 옵션 단계입니다 (참여 워커 구성을 바꾸는 게 아닙니다).\n이번 run 의 워커: {workers}\n· 기본값으로 진행 — 모든 역할을 추천 모델로 둡니다. 추천 기본값: lead·report-writer=opus, claude=opus, codex=gpt-5.5, antigravity=auto (실제 값은 runtime 기본값으로 해소). directive·관련 task 없이 바로 진행.\n· 커스터마이즈 — 역할별 모델을 직접 고르고, 추가 directive·관련 task 도 지정합니다.",
358
362
  "echo_template": "customize: {value}",
359
363
  "options": {
360
364
  "defaults": "기본값으로 진행 (역할별 추천 모델 그대로)",
@@ -387,9 +391,9 @@
387
391
  "label": "codex 워커 모델?",
388
392
  "echo_template": "codex-model: {value}"
389
393
  },
390
- "gemini_model": {
391
- "label": "gemini 워커 모델?",
392
- "echo_template": "gemini-model: {value}"
394
+ "antigravity_model": {
395
+ "label": "antigravity 워커 모델?",
396
+ "echo_template": "antigravity-model: {value}"
393
397
  },
394
398
  "report_writer_model": {
395
399
  "label": "리포트 작성자(report-writer) 모델?",
@@ -52,6 +52,7 @@ from .reconcile import (
52
52
  normalize_central_status,
53
53
  normalize_reconciled_report_status,
54
54
  reconcile_active,
55
+ reconcile_recent,
55
56
  )
56
57
  from .listing import (
57
58
  _parse_since,
@@ -115,6 +116,7 @@ __all__ = [
115
116
  "read_run_context",
116
117
  "read_run_inputs",
117
118
  "reconcile_active",
119
+ "reconcile_recent",
118
120
  "record_start",
119
121
  "remove_jsonl_row",
120
122
  "remove_reservation",
@@ -69,7 +69,7 @@ def build_analysis_packet(
69
69
  instruction_set_relative_path: str,
70
70
  fix_history_text: str = "",
71
71
  ) -> str:
72
- """Return the primary compact input for Claude/Codex/Gemini analysers."""
72
+ """Return the primary compact input for Claude/Codex/Antigravity analysers."""
73
73
  brief_text = task_brief_path.read_text(encoding="utf-8")
74
74
  profile_text = analysis_profile_path.read_text(encoding="utf-8")
75
75
  reference_text = _read_optional(reference_expectations_path)
@@ -285,21 +285,31 @@ def section_1_present_but_unparsed(report_text: str) -> bool:
285
285
  return bool(_LOOSE_SECTION_1_RE.search(report_text))
286
286
 
287
287
 
288
- def clarification_response_with_sidecars(source: Path) -> str:
289
- """clarification-response 원문 뒤에 `user-responses/` 사이드카를 덧붙인 본문.
288
+ def user_response_sidecars(source: Path) -> list[Path]:
289
+ """``source`` 형제 ``user-responses/`` ``user-response-*.md`` 목록(이름 순).
290
290
 
291
291
  ``source`` 가 ``runs/<task-type>/reports/final-report-*.md`` 레이아웃일 때만
292
292
  형제 ``user-responses/`` 디렉토리를 찾는다(HTML 뷰의 `Export user response`
293
- 가 내려준 파일을 사용자가 거기 저장). 그 외 경로·사이드카 부재 시 원문 그대로 —
294
- 호출자는 항상 함수를 거쳐 instruction-set 사본을 쓰면 된다.
293
+ 가 내려준 파일을 사용자가 거기 저장). 그 외 경로·디렉토리 부재 시 목록.
294
+ carry-in 첨부 본문(``clarification_response_with_sidecars``)과 위저드 안내
295
+ 문구의 사이드카 카운트가 같은 한 곳을 보도록 하는 단일 참조점이다.
295
296
  """
296
- text = source.read_text(encoding="utf-8")
297
297
  responses_dir = source.parent.parent / "user-responses"
298
298
  if source.parent.name != "reports" or not responses_dir.is_dir():
299
- return text
300
- sidecars = sorted(
299
+ return []
300
+ return sorted(
301
301
  p for p in responses_dir.glob("user-response-*.md") if p.is_file()
302
302
  )
303
+
304
+
305
+ def clarification_response_with_sidecars(source: Path) -> str:
306
+ """clarification-response 원문 뒤에 `user-responses/` 사이드카를 덧붙인 본문.
307
+
308
+ 사이드카 부재 시 원문 그대로 — 호출자는 항상 이 함수를 거쳐 instruction-set
309
+ 사본을 쓰면 된다.
310
+ """
311
+ text = source.read_text(encoding="utf-8")
312
+ sidecars = user_response_sidecars(source)
303
313
  if not sidecars:
304
314
  return text
305
315
  parts = [text.rstrip("\n"), "\n\n---\n\n# Attached User Responses\n"]
@@ -26,7 +26,7 @@ from .worker_prompt_headers import WorkerPromptHeaderError, worker_prompt_header
26
26
 
27
27
  SUPPORTED_CLI_WORKERS = {
28
28
  "codex": "okstra-codex-exec.sh",
29
- "gemini": "okstra-gemini-exec.sh",
29
+ "antigravity": "okstra-antigravity-exec.sh",
30
30
  }
31
31
  BACKEND_CLI_WRAPPER = "cli-wrapper"
32
32
  BACKEND_MIXED = "mixed"
@@ -35,7 +35,7 @@ REPORT_WRITER_WORKER_ID = "report-writer"
35
35
  REPORT_LANGUAGE_VALUES = {"en", "ko", "auto"}
36
36
  ANALYSIS_WORKER_LABELS = {
37
37
  "codex": "Codex worker",
38
- "gemini": "Gemini worker",
38
+ "antigravity": "Antigravity worker",
39
39
  }
40
40
 
41
41
 
@@ -13,7 +13,7 @@ import sys
13
13
  from pathlib import Path
14
14
  from typing import Iterable
15
15
 
16
- from okstra_project import ResolverError, find_task_root, resolve_project_root
16
+ from okstra_ctl.task_target import resolve_task_root, project_rel
17
17
 
18
18
 
19
19
  INPUT_FILES = (
@@ -38,7 +38,7 @@ HOT_PATH_LEAD_RESOURCES = (
38
38
  WORKER_AGENT_FILES = (
39
39
  "claude-worker.md",
40
40
  "codex-worker.md",
41
- "gemini-worker.md",
41
+ "antigravity-worker.md",
42
42
  "report-writer-worker.md",
43
43
  )
44
44
  TIMESTAMPED_ARTIFACT_RE = re.compile(r"\d{4}-\d{2}-\d{2}[_T]\d{2}-\d{2}-\d{2}")
@@ -89,40 +89,6 @@ def _load_json(path: Path) -> dict:
89
89
  return data if isinstance(data, dict) else {}
90
90
 
91
91
 
92
- def _resolve_task_root(target: str, project_root: str, cwd: str) -> tuple[Path, Path]:
93
- target_path = Path(target).expanduser()
94
- if target_path.exists():
95
- task_root = target_path.resolve()
96
- return task_root, _infer_project_root(task_root)
97
-
98
- try:
99
- resolved_project = Path(
100
- resolve_project_root(explicit_root=project_root, cwd=cwd)
101
- ).resolve()
102
- except ResolverError as exc:
103
- raise SystemExit(f"project root resolution failed: {exc}") from exc
104
-
105
- task_root = find_task_root(resolved_project, target)
106
- if task_root is None:
107
- raise SystemExit(f"no task root for task key: {target}")
108
- return task_root.resolve(), resolved_project
109
-
110
-
111
- def _infer_project_root(task_root: Path) -> Path:
112
- parts = task_root.parts
113
- if ".okstra" not in parts:
114
- return task_root
115
- idx = parts.index(".okstra")
116
- return Path(*parts[:idx]).resolve()
117
-
118
-
119
- def _project_rel(path: Path, project_root: Path) -> str:
120
- try:
121
- return str(path.resolve().relative_to(project_root.resolve()))
122
- except ValueError:
123
- return str(path)
124
-
125
-
126
92
  def _find_current_run_dir(
127
93
  task_root: Path, manifest: dict, project_root: Path
128
94
  ) -> Path | None:
@@ -166,7 +132,7 @@ def _instruction_set_metric(task_root: Path, project_root: Path) -> dict:
166
132
  packet = instruction_set / "analysis-packet.md"
167
133
  legacy_packet = instruction_set / "task-packet.md"
168
134
  return {
169
- "path": _project_rel(instruction_set, project_root),
135
+ "path": project_rel(instruction_set, project_root),
170
136
  "fileCount": file_count,
171
137
  "bytes": byte_count,
172
138
  "estimatedTokens": _estimate_tokens(files),
@@ -263,7 +229,7 @@ def _lead_phase1_metric(
263
229
  "fileCount": file_count,
264
230
  "bytes": byte_count,
265
231
  "estimatedTokens": _estimate_tokens(files),
266
- "files": [_project_rel(path, project_root) for path in files if path.is_file()],
232
+ "files": [project_rel(path, project_root) for path in files if path.is_file()],
267
233
  }
268
234
 
269
235
 
@@ -300,9 +266,9 @@ def _analysis_worker_metric(task_root: Path, project_root: Path) -> dict:
300
266
  "legacyFullContractFileCount": full_file_count,
301
267
  "estimatedPacketModeBytesPerWorker": packet_byte_count,
302
268
  "estimatedReductionPercent": reduction_percent,
303
- "files": [_project_rel(path, project_root) for path in current_files if path.is_file()],
269
+ "files": [project_rel(path, project_root) for path in current_files if path.is_file()],
304
270
  "legacyFullContractFiles": [
305
- _project_rel(path, project_root)
271
+ project_rel(path, project_root)
306
272
  for path in full_contract_files
307
273
  if path.is_file()
308
274
  ],
@@ -360,7 +326,7 @@ def _report_writer_metric(run_dir: Path | None, task_root: Path, project_root: P
360
326
  "fileCount": file_count,
361
327
  "bytes": byte_count,
362
328
  "estimatedTokens": _estimate_tokens(files),
363
- "files": [_project_rel(path, project_root) for path in files if path.is_file()],
329
+ "files": [project_rel(path, project_root) for path in files if path.is_file()],
364
330
  }
365
331
 
366
332
 
@@ -377,11 +343,11 @@ def analyze_task_bundle(task_root: Path, project_root: Path) -> dict:
377
343
 
378
344
  return {
379
345
  "ok": True,
380
- "taskRoot": _project_rel(task_root, project_root),
346
+ "taskRoot": project_rel(task_root, project_root),
381
347
  "projectRoot": str(project_root),
382
348
  "taskKey": manifest.get("taskKey", ""),
383
349
  "taskType": manifest.get("taskType", ""),
384
- "currentRunPath": _project_rel(run_dir, project_root) if run_dir else "",
350
+ "currentRunPath": project_rel(run_dir, project_root) if run_dir else "",
385
351
  "totals": {
386
352
  "taskFileCount": task_file_count,
387
353
  "taskBytes": task_bytes,
@@ -406,7 +372,7 @@ def main(argv: list[str] | None = None) -> int:
406
372
  parser.add_argument("--cwd", default=".", help="cwd for project root resolution")
407
373
  args = parser.parse_args(argv)
408
374
 
409
- task_root, project_root = _resolve_task_root(args.target, args.project_root, args.cwd)
375
+ task_root, project_root = resolve_task_root(args.target, args.project_root, args.cwd)
410
376
  result = analyze_task_bundle(task_root, project_root)
411
377
  print(json.dumps(result, ensure_ascii=False, indent=2))
412
378
  return 0
@@ -155,7 +155,7 @@ def _release_handoff_checks(project_root: Path) -> list[DoctorCheck]:
155
155
  def _improvement_discovery_checks(workspace: Path, home: Path) -> list[DoctorCheck]:
156
156
  return [
157
157
  _worker_agents_check(home, workspace, "improvement-discovery"),
158
- _file_check("gemini worker agent", _agent_path(home, "gemini")),
158
+ _file_check("antigravity worker agent", _agent_path(home, "antigravity")),
159
159
  _lens_whitelist_check(),
160
160
  ]
161
161