okstra 0.117.0 → 0.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +115 -104
  2. package/docs/architecture/storage-model.md +300 -0
  3. package/docs/architecture.md +802 -0
  4. package/docs/cli.md +658 -0
  5. package/docs/container.md +124 -0
  6. package/docs/contributor-change-matrix.md +5 -4
  7. package/docs/follow-ups/2026-07-10-final-report-option-3.md +51 -0
  8. package/docs/performance-improvement-plan-v2.md +374 -0
  9. package/docs/project-structure-overview.md +21 -10
  10. package/package.json +10 -5
  11. package/runtime/BUILD.json +2 -2
  12. package/runtime/bin/okstra-render-report-views.py +5 -35
  13. package/runtime/prompts/launch.template.md +1 -0
  14. package/runtime/python/okstra_ctl/clarification_items.py +48 -0
  15. package/runtime/python/okstra_ctl/recap.py +80 -3
  16. package/runtime/python/okstra_ctl/report_views.py +46 -6
  17. package/runtime/python/okstra_ctl/user_response.py +190 -0
  18. package/runtime/skills/okstra-inspect/SKILL.md +37 -2
  19. package/runtime/skills/okstra-pr-gen/SKILL.md +9 -8
  20. package/runtime/skills/okstra-user-response/SKILL.md +121 -0
  21. package/runtime/templates/reports/report.js +6 -3
  22. package/runtime/templates/reports/user-response.template.md +1 -0
  23. package/src/cli-registry.mjs +7 -0
  24. package/src/commands/inspect/recap.mjs +6 -1
  25. package/src/commands/inspect/user-response.mjs +26 -0
  26. package/src/lib/skill-catalog.mjs +1 -0
  27. package/README.kr.md +0 -231
  28. package/docs/kr/architecture/storage-model.md +0 -297
  29. package/docs/kr/architecture.md +0 -815
  30. package/docs/kr/cli.md +0 -657
  31. package/docs/kr/container.md +0 -122
  32. package/docs/kr/follow-ups/2026-07-10-final-report-option-3.md +0 -51
  33. package/docs/kr/performance-improvement-plan-v2.md +0 -374
  34. package/docs/kr/performance-improvement-plan.md +0 -147
@@ -0,0 +1,124 @@
1
+ # okstra container — CLI Reference
2
+
3
+ > `okstra container` is a nonlinear tool that launches code from a verified task as a local docker compose group and monitors each container. Because it is a separate entry point from the phase flags in `okstra.sh`, it is documented here rather than in [cli.md](cli.md). See [project-structure-overview](project-structure-overview.md) §4.3 for the module location.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ - **What it is:** Deploys (`up`) the integrated code for a specific task to a task-specific docker compose container group, continuously monitors logs with a watcher for each container, and manages the lifecycle through `status`/`logs`/`stop-watcher`/`down`.
10
+ - **Orchestration only (does not generate files):** **Reuses** the target project's existing `docker-compose.yml`. It does not generate configuration files; if `docker-compose.yml` is missing, it reports what is missing and stops (the same applies if only a `Dockerfile` exists).
11
+ - **Nonlinear:** This is not a phase in `PHASE_SEQUENCE`. Any task key can be launched regardless of whether it has passed verification.
12
+ - **Single entry point:** The `/okstra-container-build` skill, `bin okstra container`, and Python `okstra_ctl.container` all converge on [`scripts/okstra_ctl/container.py`](../scripts/okstra_ctl/container.py) and its `provision_container_group`.
13
+ - **Source of truth (SSOT) for container existence:** Docker labels. `registry.json` is a secondary index containing only tmux sessions/panes/findings.
14
+
15
+ ## Prerequisites
16
+
17
+ - `docker` / `docker compose` must be installed and operational. `up` fails when they are not installed, but `okstra doctor` emits only `[WARN]` and retains exit code 0 (container functionality is optional).
18
+ - The code for the target task key must be integrated into the task-key worktree HEAD. If there are unintegrated stages, `up` merges them (preserving the stage trees) before continuing; if a conflict occurs, it reports the conflicting files and stops.
19
+ - `docker-compose.yml` must exist at the worktree root.
20
+
21
+ ## Command format
22
+
23
+ ```
24
+ okstra container <up|status|logs|stop-watcher|down> --project-root <PATH> --task-key <KEY> [options]
25
+ ```
26
+
27
+ | sub-command | Behavior | Additional options |
28
+ |---|---|---|
29
+ | `up` | Verify stage integration → validate `docker-compose.yml` → compose env override → `docker compose -p <project> up -d` → poll health checks → start a tail/watcher pane for each container | — |
30
+ | `status` | Show the live container group status by querying Docker labels | — |
31
+ | `logs` | Report `watchersDir` and registered watcher entries as JSON; it does not stream Docker container logs | `--service <NAME>` (filters watcher metadata; all registered watchers when omitted) |
32
+ | `stop-watcher` | Stop the watcher panes for the task (containers remain running) | — |
33
+ | `down` | Tear down the container group and stop attached watchers | `--all` |
34
+
35
+ ## Arguments
36
+
37
+ ### `--project-root` (required)
38
+ Absolute path to the target project root. Required for every sub-command.
39
+
40
+ ### `--task-key` (effectively required)
41
+ Identifier of the task to deploy, in the form `<project-id>:<task-group>:<task-id>`. The default is an empty string, but actual operations require a valid task key.
42
+
43
+ ### `--service` (`logs` only)
44
+ `--service <NAME>` filters the returned watcher metadata by compose service name. When omitted, all registered watcher entries are returned; an unknown name produces an empty `watchers` object.
45
+
46
+ The actual `logs` output from `logs_container_group()` contains `watchersDir` and registered watcher entries in `watchers`. It does not run `docker compose logs` and does not stream Docker container logs. Inspect each watcher's `findings_path` and the files beneath `watchersDir` for monitoring results.
47
+
48
+ ### `--all` (`down` only)
49
+ Clean up **all** task container groups and watchers within the current project root's `.okstra/` scope. The boundary is limited to the `<project-root>/.okstra/` prefix, so panes belonging to **other projects** in concurrent sessions are never touched. Without `--all`, a single `down` cleans up exactly the panes for the specified task.
50
+
51
+ ## How `up` works
52
+
53
+ 1. **Resolve source tree** — Use the task-key worktree HEAD. Merge unintegrated stages (`teardown=False`, preserving stage worktrees). Stop and identify conflicting files if a conflict occurs (retries are safe because the already-merged operation is idempotent).
54
+ 2. **Validate configuration file** — Check for `docker-compose.yml` at the worktree root. If it is missing, stop after identifying the missing filename (do not generate it).
55
+ 3. **Scan bind mounts** — If the normalized output of `docker compose config` contains a host path outside the worktree (`../` or an absolute path), **warn and continue** (do not stop; warn that the container may write files to the host).
56
+ 4. **Compose env override** — In the okstra-owned worktree, layer task overrides over `.env`, write the result to `env.override`, and pass the files in the order `--env-file <worktree .env> --env-file <env.override>` (the latter takes precedence).
57
+ 5. **Deploy** — Run `docker compose -p <project-name> ... up -d`. Obtain the service list from `docker compose config --services` (the canonical source).
58
+ 6. **Poll health checks** — Use `docker compose ps` to verify that each service has started. Success means reaching healthy for services with a health check, or `running` for services without one.
59
+ 7. **Start monitoring** — If `tmux` is available, start a tail pane and watcher agent for each container in the detached session `okstra-container-<slug>`. If it is unavailable, launch only the containers and state "monitoring disabled (tmux unavailable)" in the result.
60
+
61
+ ### Fixed defaults (not currently exposed as CLI flags)
62
+
63
+ | Value | Default | Meaning |
64
+ |---|---|---|
65
+ | healthcheck timeout | 120 seconds | Stop and report services that failed to start after this limit |
66
+ | healthcheck interval | 3 seconds | Polling interval for `docker compose ps` |
67
+ | watcher scan interval | 5 seconds | Interval for scanning incremental watcher logs |
68
+
69
+ > These values exist as named arguments to `provision_container_group`, but because they are not exposed as CLI flags, they currently operate as fixed values.
70
+
71
+ ## watcher (two-stage error trigger)
72
+
73
+ One watcher per container runs in the detached session.
74
+
75
+ 1. **Lightweight scan** — Fetch incremental logs with `docker compose logs --since` and match only regular expressions (`ERROR`/`FATAL`/`Exception`/`Traceback`/abnormal exit codes, and so on). If there are no matches, proceed to the next interval without an LLM call → zero token cost during healthy periods.
76
+ 2. **Deep analysis** — Only when a pattern is detected, the watcher AI analyzes the relevant log window and appends its findings to `findings.md`. Identical error signatures are debounced (meaningful numbers such as HTTP statuses and exit codes are preserved, while only noise such as timestamps and pids is normalized). The watcher **only detects and reports**; it does not modify code or configuration.
77
+
78
+ Watcher/tail panes carry only the dedicated `@okstra_container_run` tag, so they survive even when a Claude session ends (SessionEnd `--reap`). Stop them with `stop-watcher` or `down`.
79
+
80
+ ## Labels and artifacts
81
+
82
+ Three labels are attached to deployed containers. The label queries used by `status`/`down` use them to locate the group.
83
+
84
+ | Label | Value |
85
+ |---|---|
86
+ | `okstra.task-key` | `<project-id>:<task-group>:<task-id>` |
87
+ | `okstra.project-name` | compose project name `okstra-<proj>-<group>-<task>` |
88
+ | `okstra.run-trace` | container session name (`okstra-container-<slug>`) |
89
+
90
+ All okstra artifacts are stored under `<project-root>/.okstra/tasks/<group>/<task-id>/container/` (the original project files remain unchanged):
91
+
92
+ ```
93
+ container/
94
+ ├── env.override # per-task variables layered over the project .env
95
+ ├── registry.json # tmux sessions/panes/findings (flock-guarded secondary index)
96
+ ├── deploy-state.json # compose project name, running containers, labels
97
+ └── watchers/<service>-findings.md # per-watcher error analysis log
98
+ ```
99
+
100
+ ## Exit behavior/output
101
+
102
+ Each sub-command writes its result to stdout as JSON and returns exit code 0. Validation failures (missing configuration files, merge conflicts, health check timeouts, and so on) terminate abnormally with a `PrepareError` that identifies what went wrong.
103
+
104
+ ## Usage examples
105
+
106
+ ```bash
107
+ # Deploy and start monitoring
108
+ okstra container up --project-root /path/to/proj --task-key proj:auth:login-fix
109
+
110
+ # Status
111
+ okstra container status --project-root /path/to/proj --task-key proj:auth:login-fix
112
+
113
+ # Filter watcher metadata for one service
114
+ okstra container logs --project-root /path/to/proj --task-key proj:auth:login-fix --service api
115
+
116
+ # Stop only the watcher (keep containers running)
117
+ okstra container stop-watcher --project-root /path/to/proj --task-key proj:auth:login-fix
118
+
119
+ # Tear down the group
120
+ okstra container down --project-root /path/to/proj --task-key proj:auth:login-fix
121
+
122
+ # Remove every container group for this project
123
+ okstra container down --project-root /path/to/proj --all
124
+ ```
@@ -4,12 +4,13 @@ Use this matrix before changing high-risk repo contracts. Update the source file
4
4
 
5
5
  | Change | Must update | Tests |
6
6
  |---|---|---|
7
- | Add CLI flag | `src/`, `scripts/okstra_ctl/run.py`, `docs/kr/cli.md`, `prompts/wizard/` | JS CLI tests and pytest CLI contracts |
8
- | Add Node subcommand | `src/cli-registry.mjs`, `src/commands/`, `docs/kr/cli.md`, `docs/project-structure-overview.md` | `tests-js/cli-registry.test.mjs` plus command-specific JS/Python tests |
9
- | Add public skill | `src/lib/skill-catalog.mjs`, `.claude-plugin/plugin.json`, `skills/<name>/SKILL.md`, `docs/for-ai/README.md`, `docs/project-structure-overview.md`, `README*` | `tests-js/skill-catalog.test.mjs`, `tests/contract/test_docs_runtime_contract.py` |
10
- | Change manager contract | `scripts/okstra_ctl/manager_*.py`, `src/commands/manager.mjs`, `skills/okstra-manager/SKILL.md`, `docs/for-ai/skills/okstra-manager.md`, `docs/kr/cli.md`, `docs/kr/architecture/storage-model.md` | `tests-js/manager.test.mjs`, `tests/test_okstra_manager_*.py` |
7
+ | Add CLI flag | `src/`, `scripts/okstra_ctl/run.py`, `docs/cli.md`, `prompts/wizard/` | JS CLI tests and pytest CLI contracts |
8
+ | Add Node subcommand | `src/cli-registry.mjs`, `src/commands/`, `docs/cli.md`, `docs/project-structure-overview.md` | `tests-js/cli-registry.test.mjs` plus command-specific JS/Python tests |
9
+ | Add public skill | `src/lib/skill-catalog.mjs`, `.claude-plugin/plugin.json`, `skills/<name>/SKILL.md`, `docs/for-ai/README.md`, `docs/project-structure-overview.md`, `README.md` | `tests-js/skill-catalog.test.mjs`, `tests/contract/test_docs_runtime_contract.py` |
10
+ | Change manager contract | `scripts/okstra_ctl/manager_*.py`, `src/commands/manager.mjs`, `skills/okstra-manager/SKILL.md`, `docs/for-ai/skills/okstra-manager.md`, `docs/cli.md`, `docs/architecture/storage-model.md` | `tests-js/manager.test.mjs`, `tests/test_okstra_manager_*.py` |
11
11
  | Add phase | `scripts/okstra_ctl/workflow.py`, `prompts/profiles/`, `validators/`, `tests/` | workflow and validation contract tests |
12
12
  | Change worker roster | `prompts/profiles/*.md`, `scripts/okstra_ctl/workers.py`, `tests/contract/test_repo_contracts.py` | worker roster contract tests |
13
13
  | Change report section | `schemas/final-report-v1.0.schema.json`, `templates/reports/final-report.template.md`, `scripts/okstra_ctl/render_final_report.py`, `validators/validate-run.py` | final-report schema, renderer, and validator tests |
14
+ | Change Markdown publication policy | `config/docs-publication.json`, `tools/docs_publication/`, affected public Markdown paths | `tests/docs_publication/`, `tests/contract/test_repo_contracts.py` |
14
15
 
15
16
  `runtime/` is build output. Never edit it directly; change source files and rebuild the runtime payload instead.
@@ -0,0 +1,51 @@
1
+ # Final Report Readability Follow-up: Revisit Option 3
2
+
3
+ Status: On hold
4
+ Date: 2026-07-10
5
+
6
+ ## Background
7
+
8
+ This initial readability improvement kept the scope narrow.
9
+
10
+ - Add `readerSummary` at the beginning of the Markdown final report as an entry point for the summary people should read first.
11
+ - Add a Reader Summary dashboard and reader mode to the HTML report view.
12
+ - Keep existing `final-report` data compatible through the `verdictCard` fallback.
13
+
14
+ This document keeps the larger Option 3 out of the current change and records it as a candidate to reconsider separately later.
15
+
16
+ ## Option 3 on Hold
17
+
18
+ Reconsider whether to split the `final-report` artifact itself by purpose.
19
+
20
+ The current structure retains one canonical Markdown document and the view generated from it. Option 3 would compare whether summary blocks and HTML filtering are sufficient, or whether dividing the report into purpose-specific artifacts would be better.
21
+
22
+ Candidates to compare:
23
+
24
+ - A short human handoff report and a separate audit appendix.
25
+ - From the same `data.json`, a generated `summary` view and `audit` view.
26
+ - Phase-specific slim report templates that retain only the sections on which people act first.
27
+ - Role-specific view sets such as reporter handoff, implementer handoff, verifier audit, and release handoff.
28
+
29
+ ## Reconsideration Triggers
30
+
31
+ Reopen this document if any of the following recurs.
32
+
33
+ - Even after `readerSummary` and HTML reader mode are deployed, users still say that `final-report` is difficult to read.
34
+ - Reviewers consistently skip the same audit sections or request a smaller handoff artifact.
35
+ - The same evidence is repeated across multiple sections when generating `final-report`.
36
+ - A future schema migration requires changing the report artifact contract anyway.
37
+
38
+ ## Questions to Decide
39
+
40
+ - Should Markdown remain the primary human artifact, or should `data.json` be the sole canonical source with generated views?
41
+ - Which artifact should be attached to follow-up tasks by default?
42
+ - Which sections are human-action material, and which are audit-only material?
43
+ - Should a validator enforce the split, or should it remain a renderer convention?
44
+ - How would the split affect existing `render-views`, follow-up spawning, and approval sidecars?
45
+
46
+ ## References
47
+
48
+ - Current schema: `schemas/final-report-v1.0.schema.json`
49
+ - Current Markdown template: `templates/reports/final-report.template.md`
50
+ - Current HTML renderer: `scripts/okstra_ctl/report_views.py`
51
+ - Current report UI assets: `templates/reports/report.css`, `templates/reports/report.js`
@@ -0,0 +1,374 @@
1
+ # okstra-run Performance Improvement Plan v2
2
+
3
+ ## Index
4
+
5
+ - [1. Purpose](#1-purpose)
6
+ - [2. Summary of the Current Architecture](#2-summary-of-the-current-architecture)
7
+ - [2.1 Entry Points](#21-entry-points)
8
+ - [2.2 Distinguish the Two Kinds of Phase](#22-distinguish-the-two-kinds-of-phase)
9
+ - [2.3 Cost Characteristics of the Prepare Step](#23-cost-characteristics-of-the-prepare-step)
10
+ - [2.4 Worker Structure](#24-worker-structure)
11
+ - [3. Performance Bottleneck Hypotheses](#3-performance-bottleneck-hypotheses)
12
+ - [4. Measurement Criteria](#4-measurement-criteria)
13
+ - [4.1 Measured Results (2026-06-11)](#41-measured-results-2026-06-11-fontradar-v2-api-dev-9186)
14
+ - [5. Improvement Priorities](#5-improvement-priorities)
15
+ - [P0. Baseline Measurement and Terminology](#p0-baseline-measurement-and-terminology)
16
+ - [P1. Reduce the Scope of Convergence Reverification](#p1-reduce-the-scope-of-convergence-reverification)
17
+ - [P2. Prompt Diet: Reduce Analysis Worker Input](#p2-prompt-diet-reduce-analysis-worker-input)
18
+ - [P3. Fast-track Routing](#p3-fast-track-routing)
19
+ - [P4. Evaluate Prompt Caching Feasibility](#p4-evaluate-prompt-caching-feasibility)
20
+ - [P5. Parallelize Prepare Rendering](#p5-parallelize-prepare-rendering)
21
+ - [P6. Incremental Token Usage Collection](#p6-incremental-token-usage-collection)
22
+ - [6. Parallel Work Plan](#6-parallel-work-plan)
23
+ - [7. P1 Implementation Checklist](#7-p1-implementation-checklist)
24
+ - [8. Risks and Guardrails](#8-risks-and-guardrails)
25
+ - [9. Conclusion](#9-conclusion)
26
+
27
+ ## 1. Purpose
28
+
29
+ Reduce the perceived cost of cross-verification runs started through the `okstra-run` skill or `scripts/okstra.sh`. This document separates the current architecture into its correct layers and defines improvement priorities, measurement criteria, opportunities for parallel work, and the initial implementation scope.
30
+
31
+ Key conclusions:
32
+
33
+ - The largest costs occur after worker dispatch, in repeated verification and long prompt consumption, rather than in the prepare step.
34
+ - First reduce the scope of convergence reverification to lower the number of worker calls and wall-clock time.
35
+ - Fast-track routing, prompt caching, and reductions to templates or worker definitions affect different layers and should be handled as separate work.
36
+
37
+ ## 2. Summary of the Current Architecture
38
+
39
+ ### 2.1 Entry Points
40
+
41
+ Both `scripts/okstra.sh` and `skills/okstra-run/SKILL.md` call `prepare_task_bundle()` in `scripts/okstra_ctl/run.py`. This single reference point must be preserved.
42
+
43
+ - `scripts/okstra.sh`: parses CLI arguments, calls `prepare_task_bundle()`, and runs `claude` for non-render-only executions.
44
+ - `okstra-run` skill: collects input in the current Claude session, calls the same Python entry point, and takes over the lead role.
45
+ - Shared prepare logic: `scripts/okstra_ctl/run.py`.
46
+
47
+ ### 2.2 Distinguish the Two Kinds of Phase
48
+
49
+ The current documentation and code contain two layers with similarly named phases. Performance work must not conflate them.
50
+
51
+ #### Task-type lifecycle
52
+
53
+ `PHASE_SEQUENCE` in `scripts/okstra_ctl/workflow.py` contains only the following six task types.
54
+
55
+ | Order | task-type | Responsibility |
56
+ |---|---|---|
57
+ | 1 | `requirements-discovery` | Classify the work category, route safely to the next phase, and identify missing inputs |
58
+ | 2 | `error-analysis` | Analyze symptoms, root-cause hypotheses, reproduction gaps, and verification paths |
59
+ | 3 | `implementation-planning` | Provide at least two implementation options, trade-offs, execution order, validation/rollback, and an approval request |
60
+ | 4 | `implementation` | Execute the approved plan, commit, run verifier checks, and capture rollback evidence |
61
+ | 5 | `final-verification` | Verify acceptability and residual risk, and decide whether to enter release handoff |
62
+ | 6 | `release-handoff` | Perform the commit/push/PR handoff action selected by the user |
63
+
64
+ Each okstra invocation performs exactly one task type. Moving to the next task type requires a new invocation.
65
+
66
+ #### Claude lead operating phases
67
+
68
+ Phases 1–7 in `prompts/lead/okstra-lead-contract.md` are operating steps that the lead performs within one task-type run.
69
+
70
+ | Operating phase | Name | Responsibility |
71
+ |---|---|---|
72
+ | 1 | Intake | Read the task bundle |
73
+ | 2~5 | Prompt / Team / Execution / Fallback | Prepare worker prompts, establish the team context, and dispatch workers |
74
+ | 5.5 | Convergence | Reverify worker findings and classify consensus |
75
+ | 6 | Synthesis | Dispatch the report writer or use the lead fallback |
76
+ | 7 | Persist | Collect token usage, substitute final-report placeholders, and finalize manifests/status |
77
+
78
+ Therefore, "P1 convergence improvement" in this document does not change the task-type lifecycle. It reduces the cost of the lead operating phase defined by `prompts/lead/okstra-lead-contract.md` and `prompts/lead/convergence.md`.
79
+
80
+ ### 2.3 Cost Characteristics of the Prepare Step
81
+
82
+ `prepare_task_bundle()` writes the instruction set and manifest-related files sequentially.
83
+
84
+ - Instruction set: `analysis-profile.md`, `analysis-material.md`, `task-brief.md`, optional carry-in/directive, `reference-expectations.md`, `final-report-template.md`, `claude-execution-prompt.md`, and the prompt snapshot.
85
+ - Manifest/discovery: `team-state`, `task-manifest`, `task-index`, `run-manifest`, `timeline`, task catalog, and latest task.
86
+
87
+ This serial rendering has room for improvement, but it is generally cheaper than external worker dispatch. Render parallelization is therefore not the first priority.
88
+
89
+ ### 2.4 Worker Structure
90
+
91
+ The four default worker definitions are under `agents/workers/`.
92
+
93
+ - `claude-worker.md`: Claude subagent.
94
+ - `codex-worker.md`: invokes the Codex CLI through the `okstra-codex-exec.sh` wrapper.
95
+ - `antigravity-worker.md`: invokes the Antigravity CLI through the `okstra-antigravity-exec.sh` wrapper.
96
+ - `report-writer-worker.md`: final-report author. It is not an analysis worker and does not vote in convergence.
97
+
98
+ ## 3. Performance Bottleneck Hypotheses
99
+
100
+ | ID | Bottleneck | Impact | Evidence / location | Assessment |
101
+ |---|---|---:|---|---|
102
+ | B1 | Each convergence reverify round creates another dispatch per worker | High | `prompts/lead/convergence.md` Round 1-N | **Resolved** — P1 queue pruning implemented and critic serialization parallelized (§4.1 item 2) |
103
+ | B2 | Analysis worker prompts and required reading are long | High | `prompts/lead/okstra-lead-contract.md`, `team-contract`, worker definitions | **Mostly resolved** — analysis-packet-primary measured at 22 KB/worker (§4.1) |
104
+ | B3 | The report writer rereads worker results, convergence, and the final-report template | ~~Medium~~ Low | `prompts/lead/report-writer.md` | **Input compression rejected** — measured reading time is 1–2 minutes and generation dominates (§4.1 item 3) |
105
+ | B4 | Multiple renders/writes run serially during prepare | Low–medium | `scripts/okstra_ctl/run.py` render block | Lower priority |
106
+ | B5 | The token usage collector scans session JSONL linearly | Low–medium | `scripts/okstra_token_usage/` | **Resolved** — P6 incremental cache implemented |
107
+ | B6 | Simple work uses the same full workflow | Medium | task-type lifecycle / requirements routing | Fast-track design needed — largest remaining lever |
108
+ | B7 | The report writer's final-report/data.json **output volume itself** is large (90–140 KB) | High | Measurements in §4.1 item 3 — 8–19 minutes of generation per run | Slim the report contract or select a report-writer model — **user decision required** |
109
+
110
+ Established assumptions:
111
+
112
+ - `contested` is not a classification that exists before entry into Round 2. In the current algorithm, `contested` is the final classification assigned to unresolved findings after the maximum round is reached.
113
+ - Therefore, the correct rule is not "Round 2 for contested items only," but "Round 2 only for the verification queue that remains mixed/unresolved after Round 1."
114
+
115
+ ## 4. Measurement Criteria
116
+
117
+ At minimum, improvement work compares the following metrics before and after the change.
118
+
119
+ | Metric | Collection method | Target |
120
+ |---|---|---|
121
+ | Worker dispatch count | team-state `workers[]`, convergence state round history, number of prompt files | Fewer reverify dispatches in runs with P1 applied |
122
+ | Wall-clock | team-state worker usage `durationMs`, run start/end timestamps | 20–40% reduction in convergence-heavy runs |
123
+ | Raw tokens | Lead/worker totals from the token usage collector | Fewer worker tokens associated with reverify prompts |
124
+ | Billable equivalent | `usageSummary.*BillableEquivalentTokens` | Confirm a cost reduction |
125
+ | Quality regression | Missing contested/worker-unique items in the final report and validator results | Preserve the existing contract |
126
+
127
+ Minimum fixtures before implementing P1:
128
+
129
+ 1. Early convergence: a run whose verification queue becomes empty in Round 0 or Round 1.
130
+ 2. Mixed/unresolved: a run in which some findings remain after Round 1 and require selective Round 2 processing.
131
+ 3. Worker failure: a run in which some reverify dispatches end in `timeout`/`error`.
132
+
133
+ ### 4.1 Measured Results (2026-06-11, fontradar-v2-api dev-9186)
134
+
135
+ Measurements came from artifact mtimes, team-state `phaseTimeline`, and report-writer session JSONL tool-call timelines for three real runs (requirements discovery, implementation planning, and implementation stage 1).
136
+
137
+ 1. **Wall-clock breakdown by run phase** — In analysis runs, "core analysis" accounts for only 17–24% of wall time: setup 4–6 minutes, analysis 16–24 minutes, convergence plus critic 23 minutes, and report writer 12–24 minutes.
138
+
139
+ 2. **Critic serialization** — The critic was dispatched only after reverification finished, wasting 6–12 serial minutes per run. Because the critic input is fixed to the integrated Round 0 results, dispatch now runs in parallel with the first reverify round (`prompts/lead/convergence.md` §When).
140
+
141
+ 3. **Report-writer generation dominates** — Session tool-call measurements show that reading all input (~404 KB, 16 files) takes **1–2 minutes**, generating data.json (skeleton Write followed by incremental Edit operations per section) takes **8–19 minutes**, and self-verification/audit takes about 3 minutes. B3 input compression would therefore save only about one wall-clock minute and was **rejected**. The remaining output-side lever is B7: slim the report contract (a quality trade-off requiring a user decision) or lower `--report-writer-model` using the existing knob.
142
+
143
+ 4. **Automated measurement** — The Phase 7 collector extracts the lead's `PROGRESS: phase-*` markers and persists them as team-state `phaseTimeline` (`scripts/okstra_token_usage/collect.py :: phase_timeline`). Subsequent runs can measure item 1 through `/okstra-inspect time` instead of manual mtime analysis. The reportWriter surface of `okstra context-cost` was also aligned with the actual dispatch contract (current sequence plus analysis packet).
144
+
145
+ ## 5. Improvement Priorities
146
+
147
+ ### P0. Baseline Measurement and Terminology
148
+
149
+ Goals:
150
+
151
+ - Prevent documentation and code from conflating the task-type lifecycle with lead operating phases.
152
+ - Define the P1 baseline by requiring convergence state to expose `effectiveMaxRounds`, `roundsExecuted`, `dispatchCount`, `queueSizeByRound`, and `finalClassificationCounts`.
153
+
154
+ Primary change candidates:
155
+
156
+ - `prompts/lead/convergence.md`
157
+ - `prompts/lead/okstra-lead-contract.md`
158
+ - Convergence state schema documentation, if needed
159
+
160
+ Completion criteria:
161
+
162
+ - Documentation does not use `contested` as the name of an intermediate queue.
163
+ - The metrics required for before/after comparison are available in the final report or state artifact.
164
+
165
+ ### P1. Reduce the Scope of Convergence Reverification
166
+
167
+ Goals:
168
+
169
+ - Immediately finalize findings that can be resolved in Round 1 under the default behavior.
170
+ - Run Round 2 only for the verification queue that remains `mixed` or `unresolved` after Round 1.
171
+ - Do not send findings already finalized as `full-consensus`, `partial-consensus`, or `worker-unique` back to workers.
172
+
173
+ Current problem:
174
+
175
+ - For task types with `maxRounds=2`, the documentation does not draw a sufficiently strong boundary between items remaining after Round 1 and already finalized items.
176
+ - If operators interpret the process as "reverify every item," unnecessary redispatches grow in proportion to the worker count.
177
+
178
+ Improved algorithm:
179
+
180
+ ```text
181
+ Round 0:
182
+ Parse and group worker results.
183
+ If two or more workers agree on the same semantics and ticket set, classify it as full-consensus.
184
+ Put only single-worker findings into the verification queue.
185
+
186
+ Round 1:
187
+ Reverify only queued items, batched by worker.
188
+ all agree/supplement -> classify as full-consensus and remove from the queue.
189
+ majority agree/supplement -> classify as partial-consensus and remove from the queue.
190
+ all disagree -> classify as worker-unique and remove from the queue.
191
+ mixed/error/insufficient evidence -> leave in the unresolved queue.
192
+
193
+ Optional Round 2:
194
+ Skip when the unresolved queue is empty.
195
+ If the unresolved queue is non-empty, reverify only those items.
196
+ Finally classify items that remain after Round 2:
197
+ majority agreement -> partial-consensus
198
+ otherwise -> contested
199
+ ```
200
+
201
+ Round 2 entry conditions:
202
+
203
+ - `effectiveMaxRounds >= 2`
204
+ - The unresolved queue is non-empty after Round 1.
205
+ - The unresolved cause is not solely worker failure. If every reverify worker returns a terminal non-result, record `verification-error`/blocked evidence instead of dispatching again.
206
+
207
+ Change targets:
208
+
209
+ - `prompts/lead/convergence.md`: specify queue pruning after Round 1, the Round 2 gate, and state artifact fields.
210
+ - `prompts/lead/okstra-lead-contract.md`: align the description of `convergence.maxRounds` with queue-pruned behavior.
211
+ - `prompts/lead/report-writer.md`: confirm that the final report records round history and why Round 2 was skipped.
212
+ - Validator or tests only if new convergence state fields become required.
213
+
214
+ Completion criteria:
215
+
216
+ - Findings finalized in Round 1 do not appear again in the Round 2 prompt.
217
+ - State contains `skippedReason` when Round 2 does not run.
218
+ - The final report continues to represent all four classifications: `Full Consensus`, `Partial Consensus`, `Contested`, and `Worker-Unique`.
219
+
220
+ ### P2. Prompt Diet: Reduce Analysis Worker Input
221
+
222
+ Goals:
223
+
224
+ - Preserve the current rule that analysis workers do not read the final-report template, and keep report-writer-only material out of actual dispatch prompts.
225
+ - Reduce repeated wording in worker definitions while preserving blocking contracts such as path extraction, the model line, and the error sidecar.
226
+
227
+ Cautions:
228
+
229
+ - Before extracting `agents/workers/_common.md`, confirm that install/packaging paths and skill/agent loaders support includes.
230
+ - Merely moving text into a separate file can increase cost if the runtime does not inline it and the worker must read another file.
231
+
232
+ Change targets:
233
+
234
+ - `agents/workers/codex-worker.md`
235
+ - `agents/workers/antigravity-worker.md`
236
+ - `prompts/lead/team-contract.md`
237
+ - Install/build packaging
238
+
239
+ ### P3. Fast-track Routing
240
+
241
+ Goal:
242
+
243
+ - Route work for which the full lifecycle is excessive—such as docs-only changes, typos, and clear one-file fixes—through a shorter path.
244
+
245
+ Recommended design:
246
+
247
+ - Rather than arbitrarily skipping the task-type lifecycle, have `requirements-discovery` record an explicit routing token such as `route=lite-implementation-planning` or `route=direct-implementation-planning`.
248
+ - Source edits still occur only in the `implementation` task type.
249
+ - Retain minimum verification through `final-verification` or an equivalent read-only check.
250
+
251
+ Change targets:
252
+
253
+ - `prompts/profiles/requirements-discovery.md`
254
+ - `scripts/okstra_ctl/workflow.py`
255
+ - Next-phase selection UI in `skills/okstra-run/SKILL.md`
256
+ - `skills/okstra-status/SKILL.md`
257
+ - Validator expectations
258
+
259
+ Caution:
260
+
261
+ - If "fast-track" bypasses the implementation-planning approval gate, it breaks the single reference point and approval contract. Whether to reduce or remove the approval gate requires a separate user decision.
262
+
263
+ ### P4. Evaluate Prompt Caching Feasibility
264
+
265
+ Goal:
266
+
267
+ - Use prompt caching only on transports that support it.
268
+
269
+ Current uncertainty:
270
+
271
+ - `render.py` renders Markdown files.
272
+ - Codex/Antigravity wrappers pass prompt files to CLI stdin.
273
+ - It is unclear whether API-level metadata such as `cache_control: ephemeral` is actually carried through this path.
274
+
275
+ Therefore, begin P4 with a spike rather than immediate implementation.
276
+
277
+ Validation items:
278
+
279
+ - Whether cache hints can be expressed in Claude Agent dispatch prompts.
280
+ - Whether cache hints have meaning in Codex CLI stdin prompts.
281
+ - Whether Antigravity CLI has a corresponding feature.
282
+ - Whether the token usage collector can observe changes in cache reads/creation.
283
+
284
+ ### P5. Parallelize Prepare Rendering
285
+
286
+ Goal:
287
+
288
+ - Parallelize independent file renders/writes in the prepare step.
289
+
290
+ Cautions:
291
+
292
+ - `prepare_task_bundle()` remains the single authority, so callers stay unchanged even if work is parallelized.
293
+ - Manifest/discovery rendering shares context and file-order dependencies, so do not combine those operations aggressively.
294
+ - First examine only independent instruction-set writes.
295
+
296
+ Expected effect:
297
+
298
+ - Small relative to worker dispatch cost.
299
+ - Potentially noticeable in environments with many render-only smoke tests.
300
+
301
+ ### P6. Incremental Token Usage Collection
302
+
303
+ Goal:
304
+
305
+ - Reuse a previous offset or session-summary cache instead of scanning the entire session JSONL every time.
306
+
307
+ Cautions:
308
+
309
+ - Accuracy is more important than speed because this connects to final-report placeholder substitution in Phase 7.
310
+ - Do not break aggregation across reruns, retries, or multiple subagent sessions.
311
+
312
+ ## 6. Parallel Work Plan
313
+
314
+ | Track | Work | Primary files | Parallelism | Prerequisite |
315
+ |---|---|---|---|---|
316
+ | A | P1 convergence queue pruning | `prompts/lead/convergence.md`, `prompts/lead/okstra-lead-contract.md`, report-writer contract | High | P0 terminology cleanup |
317
+ | B | P3 fast-track routing | Requirements profile, workflow/status/run UI | Medium | P0 complete; approval-gate policy decided |
318
+ | C | P5 prepare render parallelization | `scripts/okstra_ctl/run.py`, render tests | High | None |
319
+ | D | P2 prompt diet | Worker definitions, team contract, packaging | Medium | Recommended after P1 |
320
+ | E | P4 prompt-cache spike | Experiments for each wrapper/dispatch path | High | None |
321
+ | F | P6 incremental token usage | `scripts/okstra_token_usage/` | High | Collector fixtures required |
322
+
323
+ Recommended order:
324
+
325
+ 1. Start with Track A (P1). It directly reduces the largest cost and confines contract changes to documentation and lead operating phases.
326
+ 2. Track C (P5) or E (P4 spike) can proceed in parallel.
327
+ 3. Track B (P3) changes approval gates and lifecycle semantics, so it requires a separate design review first.
328
+ 4. Start Track D (P2) after the prompt contract stabilizes following P1.
329
+
330
+ ## 7. P1 Implementation Checklist
331
+
332
+ 1. Update the Round 1-N pseudocode in `prompts/lead/convergence.md` to use queue pruning.
333
+ 2. Do not use `contested` as an intermediate state; use `unresolved` or `mixed-after-round-1` for Round 2 candidates.
334
+ 3. Specify the following fields in the convergence state artifact:
335
+ - `config.effectiveMaxRounds`
336
+ - `rounds[].inputQueueSize`
337
+ - `rounds[].resolvedCount`
338
+ - `rounds[].carriedForwardCount`
339
+ - `rounds[].dispatches[]`
340
+ - `rounds[].skippedWorkers[]`
341
+ - `finalClassificationCounts`
342
+ - `round2SkippedReason`
343
+ 4. Verify that the report-writer contract includes round history and final classification counts in the final report.
344
+ 5. Create simple early-convergence and mixed/unresolved fixtures and run a dry run or contract-level test.
345
+ 6. Use the token usage collector to record before/after dispatch, token, and wall-clock measurements.
346
+
347
+ ## 8. Risks and Guardrails
348
+
349
+ - **Correlated hallucination risk**: if a majority of workers reach the same incorrect conclusion in Round 1, less additional verification occurs. The guardrails are opt-in `verificationMode=full-reanalysis` and an evidence quality check.
350
+ - **Worker-failure misclassification risk**: treating a worker timeout/error as disagreement distorts `contested`. Separate terminal non-results into `verification-error` evidence rather than votes.
351
+ - **Fast-track misclassification risk**: incorrectly classifying work as simple can leave approval or verification insufficient. P3 requires a separate policy decision about bypassing the approval gate.
352
+ - **False caching benefit risk**: API-level cache hints may be ignored on CLI stdin paths. P4 requires a spike before implementation.
353
+ - **Validator failure from template reduction**: removing final-report headings or token placeholders can break `validate-run.py` and Phase 7 substitution. P2/P4 must inventory validator contracts first.
354
+
355
+ ## 9. Conclusion
356
+
357
+ The current plan correctly makes P1 the top priority, but the earlier phrases "7-phase lifecycle" and "contested-only Round 2" did not match the code. The revised plan is ordered as follows.
358
+
359
+ 1. Use P0 to establish terminology and measurement criteria.
360
+ 2. Implement convergence queue pruning in P1.
361
+ 3. Keep P3 fast-track and P4 prompt caching as follow-up work requiring separate design and verification.
362
+ 4. Treat prepare-render parallelization and incremental token usage collection as smaller or end-of-run costs that can proceed as parallel supporting work after P1.
363
+
364
+ **2026-06-11 update** — Measurements in §4.1 confirm that P0/P1/P6, critic parallelization, and phaseTimeline instrumentation are complete, while B3 (report-writer input compression) was rejected. Only two priorities remain, and both require a user decision first:
365
+
366
+ 1. **B7 — reduce report-writer output-side cost**: slim the report contract (reduce the template/schema and change validator contracts) or lower the default report-writer model. Estimated saving: 5–12 minutes per run.
367
+ 2. **B6/P3 — fast-track routing**: shorten the lifecycle for simple work. Requires an approval-gate policy decision.
368
+
369
+ ### Implementation Plan Links
370
+
371
+ - P0 + P1: implemented in convergence state v1.2
372
+ - P6: implemented in incremental token-usage scanning
373
+ - Critic parallelization + phaseTimeline instrumentation: implemented directly without a plan (2026-06-11; see the corresponding `CHANGES.md` entry)
374
+ - P3 / P4 / P5 / B7: not written; each track requires a separate plan