okstra 0.86.0 → 0.87.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.
Files changed (103) 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/report_views.py +7 -13
  64. package/runtime/python/okstra_ctl/run.py +16 -16
  65. package/runtime/python/okstra_ctl/run_context.py +1 -1
  66. package/runtime/python/okstra_ctl/seeding.py +1 -1
  67. package/runtime/python/okstra_ctl/task_target.py +44 -0
  68. package/runtime/python/okstra_ctl/team.py +1 -1
  69. package/runtime/python/okstra_ctl/wizard.py +55 -30
  70. package/runtime/python/okstra_ctl/workers.py +3 -3
  71. package/runtime/python/okstra_ctl/workflow.py +1 -1
  72. package/runtime/python/okstra_ctl/worktree.py +1 -1
  73. package/runtime/python/okstra_token_usage/__init__.py +2 -3
  74. package/runtime/python/okstra_token_usage/antigravity.py +26 -0
  75. package/runtime/python/okstra_token_usage/blocks.py +4 -0
  76. package/runtime/python/okstra_token_usage/collect.py +20 -15
  77. package/runtime/python/okstra_token_usage/paths.py +0 -1
  78. package/runtime/python/okstra_token_usage/pricing.py +6 -3
  79. package/runtime/schemas/final-report-v1.0.schema.json +1 -1
  80. package/runtime/skills/okstra-brief/SKILL.md +1 -1
  81. package/runtime/skills/okstra-inspect/SKILL.md +85 -21
  82. package/runtime/skills/okstra-run/SKILL.md +3 -3
  83. package/runtime/skills/okstra-setup/SKILL.md +2 -2
  84. package/runtime/templates/prd/brief.template.md +2 -2
  85. package/runtime/templates/reports/i18n/en.json +1 -1
  86. package/runtime/templates/reports/i18n/ko.json +1 -1
  87. package/runtime/templates/reports/report.js +5 -11
  88. package/runtime/templates/reports/settings.template.json +2 -2
  89. package/runtime/templates/reports/task-brief.template.md +2 -2
  90. package/runtime/templates/worker-prompt-preamble.md +7 -7
  91. package/runtime/validators/forbidden_actions.py +1 -1
  92. package/runtime/validators/lib/fixtures.sh +3 -3
  93. package/runtime/validators/lib/validate-assets.sh +1 -1
  94. package/runtime/validators/validate-run.py +8 -8
  95. package/src/cli-registry.mjs +7 -0
  96. package/src/codex-dispatch.mjs +3 -3
  97. package/src/codex-run.mjs +2 -2
  98. package/src/doctor.mjs +1 -1
  99. package/src/error-report.mjs +27 -0
  100. package/src/install.mjs +1 -1
  101. package/src/render-bundle.mjs +1 -1
  102. package/src/uninstall.mjs +2 -2
  103. package/runtime/python/okstra_token_usage/gemini.py +0 -82
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Claude lead orchestrates multiple AI workers (Claude, Codex, Gemini) against a prepared task bundle, collects their independent outputs, supervises convergence, and ensures the final report is produced. When `Report writer worker` is in the selected roster, the final report file is **authored by the Report writer worker** — Claude lead reviews and approves but does not write the file itself. Claude lead never substitutes its own reasoning for a worker result, and never bypasses a rostered Report writer worker by writing the report directly.
5
+ Claude lead orchestrates multiple AI workers (Claude, Codex, Antigravity) against a prepared task bundle, collects their independent outputs, supervises convergence, and ensures the final report is produced. When `Report writer worker` is in the selected roster, the final report file is **authored by the Report writer worker** — Claude lead reviews and approves but does not write the file itself. Claude lead never substitutes its own reasoning for a worker result, and never bypasses a rostered Report writer worker by writing the report directly.
6
6
 
7
7
  ## When to Use
8
8
 
@@ -44,7 +44,7 @@ This document is the operating contract and phase index. Detailed procedures liv
44
44
  ## Core operating contract
45
45
 
46
46
  - `Claude lead` owns orchestration, convergence supervision, and final-report ownership (review/approval). It does NOT author the final-report file when `Report writer worker` is in the roster.
47
- - Standard worker roles: `Claude worker`, `Codex worker`, `Gemini worker`, `Report writer worker`. If the current run selects a subset, use only that subset with exact role labels from the task bundle.
47
+ - Standard worker roles: `Claude worker`, `Codex worker`, `Antigravity worker`, `Report writer worker`. If the current run selects a subset, use only that subset with exact role labels from the task bundle.
48
48
  - `Report writer worker`, when in the roster, is the **author** of the final-report file. Lead reviews the draft and may request a revision via a follow-up dispatch, but MUST NOT write the report itself as a "shortcut". The only legal lead-authored fallback is when a Report writer worker dispatch was actually attempted and recorded a terminal status of `error`/`timeout`/`not-run` with an explicit reason in team-state — see [report-writer](./report-writer.md) "Lead-authored fallback".
49
49
  - "Session resume", "team is no longer alive", and similar are NOT valid reasons to skip Report writer worker dispatch — see [report-writer](./report-writer.md) "Resume-safe dispatch".
50
50
  - If the brief is incomplete, continue with explicit uncertainty markers rather than fabricating confidence.
@@ -105,7 +105,7 @@ These lines are the only structured signal the user has during a long run. Do NO
105
105
 
106
106
  **The lead never invents a model.** Every role's model is read from `task-manifest.json` → `resultContract.requiredWorkerRoles[*].modelExecutionValue` (and the lead model metadata). A missing assignment is a manifest defect, not a license to fall back — see [team-contract](./team-contract.md) "Model Assignment Rules". The manifest is always populated at run-prep time by the CLI, which seeds these values from `OKSTRA_DEFAULT_*_MODEL` (`scripts/okstra_ctl/run.py`).
107
107
 
108
- **Reading the assignment is not enough — it must be applied at spawn.** For the in-process Claude subagents (`Claude worker`, `Report writer worker`), the manifest value is bound only when lead passes it as the `Agent(...)` `model:` parameter; their `model: inherit` frontmatter otherwise follows the lead's own model. See "Model Assignment Rules" #3–#5 in [team-contract](./team-contract.md) for the spawn rule, the family-token mapping, and the Codex/Gemini exemption.
108
+ **Reading the assignment is not enough — it must be applied at spawn.** For the in-process Claude subagents (`Claude worker`, `Report writer worker`), the manifest value is bound only when lead passes it as the `Agent(...)` `model:` parameter; their `model: inherit` frontmatter otherwise follows the lead's own model. See "Model Assignment Rules" #3–#5 in [team-contract](./team-contract.md) for the spawn rule, the family-token mapping, and the Codex/Antigravity exemption.
109
109
 
110
110
  The table below documents those prep-time seed values **for reference only** — it is NOT a lead-applied fallback:
111
111
 
@@ -115,20 +115,20 @@ The table below documents those prep-time seed values **for reference only** —
115
115
  | Report writer worker | opus | report-writer-worker | `agents/workers/report-writer-worker.md` |
116
116
  | Claude worker | opus | claude-worker | `agents/workers/claude-worker.md` |
117
117
  | Codex worker | gpt-5.5 | codex-worker | generated from `agents/workers/_cli-wrapper-template.md` + `codex-worker.params.json` |
118
- | Gemini worker | auto | gemini-worker | generated from `agents/workers/_cli-wrapper-template.md` + `gemini-worker.params.json` |
118
+ | Antigravity worker | auto | antigravity-worker | generated from `agents/workers/_cli-wrapper-template.md` + `antigravity-worker.params.json` |
119
119
 
120
- All three analysis workers use dedicated agent definitions; Codex/Gemini wrappers handle external CLI invocation internally; Claude worker runs as an in-process subagent with explicitly registered MCP tools so it does not fall back to `claude --mcp-cli` Bash invocations.
120
+ All three analysis workers use dedicated agent definitions; Codex/Antigravity wrappers handle external CLI invocation internally; Claude worker runs as an in-process subagent with explicitly registered MCP tools so it does not fall back to `claude --mcp-cli` Bash invocations.
121
121
 
122
122
  ### Implementation phase: Executor binding
123
123
 
124
- For `--task-type implementation` runs, the task bundle additionally pins one of `claude` / `codex` / `gemini` as the Executor — the only worker permitted to mutate project files in that run. The binding is exposed in two canonical places:
124
+ For `--task-type implementation` runs, the task bundle additionally pins one of `claude` / `codex` / `antigravity` as the Executor — the only worker permitted to mutate project files in that run. The binding is exposed in two canonical places:
125
125
 
126
126
  - `instruction-set/analysis-profile.md` — top "Executor binding" block (provider, displayName, workerAgent, model)
127
127
  - `runs/implementation/manifests/run-manifest-*.json` — `teamContract.executor` object (same fields plus `appliesTo: "implementation"`)
128
128
 
129
129
  Lead MUST dispatch Edit/Write-bearing work only through the `workerAgent` declared there. The other two providers still run as read-only verifiers in the same run; the executor's own provider is *also* dispatched separately as a verifier (a fresh CLI session) so the diff is reviewed by a context-isolated session. Session isolation is the primary self-review safeguard — same-model executor and same-provider verifier is acceptable when running in distinct sessions. Selecting a different model variant (e.g. executor=opus / Claude verifier=sonnet) is recommended but no longer mandatory.
130
130
 
131
- Executor is chosen at run-prep time via `--executor <claude|codex|gemini>` (or `OKSTRA_DEFAULT_EXECUTOR`, fallback `claude`); the model used by the executor is taken from the corresponding worker model flag (`--claude-model` / `--codex-model` / `--gemini-model`). For Codex/Gemini executors, the underlying file mutation happens inside the executor CLI's own auto-edit mode (e.g. `codex exec --sandbox workspace-write`), not through Claude-side Edit/Write tools.
131
+ Executor is chosen at run-prep time via `--executor <claude|codex|antigravity>` (or `OKSTRA_DEFAULT_EXECUTOR`, fallback `claude`); the model used by the executor is taken from the corresponding worker model flag (`--claude-model` / `--codex-model` / `--antigravity-model`). For Codex/Antigravity executors, the underlying file mutation happens inside the executor CLI's own auto-edit mode (e.g. `codex exec --sandbox workspace-write`), not through Claude-side Edit/Write tools.
132
132
 
133
133
  #### Task worktree (BLOCKING for every task-type)
134
134
 
@@ -196,7 +196,7 @@ These phases are governed by [team-contract](./team-contract.md). It is the cano
196
196
 
197
197
  - Worker prompt anchor headers and body composition rules.
198
198
  - The `[Required reading]` clause (analysis-packet primary input for analysis workers, full source files for report-writer, scoped inputs for reverify dispatches).
199
- - The `[Error reporting]` clause and the asymmetry between claude-worker and codex/gemini-worker prompts.
199
+ - The `[Error reporting]` clause and the asymmetry between claude-worker and codex/antigravity-worker prompts.
200
200
  - Worker output contract (sections 0–5), header standard, terminal statuses, errors-sidecar schema.
201
201
  - Token-usage tracking conventions.
202
202
 
@@ -213,7 +213,7 @@ These phases are governed by [team-contract](./team-contract.md). It is the cano
213
213
  4. If `TeamCreate` succeeds, proceed to Phase 4 (dispatch with `team_name`).
214
214
  5. If `TeamCreate` fails (tool unavailable, permission denied, environment lacks Agent Teams support), proceed to Phase 5 fallback (dispatch with `run_in_background: true` and no `team_name`).
215
215
 
216
- Use agent and subagent names that map cleanly to the selected worker roles. Do not create ambiguous role names that differ from `Claude worker`, `Codex worker`, `Gemini worker`, or `Report writer worker`.
216
+ Use agent and subagent names that map cleanly to the selected worker roles. Do not create ambiguous role names that differ from `Claude worker`, `Codex worker`, `Antigravity worker`, or `Report writer worker`.
217
217
 
218
218
  If the launch prompt contains `Tmux Worker Dispatch Gate`, Phase 3 is recorded as skipped with `reason: "tmux-pane"` and Phase 4 dispatch is performed only through `okstra team dispatch` followed by `okstra team await`. In this branch, calling `TeamCreate` or `Agent(...)` is a contract violation; worker completion is read from `workerDispatches[]` plus result files.
219
219
 
@@ -222,9 +222,9 @@ If the launch prompt contains `Tmux Worker Dispatch Gate`, Phase 3 is recorded a
222
222
 
223
223
  Spawn **analysis workers only** in the same turn (Phase 4 in Teams mode; Phase 5 with `run_in_background: true` and no `team_name` when Teams unavailable). Preserve exact roster, role labels, assigned models from the task bundle.
224
224
 
225
- **Agent `name` on dispatch (BLOCKING — token-usage attribution depends on it).** Every analysis-worker `Agent(...)` call MUST set `name: "<workerId>-worker"` — `name: "claude-worker"` / `name: "codex-worker"` / `name: "gemini-worker"` — exactly as the report-writer dispatch sets `name: "report-writer"` ([report-writer](./report-writer.md)). The Agent harness records this `name` as `agentName` in the subagent session jsonl, and the Phase 7 token collector matches each worker's session by that `agentName` (`okstra_token_usage/collect.py`). A worker dispatched **without** `name` produces a session with no `agentName`; the collector cannot attribute it and records the worker as `source: "unavailable"` even though the session exists and is team-tagged (observed in `dev-9692` error-analysis: `claude`/`codex` workers dispatched without `name` → both `unavailable`, while the named `report-writer` collected normally). Convergence reverify dispatches keep the prefix (`<workerId>-worker-reverify-r<N>`). For `implementation` and `final-verification` dispatches the `name` carries the **functional role** so the FleetView teammate pill and trace panes name the actual job instead of a generic `worker`: the Executor dispatch sets `name: "<workerId>-executor"` (e.g. `codex-executor`) and every verifier dispatch sets `name: "<workerId>-verifier"` (e.g. `claude-verifier`). These role suffixes still attribute correctly — the collector matches any `agentName` beginning `<workerId>-` (`okstra_token_usage/collect.py` `match_prefixes`). **For every CLI (Codex / Gemini) dispatch, Lead MUST inject a `**Pane role:**` line into the dispatched prompt body whose value is the Agent `name` with the leading `<cli>-` prefix removed** — the wrapper subagent reads it and passes it as the wrapper's 5th `<role>` argument so the tmux trace pane title reads `<cli>-<role>` (which equals the FleetView teammate name) instead of a generic `<cli>-worker` (see `agents/workers/_cli-wrapper-template.md`). So `name: "codex-worker"` → `**Pane role:** worker`, `name: "codex-worker-reverify-r1"` → `**Pane role:** worker-reverify-r1`, `name: "codex-executor"` → `**Pane role:** executor`, `name: "codex-verifier"` → `**Pane role:** verifier`. The wrapper defaults to `worker` when the line is absent, but always inject it so the pane names the actual job.
225
+ **Agent `name` on dispatch (BLOCKING — token-usage attribution depends on it).** Every analysis-worker `Agent(...)` call MUST set `name: "<workerId>-worker"` — `name: "claude-worker"` / `name: "codex-worker"` / `name: "antigravity-worker"` — exactly as the report-writer dispatch sets `name: "report-writer"` ([report-writer](./report-writer.md)). The Agent harness records this `name` as `agentName` in the subagent session jsonl, and the Phase 7 token collector matches each worker's session by that `agentName` (`okstra_token_usage/collect.py`). A worker dispatched **without** `name` produces a session with no `agentName`; the collector cannot attribute it and records the worker as `source: "unavailable"` even though the session exists and is team-tagged (observed in `dev-9692` error-analysis: `claude`/`codex` workers dispatched without `name` → both `unavailable`, while the named `report-writer` collected normally). Convergence reverify dispatches keep the prefix (`<workerId>-worker-reverify-r<N>`). For `implementation` and `final-verification` dispatches the `name` carries the **functional role** so the FleetView teammate pill and trace panes name the actual job instead of a generic `worker`: the Executor dispatch sets `name: "<workerId>-executor"` (e.g. `codex-executor`) and every verifier dispatch sets `name: "<workerId>-verifier"` (e.g. `claude-verifier`). These role suffixes still attribute correctly — the collector matches any `agentName` beginning `<workerId>-` (`okstra_token_usage/collect.py` `match_prefixes`). **For every CLI (Codex / Antigravity) dispatch, Lead MUST inject a `**Pane role:**` line into the dispatched prompt body whose value is the Agent `name` with the leading `<cli>-` prefix removed** — the wrapper subagent reads it and passes it as the wrapper's 5th `<role>` argument so the tmux trace pane title reads `<cli>-<role>` (which equals the FleetView teammate name) instead of a generic `<cli>-worker` (see `agents/workers/_cli-wrapper-template.md`). So `name: "codex-worker"` → `**Pane role:** worker`, `name: "codex-worker-reverify-r1"` → `**Pane role:** worker-reverify-r1`, `name: "codex-executor"` → `**Pane role:** executor`, `name: "codex-verifier"` → `**Pane role:** verifier`. The wrapper defaults to `worker` when the line is absent, but always inject it so the pane names the actual job.
226
226
 
227
- **Agent `model:` on dispatch (BLOCKING — assignment is otherwise ignored).** The `Claude worker` `Agent(...)` call MUST set `model: "<family token of that role's modelExecutionValue>"` (`fable` / `opus` / `sonnet` / `haiku`), per [team-contract](./team-contract.md) "Model Assignment Rules" #3–#4. The claude-worker definition is `model: inherit`, so omitting this parameter makes the worker silently run on the lead's model instead of its manifest assignment — the assigned-vs-actual deviation. `Codex worker` / `Gemini worker` are exempt: their CLI model is applied via the wrapper's own `--model` argument, so leave their Agent `model:` at `inherit` (rule #5).
227
+ **Agent `model:` on dispatch (BLOCKING — assignment is otherwise ignored).** The `Claude worker` `Agent(...)` call MUST set `model: "<family token of that role's modelExecutionValue>"` (`fable` / `opus` / `sonnet` / `haiku`), per [team-contract](./team-contract.md) "Model Assignment Rules" #3–#4. The claude-worker definition is `model: inherit`, so omitting this parameter makes the worker silently run on the lead's model instead of its manifest assignment — the assigned-vs-actual deviation. `Codex worker` / `Antigravity worker` are exempt: their CLI model is applied via the wrapper's own `--model` argument, so leave their Agent `model:` at `inherit` (rule #5).
228
228
 
229
229
  The no-`team_name` fallback (Phase 5) is legal when team-state's `teamCreate.status` is `"error"` (TeamCreate attempted and failed) OR `"skipped"` with `reason: "concurrent-run"` (the launch prompt's "Concurrent-run: no-team background" gate pre-decided no team to avoid racing a concurrent same-task run's `~/.claude/teams/` config). In both cases `teamCreate` is recorded in team-state before any dispatch. If `teamCreate` is missing or `attempted: false`, the correct action when an Agent dispatch is rejected for a missing team is to GO BACK to Phase 3 and call `TeamCreate` — never to strip `team_name` and continue.
230
230
 
@@ -239,7 +239,7 @@ The launch prompt's `## Run Logs (error-log wiring)` section gives Lead the reso
239
239
 
240
240
  Workers are contractually required to extract these two lines and abort with `<WORKER>_ERRORS_PATH_MISSING` if either is absent (see each worker definition's "Path extraction (BLOCKING)" block). Omitting these headers reproduces the historical bug class where every run's `errors-<task-type>-<seq>.jsonl` stayed empty because workers had only template placeholders to work from.
241
241
 
242
- After each worker terminates, BEFORE classifying its terminal status, verify the canonical result file exists at the absolute path resolved from the `**Result Path:**` header. If it is absent — or the wrapper sub-agent returned `CODEX_RESULT_MISSING` / `GEMINI_RESULT_MISSING` — re-dispatch the SAME worker once with the byte-identical prompt. Only after the second attempt also misses may the role be classified `error` with `--message "result-missing after 1 retry"`. Full rules: [team-contract](./team-contract.md) "Lead Redispatch Policy on Result-Missing".
242
+ After each worker terminates, BEFORE classifying its terminal status, verify the canonical result file exists at the absolute path resolved from the `**Result Path:**` header. If it is absent — or the wrapper sub-agent returned `CODEX_RESULT_MISSING` / `ANTIGRAVITY_RESULT_MISSING` — re-dispatch the SAME worker once with the byte-identical prompt. Only after the second attempt also misses may the role be classified `error` with `--message "result-missing after 1 retry"`. Full rules: [team-contract](./team-contract.md) "Lead Redispatch Policy on Result-Missing".
243
243
 
244
244
  After each worker terminates (any terminal status), if its errors sidecar exists, dump it to the run error log using the same resolved paths from the launch prompt:
245
245
 
@@ -250,7 +250,7 @@ okstra error-log append-from-worker \
250
250
  --task-key <taskKey> --agent <agent> --agent-role <role> --model <model>
251
251
  ```
252
252
 
253
- For Codex/Gemini wrappers: if the CLI returns non-zero, times out, or hits a rate limit, immediately call `okstra error-log append-observed --error-type cli-failure ...` with the captured exit code, duration, message, and stderr excerpt. The wrapper subagent does this from inside its own Bash tool — Lead does NOT need to re-record. Token usage is NOT available from Agent tool results in real time; it is collected post-hoc at the start of Phase 7.
253
+ For Codex/Antigravity wrappers: if the CLI returns non-zero, times out, or hits a rate limit, immediately call `okstra error-log append-observed --error-type cli-failure ...` with the captured exit code, duration, message, and stderr excerpt. The wrapper subagent does this from inside its own Bash tool — Lead does NOT need to re-record. Token usage is NOT available from Agent tool results in real time; it is collected post-hoc at the start of Phase 7.
254
254
 
255
255
  ## Phase 5.5: Convergence loop
256
256
 
@@ -319,7 +319,7 @@ Distinct from Phase 5.5 finding convergence:
319
319
  Lead's responsibilities in this sub-step (in order):
320
320
 
321
321
  1. Extract `P-*` plan items from the draft report's `## 5.4 Implementation Plan Deliverables` per the prefix → source-section mapping in the convergence contract.
322
- 2. Dispatch a single plan-body reverify round to every analyser worker in the roster (`claude`, `codex`, and `gemini` when opted in). `Report writer worker` is NOT a participant in this round.
322
+ 2. Dispatch a single plan-body reverify round to every analyser worker in the roster (`claude`, `codex`, and `antigravity` when opted in). `Report writer worker` is NOT a participant in this round.
323
323
  3. Aggregate verdicts and resolve the gate result to one of `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result`.
324
324
  4. Write `runs/<task-type>/state/plan-body-verification.json` (schema in the convergence contract).
325
325
  5. Populate `### 5.5.9 Plan Body Verification` in the final-report file (template at `templates/reports/final-report.template.md` §5.5.9 — Round count, Gate result, Verdict table, Dissent log).
@@ -381,7 +381,7 @@ After persistence, reply briefly in the resolved Report Language with: completio
381
381
  | Injecting `[Required reading]` into lightweight reverify prompts | Lightweight reverify forbids re-reading source materials — see [convergence](./convergence.md) "Reverify prompt: required-reading suppression" |
382
382
  | Letting `convergence.maxRounds` default to 2 for `requirements-discovery` | Resolve effective default to `1` for discovery and record in convergence state artifact |
383
383
  | Issuing serial Read calls in Phase 1 | The intake files are independent — issue all Read calls in a single message (parallel) |
384
- | Flagging the claude-worker dispatch prompt as "incomplete" because it lacks `[Required reading]` / `[Error reporting]` blocks | Intentional asymmetry — see [team-contract](./team-contract.md) "Asymmetry between claude-worker and codex/gemini-worker prompts" |
384
+ | Flagging the claude-worker dispatch prompt as "incomplete" because it lacks `[Required reading]` / `[Error reporting]` blocks | Intentional asymmetry — see [team-contract](./team-contract.md) "Asymmetry between claude-worker and codex/antigravity-worker prompts" |
385
385
  | Waiting silently while the dispatched `claude-worker` Agent call returns nothing for many minutes (the dev-9495 pattern: two 28+25-minute hangs before lead manually `tmux kill-pane`d) | The claude-worker MUST append a `- PROGRESS: <stage> <ISO-UTC>` line to its audit sidecar (`runs/<task-type>/worker-results/claude-worker-audit-<task-type>-<seq>.md`) at least every 5 minutes (see `agents/workers/claude-worker.md` "Heartbeat" rule). If the sidecar is absent or its mtime is >5 minutes stale, treat the dispatch as `timeout` and redispatch once with a byte-identical prompt; after a second silent hang, record terminal status `timeout` with the missing-sidecar reason in team-state. The authoritative completion signal is the **result file's appearance**, detected via self-scheduled polling (see [team-contract](./team-contract.md) "Worker-completion detection (self-scheduled polling)") — NOT the Agent-call return, which under `team_name` dispatch is just an immediate `Spawned successfully` ack. The heartbeat sidecar is an auxiliary liveness signal layered on top: a missing sidecar after the result file appears is itself a contract violation per the heartbeat rule |
386
386
  | Re-sending confirmed findings (`full-consensus`/`partial-consensus`/`worker-unique`) to a worker in Round 2 | Queue pruning rule — see [convergence](./convergence.md) "Round 1-N: Re-verification Loop (queue-pruned)" |
387
387
  | Aggregating a `timeout`/`error` reverify dispatch as `DISAGREE` | Worker failure handling — record as `verification-error` and add to `skippedWorkers[]`. See [convergence](./convergence.md) "Worker failure handling in reverify" |
@@ -158,17 +158,17 @@ The final report follows the structure encoded in `schemas/final-report-v1.0.sch
158
158
  | Claude Code | Claude lead | opus-4-6 | completed | 10,479,327 | 1,769,798 | $26.55 | 59m 12s | Final synthesis status |
159
159
  | Claude Code | Claude worker | sonnet | completed | 1,941,396 | 475,136 | $1.43 | 13m 33s | Key findings summary |
160
160
  | Codex | Codex worker | gpt-5.5 | completed | 2,274,011 (CLI: 5,261,833) | 586,223 | $8.79 (+ CLI $4.20) | 22m 06s | Key findings summary |
161
- | Gemini | Gemini worker | auto | completed | 3,107,795 | 746,623 | $11.20 | 22m 06s | Key findings summary |
161
+ | Antigravity | Antigravity worker | auto | completed | 3,107,795 | 746,623 | $11.20 | 22m 06s | Key findings summary |
162
162
  | Claude Code | Report writer | opus-4-6 | completed | 665,497 | 267,210 | $4.01 | 4m 20s | Report organization |
163
163
  ```
164
164
 
165
165
  Table Generation Rules:
166
166
  - The first row is always `Claude lead` with data from `leadUsage`; subsequent rows follow `recommendedWorkers` / `resultContract.requiredWorkerRoles` order.
167
- - Agent labels: Claude worker/Report writer → "Claude Code", Codex worker → "Codex", Gemini worker → "Gemini".
167
+ - Agent labels: Claude worker/Report writer → "Claude Code", Codex worker → "Codex", Antigravity worker → "Antigravity".
168
168
  - **처리 토큰** = `usage.totalTokens` (input + output + cache_creation + cache_read; the raw volume processed).
169
169
  - **환산 토큰** = `usage.billableEquivalentTokens` (cache reads weighted at 0.1×, cache_creation 1.25×, output 5×; useful as a single number for "how big was this session in cost terms").
170
- - **비용 (USD)** = `usage.estimatedCostUsd`. For Codex/Gemini workers that actually invoked the CLI, append `(+ CLI $X.XX)` from `usage.cliEstimatedCostUsd`.
171
- - For Codex/Gemini workers, append `(CLI: <cliTotalTokens>)` to the 처리 토큰 cell when `usage.cliTotalTokens` is set.
170
+ - **비용 (USD)** = `usage.estimatedCostUsd`. For Codex/Antigravity workers that actually invoked the CLI, append `(+ CLI $X.XX)` from `usage.cliEstimatedCostUsd`.
171
+ - For Codex/Antigravity workers, append `(CLI: <cliTotalTokens>)` to the 처리 토큰 cell when `usage.cliTotalTokens` is set.
172
172
  - Status values are retrieved from team-state; format duration as `Xm Ys` from `usage.durationMs`.
173
173
  - Workers with status `not-run` or with `source: "unavailable"` show `--` for tokens/cost/duration; quote the `note` underneath the table if useful.
174
174
 
@@ -186,7 +186,7 @@ Example (English mode shown — the renderer substitutes Korean when `meta.repor
186
186
  | Lead | 10,479,327 | 1,769,798 | $26.55 |
187
187
  | Worker subtotal | 7,988,699 | 2,075,192 | $25.43 |
188
188
  | **Grand total** | **18,468,026** | **3,844,990** | **$51.97** |
189
- | Codex/Gemini CLI add-on | | | $0.00 |
189
+ | Codex/Antigravity CLI add-on | | | $0.00 |
190
190
 
191
191
  > **How to read**: "Raw tokens" is the total tokens the model actually processed (input + output + cache_creation + cache_read). In long sessions cache_read can account for 95%+ making the number look large. "Billable tokens" weights cache_read at 0.1×, cache_creation at 1.25×, and output at 5× to give an input-equivalent figure closer to actual cost. Costs are estimates based on published Anthropic/OpenAI/Google pricing.
192
192
  ```
@@ -201,7 +201,7 @@ Token Summary Generation Rules:
201
201
  - **Lead** row: `usageSummary.leadTotalTokens` / `usageSummary.leadBillableEquivalentTokens` / `usageSummary.estimatedCostUsd.lead`.
202
202
  - **Worker subtotal** (ko: `Worker 합계`) row: `usageSummary.workerTotalTokens` / `usageSummary.workerBillableEquivalentTokens` / `usageSummary.estimatedCostUsd.claudeWorkers`.
203
203
  - **Grand total** (ko: `전체 합계`) row: `usageSummary.grandTotalTokens` / `usageSummary.grandBillableEquivalentTokens` / sum of `lead + claudeWorkers`.
204
- - **Codex/Gemini CLI add-on** (ko: `Codex/Gemini CLI 추가 비용`) row: `usageSummary.estimatedCostUsd.cliWorkers`. If 0, still show the row so the reader sees that no CLI work was billed under those providers (or that CLI fallback occurred).
204
+ - **Codex/Antigravity CLI add-on** (ko: `Codex/Antigravity CLI 추가 비용`) row: `usageSummary.estimatedCostUsd.cliWorkers`. If 0, still show the row so the reader sees that no CLI work was billed under those providers (or that CLI fallback occurred).
205
205
  - Format tokens with comma separators (e.g., `32,500`); format USD with two decimals (e.g., `$1.43`).
206
206
  - If `lead` or any `worker.usage` has `source: "unavailable"`, show `--` for that row and append a one-line note (`reason: <note>`).
207
207
  - If pricing for a model is unknown, the script omits `estimatedCostUsd` for that block — show `N/A` in that column and add a note like `pricing missing for model <model>`.
@@ -13,19 +13,19 @@ okstra tasks are always operated using the `Claude lead` + required worker team
13
13
 
14
14
  ### Role Definitions
15
15
 
16
- **All analysis workers (Claude / Codex / Gemini) share an identical core responsibility.** Specialization is additive — it lives in optional Section 6 of the worker output, NOT in differentiated core questions. This is intentional: cross-verification only converges if all three workers are answering the same questions against the same brief. Disjoint per-worker scopes produce union-of-perspectives, not triangulation.
16
+ **All analysis workers (Claude / Codex / Antigravity) share an identical core responsibility.** Specialization is additive — it lives in optional Section 6 of the worker output, NOT in differentiated core questions. This is intentional: cross-verification only converges if all three workers are answering the same questions against the same brief. Disjoint per-worker scopes produce union-of-perspectives, not triangulation.
17
17
 
18
18
  | Role | Core responsibility | Specialization lens (Section 6 only) | subagent_type | Notes |
19
19
  |------|------|------|---------------|------|
20
20
  | Claude lead | orchestration + convergence supervision + final-report review/approval | — | -- | Does NOT author the final-report file when `Report writer worker` is in the roster |
21
21
  | Claude worker | Answer every brief question across feasibility, requirement interpretation, hidden assumptions, and alternatives — with file:line evidence | broad reasoning depth, hidden assumptions, execution-risk surfacing | claude-worker | `agents/workers/claude-worker.md` |
22
22
  | Codex worker | Same core responsibility as Claude worker — identical questions, identical sections 1–5 | implementation realism, code-path implications, edge cases, technical trade-offs | codex-worker | generated from `agents/workers/_cli-wrapper-template.md` + `codex-worker.params.json` |
23
- | Gemini worker | Same core responsibility as Claude worker — identical questions, identical sections 1–5 | requirement interpretation, consistency, safety, alternative viewpoints | gemini-worker | generated from `agents/workers/_cli-wrapper-template.md` + `gemini-worker.params.json` |
23
+ | Antigravity worker | Same core responsibility as Claude worker — identical questions, identical sections 1–5 | requirement interpretation, consistency, safety, alternative viewpoints | antigravity-worker | generated from `agents/workers/_cli-wrapper-template.md` + `antigravity-worker.params.json` |
24
24
  | Report writer worker | **Authors** the final-report file in Phase 6. NOT an analysis worker. | — | report-writer-worker | `agents/workers/report-writer-worker.md`. Excluded from Phase 4/5 and convergence |
25
25
 
26
26
  **Model assignment has no default.** The model for every role comes from `resultContract.requiredWorkerRoles[*].modelExecutionValue` in `task-manifest.json` (and lead model metadata). There is no per-role hard-coded fallback — see "Model Assignment Rules" below.
27
27
 
28
- **Dispatch-prompt invariant (BLOCKING).** Lead's dispatch prompt body for Claude / Codex / Gemini workers MUST be byte-identical except for the role label and any wrapper-specific path headers (e.g. `**Worktree:**`, `**Errors sidecar path:**`). Lead MUST NOT bias the brief by inserting per-worker emphasis sentences ("you focus on X") into the body. Bias-by-prompt reproduces the historical failure mode where Claude commented only on assumptions, Codex only on code paths, and Gemini only on requirements — leaving convergence with nothing to converge on.
28
+ **Dispatch-prompt invariant (BLOCKING).** Lead's dispatch prompt body for Claude / Codex / Antigravity workers MUST be byte-identical except for the role label and any wrapper-specific path headers (e.g. `**Worktree:**`, `**Errors sidecar path:**`). Lead MUST NOT bias the brief by inserting per-worker emphasis sentences ("you focus on X") into the body. Bias-by-prompt reproduces the historical failure mode where Claude commented only on assumptions, Codex only on code paths, and Antigravity only on requirements — leaving convergence with nothing to converge on.
29
29
 
30
30
  ### Model Assignment Rules
31
31
 
@@ -33,7 +33,7 @@ okstra tasks are always operated using the `Claude lead` + required worker team
33
33
  2. If `modelExecutionValue` differs from `model`, use `modelExecutionValue` during execution.
34
34
  3. **Spawn-time enforcement for in-process Claude subagents (BLOCKING).** `Claude worker` and `Report writer worker` are in-process Claude subagents whose agent definitions declare `model: inherit` (`agents/workers/claude-worker.md`, `agents/workers/report-writer-worker.md`). `inherit` follows the **lead's** runtime model, NOT the role's assignment — so an opus assignment silently runs on a sonnet lead. To make the assignment binding (not merely declared), lead MUST pass an explicit `model:` parameter on every `Agent(...)` dispatch for these two roles, derived from that role's `modelExecutionValue`. The dispatch `model:` parameter overrides the `inherit` frontmatter; the frontmatter remains only as the fallback when no parameter is supplied. Omitting `model:` on a Claude-side dispatch is a contract violation that reproduces the assigned-vs-actual model deviation.
35
35
  4. **`modelExecutionValue` → Agent `model:` family token.** The Agent tool's `model` parameter accepts family tokens only — `fable` / `opus` / `sonnet` / `haiku` (an exact version such as `claude-opus-4-7` is NOT a valid value). Map by prefix: a `modelExecutionValue` of `fable*` / `claude-fable*` → `"fable"`, `opus*` / `claude-opus*` → `"opus"`, `sonnet*` / `claude-sonnet*` → `"sonnet"`, `haiku*` / `claude-haiku*` → `"haiku"`. This enforces the assignment at **family granularity** (fable vs opus vs sonnet vs haiku); the exact version within a family is still inherited from the lead session and cannot be pinned via this parameter.
36
- 5. **Codex / Gemini wrappers are out of scope for the Agent `model:` rule.** `Codex worker` / `Gemini worker` subagents are Claude wrappers that shell out to an external CLI; the role's `modelExecutionValue` is already applied via the CLI's own `--model <modelExecutionValue>` argument (see `agents/workers/_cli-wrapper-template.md`). The Agent `model:` parameter for these wrappers would only set the wrapper's own orchestration model, not the external CLI's model — leave it at `inherit` and do NOT map it from `modelExecutionValue`.
36
+ 5. **Codex / Antigravity wrappers are out of scope for the Agent `model:` rule.** `Codex worker` / `Antigravity worker` subagents are Claude wrappers that shell out to an external CLI; the role's `modelExecutionValue` is already applied via the CLI's own `--model <modelExecutionValue>` argument (see `agents/workers/_cli-wrapper-template.md`). The Agent `model:` parameter for these wrappers would only set the wrapper's own orchestration model, not the external CLI's model — leave it at `inherit` and do NOT map it from `modelExecutionValue`.
37
37
 
38
38
  ### Dynamic Worker Role Determination
39
39
 
@@ -43,8 +43,8 @@ Only workers selected from `recommendedWorkers` in `task-manifest.json` and `res
43
43
 
44
44
  - If one worker is selected: "`<role>` is the required worker role for this run."
45
45
  - If two or more workers are selected: "`<role1>`, `<role2>`, and `<role3>` are required worker roles."
46
- - If Gemini is selected: "`Gemini worker` must be attempted in this workflow."
47
- - If Gemini is not selected: "`Gemini worker` is not selected for this run, so it does not need to be attempted."
46
+ - If Antigravity is selected: "`Antigravity worker` must be attempted in this workflow."
47
+ - If Antigravity is not selected: "`Antigravity worker` is not selected for this run, so it does not need to be attempted."
48
48
 
49
49
  ## Operating Rules
50
50
 
@@ -68,7 +68,7 @@ Every worker prompt MUST start with the following anchor headers, in this exact
68
68
  1. `**Project Root:** <absolute-path>` — absolute target project root (from `{{PROJECT_ROOT}}` in the lead's prompt). Required so the worker can self-anchor without relying on inherited cwd.
69
69
  2. `**Prompt History Path:** <project-relative-path>`
70
70
  3. `**Result Path:** <project-relative-path>` — canonical destination for the worker's result file. Workers resolve it to absolute against `**Project Root:**` and use it for the post-completion existence check (see CLI wrapper agents' step 8c, and Lead's redispatch policy below). The path identifies a single file; do NOT deliver a directory.
71
- 4. `Assigned worker prompt history path: <absolute-path>` — same as the prompt-history path but resolved against `Project Root`. Codex/Gemini wrapper subagents extract this exact line.
71
+ 4. `Assigned worker prompt history path: <absolute-path>` — same as the prompt-history path but resolved against `Project Root`. Codex/Antigravity wrapper subagents extract this exact line.
72
72
  5. `**Worker Preamble Path:** <absolute-path>` — points to `~/.okstra/templates/worker-prompt-preamble.md` (canonical SSOT for Required Reading + Error Reporting + Anchor / Output sections). Workers Read this file end-to-end before producing any output. This anchor replaces the ~80 lines of inlined `[Required reading]` / `[Error reporting]` boilerplate that earlier versions injected into every dispatch.
73
73
  6. `**Coding preflight pack:** <absolute-path>` — points to the installed runtime resource pack under `<OKSTRA_HOME>/prompts/coding-preflight`. Implementation executors and verifiers use this to read `overview.md`, `clean-code.md`, and routed language/framework/architecture resources. Other worker roles may ignore it.
74
74
  7. `**Errors log path:** <absolute-path>` — run-level errors JSONL.
@@ -78,11 +78,11 @@ The body must include: role name, task type, task key, required bundle paths, as
78
78
 
79
79
  When a worker reads any project-relative path from the prompt, it MUST resolve it against `Project Root` (e.g. `<Project Root>/<Result Path>`) — never use bare relative paths that depend on cwd.
80
80
 
81
- If the task brief contains an `## Available MCP Servers` section, inject only the one-line pointer into every analysis worker's prompt (and into the report-writer prompt when it is dispatched in Phase 6) — the brief is already in every worker's [Required reading], so verbatim copy is redundant: `**MCP servers:** follow the task brief's "## Available MCP Servers" section (already in your Required reading).` Codex/Gemini workers run external CLIs whose MCP availability is governed by their own CLI configs; they can record `MCP not available in this CLI` cleanly after reading that section in the brief.
81
+ If the task brief contains an `## Available MCP Servers` section, inject only the one-line pointer into every analysis worker's prompt (and into the report-writer prompt when it is dispatched in Phase 6) — the brief is already in every worker's [Required reading], so verbatim copy is redundant: `**MCP servers:** follow the task brief's "## Available MCP Servers" section (already in your Required reading).` Codex/Antigravity workers run external CLIs whose MCP availability is governed by their own CLI configs; they can record `MCP not available in this CLI` cleanly after reading that section in the brief.
82
82
 
83
83
  Before dispatching any required worker, lead persists the exact worker prompt to the assigned current-run prompt history path under `runs/<task-type>/prompts/`. Do not use `/tmp/*prompt*.txt` as the canonical artifact path.
84
84
 
85
- Send byte-identical dispatch prompts to every analysis worker (Claude / Codex / Gemini), modulo the role label and the wrapper-specific path headers enumerated in the "Dispatch-prompt invariant" rule of the Role Definitions section. The prior "role-specific emphasis" guidance is retired — emphasis in the body biases each worker toward its lens and silently kills convergence (see Role Definitions for the failure mode). Specialization lives in Section 6 of the worker output, not in the dispatch prompt body.
85
+ Send byte-identical dispatch prompts to every analysis worker (Claude / Codex / Antigravity), modulo the role label and the wrapper-specific path headers enumerated in the "Dispatch-prompt invariant" rule of the Role Definitions section. The prior "role-specific emphasis" guidance is retired — emphasis in the body biases each worker toward its lens and silently kills convergence (see Role Definitions for the failure mode). Specialization lives in Section 6 of the worker output, not in the dispatch prompt body.
86
86
 
87
87
  ### Required Reading + Error Reporting via Worker Preamble (SSOT)
88
88
 
@@ -97,13 +97,13 @@ Audience-scoped file enumeration (BLOCKING — performance optimization):
97
97
 
98
98
  | Recipient | Files the lead lists under `## Inputs` |
99
99
  |---|---|
100
- | Claude / Codex / Gemini analysis workers | `analysis-packet.md` as primary input; source/fallback paths may be listed below it but are not automatic first-read files |
100
+ | Claude / Codex / Antigravity analysis workers | `analysis-packet.md` as primary input; source/fallback paths may be listed below it but are not automatic first-read files |
101
101
  | Report writer worker (Phase 6) | task-brief, analysis-profile, analysis-material, reference-expectations, clarification-response (if carry-in), **plus** the instruction-set-local `final-report-template.md` (phase-stripped) and `final-report-schema.json` (per-task-type excerpt) — NOT the full `templates/reports/...` / `schemas/...` sources |
102
102
  | Reverify dispatches | none — the lead provides only the items to reverify |
103
103
 
104
- Asymmetry note: `claude-worker` runs in-process and the Agent SDK auto-loads its agent definition; lead's dispatch prompt body for claude-worker can therefore be shorter than for codex/gemini. The Worker Preamble pointer is still emitted for all three so the contract source is identical regardless of dispatch path.
104
+ Asymmetry note: `claude-worker` runs in-process and the Agent SDK auto-loads its agent definition; lead's dispatch prompt body for claude-worker can therefore be shorter than for codex/antigravity. The Worker Preamble pointer is still emitted for all three so the contract source is identical regardless of dispatch path.
105
105
 
106
- Send byte-identical dispatch prompts to every analysis worker (Claude / Codex / Gemini), modulo the role label and the wrapper-specific path headers. The prior "role-specific emphasis" guidance is retired — specialization lives in Section 6 of the worker output, not in the dispatch prompt body.
106
+ Send byte-identical dispatch prompts to every analysis worker (Claude / Codex / Antigravity), modulo the role label and the wrapper-specific path headers. The prior "role-specific emphasis" guidance is retired — specialization lives in Section 6 of the worker output, not in the dispatch prompt body.
107
107
 
108
108
  ## Terminal Statuses
109
109
 
@@ -118,7 +118,7 @@ Terminal statuses that can be recorded for a worker:
118
118
 
119
119
  ## Worker-completion detection (self-scheduled polling)
120
120
 
121
- **SSOT.** This section is the single source of truth for how Lead detects worker completion across all phases and all worker kinds (Claude teammate, Codex / Gemini wrappers). Other documents (`prompts/lead/okstra-lead-contract.md`, `report-writer`, `convergence`) reference this section by name; they MUST NOT restate the algorithm.
121
+ **SSOT.** This section is the single source of truth for how Lead detects worker completion across all phases and all worker kinds (Claude teammate, Codex / Antigravity wrappers). Other documents (`prompts/lead/okstra-lead-contract.md`, `report-writer`, `convergence`) reference this section by name; they MUST NOT restate the algorithm.
122
122
 
123
123
  Lead dispatches workers asynchronously: an `Agent` call carrying `team_name` returns `Spawned successfully` **immediately** — that ack is NOT a completion. Lead MUST NOT treat the spawn ack as completion, and MUST NOT end its turn with a prose "waiting for ..." statement (that path stalls the run — the Agent Teams idle-notification is experimental and can be dropped, leaving Lead parked until the user manually nudges it). Instead:
124
124
 
@@ -146,7 +146,7 @@ For the Claude Code `team` backend, use the self-scheduled polling protocol belo
146
146
  echo "ALL_WORKERS_DONE"
147
147
  ```
148
148
 
149
- The `sleep 5` inside this `until` loop is legal ONLY because the poll runs under `run_in_background: true`. A foreground `sleep` of 5s or longer is blocked by the harness anti-circumvention rule (see the Codex / Gemini wrapper `BashOutput` polling contract above) — do NOT lift this loop into a foreground `Bash`.
149
+ The `sleep 5` inside this `until` loop is legal ONLY because the poll runs under `run_in_background: true`. A foreground `sleep` of 5s or longer is blocked by the harness anti-circumvention rule (see the Codex / Antigravity wrapper `BashOutput` polling contract above) — do NOT lift this loop into a foreground `Bash`.
150
150
  3. End the turn. The harness auto-resumes Lead when the background poll exits — on completion (`ALL_WORKERS_DONE`) OR timeout (`POLL_TIMEOUT`) — with no mailbox / idle-notification dependency and no user nudge.
151
151
  4. On resume, for every path still in the pending set: verify the file exists AND passes the standardized worker-result header check (see "Worker Result Header Standard" below). Move each passing worker to the **done set**.
152
152
  5. Termination:
@@ -163,16 +163,16 @@ For the Claude Code `team` backend, use the self-scheduled polling protocol belo
163
163
  | implementation | 20 min | 40 min |
164
164
  | final-verification | 10 min | 20 min |
165
165
 
166
- Relationship to the Codex / Gemini wrapper polling contract: that contract (in the errors-sidecar section above) governs how a *wrapper subagent* waits on its own external CLI via `BashOutput`. This section governs how *Lead* waits on the worker subagents themselves. The two compose — Lead's background poll watches the result files; each wrapper independently watches its CLI — and neither imposes a timeout on the other (see "No external timeout on wrapper subagents").
166
+ Relationship to the Codex / Antigravity wrapper polling contract: that contract (in the errors-sidecar section above) governs how a *wrapper subagent* waits on its own external CLI via `BashOutput`. This section governs how *Lead* waits on the worker subagents themselves. The two compose — Lead's background poll watches the result files; each wrapper independently watches its CLI — and neither imposes a timeout on the other (see "No external timeout on wrapper subagents").
167
167
 
168
168
  ## Lead Redispatch Policy on Result-Missing
169
169
 
170
- After each worker subagent returns (regardless of role), Lead MUST verify the canonical result file exists at the absolute path resolved from the `**Result Path:**` anchor header (against `**Project Root:**`). The check is identical for in-process workers (claude-worker) and CLI-wrapper workers (codex-worker / gemini-worker).
170
+ After each worker subagent returns (regardless of role), Lead MUST verify the canonical result file exists at the absolute path resolved from the `**Result Path:**` anchor header (against `**Project Root:**`). The check is identical for in-process workers (claude-worker) and CLI-wrapper workers (codex-worker / antigravity-worker).
171
171
 
172
172
  **Triggers (any of):**
173
173
 
174
- - The wrapper subagent returned an explicit `*_RESULT_MISSING` sentinel (codex-worker / gemini-worker step 8c — `CODEX_RESULT_MISSING` / `GEMINI_RESULT_MISSING`).
175
- - The result file is absent at the resolved absolute path even though the worker returned without a `*_RESULT_MISSING` sentinel — for example, claude-worker returned its final assistant message but never persisted the artifact, or the wrapper exited 0 and the codex/gemini sub-agent forwarded raw stdout despite the contract.
174
+ - The wrapper subagent returned an explicit `*_RESULT_MISSING` sentinel (codex-worker / antigravity-worker step 8c — `CODEX_RESULT_MISSING` / `ANTIGRAVITY_RESULT_MISSING`).
175
+ - The result file is absent at the resolved absolute path even though the worker returned without a `*_RESULT_MISSING` sentinel — for example, claude-worker returned its final assistant message but never persisted the artifact, or the wrapper exited 0 and the codex/antigravity sub-agent forwarded raw stdout despite the contract.
176
176
  - The result file exists but cannot be parsed (frontmatter unreadable, sections 1–5 entirely missing). A truncated file in the middle of section 5 is NOT covered here — it goes to the validator's regular `error` path, not the retry path.
177
177
 
178
178
  **One-retry policy:**
@@ -184,9 +184,9 @@ After each worker subagent returns (regardless of role), Lead MUST verify the ca
184
184
 
185
185
  **Logging.** Lead records the first attempt's `cli-failure` (already emitted by the wrapper sub-agent) as-is. The retry, on success, is logged via the normal worker-completion path; on failure (second `*_RESULT_MISSING`), Lead records a single `contract-violation` entry with `--message "result-missing after 1 retry"` referencing both attempts' bash_ids / prompt-history paths.
186
186
 
187
- **Diagnostic sidecar (advisory).** Both codex/gemini wrappers also write a heartbeat sidecar at `<prompt-path>.status.json` recording `started_ts`, `ended_ts`, `exit_code`, `duration_ms`, and the canonical `log_path` (see `scripts/okstra-wrapper-status.py` for the schema). Lead MAY read this sidecar when deciding whether the first attempt actually launched the CLI (stage=`exited`, `exit_code=0`, non-zero `duration_ms`) versus failed before reaching it (sidecar absent, or stage=`started` with no exit fields). The sidecar is best-effort — its absence is NOT by itself a reason to skip the retry; the canonical trigger remains the missing result file.
187
+ **Diagnostic sidecar (advisory).** Both codex/antigravity wrappers also write a heartbeat sidecar at `<prompt-path>.status.json` recording `started_ts`, `ended_ts`, `exit_code`, `duration_ms`, and the canonical `log_path` (see `scripts/okstra-wrapper-status.py` for the schema). Lead MAY read this sidecar when deciding whether the first attempt actually launched the CLI (stage=`exited`, `exit_code=0`, non-zero `duration_ms`) versus failed before reaching it (sidecar absent, or stage=`started` with no exit fields). The sidecar is best-effort — its absence is NOT by itself a reason to skip the retry; the canonical trigger remains the missing result file.
188
188
 
189
- **Rationale.** Observed failure mode: the CLI (codex/gemini) streams its full analysis to stdout but hits its token budget or a sandbox EPERM mid-`Write` of the result file, exiting 0 with no artifact. Forwarding the partial stdout silently degrades synthesis; classifying the role as `error` without retrying gives up a recoverable signal. A single retry catches the transient class of this failure (re-dispatch with the same prompt typically succeeds when the underlying cause was an intermittent sandbox lock or a token-budget spike) while bounding the retry cost to a known upper bound (~2× the original wrapper budget per role).
189
+ **Rationale.** Observed failure mode: the CLI (codex/antigravity) streams its full analysis to stdout but hits its token budget or a sandbox EPERM mid-`Write` of the result file, exiting 0 with no artifact. Forwarding the partial stdout silently degrades synthesis; classifying the role as `error` without retrying gives up a recoverable signal. A single retry catches the transient class of this failure (re-dispatch with the same prompt typically succeeds when the underlying cause was an intermittent sandbox lock or a token-budget spike) while bounding the retry cost to a known upper bound (~2× the original wrapper budget per role).
190
190
 
191
191
  ## Worker Output Contract
192
192
 
@@ -203,7 +203,7 @@ id: "<task-key with ':' replaced by '-'>"
203
203
  aliases: ["<id>-<task-type>"]
204
204
  tags: ["worker-result", "<task-type>"]
205
205
  taskType: "<task-type>"
206
- workerId: "<claude|codex|gemini|report-writer>"
206
+ workerId: "<claude|codex|antigravity|report-writer>"
207
207
  task-id: "<task-id>"
208
208
  task-group: "<task-group>"
209
209
  project-id: "<project-id>"
@@ -232,7 +232,7 @@ Rules:
232
232
  - `id` is the run's `task-key` with `:` replaced by `-`. It is a scalar string, NOT an array.
233
233
  - `aliases` is a YAML array containing a single value `"<id>-<task-type>"`.
234
234
  - `taskType` mirrors the run's task type (`requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`, `final-verification`, `release-handoff`).
235
- - `workerId` identifies which worker produced the file. Required values: `claude` / `codex` / `gemini` / `report-writer`.
235
+ - `workerId` identifies which worker produced the file. Required values: `claude` / `codex` / `antigravity` / `report-writer`.
236
236
  - Other fields (`task-id`, `task-group`, `project-id`, `date`) MUST match the input files' frontmatter exactly. If the input frontmatter is missing or unreadable, the worker MUST record a `tool-failure` and stop instead of guessing.
237
237
 
238
238
  The same frontmatter contract applies to the `Report writer worker`'s final-report file — the report-writer copies these values from its inputs and only swaps `workerId` to `report-writer`.
@@ -248,9 +248,9 @@ A successful worker result must include the following sections in this exact ord
248
248
  5. Recommended Next Actions
249
249
  6. **Specialization Lens (optional, worker-specific deep dive)** — additive content produced from this worker's specialization lens (see Role Definitions table). Items here are NOT subject to convergence cross-verification and MUST NOT duplicate sections 1–5. If the worker has nothing additional to add from its lens, omit Section 6 entirely or write `- No additional lens-specific findings.`
250
250
 
251
- **Sections 1–5 are the common core.** Every analysis worker (Claude / Codex / Gemini) MUST cover the same set of dimensions in sections 1–5 — feasibility, requirement interpretation, hidden assumptions, alternatives, and execution risk — regardless of which model is producing the result. The point of running three models is to triangulate the same answer space, not to partition it. A worker that produces "Findings" populated only with items from its own lens (e.g. Codex only listing implementation-feasibility findings) is in breach of contract; convergence will treat coverage gaps as `verification-error`.
251
+ **Sections 1–5 are the common core.** Every analysis worker (Claude / Codex / Antigravity) MUST cover the same set of dimensions in sections 1–5 — feasibility, requirement interpretation, hidden assumptions, alternatives, and execution risk — regardless of which model is producing the result. The point of running three models is to triangulate the same answer space, not to partition it. A worker that produces "Findings" populated only with items from its own lens (e.g. Codex only listing implementation-feasibility findings) is in breach of contract; convergence will treat coverage gaps as `verification-error`.
252
252
 
253
- **Section 6 is the only legal home for specialization.** When the worker has a depth-of-perspective contribution that genuinely sits outside the common core (e.g. a Codex-specific stack-trace decomposition, a Claude-specific assumption-chain teardown, a Gemini-specific alternative-architecture sketch), put it there. Lead and convergence treat Section 6 as additive context, not as input to consensus measurement.
253
+ **Section 6 is the only legal home for specialization.** When the worker has a depth-of-perspective contribution that genuinely sits outside the common core (e.g. a Codex-specific stack-trace decomposition, a Claude-specific assumption-chain teardown, a Antigravity-specific alternative-architecture sketch), put it there. Lead and convergence treat Section 6 as additive context, not as input to consensus measurement.
254
254
 
255
255
  Code evidence must include file paths and line numbers.
256
256
 
@@ -329,14 +329,14 @@ without proceeding — this is the contractual replacement for the previous
329
329
  "derive from template placeholders" behavior, which silently produced
330
330
  empty run-level error logs in production.
331
331
 
332
- - `cli-failure` events are recorded by the wrapper subagent itself (Codex / Gemini), but **directly to the run-level error log** via `okstra error-log append-observed --error-type cli-failure ...` — NOT via the sidecar. The sidecar is an in-process tool-failure channel only.
333
- - **Wrapper invocation arity.** Both `okstra-codex-exec.sh` and `okstra-gemini-exec.sh` accept four required positional arguments plus an optional fifth `<role>`: `<project-root> <model> <prompt-path> <worktree-path> [<role>]`. The fourth (worktree) argument is **mandatory for implementation phase** and optional otherwise. For codex it becomes `--add-dir <worktree>` (sandbox write access); for gemini it is appended to `--include-directories`. Omitting it during implementation causes the codex sandbox to reject every Edit/Write targeting the worktree with EPERM. Workers extract the path from the `**Worktree:**` / `EXECUTOR_WORKTREE_PATH` / `cwd for every mutating command:` line in the lead prompt. The optional fifth `<role>` is folded into both the caller (worker) pane title `<cli>-<role>-<pid>` and the sibling trace-pane title `<cli>-<role>-<pid>-tail` (e.g. `codex-executor-93421` ↔ `codex-executor-93421-tail`). `<pid>` is the wrapper's own PID and disambiguates concurrent dispatches of the same role. The role value comes from the dispatch prompt's `**Pane role:**` line: `executor` on an `implementation` Executor dispatch, `verifier` on an `implementation` / `final-verification` verifier dispatch, so the trace pane names the actual job rather than a generic `worker`. When no `**Pane role:**` line is present (analysis phases), pass the literal `worker` (the wrapper also defaults to `worker` if the argument is omitted).
334
- - **Background dispatch + polling contract (Codex / Gemini wrappers).** Both wrapper subagents MUST dispatch `okstra-codex-exec.sh` / `okstra-gemini-exec.sh` via `Bash(run_in_background: true)` and poll with `BashOutput(bash_id)` until the shell reports `status == "completed"`, capped at 30 minutes (1800s) of wall-clock elapsed time. `BashOutput` itself is the wait primitive — call it back-to-back; do NOT insert a standalone `sleep` between polls. The Claude Code harness blocks `sleep` calls of 5 seconds or longer as a circumvention vector and explicitly forbids chaining shorter sleeps inside until-loops to work around the block. Workers that hit the contract bug must NOT self-recover with `until ...; do sleep 2; done` wrappers — that path violates the harness anti-circumvention rule, even though it superficially "works". The legacy "single foreground `Bash` with 120000ms timeout" rule, and the subsequent "60-second cadence with `sleep 60` between polls" rule, are both retired. The current rule applies in **every phase** (analysis runs typically complete in 1–2 `BashOutput` calls, so there is no regression for short jobs). Recording responsibilities:
332
+ - `cli-failure` events are recorded by the wrapper subagent itself (Codex / Antigravity), but **directly to the run-level error log** via `okstra error-log append-observed --error-type cli-failure ...` — NOT via the sidecar. The sidecar is an in-process tool-failure channel only.
333
+ - **Wrapper invocation arity.** Both `okstra-codex-exec.sh` and `okstra-antigravity-exec.sh` accept four required positional arguments plus an optional fifth `<role>`: `<project-root> <model> <prompt-path> <worktree-path> [<role>]`. The fourth (worktree) argument is **mandatory for implementation phase** and optional otherwise. For codex it becomes `--add-dir <worktree>` (sandbox write access); for antigravity it is appended to `--include-directories`. Omitting it during implementation causes the codex sandbox to reject every Edit/Write targeting the worktree with EPERM. Workers extract the path from the `**Worktree:**` / `EXECUTOR_WORKTREE_PATH` / `cwd for every mutating command:` line in the lead prompt. The optional fifth `<role>` is folded into both the caller (worker) pane title `<cli>-<role>-<pid>` and the sibling trace-pane title `<cli>-<role>-<pid>-tail` (e.g. `codex-executor-93421` ↔ `codex-executor-93421-tail`). `<pid>` is the wrapper's own PID and disambiguates concurrent dispatches of the same role. The role value comes from the dispatch prompt's `**Pane role:**` line: `executor` on an `implementation` Executor dispatch, `verifier` on an `implementation` / `final-verification` verifier dispatch, so the trace pane names the actual job rather than a generic `worker`. When no `**Pane role:**` line is present (analysis phases), pass the literal `worker` (the wrapper also defaults to `worker` if the argument is omitted).
334
+ - **Background dispatch + polling contract (Codex / Antigravity wrappers).** Both wrapper subagents MUST dispatch `okstra-codex-exec.sh` / `okstra-antigravity-exec.sh` via `Bash(run_in_background: true)` and poll with `BashOutput(bash_id)` until the shell reports `status == "completed"`, capped at 30 minutes (1800s) of wall-clock elapsed time. `BashOutput` itself is the wait primitive — call it back-to-back; do NOT insert a standalone `sleep` between polls. The Claude Code harness blocks `sleep` calls of 5 seconds or longer as a circumvention vector and explicitly forbids chaining shorter sleeps inside until-loops to work around the block. Workers that hit the contract bug must NOT self-recover with `until ...; do sleep 2; done` wrappers — that path violates the harness anti-circumvention rule, even though it superficially "works". The legacy "single foreground `Bash` with 120000ms timeout" rule, and the subsequent "60-second cadence with `sleep 60` between polls" rule, are both retired. The current rule applies in **every phase** (analysis runs typically complete in 1–2 `BashOutput` calls, so there is no regression for short jobs). Recording responsibilities:
335
335
  - Successful completion: return the wrapper's accumulated stdout from the final `BashOutput`. No log entry.
336
336
  - Non-zero `exit_code` reported by `BashOutput`: record a `cli-failure` to the run-level error log with the real `exit_code` and observed `duration-ms`.
337
337
  - Polling cap reached: before `KillShell`, perform a one-shot **mtime-grace check** on the wrapper's live log (`<prompt>.log`). If the log was written within the last 90 seconds AND grace has not yet been applied this loop, extend the cap from 1800s → 2100s (one-shot +5min) and continue polling. Otherwise (log stale, OR grace already applied), call `KillShell(shell_id)`, record `cli-failure` with `--exit-code 124 --duration-ms <observed_ms> --message "<wrapper> exceeded polling cap (grace=<applied|not-applied>, last_mtime_age=<n>s)"`, then return the language-specific `*_CLI_TIMEOUT` sentinel. The grace exists to absorb token-budget spikes where the CLI is genuinely still producing output past the 30-minute mark; it is a one-shot soft extension, NOT a loop.
338
338
  - Token-usage matching is unaffected: the wrapper subagent stays alive throughout polling, so the wrapper's jsonl timestamp window continues to cover the underlying CLI rollout's full duration (see §"Token-usage accounting" below).
339
- - **No external timeout on wrapper subagents.** The codex/gemini wrapper subagent's polling loop (with optional mtime grace) is the SINGLE timeout authority for its dispatch. Lead MUST NOT impose a separate `Agent()` call timeout, an outer `Bash` wall-clock deadline, or any other mechanism that terminates the subagent before its own polling cap is reached. Doing so reproduces the historical failure mode that motivated this rule: Lead aborts the subagent at e.g. 18 minutes, the subagent returns nothing, and Lead classifies the role as "no response" while the underlying CLI was actively working. The wrapper's polling cap (30min + optional 5min grace) is calibrated so that, combined with Lead's redispatch policy (see "Lead Redispatch Policy on Result-Missing"), a recoverable single-run failure costs at most ~70 minutes of wall-clock — predictable enough to plan around. If a specific run requires a tighter cap, lower it in the wrapper subagent's polling contract (single source of truth), NOT by layering Lead-side timeouts.
339
+ - **No external timeout on wrapper subagents.** The codex/antigravity wrapper subagent's polling loop (with optional mtime grace) is the SINGLE timeout authority for its dispatch. Lead MUST NOT impose a separate `Agent()` call timeout, an outer `Bash` wall-clock deadline, or any other mechanism that terminates the subagent before its own polling cap is reached. Doing so reproduces the historical failure mode that motivated this rule: Lead aborts the subagent at e.g. 18 minutes, the subagent returns nothing, and Lead classifies the role as "no response" while the underlying CLI was actively working. The wrapper's polling cap (30min + optional 5min grace) is calibrated so that, combined with Lead's redispatch policy (see "Lead Redispatch Policy on Result-Missing"), a recoverable single-run failure costs at most ~70 minutes of wall-clock — predictable enough to plan around. If a specific run requires a tighter cap, lower it in the wrapper subagent's polling contract (single source of truth), NOT by layering Lead-side timeouts.
340
340
  - `contract-violation` events (C) are recorded by Lead via `okstra error-log append-observed --error-type contract-violation ...` after inspecting worker outputs.
341
341
  - Lead's responsibility regarding the sidecar is to dump it to the run-level error log via `okstra error-log append-from-worker` after each worker terminates; Lead does not write into the sidecar.
342
342
 
@@ -413,9 +413,9 @@ okstra token-usage /abs/path/to/run/state/team-state-<task-type>-<seq>.json --wr
413
413
  `okstra token-usage` is a thin Node-side wrapper around the python helper installed at `~/.okstra/bin/okstra-token-usage.py`. Calling the python script directly with `python3 "$HOME/..."` is forbidden — the `$HOME` expansion breaks the literal-token permission match and forces a confirmation prompt every call.
414
414
 
415
415
  The script reads:
416
- - `~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl` for the lead and every Claude-side worker (Claude worker, Report writer worker, plus the Claude wrappers around Codex/Gemini workers). Sessions are discovered by the recorded team-state `teamName`, lead is identified by `lead.sessionId`, and other workers are identified by `agentName` (e.g. `claude-worker`, `codex-worker`, `gemini-worker`, `report-writer`). **For this `agentName` match to work, Lead MUST set the Agent `name` arg to `<workerId>-worker` on every dispatch** (see [agents okstra-lead-contract.md Phase 4 — "Agent `name` on dispatch"](./okstra-lead-contract.md)); a worker dispatched without `name` carries no `agentName`, so the collector cannot attribute its session and records it `unavailable` (now surfaced as a `usageSummary.unattributedTeamSessions` entry rather than dropped silently).
416
+ - `~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl` for the lead and every Claude-side worker (Claude worker, Report writer worker, plus the Claude wrappers around Codex/Antigravity workers). Sessions are discovered by the recorded team-state `teamName`, lead is identified by `lead.sessionId`, and other workers are identified by `agentName` (e.g. `claude-worker`, `codex-worker`, `antigravity-worker`, `report-writer`). **For this `agentName` match to work, Lead MUST set the Agent `name` arg to `<workerId>-worker` on every dispatch** (see [agents okstra-lead-contract.md Phase 4 — "Agent `name` on dispatch"](./okstra-lead-contract.md)); a worker dispatched without `name` carries no `agentName`, so the collector cannot attribute its session and records it `unavailable` (now surfaced as a `usageSummary.unattributedTeamSessions` entry rather than dropped silently).
417
417
  - `~/.codex/sessions/Y/M/D/rollout-*.jsonl` for the underlying Codex CLI session (matched by `cwd` and timestamp window of the wrapper subagent). Last `event_msg.token_count.total_token_usage.total_tokens` is the session total.
418
- - `~/.gemini/tmp/<project>/chats/session-*.json` for the underlying Gemini CLI session. Sum of per-message `tokens.total`.
418
+ - `~/.antigravity/tmp/<project>/chats/session-*.json` for the underlying Antigravity CLI session. Sum of per-message `tokens.total`.
419
419
 
420
420
  ### Resulting team-state shape
421
421
 
@@ -459,7 +459,7 @@ The script reads:
459
459
  ### Notes
460
460
 
461
461
  - `totalTokens` in Claude usage blocks is the sum of input + output + cache_creation + cache_read tokens (the cache figures dominate in long sessions).
462
- - For Codex/Gemini workers, `usage.totalTokens` reflects the **Claude wrapper subagent** spend (the Claude tokens consumed by the codex-worker / gemini-worker subagent itself). The optional `cliTotalTokens` is the underlying CLI's own tokens. They are NOT additive in any meaningful way (different providers, different prices) — keep them separate.
462
+ - For Codex/Antigravity workers, `usage.totalTokens` reflects the **Claude wrapper subagent** spend (the Claude tokens consumed by the codex-worker / antigravity-worker subagent itself). The optional `cliTotalTokens` is the underlying CLI's own tokens. They are NOT additive in any meaningful way (different providers, different prices) — keep them separate.
463
463
  - If a worker has status `not-run`, the script records an "unavailable" block.
464
464
  - If the lead jsonl is missing (e.g. if `lead.sessionId` was never persisted), the script records an "unavailable" block with the searched path. Always populate `lead.sessionId` in team-state at Phase 3 — the okstra.sh launcher already passes it as `CLAUDE_SESSION_ID`.
465
465
  - Convergence re-verification agents are dispatched as fresh subagents under the same `teamName` and will be discovered automatically. If you want them split out, set a distinct `agentName` on dispatch and post-process.
@@ -3,7 +3,7 @@ Single source for the executor's Coding-conventions preflight gate. Two delivery
3
3
  paths converge here (see _implementation-executor.md "Pre-implementation context
4
4
  exploration"):
5
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
6
+ - codex / antigravity executor cannot read this path (it sits outside the CLI
7
7
  sandbox and the CLI only sees its stdin prompt), so the lead appends this
8
8
  file's body into the persisted executor prompt at dispatch time.
9
9
  The `Coding-conventions preflight` heading below is the literal string the CLI
@@ -18,4 +18,4 @@ Load the applicable coding conventions for every language the diff will touch, t
18
18
  - **Resource selection — read the routed pack, never inline it here.** Use this worker prompt's `**Coding preflight pack:**` anchor header as the absolute path to the installed routed pack. Detect each touched file's language and framework (extension / project manifest: `package.json`, `Cargo.toml`, `pyproject.toml`, `pom.xml`, `build.gradle*`, `prisma/schema.prisma`) and read resources from that pack via the Read tool by absolute path. Always read `overview.md` (the router) + `clean-code.md`, then select per the router's three ordered stages — Stage 1 language → `languages/<lang>.md`, Stage 2 framework → `frameworks/<fw>.md` (e.g. `frameworks/node-server.md` for server-side Node), Stage 3 architecture → `architectures/<arch>.md` (e.g. `architectures/hexagonal.md` for ports-and-adapters / NestJS-hex). Each stage is a list of rules; include EVERY matching resource (a change set can touch multiple languages/frameworks/architectures) — do not stop at the first match. These files are runtime resources, not Skill-tool skills, so always read them by path.
19
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
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 resolved coding-preflight pack 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: resource-unavailable → applied <project rules + agnostic principles>` in the final report. Never claim a resource read that did not happen.
21
+ - **Graceful degradation (codex / antigravity executor runtimes, or any runtime where the resolved coding-preflight pack 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: resource-unavailable → applied <project rules + agnostic principles>` in the final report. Never claim a resource read that did not happen.
@@ -8,12 +8,12 @@ profile document.
8
8
  - Team contract (shared):
9
9
  - `Claude lead` is synthesis-only and stays distinct from `Claude worker` (or, in `implementation`, the `Executor` and verifiers).
10
10
  - `Report writer worker` is the **author** of the final-report file; `Claude lead` reviews and approves the produced draft and does NOT write the file itself (see `team-contract` and `report-writer` for the authoritative contract).
11
- - default model assignments are resolved from centralised defaults; the fallback values are `Claude lead`/`Report writer worker`=`opus`, `Claude worker`=`opus`, `Codex worker`=`gpt-5.5`, `Gemini worker`=`auto`. Phase-specific overrides (e.g. `implementation`'s executor binding) live in the per-profile document.
11
+ - default model assignments are resolved from centralised defaults; the fallback values are `Claude lead`/`Report writer worker`=`opus`, `Claude worker`=`opus`, `Codex worker`=`gpt-5.5`, `Antigravity worker`=`auto`. Phase-specific overrides (e.g. `implementation`'s executor binding) live in the per-profile document.
12
12
  - every required worker listed in the per-profile `Required workers:` block must be attempted; the final verdict waits until each has either a result or an explicit terminal status (`timeout`, `error`, `not-run`).
13
13
  - unnamed generic parallel workers must not replace the required role roster, and no additional sub-agent dispatch is allowed beyond this roster.
14
14
  - Worker interaction model (shared — read before inferring behaviour from the roster):
15
15
  - the per-profile `Required workers:` block is a **roster**, not a behaviour contract. Each role's interaction mode changes across operating phases of the same run.
16
- - **Phase 4 / 5 (independent analysis)**: analyser workers (`claude`, `codex`, `gemini` when opted in) produce findings independently and have no access to one another's outputs. `report-writer` does not analyse.
16
+ - **Phase 4 / 5 (independent analysis)**: analyser workers (`claude`, `codex`, `antigravity` when opted in) produce findings independently and have no access to one another's outputs. `report-writer` does not analyse.
17
17
  - **Phase 5.5 (convergence — peer review by workers)**: the lead replays each analyser's findings to the *other* analysers and collects `AGREE` / `DISAGREE` / `SUPPLEMENT` verdicts across up to `effectiveMaxRounds` rounds. Workers act as peer reviewers of each other's findings in this phase; the lead mediates but does not vote. See `prompts/lead/convergence.md` for the round protocol, queue invariants, and final classification (`full-consensus` / `partial-consensus` / `contested` / `worker-unique`). For `requirements-discovery`, `error-analysis`, and `implementation-planning` this phase runs in **adversarial mode** (`convergence.adversarial=true`): verifiers try to refute each finding against its cited evidence and the burden of proof sits on the claim — see that skill's §"Adversarial Verification Mode".
18
18
  - Do NOT conclude "no peer review happens" from the roster alone — every profile that lists ≥2 analyser workers runs convergence by default (`convergence.enabled=true` in `task-manifest.json`).
19
19
  - Tooling — read-only MCP availability (shared):
@@ -30,14 +30,14 @@ profile document.
30
30
  - Anti-escalation rule (shared):
31
31
  - treating "다음 단계 진행해" or equivalent user phrases as authorisation to start a *different* lifecycle phase is forbidden. The next phase begins only in a separate okstra run launched with the new `--task-type`. Per-profile documents may further restrict this within their own scope.
32
32
  - Run-start pane recording (shared — runs ONCE at run start, before the FIRST worker dispatch):
33
- - The codex/gemini wrappers now self-anchor their trace pane by walking their own ancestor PIDs against tmux `pane_pid`s (see `lib/okstra/tmux-pane.sh`), so they no longer depend on this file. The lead still records its own pane id here for the cleanup steps below (which-pane-to-never-kill) and as the "am I in tmux" gate. A bare `tmux display-message -p '#{pane_id}'` is NOT reliable for this — Claude Code's Bash tool strips `$TMUX`/`$TMUX_PANE`, so that command returns the most-recently-active *client's* pane (often a different session, or a foreign pane when the lead is launched outside tmux entirely). The lead therefore records via the same ancestry resolver.
33
+ - The codex/antigravity wrappers now self-anchor their trace pane by walking their own ancestor PIDs against tmux `pane_pid`s (see `lib/okstra/tmux-pane.sh`), so they no longer depend on this file. The lead still records its own pane id here for the cleanup steps below (which-pane-to-never-kill) and as the "am I in tmux" gate. A bare `tmux display-message -p '#{pane_id}'` is NOT reliable for this — Claude Code's Bash tool strips `$TMUX`/`$TMUX_PANE`, so that command returns the most-recently-active *client's* pane (often a different session, or a foreign pane when the lead is launched outside tmux entirely). The lead therefore records via the same ancestry resolver.
34
34
  - The lead MUST run once, at run start: `mkdir -p "<RUN_DIR>/state" && { . "$HOME/.okstra/bin/lib/okstra/tmux-pane.sh" 2>/dev/null && okstra_resolve_caller_pane; } > "<RUN_DIR>/state/lead-pane.id" 2>/dev/null || true` (substitute the run's absolute `RUN_DIR`). When the lead is not inside a tmux pane (e.g. Claude launched from the GUI app) no ancestor matches a pane, the file is empty, and every pane step below silently no-ops — that empty/absent file is the single signal that the lead is not in tmux.
35
35
  - Phase-start pane reset (shared — runs BEFORE dispatching each new worker batch):
36
- - okstra creates two kinds of tmux pane per run: (a) **worker-agent panes** the harness gives to dispatched subagents (titled `claude-worker` / `codex-worker` / `gemini-worker` / `report-writer-worker`), and (b) **trace panes** the codex/gemini wrappers spawn (`<cli>-<role>-<pid>-tail`). Both accumulate across internal phases because each new phase dispatches a fresh worker batch and the prior panes are never reclaimed.
36
+ - okstra creates two kinds of tmux pane per run: (a) **worker-agent panes** the harness gives to dispatched subagents (titled `claude-worker` / `codex-worker` / `antigravity-worker` / `report-writer-worker`), and (b) **trace panes** the codex/antigravity wrappers spawn (`<cli>-<role>-<pid>-tail`). Both accumulate across internal phases because each new phase dispatches a fresh worker batch and the prior panes are never reclaimed.
37
37
  - When `<RUN_DIR>/state/lead-pane.id` is non-empty (the lead is in tmux), the lead MUST run `$HOME/.okstra/bin/okstra-trace-cleanup.sh --run-dir "<RUN_DIR>"` **immediately before** dispatching the next phase's workers — i.e. just before emitting each `PROGRESS: phase-5.5-convergence round=<N>` marker and just before `PROGRESS: phase-6-synthesis dispatching report-writer-worker`. This closes every prior-phase okstra pane (worker-agent + trace) for this run, while NEVER killing the lead's own pane.
38
38
  - This is **automatic and silent** — NO user prompt. Report it in one short line (e.g. `이전 phase okstra pane 3개 정리`) and proceed. It is silent-skipped when the lead is not in tmux; the lead MUST NOT fabricate a synthetic pane list in that case.
39
39
  - Phase wrap-up — okstra pane disposition (shared, runs AFTER Phase 7 persistence/token collection and BEFORE teammate teardown):
40
- - At run end the only residual okstra panes are the LAST phase's (e.g. the `report-writer-worker` agent pane and any codex/gemini trace pane). `okstra-trace-cleanup.sh --list --run-dir "<RUN_DIR>"` returns one tab-separated `<pane_id>\t<pane_title>` line per residual okstra pane (worker-agent + trace) for this run.
40
+ - At run end the only residual okstra panes are the LAST phase's (e.g. the `report-writer-worker` agent pane and any codex/antigravity trace pane). `okstra-trace-cleanup.sh --list --run-dir "<RUN_DIR>"` returns one tab-separated `<pane_id>\t<pane_title>` line per residual okstra pane (worker-agent + trace) for this run.
41
41
  - When `<RUN_DIR>/state/lead-pane.id` is non-empty, after the final-report file has been written and the routing recommendation has been issued, the lead MUST run `$HOME/.okstra/bin/okstra-trace-cleanup.sh --list --run-dir "<RUN_DIR>"` exactly once. The output lists every residual okstra pane (worker-agent + trace) for this run, never the lead's own pane.
42
42
  - If the list is empty, skip the question — there is nothing to ask about (the phase-start resets above usually already cleared prior phases).
43
43
  - Otherwise the lead MUST present the user with a strict binary choice **before** declaring the phase complete. Use one prompt of this shape (Korean preferred, English acceptable if the rest of the run is in English):
@@ -103,8 +103,8 @@ profile document.
103
103
  - The top-of-report `## Verdict Card` block is mandatory in every final-report. Its `Verdict Token`, `Direction`, and `Next Step` cells MUST byte-match the corresponding cells in `## 7. Final Verdict` and the first item of `## 3. Recommended Next Steps`. The validator treats the card as a non-authoritative index — when card values diverge from the authoritative sections, the run is `contract-violated`.
104
104
  - Cross-worker traceability (shared — applies to every analysis worker output and to the lead's `## 6.` / `## 2.` tables in the final-report):
105
105
  - **Worker-side item IDs (free-form but unique within the worker).** Every row item in sections 1–5 (and any optional section 6) of an analysis worker's output MUST carry an item ID that is unique within that one worker's result file. The ID convention is the worker's choice — `F-001` / `F-002` per the suggested schema, `1.1` / `1.2` / `1.3` as Codex tends to use, or any other shape — but it MUST appear as the leading column of the row (for table-form items) or as a `[<ID>]` prefix (for bullet/numbered items). Workers that emit findings without IDs make cross-worker reconciliation impossible.
106
- - **Lead-side ID assignment + source preservation.** When the lead (or `report-writer-worker`) synthesises `## 6.1 Consensus` / `## 6.2 Differences` / `## 2.1 Primary Evidence` rows from worker outputs, the lead assigns a fresh `C-NNN` / `D-NNN` / `E-NNN` row ID. The `Source items` column (or, where the template still calls it `Supporting workers` / `Workers (position)` / `Source`, that same column) MUST list every contributing worker:item pair (e.g. `claude:F-001, codex:1.1, gemini:F-3`) so a reviewer can trace the synthesised row back to each worker's original wording without re-reading every worker-results file. Bare worker names without item IDs (e.g. `claude, codex, gemini`) are deprecated for these tables; the validator does not yet fail on them but the readability pass treats it as a contract violation.
107
- - **Why this matters.** A real run had `claude=F-1..F-11`, `codex=1.1..1.8`, `gemini=F-3..F-9` — three incompatible ID schemes. When the lead synthesised `C-1..C-8`, the link from `C-3` back to "which sentence in which worker file" was lost. Source-item preservation restores that link without forcing every worker to adopt a single ID prefix, which would over-constrain worker output style.
106
+ - **Lead-side ID assignment + source preservation.** When the lead (or `report-writer-worker`) synthesises `## 6.1 Consensus` / `## 6.2 Differences` / `## 2.1 Primary Evidence` rows from worker outputs, the lead assigns a fresh `C-NNN` / `D-NNN` / `E-NNN` row ID. The `Source items` column (or, where the template still calls it `Supporting workers` / `Workers (position)` / `Source`, that same column) MUST list every contributing worker:item pair (e.g. `claude:F-001, codex:1.1, antigravity:F-3`) so a reviewer can trace the synthesised row back to each worker's original wording without re-reading every worker-results file. Bare worker names without item IDs (e.g. `claude, codex, antigravity`) are deprecated for these tables; the validator does not yet fail on them but the readability pass treats it as a contract violation.
107
+ - **Why this matters.** A real run had `claude=F-1..F-11`, `codex=1.1..1.8`, `antigravity=F-3..F-9` — three incompatible ID schemes. When the lead synthesised `C-1..C-8`, the link from `C-3` back to "which sentence in which worker file" was lost. Source-item preservation restores that link without forcing every worker to adopt a single ID prefix, which would over-constrain worker output style.
108
108
  - Audit sidecar (shared — applies to every analysis-worker output and every final-report):
109
109
  - Reading Confirmation lines (one short line per input file confirming end-to-end reading) live in the **worker audit sidecar** at `runs/<task-type>/worker-results/<worker>-audit-<task-type>-<seq>.md`, NOT in the worker's main worker-results file. The worker-results body starts at section 1 (Findings). The validator fails worker-results files that contain a `## 0. Reading Confirmation` heading.
110
110
  - The audit sidecar carries any other meta the worker wants to log (tool-call counts, MCP query summaries, timing notes). The lead's final-report does NOT duplicate this content — it is consumed by the validator and by post-run audit tooling, not by end-user readers.
@@ -17,7 +17,7 @@ are collected and convergence finished. Phase 1-5 do not need it.
17
17
  - **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
18
  - **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
19
  - **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.
20
- - **Verifier results**: a section per verifier present in the resolved roster (`Claude verifier`, `Codex verifier`, and `Gemini verifier` when opted in) containing:
20
+ - **Verifier results**: a section per verifier present in the resolved roster (`Claude verifier`, `Codex verifier`, and `Antigravity verifier` when opted in) containing:
21
21
  - their independent verdict (PASS / CONCERNS / FAIL),
22
22
  - cited diff snippets supporting the verdict,
23
23
  - the verifier's `Read-only command log` (every command they ran with exact invocation and exit code, in execution order — copied verbatim from the worker result),