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.
- package/docs/kr/architecture.md +27 -27
- package/docs/kr/cli.md +21 -21
- package/docs/kr/performance-improvement-plan-v2.md +4 -4
- package/docs/kr/performance-improvement-plan.md +3 -3
- package/docs/project-structure-overview.md +6 -6
- package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +724 -0
- package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +123 -0
- package/docs/task-process/error-analysis.md +1 -1
- package/docs/task-process/final-verification.md +4 -4
- package/docs/task-process/implementation-planning.md +2 -2
- package/docs/task-process/implementation.md +3 -3
- package/docs/task-process/requirements-discovery.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/{gemini-worker.md → antigravity-worker.md} +56 -56
- package/runtime/agents/workers/claude-worker.md +2 -2
- package/runtime/agents/workers/codex-worker.md +1 -1
- package/runtime/agents/workers/report-writer-worker.md +2 -2
- package/runtime/bin/lib/okstra/cli.sh +3 -3
- package/runtime/bin/lib/okstra/globals.sh +8 -8
- package/runtime/bin/lib/okstra/interactive.sh +1 -1
- package/runtime/bin/lib/okstra/usage.sh +7 -7
- package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +5 -3
- package/runtime/bin/lib/okstra-ctl/prepare.sh +4 -2
- package/runtime/bin/{okstra-gemini-exec.sh → okstra-antigravity-exec.sh} +67 -60
- package/runtime/bin/okstra-error-log.py +2 -1
- package/runtime/bin/okstra-token-usage.py +3 -4
- package/runtime/bin/okstra-trace-cleanup.sh +4 -4
- package/runtime/bin/okstra-wrapper-status.py +3 -3
- package/runtime/bin/okstra.sh +1 -1
- package/runtime/prompts/launch.template.md +3 -3
- package/runtime/prompts/lead/context-loader.md +1 -1
- package/runtime/prompts/lead/convergence.md +8 -8
- package/runtime/prompts/lead/okstra-lead-contract.md +15 -15
- package/runtime/prompts/lead/report-writer.md +6 -6
- package/runtime/prompts/lead/team-contract.md +31 -31
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +2 -2
- package/runtime/prompts/profiles/_common-contract.md +7 -7
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +6 -6
- package/runtime/prompts/profiles/_implementation-verifier.md +4 -4
- package/runtime/prompts/profiles/_stage-discipline.md +1 -1
- package/runtime/prompts/profiles/error-analysis.md +1 -1
- package/runtime/prompts/profiles/final-verification.md +1 -1
- package/runtime/prompts/profiles/forbidden-actions.json +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +1 -1
- package/runtime/prompts/profiles/implementation.md +3 -3
- package/runtime/prompts/profiles/improvement-discovery.md +3 -3
- package/runtime/prompts/profiles/requirements-discovery.md +1 -1
- package/runtime/prompts/wizard/prompts.ko.json +9 -5
- package/runtime/python/okstra_ctl/__init__.py +2 -0
- package/runtime/python/okstra_ctl/analysis_packet.py +1 -1
- package/runtime/python/okstra_ctl/clarification_items.py +17 -7
- package/runtime/python/okstra_ctl/codex_dispatch.py +2 -2
- package/runtime/python/okstra_ctl/context_cost.py +10 -44
- package/runtime/python/okstra_ctl/doctor.py +1 -1
- package/runtime/python/okstra_ctl/error_report.py +185 -0
- package/runtime/python/okstra_ctl/improvement_lenses.py +1 -1
- package/runtime/python/okstra_ctl/models.py +10 -10
- package/runtime/python/okstra_ctl/paths.py +9 -9
- package/runtime/python/okstra_ctl/reconcile.py +74 -11
- package/runtime/python/okstra_ctl/render.py +21 -21
- package/runtime/python/okstra_ctl/report_views.py +7 -13
- package/runtime/python/okstra_ctl/run.py +16 -16
- package/runtime/python/okstra_ctl/run_context.py +1 -1
- package/runtime/python/okstra_ctl/seeding.py +1 -1
- package/runtime/python/okstra_ctl/task_target.py +44 -0
- package/runtime/python/okstra_ctl/team.py +1 -1
- package/runtime/python/okstra_ctl/wizard.py +55 -30
- package/runtime/python/okstra_ctl/workers.py +3 -3
- package/runtime/python/okstra_ctl/workflow.py +1 -1
- package/runtime/python/okstra_ctl/worktree.py +1 -1
- package/runtime/python/okstra_token_usage/__init__.py +2 -3
- package/runtime/python/okstra_token_usage/antigravity.py +26 -0
- package/runtime/python/okstra_token_usage/blocks.py +4 -0
- package/runtime/python/okstra_token_usage/collect.py +20 -15
- package/runtime/python/okstra_token_usage/paths.py +0 -1
- package/runtime/python/okstra_token_usage/pricing.py +6 -3
- package/runtime/schemas/final-report-v1.0.schema.json +1 -1
- package/runtime/skills/okstra-brief/SKILL.md +1 -1
- package/runtime/skills/okstra-inspect/SKILL.md +85 -21
- package/runtime/skills/okstra-run/SKILL.md +3 -3
- package/runtime/skills/okstra-setup/SKILL.md +2 -2
- package/runtime/templates/prd/brief.template.md +2 -2
- package/runtime/templates/reports/i18n/en.json +1 -1
- package/runtime/templates/reports/i18n/ko.json +1 -1
- package/runtime/templates/reports/report.js +5 -11
- package/runtime/templates/reports/settings.template.json +2 -2
- package/runtime/templates/reports/task-brief.template.md +2 -2
- package/runtime/templates/worker-prompt-preamble.md +7 -7
- package/runtime/validators/forbidden_actions.py +1 -1
- package/runtime/validators/lib/fixtures.sh +3 -3
- package/runtime/validators/lib/validate-assets.sh +1 -1
- package/runtime/validators/validate-run.py +8 -8
- package/src/cli-registry.mjs +7 -0
- package/src/codex-dispatch.mjs +3 -3
- package/src/codex-run.mjs +2 -2
- package/src/doctor.mjs +1 -1
- package/src/error-report.mjs +27 -0
- package/src/install.mjs +1 -1
- package/src/render-bundle.mjs +1 -1
- package/src/uninstall.mjs +2 -2
- package/runtime/python/okstra_token_usage/gemini.py +0 -82
|
@@ -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-
|
|
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
|
|
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
|
|
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", "
|
|
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 /
|
|
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
|
|
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
|
|
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/
|
|
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`, `--
|
|
259
|
-
- for `taskType: implementation`: `teamContract.executor.provider` → `--executor <claude|codex|
|
|
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:
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
|
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/
|
|
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/
|
|
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
|
|
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` / `
|
|
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,
|
|
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
|
-
--
|
|
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/
|
|
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-
|
|
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/
|
|
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/
|
|
89
|
+
Codex/Antigravity는 이 코드베이스를 모릅니다. 핵심 용어 5-15개를 한 문장씩 정의.
|
|
90
90
|
없는 용어를 워커가 추측하면 분석 품질이 즉시 떨어집니다.
|
|
91
91
|
-->
|
|
92
92
|
|
|
@@ -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), <
|
|
7
|
-
* input revealed when select == "__other__"), <
|
|
8
|
-
* data-response-id> (
|
|
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('
|
|
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('
|
|
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__";
|
|
@@ -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 /
|
|
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,
|
|
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 /
|
|
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 /
|
|
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`, `
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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/
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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/
|
|
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 /
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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`, `
|
|
1021
|
-
# split on that suffix — otherwise `
|
|
1022
|
-
# ambiguously parses as `worker=
|
|
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", "
|
|
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 "
|
package/src/cli-registry.mjs
CHANGED
|
@@ -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",
|