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
@@ -8,7 +8,6 @@ from pathlib import Path
8
8
  HOME = Path.home()
9
9
  CLAUDE_PROJECTS = HOME / ".claude" / "projects"
10
10
  CODEX_SESSIONS = HOME / ".codex" / "sessions"
11
- GEMINI_TMP = HOME / ".gemini" / "tmp"
12
11
 
13
12
 
14
13
  def utc_now() -> str:
@@ -8,7 +8,8 @@ provider:
8
8
  `claude-haiku-4-5-*`, `claude-3-5-sonnet-*`, `claude-3-5-haiku-*`,
9
9
  `claude-3-opus-*`, `claude-3-haiku-*`.
10
10
  * OpenAI / Codex — `gpt-5*`, `gpt-4o*`, `gpt-4*`.
11
- * Google / Gemini — `gemini-2.5-pro*`, `gemini-2.5-flash*`, `gemini-2.0-flash*`.
11
+ * Google / Gemini — `gemini-3.5-flash*`, `gemini-3.1-pro*`, `gemini-3-flash*`,
12
+ `gemini-2.5-pro*`, `gemini-2.5-flash*`, `gemini-2.0-flash*`.
12
13
 
13
14
  Insertion order is the match order, so list more specific keys first. Update
14
15
  when providers change list pricing.
@@ -112,7 +113,9 @@ GEMINI_PRICING = {
112
113
  # Both dotted (`gemini-3.1-pro`) and hyphenated (`gemini-3-1-pro`) id
113
114
  # forms appear in the wild, so include both for the new 3.x families.
114
115
 
115
- # Gemini 3 series (preview).
116
+ # Gemini 3 series.
117
+ "3.5-flash": (1.50, 9.00),
118
+ "3-5-flash": (1.50, 9.00),
116
119
  "3.1-pro": (2.00, 12.0),
117
120
  "3-1-pro": (2.00, 12.0),
118
121
  "3-flash": (0.50, 3.00),
@@ -203,7 +206,7 @@ def codex_cost_usd(model: str | None, input_t: int, cached_input_t: int, output_
203
206
  return round((fresh * pi + cached_input_t * pci + output_t * po) / 1_000_000, 4)
204
207
 
205
208
 
206
- def gemini_cost_usd(model: str | None, input_t: int, output_t: int) -> float | None:
209
+ def antigravity_cost_usd(model: str | None, input_t: int, output_t: int) -> float | None:
207
210
  p = _match_pricing(model, GEMINI_PRICING)
208
211
  if p is None:
209
212
  return None
@@ -884,7 +884,7 @@
884
884
  "required": ["agent", "role", "model", "status", "summary"],
885
885
  "additionalProperties": false,
886
886
  "properties": {
887
- "agent": { "enum": ["Claude Code", "Codex", "Gemini"] },
887
+ "agent": { "enum": ["Claude Code", "Codex", "Antigravity"] },
888
888
  "role": { "type": "string", "minLength": 1 },
889
889
  "model": { "type": "string", "minLength": 1 },
890
890
  "status": { "$ref": "#/$defs/WorkerStatus" },
@@ -462,7 +462,7 @@ on a project-internal concrete object whenever possible.
462
462
  `<PROJECT_ROOT>`) and the canonical symbol name. Record the resolution
463
463
  under `Augmentation > Domain alignment` with the `evidence-link` label,
464
464
  and link the absolute path from `Related Artifacts`. This is what makes
465
- the brief portable across downstream workers (Claude / Codex / Gemini)
465
+ the brief portable across downstream workers (Claude / Codex / Antigravity)
466
466
  that may operate in separate worktrees and need to point at the same
467
467
  object.
468
468
  - **Conversion-block signal** — when a reporter statement cannot be
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: okstra-inspect
3
3
  description: |
4
- Use for any read-side okstra inspection or status mutation. Single skill dispatches by sub-command to six facets — status, history, report, time, logs, cost. Trigger words include "okstra status", "task status", "current phase", "next phase", "okstra status set", "okstra mark", "<task-id> done|in-progress|진행중|완료", "okstra history", "past runs", "re-run", "resume", "list tasks", "find report", "show report for", "read the okstra report", "continue from report", "작업 시간", "소요 시간", "time summary", "duration", "elapsed", "얼마나 걸렸", "시간 분석", "okstra logs", "로그 현황", "로그 파일", "log size", "log status", "로그 정리", "log cleanup", "okstra context-cost", "context cost", "context-cost", "컨텍스트 비용", "읽기 비용", "산출물 비용".
4
+ Use for any read-side okstra inspection or status mutation. Single skill dispatches by sub-command to seven facets — status, history, report, time, logs, cost, errors. Trigger words include "okstra status", "task status", "current phase", "next phase", "okstra status set", "okstra mark", "<task-id> done|in-progress|진행중|완료", "okstra history", "past runs", "re-run", "resume", "list tasks", "find report", "show report for", "read the okstra report", "continue from report", "작업 시간", "소요 시간", "time summary", "duration", "elapsed", "얼마나 걸렸", "시간 분석", "okstra logs", "로그 현황", "로그 파일", "log size", "log status", "로그 정리", "log cleanup", "okstra context-cost", "context cost", "context-cost", "컨텍스트 비용", "읽기 비용", "산출물 비용", "okstra errors", "error report", "에러 리포트", "에러 보고", "에러 모아줘", "실패 로그 정리".
5
5
  ---
6
6
 
7
7
  # OKSTRA Inspect
8
8
 
9
- Single read-side entry point for okstra runtime inspection plus the one write-side mutation that belongs here (`workStatus`). Sub-commands:
9
+ Single read-side entry point for okstra runtime inspection plus the one status mutation that belongs here (`workStatus`) and read-derived artifact rendering (`errors` report). Sub-commands:
10
10
 
11
11
  | Sub-command | What it does |
12
12
  |---|---|
@@ -14,8 +14,9 @@ Single read-side entry point for okstra runtime inspection plus the one write-si
14
14
  | `history` | List past okstra runs; assemble re-run or resume command. |
15
15
  | `report` | Resolve final-report path for a task-key. Optionally read it. |
16
16
  | `time` | Per-task-type and per-worker duration breakdown for a task. |
17
- | `logs` | Inventory codex/gemini wrapper `.log` sidecars; emit cleanup commands. |
17
+ | `logs` | Inventory codex/antigravity wrapper `.log` sidecars; emit cleanup commands. |
18
18
  | `cost` | Estimate file/read context cost for a task bundle. |
19
+ | `errors` | Aggregate okstra-run error logs for a task into a timestamped markdown report; print a summary. |
19
20
 
20
21
  ## Step 0: Verify okstra runtime + project setup (shared)
21
22
 
@@ -245,7 +246,7 @@ When a user selects a specific task:
245
246
 
246
247
  Builds a fresh run — new run-seq, new manifest, new report — using parameters from a previous `run-manifest-*.json`. Does NOT touch old artifacts; use `history.4` to continue an interrupted session.
247
248
 
248
- 1. Pick the source run-manifest: `runManifestPath` from `history.2`, or task's `latestRunManifestPath` from `history.1`.
249
+ 1. Pick the source run-manifest: `runManifestPath` from `history.2`, or task's `latestRunManifestPath` from `history.1`. Note: `latestRunManifestPath` is projected from the timeline's latest run, so it is empty when the task has no recorded run yet (timeline absent) — in that case fall back to a `history.2` per-run `runManifestPath`, or ask the user.
249
250
  2. Read the manifest and extract required arguments:
250
251
  - `projectId` → `--project-id`
251
252
  - `taskGroup` → `--task-group`
@@ -255,8 +256,8 @@ Builds a fresh run — new run-seq, new manifest, new report — using parameter
255
256
  3. Optional arguments (include only when present in source):
256
257
  - `recommendedWorkers` → `--workers` (comma-separated)
257
258
  - `relatedTasks` → `--related-tasks`
258
- - model overrides → `--claude-model`, `--codex-model`, `--gemini-model`
259
- - for `taskType: implementation`: `teamContract.executor.provider` → `--executor <claude|codex|gemini>` when different from `claude`.
259
+ - model overrides → `--claude-model`, `--codex-model`, `--antigravity-model`
260
+ - for `taskType: implementation`: `teamContract.executor.provider` → `--executor <claude|codex|antigravity>` when different from `claude`.
260
261
  4. **`taskType: implementation` only — resolve `--base-ref`:** base ref is NOT in the run-manifest; it lives in the worktree registry at `~/.okstra/worktrees/registry.json`. If a worktree is already registered, existing branch & base are reused — omit `--base-ref` unless the user explicitly wants a different starting point. If no worktree is registered (cleaned up), `--base-ref` is mandatory — ask the user before running.
261
262
  5. Display the assembled command:
262
263
  ```bash
@@ -299,7 +300,7 @@ B. **`task-manifest.json` (direct):** if catalog missing, slugify task-group / t
299
300
 
300
301
  C. **`timeline.json` (specific run):** for a specific date or run, read `.okstra/tasks/<group-segment>/<id-segment>/history/timeline.json`, filter `runs[]` by `runTimestamp` / `status` / `taskType`, use `runs[].reportPath`.
301
302
 
302
- D. **Specific task-type (fallback):** `latestReportPath` is task-type-agnostic. For a specific task-type's latest report, look under `.okstra/tasks/<group-segment>/<id-segment>/runs/<task-type-segment>/reports/`, filename pattern `final-report-<task-type-segment>-<NNN>.md` per `scripts/okstra_ctl/sequence.py:31`. Highest seq is latest. Stage-isolated runs (`implementation`, single-stage `final-verification`) keep their reports one level deeper at `runs/<task-type-segment>/stage-<N>/reports/` — scan those subdirectories too; seq is independent per stage. Cross-verify with `timeline.json`'s `runs[].taskType` filter.
303
+ D. **Specific task-type (fallback):** `latestReportPath` is task-type-agnostic. For a specific task-type's latest report, look under `.okstra/tasks/<group-segment>/<id-segment>/runs/<task-type-segment>/reports/`, filename pattern `final-report-<task-type-segment>-<NNN>.md` per `scripts/okstra_ctl/sequence.py:30`. Highest seq is latest. Stage-isolated runs (`implementation`, single-stage `final-verification`) keep their reports one level deeper at `runs/<task-type-segment>/stage-<N>/reports/` — scan those subdirectories too; seq is independent per stage. Cross-verify with `timeline.json`'s `runs[].taskType` filter.
303
304
 
304
305
  ### report.2 — Confirm existence
305
306
 
@@ -344,11 +345,11 @@ After reading the report, surface follow-up options:
344
345
 
345
346
  Trigger phrases: "작업 시간", "소요 시간", "time summary", "duration", "elapsed", "얼마나 걸렸", "시간 분석".
346
347
 
347
- Aggregate elapsed work time for a given task, grouped by **task type** and broken down by **worker** (lead, claude, codex, gemini, report-writer).
348
+ Aggregate elapsed work time for a given task, grouped by **task type** and broken down by **worker** (lead, claude, codex, antigravity, report-writer).
348
349
 
349
350
  **Data sources** (both collected by okstra):
350
351
 
351
- 1. `.okstra/tasks/<task-group>/<task-id>/history/timeline.json` — `runs` array with `runTimestamp`, `taskType`, `status`, `teamStatePath`, `taskRootPath`. Both path fields may be either project-root-relative or task-root-relative depending on which `render.py` version wrote the manifest.
352
+ 1. `.okstra/tasks/<task-group>/<task-id>/history/timeline.json` — `runs` array with `runTimestamp`, `taskType`, `status`, `teamStatePath`. `teamStatePath` is project-root-relative (written by `render.py` via `_rel(project_root, ...)`).
352
353
  2. Each run's `.../runs/<task-type>/state/team-state-<suffix>.json` — populated by `scripts/okstra-token-usage.py` at Phase 7. Contains `leadUsage.{startedAt, endedAt, durationMs}` and `workers[].{workerId, agent, usage.{startedAt, endedAt, durationMs}}`.
353
354
 
354
355
  If a run never reached Phase 7, its `team-state` lacks `durationMs`. Mark such runs as `unavailable` rather than guessing.
@@ -366,10 +367,7 @@ If `task-catalog.json` is missing: `No okstra history found. Run /okstra-run fir
366
367
 
367
368
  For each entry in `timeline.json`'s `runs` array:
368
369
 
369
- 1. Resolve the `team-state` file via two-step lookup:
370
- a. First try `<projectRoot>/<teamStatePath>`.
371
- b. If that file does not exist, fall back to `<projectRoot>/<taskRootPath>/<teamStatePath>` (the manifest's `taskRootPath` is task-root relative to project root; `teamStatePath` written by `render.py` is task-root-relative in many runs).
372
- If neither resolves, treat the run as `unavailable`.
370
+ 1. Resolve the `team-state` file at `<projectRoot>/<teamStatePath>` — `teamStatePath` is project-root-relative. If `teamStatePath` is empty or the file does not exist on disk, treat the run as `unavailable`.
373
371
  2. Extract `taskType` from the timeline entry (authoritative), `leadUsage.durationMs` and `leadUsage.{startedAt,endedAt}`, and for each `worker` in `workers[]`: `workerId`, `agent`, `usage.durationMs`. Read defensively — `usage` (and `leadUsage`) may be:
374
372
  - a normal `usage_block` with `durationMs >= 0`,
375
373
  - a `na_block` with `{"source": "unavailable", "durationMs": 0, "note": ...}` when Phase 7 collection failed,
@@ -398,7 +396,7 @@ Worked example for one run with three concurrent workers:
398
396
  lead [================================] durationMs = 1800000 (30:00)
399
397
  claude [============] durationMs = 720000 (12:00)
400
398
  codex [==============] durationMs = 840000 (14:00)
401
- gemini [========] durationMs = 480000 (08:00)
399
+ antigravity [========] durationMs = 480000 (08:00)
402
400
  ```
403
401
 
404
402
  - `CPU sum` for the run = `1800000 + 720000 + 840000 + 480000` = `3840000` (`01:04:00`)
@@ -417,7 +415,7 @@ For each task type, list one row per `workerId` actually present, plus `lead`. A
417
415
  - If `Runs == 0` for a worker, **omit the row entirely** rather than dividing by zero.
418
416
  - `Avg/run = Total / Runs` (integer ms, then format to `HH:MM:SS`).
419
417
 
420
- Use the `workerId` from team-state. Valid enum: `lead, claude, codex, gemini, report-writer`.
418
+ Use the `workerId` from team-state. Valid enum: `lead, claude, codex, antigravity, report-writer`.
421
419
 
422
420
  Display rule for `workerId` vs `agent`:
423
421
  - If every run of this task type used `agent == workerId` for this row, display the bare `workerId`.
@@ -463,7 +461,7 @@ team-state written by collector ≥ v0.73 carries a `phaseTimeline` block — th
463
461
  | lead | 2 | 00:12:08 | 00:06:04 |
464
462
  | claude | 2 | 00:09:12 | 00:04:36 |
465
463
  | codex | 2 | 00:07:40 | 00:03:50 |
466
- | gemini | 2 | 00:03:12 | 00:01:36 |
464
+ | antigravity | 2 | 00:03:12 | 00:01:36 |
467
465
  | report-writer | 2 | 00:01:00 | 00:00:30 |
468
466
 
469
467
  > Unavailable: 1 run (implementation / 2026-04-30_03-03-48) — team-state has no durationMs (Phase 7 not reached)
@@ -595,14 +593,14 @@ Interpretation rules:
595
593
 
596
594
  Trigger phrases: "okstra logs", "로그 현황", "로그 파일", "log files", "log size", "log status", "로그 정리", "log cleanup".
597
595
 
598
- Read-only inventory of codex/gemini wrapper log files written next to each prompt history file (`<prompt>.log`). Reports sizes, ages, totals, and suggests cleanup commands. **Does not delete** — the user runs whichever `find … -delete` line they like.
596
+ Read-only inventory of codex/antigravity wrapper log files written next to each prompt history file (`<prompt>.log`). Reports sizes, ages, totals, and suggests cleanup commands. **Does not delete** — the user runs whichever `find … -delete` line they like.
599
597
 
600
- **Background:** codex/gemini wrappers (`okstra-codex-exec.sh`, `okstra-gemini-exec.sh`) write a sidecar log next to each prompt history file:
598
+ **Background:** codex/antigravity wrappers (`okstra-codex-exec.sh`, `okstra-antigravity-exec.sh`) write a sidecar log next to each prompt history file:
601
599
 
602
600
  ```
603
601
  .okstra/tasks/<task-group>/<task-id>/runs/<phase>/prompts/
604
- <worker>-prompt-<phase>-<seq>.md <-- prompt (git-tracked)
605
- <worker>-prompt-<phase>-<seq>.log <-- live stdout+stderr mirror
602
+ <worker>-worker-prompt-<phase>-<seq>.md <-- prompt (git-tracked)
603
+ <worker>-worker-prompt-<phase>-<seq>.log <-- live stdout+stderr mirror
606
604
  ```
607
605
 
608
606
  The log is truncated at each dispatch (`: > "$log_path"`) — only the latest run for a given seq is preserved. Different seqs keep separate files. Long-running implementation dispatches can produce multi-MB logs; analysis-phase dispatches are typically smaller.
@@ -634,7 +632,7 @@ If empty, report `No wrapper log files found under <projectRoot>` and exit.
634
632
  | # | Task | Phase | Worker | Seq | Size | Age | Path |
635
633
  |---|------|-------|--------|-----|------|-----|------|
636
634
 
637
- Parse fields from the path: task-group / task-id from the `tasks/<task-group>/<task-id>/` segment; phase from `runs/<phase>/`; worker from filename prefix before `-prompt-`; seq from filename suffix (last 3-digit segment). Format sizes as KB/MB. Format age as `Nd` (days) or `Nh` (hours) from `mtime` relative to "now".
635
+ Parse fields from the path: task-group / task-id from the `tasks/<task-group>/<task-id>/` segment; phase from `runs/<phase>/`; worker from filename prefix before `-worker-prompt-` (the wrapper names files `<worker>-worker-prompt-<phase>-<seq>.log`); seq from filename suffix (last 3-digit segment). Format sizes as KB/MB. Format age as `Nd` (days) or `Nh` (hours) from `mtime` relative to "now".
638
636
 
639
637
  **Table B — Per-task totals:**
640
638
 
@@ -694,6 +692,72 @@ Substitute the literal `<PROJECT_ROOT>` with the resolved absolute path so the c
694
692
 
695
693
  ---
696
694
 
695
+ ## errors
696
+
697
+ Trigger phrases: "okstra errors", "error report", "에러 리포트", "에러 보고", "에러 모아줘", "실패 로그 정리".
698
+
699
+ Aggregate a task's okstra-run error logs (`runs/*/logs/errors-*.jsonl`, lead-observed + worker-reported) into a timestamped markdown report and summarize it. This sub-command renders a **read-derived artifact** (a `.md` file) but never mutates task state (`task-manifest.json`, catalog, timeline).
700
+
701
+ ### errors.1 — Resolve target
702
+
703
+ Accepted target forms (same as `cost`):
704
+
705
+ 1. Full task-key: `<project-id>:<task-group>:<task-id>`.
706
+ 2. Task id only — read `.okstra/discovery/task-catalog.json`, match `taskId` case-insensitively (multiple → list and ask; none → report not found).
707
+ 3. Task root path.
708
+
709
+ ### errors.2 — Run the renderer
710
+
711
+ Use the CLI output as the source of truth:
712
+
713
+ ```bash
714
+ okstra error-report <resolved-target> --project-root <projectRoot>
715
+ ```
716
+
717
+ For a task-root path, run `okstra error-report <path>` directly. Do not parse the jsonl files by hand unless the CLI fails and the user explicitly asks for a manual fallback.
718
+
719
+ ### errors.3 — Summarize output
720
+
721
+ Parse the stdout JSON and report:
722
+
723
+ | Field | Source |
724
+ |---|---|
725
+ | Report file | `reportPath` (project-root-relative `.md`) |
726
+ | Total errors | `totals.errorCount` |
727
+ | Logs (runs) | `totals.runCount` |
728
+ | By errorType | `totals.byErrorType` (tool-failure / cli-failure / contract-violation) |
729
+ | By source | `totals.bySource` (lead-observed / worker-reported) |
730
+ | By phase | `byPhase[]` |
731
+ | By agent | `byAgent[]` |
732
+ | Parse-skipped lines | `parseSkipped` |
733
+
734
+ - If `reportPath` is empty AND `totals.errorCount == 0`: report `이 task 에는 기록된 에러 로그가 없습니다.` and do not claim a file was written.
735
+ - Otherwise show the `.md` path and offer to read it.
736
+ - If `parseSkipped > 0`, surface it (do not silently hide malformed lines).
737
+
738
+ ### errors — Output template
739
+
740
+ ```markdown
741
+ ## okstra Error Report — <task-key>
742
+
743
+ - Report: `<reportPath-or-->`
744
+ - Total errors: <N> across <runCount> log(s)
745
+ - By type: <tool-failure: a, cli-failure: b, ...>
746
+ - By source: <lead-observed: x, worker-reported: y>
747
+
748
+ | Phase | Count |
749
+ |---|---:|
750
+ | implementation | 3 |
751
+
752
+ | Agent | Count |
753
+ |---|---:|
754
+ | codex-worker | 2 |
755
+
756
+ <If parseSkipped > 0: "⚠ 파싱 건너뛴 줄: <N>">
757
+ ```
758
+
759
+ ---
760
+
697
761
  ## Output Rules (shared)
698
762
 
699
763
  - Responses should be concise and written in Korean unless the user requests otherwise.
@@ -49,7 +49,7 @@ The wizard tells you *which UI to use* via `kind` (and the optional `multi` flag
49
49
 
50
50
  The `branch_confirm` step (shown just before `confirm`) is a normal `pick` step and is rendered the same way — no special handling needed. Its options always include `중단` (abort); `base-ref 다시 고르기` (edit) appears only when a new branch would be created from the user-chosen base-ref. For `implementation` runs the wizard previews the **stage worktree** this run will actually use (not the task-key directory); render its label verbatim.
51
51
 
52
- Never invent additional questions. Never reorder. **Never drop, hide, or merge a `pick` / `pick_group` option** — render every `options[]` entry as its own selectable `AskUserQuestion` choice, including entries that carry a `(default)` / `(recommended)` suffix. Do NOT collapse a multi-option pick into a "recommended + 직접 입력 / Other" shortlist: the wizard's `options[]` array IS the complete, authoritative choice set. Example: the `executor` step always emits `claude` / `codex` / `gemini` — show all three, never just `claude`. The run-prompt recommendation rule (1–2 추천 + 직접 입력) applies ONLY to prompts this skill authors itself (e.g. the conformance-waiver picker), never to wizard-provided `options[]`. Never use `AskUserQuestion` for `text` prompts — the wizard explicitly chose `text` to avoid the picker-Other re-render lag.
52
+ Never invent additional questions. Never reorder. **Never drop, hide, or merge a `pick` / `pick_group` option** — render every `options[]` entry as its own selectable `AskUserQuestion` choice, including entries that carry a `(default)` / `(recommended)` suffix. Do NOT collapse a multi-option pick into a "recommended + 직접 입력 / Other" shortlist: the wizard's `options[]` array IS the complete, authoritative choice set. Example: the `executor` step always emits `claude` / `codex` / `antigravity` — show all three, never just `claude`. The run-prompt recommendation rule (1–2 추천 + 직접 입력) applies ONLY to prompts this skill authors itself (e.g. the conformance-waiver picker), never to wizard-provided `options[]`. Never use `AskUserQuestion` for `text` prompts — the wizard explicitly chose `text` to avoid the picker-Other re-render lag.
53
53
 
54
54
  ## Step 1: Verify okstra runtime + project setup
55
55
 
@@ -95,7 +95,7 @@ Repeat until `next.kind == "done"` (or `"aborted"` — terminal cancel, see "How
95
95
 
96
96
  1. **Render** the prompt according to `kind` (and `multi` for pick):
97
97
  - `pick` + `multi: false` → `AskUserQuestion` with `multiSelect: false`, `label`, and `options`. The user's chosen option's `value` is the answer string.
98
- - `pick` + `multi: true` → `AskUserQuestion` with `multiSelect: true`, `label`, and `options`. Join the selected `value`s with `,` into a single literal CSV string (e.g. `"claude,codex,gemini"`) and submit it as a single `--answer "claude,codex,gemini"`. Empty selection submits `--answer ""` and the wizard re-prompts.
98
+ - `pick` + `multi: true` → `AskUserQuestion` with `multiSelect: true`, `label`, and `options`. Join the selected `value`s with `,` into a single literal CSV string (e.g. `"claude,codex,antigravity"`) and submit it as a single `--answer "claude,codex,antigravity"`. Empty selection submits `--answer ""` and the wizard re-prompts.
99
99
  - `pick_group` → one `AskUserQuestion` with one question per `questions[]` entry (tab). Map each tab's selected `value` back by `questions[].step`, assemble a JSON object, and submit it as a single literal `--answer '<json>'`.
100
100
  - `text` → plain text message containing `label`. Consume the user's next reply verbatim as the answer string (empty reply = empty string).
101
101
  2. **Submit** the answer — call `okstra wizard step` with the literal state-file path from Step 2 and the literal user answer (no shell variables, no `$(...)`):
@@ -175,7 +175,7 @@ okstra render-bundle \
175
175
  --lead-model "<args.lead-model>" \
176
176
  --claude-model "<args.claude-model>" \
177
177
  --codex-model "<args.codex-model>" \
178
- --gemini-model "<args.gemini-model>" \
178
+ --antigravity-model "<args.antigravity-model>" \
179
179
  --report-writer-model "<args.report-writer-model>" \
180
180
  --related-tasks "<args.related-tasks>" \
181
181
  --clarification-response "<args.clarification-response>" \
@@ -222,10 +222,10 @@ field is optional; declare only what your conformance scripts use.
222
222
  provisions `<PROJECT_ROOT>/.claude/settings.local.json` as a symlink to
223
223
  `~/.okstra/templates/settings.local.json`. The template is installed
224
224
  by `okstra install` 0.14.0+ and contains the Bash permission rules
225
- required for the codex/gemini worker wrappers:
225
+ required for the codex/antigravity worker wrappers:
226
226
 
227
227
  - `Bash($HOME/.okstra/bin/okstra-codex-exec.sh:*)`
228
- - `Bash($HOME/.okstra/bin/okstra-gemini-exec.sh:*)`
228
+ - `Bash($HOME/.okstra/bin/okstra-antigravity-exec.sh:*)`
229
229
 
230
230
  Claude Code automatically loads `.claude/settings.local.json` whenever
231
231
  it operates inside that project, so okstra workers dispatched from
@@ -14,7 +14,7 @@ taskType: "{{FM_TASK_TYPE}}"
14
14
  # OKSTRA Task Brief
15
15
 
16
16
  <!--
17
- 이 brief은 okstra 워커(Claude/Codex/Gemini)가 코드베이스/도메인 사전지식 없이 분석할 수 있도록 준비하는 단일 source-of-truth 문서입니다.
17
+ 이 brief은 okstra 워커(Claude/Codex/Antigravity)가 코드베이스/도메인 사전지식 없이 분석할 수 있도록 준비하는 단일 source-of-truth 문서입니다.
18
18
 
19
19
  원칙:
20
20
  1. 워커는 외부 링크에 접근할 수 없음 → 모든 1차 증거는 inline으로 박을 것 (fenced code block).
@@ -86,7 +86,7 @@ taskType: "{{FM_TASK_TYPE}}"
86
86
  ## Domain Glossary
87
87
 
88
88
  <!--
89
- Codex/Gemini는 이 코드베이스를 모릅니다. 핵심 용어 5-15개를 한 문장씩 정의.
89
+ Codex/Antigravity는 이 코드베이스를 모릅니다. 핵심 용어 5-15개를 한 문장씩 정의.
90
90
  없는 용어를 워커가 추측하면 분석 품질이 즉시 떨어집니다.
91
91
  -->
92
92
 
@@ -53,7 +53,7 @@
53
53
  "rowLead": "Lead",
54
54
  "rowWorkerTotal": "Worker subtotal",
55
55
  "rowGrandTotal": "**Grand total**",
56
- "rowCliExtra": "Codex/Gemini CLI add-on"
56
+ "rowCliExtra": "Codex/Antigravity CLI add-on"
57
57
  },
58
58
  "verdictCard": {
59
59
  "tableHeaderLabel": "Item",
@@ -53,7 +53,7 @@
53
53
  "rowLead": "Lead",
54
54
  "rowWorkerTotal": "Worker 합계",
55
55
  "rowGrandTotal": "**전체 합계**",
56
- "rowCliExtra": "Codex/Gemini CLI 추가 비용"
56
+ "rowCliExtra": "Codex/Antigravity CLI 추가 비용"
57
57
  },
58
58
  "verdictCard": {
59
59
  "tableHeaderLabel": "항목",
@@ -3,10 +3,9 @@
3
3
  * Responsibilities:
4
4
  * 1. Collect entry values for every <tr data-response-id> whose
5
5
  * Status is open/answered (disabled rows skipped automatically).
6
- * Widgets: <select> (enum decision), <input data-other-for> (기타
7
- * input revealed when select == "__other__"), <input
8
- * data-response-id> (material/data-point single-line), <textarea>
9
- * (everything else / fallback).
6
+ * Widgets: <select> (enum decision), <textarea data-other-for>
7
+ * (기타 input revealed when select == "__other__"), <textarea
8
+ * data-response-id> (everything else / fallback).
10
9
  * 2. Serialise the entries into markdown whose bytes are IDENTICAL
11
10
  * to scripts/okstra_ctl/report_views.py serialize_user_response.
12
11
  * 3. Write the result to <pre id="user-response-output">, offer a
@@ -56,7 +55,7 @@
56
55
  if (picked === "") return "";
57
56
  if (picked === "__other__") {
58
57
  var rid = sel.getAttribute("data-response-id") || "";
59
- var other = row.querySelector('input[data-other-for="' + rid + '"]');
58
+ var other = row.querySelector('textarea[data-other-for="' + rid + '"]');
60
59
  return other ? trimMultiline(other.value) : "";
61
60
  }
62
61
  var opt = sel.options[sel.selectedIndex];
@@ -69,11 +68,6 @@
69
68
  if (ta.disabled) return "";
70
69
  return trimMultiline(ta.value);
71
70
  }
72
- var inp = row.querySelector("input[data-response-id]");
73
- if (inp) {
74
- if (inp.disabled) return "";
75
- return trimMultiline(inp.value);
76
- }
77
71
  return "";
78
72
  }
79
73
 
@@ -119,7 +113,7 @@
119
113
  for (var i = 0; i < selects.length; i++) {
120
114
  (function (sel) {
121
115
  var rid = sel.getAttribute("data-response-id") || "";
122
- var other = document.querySelector('input[data-other-for="' + rid + '"]');
116
+ var other = document.querySelector('textarea[data-other-for="' + rid + '"]');
123
117
  if (!other) return;
124
118
  var update = function () {
125
119
  other.hidden = sel.value !== "__other__";
@@ -21,8 +21,8 @@
21
21
  "Bash($HOME/.okstra/bin/:*)",
22
22
  "Bash(codex)",
23
23
  "Bash(codex:*)",
24
- "Bash(gemini)",
25
- "Bash(gemini:*)",
24
+ "Bash(agy)",
25
+ "Bash(agy:*)",
26
26
  "Bash(claude)",
27
27
  "Bash(claude:*)"
28
28
  ]
@@ -152,14 +152,14 @@ To declare servers, add entries shaped `{ "name": "<server>", "description": "..
152
152
  How to invoke (worker-by-worker):
153
153
 
154
154
  - **Claude lead / Claude worker / Report writer worker**: invoke the MCP tool **directly by its tool name** (e.g. `mcp__<server>__<tool>`) through the host's tool interface. **Do NOT call it via `Bash`** — these names are MCP tools, not shell commands; running them in a shell will always fail with `command not found` regardless of permission settings.
155
- - **Codex worker / Gemini worker**: invoke through the external CLI's own MCP transport (e.g. `codex mcp call <server> <tool> <args>` for Codex CLI; the equivalent Gemini CLI MCP invocation for Gemini). If the worker's CLI has no matching MCP config, treat the server as unavailable for this run and record `MCP not available in this CLI` in `Missing Information or Assumptions` — do **not** attempt a shell fallback such as `mysql -h ...` or piping a tool name into `bash`.
155
+ - **Codex worker / Antigravity worker**: invoke through the external CLI's own MCP transport (e.g. `codex mcp call <server> <tool> <args>` for Codex CLI; the equivalent Antigravity CLI MCP invocation for Antigravity). If the worker's CLI has no matching MCP config, treat the server as unavailable for this run and record `MCP not available in this CLI` in `Missing Information or Assumptions` — do **not** attempt a shell fallback such as `mysql -h ...` or piping a tool name into `bash`.
156
156
  - All workers: cite the exact server, tool, and SELECT (or `WHERE` filters) used in the result file. Tool-call failures must be logged in the worker's `*-errors.json` (commandKind `mcp_call`) so the lead can decide whether to retry under a different worker.
157
157
 
158
158
  Usage policy:
159
159
 
160
160
  - **Allowed phases**: `requirements-discovery`, `error-analysis`, `implementation-planning`, `final-verification`. Use only when local schema/data evidence improves the answer. Always cite the server, table, and the SELECT used as evidence in worker output.
161
161
  - **`implementation` phase**: read-only MCP queries are permitted as cross-checks; MCP MUST NOT be used as a write path even if a write tool becomes available — schema/data mutations belong in the codebase migration files reviewed by humans.
162
- - **External CLI workers (Codex, Gemini)**: can use these MCP servers ONLY if their CLI's own MCP configuration is set up to mirror the same servers. If not configured, the worker should record `MCP not available in this CLI` in `Missing Information or Assumptions` rather than guessing.
162
+ - **External CLI workers (Codex, Antigravity)**: can use these MCP servers ONLY if their CLI's own MCP configuration is set up to mirror the same servers. If not configured, the worker should record `MCP not available in this CLI` in `Missing Information or Assumptions` rather than guessing.
163
163
  - **Forbidden**: connecting to non-listed databases, running anything that mutates state (server is read-only — flagged write attempts are a contract violation), persisting query results outside the run's own artifact directories.
164
164
  - **Limits**: `maxRows: 1000` per query (server-enforced). For larger scans, page via `WHERE` predicates and document the strategy.
165
165
 
@@ -16,7 +16,7 @@ Different recipients need different files. Do NOT include `final-report-template
16
16
 
17
17
  | Recipient | Files included in `[Required reading]` |
18
18
  |---|---|
19
- | Claude / Codex / Gemini analysis workers | analysis-packet.md as the primary compact input; task-brief, analysis-profile, analysis-material, reference-expectations, and clarification-response remain source/fallback paths, not automatic first-read files |
19
+ | Claude / Codex / Antigravity analysis workers | analysis-packet.md as the primary compact input; task-brief, analysis-profile, analysis-material, reference-expectations, and clarification-response remain source/fallback paths, not automatic first-read files |
20
20
  | Report writer worker (Phase 6) | all of the above **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 |
21
21
  | Reverify dispatches (Phase 5.5, lightweight mode) | **do NOT inject `[Required reading]` at all** — see [convergence](../prompts/lead/convergence.md) "Reverify prompt: required-reading suppression". |
22
22
 
@@ -55,7 +55,7 @@ If the sidecar file does not exist, create it with `{"schemaVersion": 1, "errors
55
55
  ### Rules
56
56
 
57
57
  - Do NOT include `source` / `recordedAt` / `agent` / `agentRole` / `model` / `taskKey` — the lead fills those in when dumping the sidecar to the run-level errors log via `okstra-error-log.py append-from-worker`.
58
- - Do NOT use `errorType` values other than `"tool-failure"` in the sidecar. `cli-failure` events are recorded by CLI wrapper agents (codex / gemini) directly to the run-level errors log, not via the sidecar. `contract-violation` events are recorded by the lead after inspecting worker outputs.
58
+ - Do NOT use `errorType` values other than `"tool-failure"` in the sidecar. `cli-failure` events are recorded by CLI wrapper agents (codex / antigravity) directly to the run-level errors log, not via the sidecar. `contract-violation` events are recorded by the lead after inspecting worker outputs.
59
59
  - Continue your task after recording; do not abort unless the failure makes the task impossible.
60
60
 
61
61
  ### Path extraction (BLOCKING)
@@ -65,7 +65,7 @@ Before recording anything, extract the absolute paths verbatim from the lead's d
65
65
  - `**Errors log path:** <abs-path>` — the run-level errors JSONL. Used by CLI wrapper agents via `okstra-error-log.py append-observed` for `cli-failure` events.
66
66
  - `**Errors sidecar path:** <abs-path>` — this worker's per-run sidecar JSON. Used by all workers for `tool-failure` events.
67
67
 
68
- If a required header line is absent from the dispatch prompt, return `<SENTINEL_PREFIX>_ERRORS_PATH_MISSING: lead prompt did not include **Errors log path:** / **Errors sidecar path:** headers` (substitute the worker's sentinel prefix — `CLAUDE_WORKER`, `CODEX`, `GEMINI`, or `REPORT_WRITER`) without proceeding. Do NOT synthesize the path from `<runDir>/logs/...` — that template syntax is documentation only; historical failure mode produced silently empty run-level error logs.
68
+ If a required header line is absent from the dispatch prompt, return `<SENTINEL_PREFIX>_ERRORS_PATH_MISSING: lead prompt did not include **Errors log path:** / **Errors sidecar path:** headers` (substitute the worker's sentinel prefix — `CLAUDE_WORKER`, `CODEX`, `ANTIGRAVITY`, or `REPORT_WRITER`) without proceeding. Do NOT synthesize the path from `<runDir>/logs/...` — that template syntax is documentation only; historical failure mode produced silently empty run-level error logs.
69
69
 
70
70
  ---
71
71
 
@@ -76,7 +76,7 @@ Every worker prompt MUST begin with these anchor headers, in this exact order, b
76
76
  1. `**Project Root:** <absolute-path>` — required so the worker can self-anchor without relying on inherited cwd.
77
77
  2. `**Prompt History Path:** <project-relative-path>`
78
78
  3. `**Result Path:** <project-relative-path>` — canonical destination for the worker's result file.
79
- 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.
79
+ 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.
80
80
  5. `**Worker Preamble Path:** <absolute-path>` — points to THIS file. Workers Read it end-to-end before doing anything else.
81
81
  6. `**Errors log path:** <absolute-path>` — run-level JSONL (see Error reporting above).
82
82
  7. `**Errors sidecar path:** <absolute-path>` — per-worker JSON (see Error reporting above).
@@ -84,7 +84,7 @@ Every worker prompt MUST begin with these anchor headers, in this exact order, b
84
84
  For the **implementation phase** specifically, the dispatched prompt MUST also include:
85
85
 
86
86
  - `**Worktree:** <absolute-path>` — the task worktree path.
87
- - `cwd for every mutating command: <absolute-path>` — same as Worktree path; used by codex / gemini wrappers as `--add-dir` / `--include-directories`.
87
+ - `cwd for every mutating command: <absolute-path>` — same as Worktree path; used by codex / antigravity wrappers as `--add-dir` / `--include-directories`.
88
88
 
89
89
  For the **final-verification phase** specifically, the dispatched prompt MUST also include the verification target snapshot so every analyser verifies the SAME target the lead captured at the entry gate:
90
90
 
@@ -99,7 +99,7 @@ When a worker reads any project-relative path from the prompt, it MUST resolve i
99
99
 
100
100
  ## Worker output sections (analysis workers)
101
101
 
102
- Every analysis worker (Claude / Codex / Gemini) produces sections 1–5 with the same dimensions. The lead does NOT bias worker prompts with per-worker emphasis — sections 1–5 are the common core, and specialization lives only in optional Section 6.
102
+ Every analysis worker (Claude / Codex / Antigravity) produces sections 1–5 with the same dimensions. The lead does NOT bias worker prompts with per-worker emphasis — sections 1–5 are the common core, and specialization lives only in optional Section 6.
103
103
 
104
104
  1. **Findings** — what you identified
105
105
  2. **Missing Information or Assumptions** — gaps in the analysis
@@ -122,7 +122,7 @@ The short message you return inline to the lead — the text shown to the user a
122
122
  **Model:** <Role>, <modelExecutionValue>
123
123
  ```
124
124
 
125
- Emit that line first, then your normal status / summary text on the following lines. This keeps the acting model visible in every worker box — across every provider (Claude / Codex / Gemini / report-writer) and every dispatch type (initial analysis, convergence reverify, report authoring). Copy the value exactly; never guess, abbreviate, or substitute a provider default. If your prompt carries no `**Model:**` line, say so in the return message rather than inventing one. Each worker spec applies this rule at its own concrete return point — see `agents/workers/claude-worker.md` "Stop Condition", `agents/workers/_cli-wrapper-template.md` step 8d, and `agents/workers/report-writer-worker.md` "Authoring Contract".
125
+ Emit that line first, then your normal status / summary text on the following lines. This keeps the acting model visible in every worker box — across every provider (Claude / Codex / Antigravity / report-writer) and every dispatch type (initial analysis, convergence reverify, report authoring). Copy the value exactly; never guess, abbreviate, or substitute a provider default. If your prompt carries no `**Model:**` line, say so in the return message rather than inventing one. Each worker spec applies this rule at its own concrete return point — see `agents/workers/claude-worker.md` "Stop Condition", `agents/workers/_cli-wrapper-template.md` step 8d, and `agents/workers/report-writer-worker.md` "Authoring Contract".
126
126
 
127
127
  ## Writing style (all prose output — analysis workers + report-writer)
128
128
 
@@ -12,7 +12,7 @@ Bash tool_use 명령을 phase deny-list 와 대조해 위반을 기계적으로
12
12
  - Bash tool_use 의 `input.command` 만 본다 — text 블록(설명/금지어 언급)이나 다른
13
13
  tool 의 인자는 보지 않으므로 "npm publish 하지 말 것" 같은 산문은 잡히지 않는다.
14
14
 
15
- 한계 1: claude-code 세션 jsonl 만 스캔한다. codex/gemini lead·worker 는 동일 형식의
15
+ 한계 1: claude-code 세션 jsonl 만 스캔한다. codex/antigravity lead·worker 는 동일 형식의
16
16
  tool_use transcript 를 ~/.claude/projects 에 남기지 않으므로 이 스캐너의 사정권 밖이며,
17
17
  해당 런타임의 금지 행위는 여전히 수동 감사에 의존한다.
18
18
  한계 2: deny-list 는 Bash 명령 문자열 전체를 검색하므로, 금지 토큰이 인자/메시지에
@@ -190,13 +190,13 @@ final_status_path = project_root / run_manifest["expectedStatusPath"]
190
190
  status_by_worker_id = {
191
191
  "claude": "completed",
192
192
  "codex": "timeout",
193
- "gemini": "error",
193
+ "antigravity": "error",
194
194
  "report-writer": "completed",
195
195
  }
196
196
  reason_by_worker_id = {
197
197
  "claude": "",
198
198
  "codex": "Validation fixture timeout",
199
- "gemini": "Validation fixture execution error",
199
+ "antigravity": "Validation fixture execution error",
200
200
  "report-writer": "",
201
201
  }
202
202
 
@@ -371,7 +371,7 @@ report_lines.extend(
371
371
  "| Lead | `1` | `1` | `$0.01` |",
372
372
  "| Worker 합계 | `1` | `1` | `$0.01` |",
373
373
  "| **전체 합계** | **`2`** | **`2`** | **`$0.02`** |",
374
- "| Codex/Gemini CLI 추가 비용 | | | `$0.00` |",
374
+ "| Codex/Antigravity CLI 추가 비용 | | | `$0.00` |",
375
375
  "",
376
376
  "## 7. Final Verdict",
377
377
  "",
@@ -43,7 +43,7 @@ def check(source_path: Path, target_path: Path) -> None:
43
43
  #
44
44
  # `_cli-wrapper-template.md` is a build-time render INPUT, not a shipped
45
45
  # artifact — tools/build.mjs renders it (with each *.params.json) into
46
- # codex-worker.md / gemini-worker.md and excludes the template itself from the
46
+ # codex-worker.md / antigravity-worker.md and excludes the template itself from the
47
47
  # runtime payload. Skip it here so parity is checked only on shipped files.
48
48
  # Keep this set in sync with TEMPLATE_INPUT_BASENAMES in tools/build.mjs.
49
49
  template_input_basenames = {"_cli-wrapper-template.md"}
@@ -610,7 +610,7 @@ _TOKEN_USAGE_SENTINEL_VALUES = frozenset(
610
610
  )
611
611
 
612
612
  # Numeric "valid zero" patterns. These ARE allowed in the CLI row when no
613
- # Codex/Gemini CLI work was billed; rejected everywhere else.
613
+ # Codex/Antigravity CLI work was billed; rejected everywhere else.
614
614
  _TOKEN_USAGE_ZERO_VALUES = frozenset({"0", "$0.00", "$0", "0.00"})
615
615
 
616
616
 
@@ -630,7 +630,7 @@ def _scan_token_usage_summary(
630
630
  real source of `0` / `$0.00` / `pending` shipping in real reports.
631
631
 
632
632
  Rules:
633
- - The Codex/Gemini CLI 추가 비용 row may carry an empty cell or
633
+ - The Codex/Antigravity CLI 추가 비용 row may carry an empty cell or
634
634
  `$0.00` (no CLI work was billed). Sentinel words are still
635
635
  rejected.
636
636
  - Every other row's backtick-wrapped cells must be either a
@@ -665,7 +665,7 @@ def _scan_token_usage_summary(
665
665
  continue
666
666
  label_cell = cells[0].strip("* `")
667
667
  # The CLI row's label always contains the word "CLI" — matching
668
- # `Codex/Gemini CLI 추가 비용` regardless of formatting variations.
668
+ # `Codex/Antigravity CLI 추가 비용` regardless of formatting variations.
669
669
  is_cli_row = "CLI" in label_cell
670
670
  for raw_cell in cells[1:]:
671
671
  for value in _TOKEN_USAGE_BACKTICK_CELL_RE.findall(raw_cell):
@@ -689,7 +689,7 @@ def _scan_token_usage_summary(
689
689
  "tokens. Re-run `okstra token-usage "
690
690
  "<team-state> --write --summary --substitute-data "
691
691
  "<report-path>` to repopulate from session jsonls. The "
692
- "Codex/Gemini CLI row is the only place `$0.00` is "
692
+ "Codex/Antigravity CLI row is the only place `$0.00` is "
693
693
  "allowed (when no CLI work was billed)."
694
694
  )
695
695
 
@@ -1017,9 +1017,9 @@ def validate_report(
1017
1017
 
1018
1018
  # Worker-results filename pattern: `<worker-role>-<task-type>-<seq>.md`.
1019
1019
  # Every analysis-worker role name ends in `-worker` (`claude-worker`,
1020
- # `codex-worker`, `gemini-worker`, `report-writer-worker`), so anchor the
1021
- # split on that suffix — otherwise `gemini-worker-error-analysis-001.md`
1022
- # ambiguously parses as `worker=gemini, task=worker-error-analysis`.
1020
+ # `codex-worker`, `antigravity-worker`, `report-writer-worker`), so anchor the
1021
+ # split on that suffix — otherwise `antigravity-worker-error-analysis-001.md`
1022
+ # ambiguously parses as `worker=antigravity, task=worker-error-analysis`.
1023
1023
  # Audit sidecars (`*-audit-*`) and errors sidecars (`.json`) are not
1024
1024
  # matched here.
1025
1025
  _WORKER_RESULT_BASENAME_RE = re.compile(
@@ -2037,7 +2037,7 @@ def _accuracy_failures(updated: dict) -> list[str]:
2037
2037
  f"worker `{role}` (status=completed) has no usage data — "
2038
2038
  f"{usage.get('note', 'reason unknown')}."
2039
2039
  )
2040
- if worker.get("agent") in ("codex", "gemini") and usage.get("source") != "unavailable":
2040
+ if worker.get("agent") in ("codex", "antigravity") and usage.get("source") != "unavailable":
2041
2041
  if "cliTotalTokens" not in usage:
2042
2042
  reasons.append(
2043
2043
  f"worker `{role}` ({worker.get('agent')}) wrapper jsonl was located "
@@ -103,6 +103,13 @@ export const COMMAND_REGISTRY = [
103
103
  category: "introspection",
104
104
  summary: ["Estimate file/read context cost for a task bundle"],
105
105
  },
106
+ {
107
+ name: "error-report",
108
+ module: "./error-report.mjs",
109
+ export: "run",
110
+ category: "introspection",
111
+ summary: ["Aggregate okstra-run error logs into a task-level report"],
112
+ },
106
113
  {
107
114
  name: "worktree-lookup",
108
115
  module: "./worktree-lookup.mjs",