okstra 0.206.1 → 0.207.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.
- package/README.md +1 -1
- package/dist/cli-registry.mjs +7 -1
- package/dist/cli-registry.mjs.map +1 -1
- package/docs/architecture/storage-model.md +1 -0
- package/docs/architecture.md +28 -4
- package/docs/cli.md +13 -11
- package/docs/project-structure-overview.md +4 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/operations/code-review.json +1 -1
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/bin/okstra-compact-reminder.sh +1 -1
- package/runtime/prompts/duties/direction-selection-worker.json +1 -1
- package/runtime/prompts/launch.template.md +1 -1
- package/runtime/prompts/lead/adapters/cmux.md +4 -3
- package/runtime/prompts/lead/convergence.md +41 -9
- package/runtime/prompts/lead/okstra-lead-contract.md +31 -19
- package/runtime/prompts/lead/report-writer.md +8 -6
- package/runtime/prompts/profiles/_clarification-recommendation.md +4 -4
- package/runtime/prompts/profiles/_common-contract.md +1 -1
- package/runtime/prompts/wizard/prompts.ko.json +2 -1
- package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +5 -5
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/external/relay.md +3 -2
- package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +1 -1
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +17 -26
- package/runtime/python/okstra_ctl/agent/prompt_cli/batch.py +183 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +60 -10
- package/runtime/python/okstra_ctl/agent/prompt_cli/jobs.py +21 -4
- package/runtime/python/okstra_ctl/approval_decisions.py +32 -2
- package/runtime/python/okstra_ctl/assignment_resolver.py +8 -0
- package/runtime/python/okstra_ctl/blocking_checks.py +7 -0
- package/runtime/python/okstra_ctl/code_review_target.py +92 -6
- package/runtime/python/okstra_ctl/dispatch_checkpoints.py +121 -0
- package/runtime/python/okstra_ctl/dispatch_core.py +54 -32
- package/runtime/python/okstra_ctl/dispatch_state.py +12 -5
- package/runtime/python/okstra_ctl/domain/provider.py +5 -0
- package/runtime/python/okstra_ctl/domain/worker_presentation.py +21 -2
- package/runtime/python/okstra_ctl/domain/write_policy.py +2 -1
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +19 -8
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +5 -0
- package/runtime/python/okstra_ctl/lead_progress.py +33 -1
- package/runtime/python/okstra_ctl/manager_view.py +26 -19
- package/runtime/python/okstra_ctl/model_io/lines.py +21 -4
- package/runtime/python/okstra_ctl/models.py +4 -1
- package/runtime/python/okstra_ctl/operation_invocation.py +11 -2
- package/runtime/python/okstra_ctl/phases/final_verification/profile.md +1 -1
- package/runtime/python/okstra_ctl/phases/implementation/instructions/_implementation-executor.md +1 -1
- package/runtime/python/okstra_ctl/phases/implementation/instructions/_implementation-verifier.md +14 -3
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/profile.md +1 -1
- package/runtime/python/okstra_ctl/phases/implementation_planning/profile.md +1 -1
- package/runtime/python/okstra_ctl/phases/technical_verification/profile.md +1 -1
- package/runtime/python/okstra_ctl/process_group.py +118 -0
- package/runtime/python/okstra_ctl/render.py +6 -2
- package/runtime/python/okstra_ctl/report_assembly.py +17 -2
- package/runtime/python/okstra_ctl/report_finalize.py +106 -2
- package/runtime/python/okstra_ctl/run.py +1 -1
- package/runtime/python/okstra_ctl/run_artifact_prune.py +200 -0
- package/runtime/python/okstra_ctl/team.py +108 -9
- package/runtime/python/okstra_ctl/wizard/steps_options.py +8 -0
- package/runtime/python/okstra_ctl/worker_dispatch.py +44 -3
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +19 -0
- package/runtime/python/okstra_ctl/worker_runner.py +21 -3
- package/runtime/python/okstra_ctl/write_policy.py +57 -7
- package/runtime/python/okstra_project/dirs.py +14 -0
- package/runtime/python/okstra_project/resolver.py +2 -1
- package/runtime/schemas/execution-manifest-v2.schema.json +2 -1
- package/runtime/skills/okstra-code-review/SKILL.md +70 -32
- package/runtime/skills/okstra-code-review/references/review-calibration.md +26 -6
- package/runtime/skills/okstra-run/SKILL.md +2 -2
- package/runtime/templates/manager/view.template.html +18 -1
|
@@ -18,11 +18,16 @@ A cell covers its whole rule group, so it can carry several findings from severa
|
|
|
18
18
|
rule: DRY
|
|
19
19
|
line: 42
|
|
20
20
|
severity: must-fix
|
|
21
|
+
timing: now
|
|
21
22
|
snippet: `discount = subtotal * 0.15 if tier == "gold" else 0`
|
|
23
|
+
failure: when the gold rate changes in `domain/tiers.py`, this line keeps charging 15% and the two prices disagree.
|
|
24
|
+
evidence: `domain/tiers.py:18`
|
|
22
25
|
note: The same tier→rate table is already in `domain/tiers.py:18`; a rate change now has two homes. Call the existing lookup instead of re-expressing it here.
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
Fields: `cell` (`target × axis`, exactly as the census wrote it — the axis is the rule group, and there is never one cell per individual rule), `verdict` (`clean` | `finding`), `rule` (the specific rule this finding violates, spelled as its pack spells it; omitted on `clean`), `line` (a line **this diff changed
|
|
28
|
+
Fields: `cell` (`target × axis`, exactly as the census wrote it — the axis is the rule group, and there is never one cell per individual rule), `verdict` (`clean` | `finding`), `rule` (the specific rule this finding violates, spelled as its pack spells it; omitted on `clean`), `line` (a line **this diff changed**, numbered at the head commit), `severity`, `timing` (`now` | `park`, below), `snippet` (the quoted changed line, verbatim — the orchestrator locates the finding by it), `failure` (required at `must-fix` and `should-fix`: the input or state that produces the wrong result, and what goes wrong), `evidence` (required at `must-fix` and `should-fix`: every `path:line` you opened to establish the failure — the definitions of the symbols the claim depends on, not only the cited line), `note` (1–2 sentences: what is wrong plus a concrete fix).
|
|
29
|
+
|
|
30
|
+
**Open the definition before you claim its behaviour.** A claim about what a called function, method, or value does — that it reads `this`, throws, mutates its argument, returns `null` — cites that definition in `evidence`. A claim you could not check against its definition is not a finding; it is `clean`. The orchestrator opens every `evidence` location and rejects a finding the code contradicts.
|
|
26
31
|
|
|
27
32
|
There is no length budget. Dropping a real finding to stay brief is the failure this review exists to prevent, and a missing cell is re-dispatched as unfinished work, never read as a clean.
|
|
28
33
|
|
|
@@ -36,6 +41,15 @@ There is no length budget. Dropping a real finding to stay brief is the failure
|
|
|
36
41
|
|
|
37
42
|
Grade the defect, not your confidence. If you are not confident, the verdict is `clean` — see the hedge test below.
|
|
38
43
|
|
|
44
|
+
**Name the failure.** A `must-fix` or `should-fix` states the input or state that produces the wrong result (`if the header is absent, line 42 throws before the 401 is returned`). Code that works as written is not a defect, however you would have written it differently: alternative structures, defensive guards for states no caller reaches, and "consider extracting / renaming / memoizing" are improvements. An improvement is either `park` or `clean`, never a `now` finding.
|
|
45
|
+
|
|
46
|
+
## Timing — `now` or `park`
|
|
47
|
+
|
|
48
|
+
- `now` — this change should fix it before it merges: a defect on a changed line, or a rule violation the change introduced.
|
|
49
|
+
- `park` — real, but not this change's to fix: the fix lies outside the diff, or the code is correct and the finding asks for more (a regression test for behaviour that already works, a follow-up refactor). Parked findings are listed in the report and **do not score**.
|
|
50
|
+
|
|
51
|
+
Every finding carries `timing`. When unsure, ask whether merging without the fix leaves this change wrong; if not, it is `park`.
|
|
52
|
+
|
|
39
53
|
## When `clean` is the right verdict
|
|
40
54
|
|
|
41
55
|
`clean` is a result, not a concession. Return it when:
|
|
@@ -62,19 +76,25 @@ Loose typing in test files (`any`, dynamic casts, untyped fixtures) is a **typin
|
|
|
62
76
|
|
|
63
77
|
## The report
|
|
64
78
|
|
|
65
|
-
Merged by the orchestrator, written to `reviewPath`. Sections, in this order, empty ones omitted except `Coverage` and `Score`:
|
|
79
|
+
Merged and adjudicated by the orchestrator, written to `reviewPath`. Sections, in this order, empty ones omitted except `Coverage` and `Score`:
|
|
66
80
|
|
|
67
81
|
```
|
|
68
82
|
## Coverage
|
|
69
83
|
## Must-fix
|
|
70
84
|
## Should-fix
|
|
71
85
|
## Nits
|
|
86
|
+
## Parked
|
|
87
|
+
## Rejected
|
|
72
88
|
## Score
|
|
73
89
|
```
|
|
74
90
|
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
77
|
-
- **
|
|
91
|
+
- **Must-fix / Should-fix / Nits** — confirmed `now` findings only.
|
|
92
|
+
- **Parked** — `park` findings, with their severity, not scored.
|
|
93
|
+
- **Rejected** — findings the orchestrator's adjudication disproved or that cite no changed line: the reviewer's claim in one line, then the contradicting `path:line` and what it shows. Not scored.
|
|
94
|
+
|
|
95
|
+
- **Coverage** — two or three lines: the reviewers (`provider/model`, one or two); N changed files → S `structural` / F `semantic` / T `state-and-tests` / G `general` cells, all verdicted by every reviewer; M files excluded with reasons; the applied packs, and any pack that was unavailable; and how the findings were settled — agreed, graded by the orchestrator, confirmed by the orchestrator, rejected. The four cell counts are at the census's granularity — one cell per target per axis.
|
|
96
|
+
- **Findings** — each one opens with `` `path/to/file.py:42` `` + the verdict's `rule` name + severity + points, then the snippet as a blockquote, then the 1–2 sentence note with its fix. Its note then says how it was settled: `agreed`, `graded by orchestrator` (with both reviewers' values), or `confirmed by orchestrator`.
|
|
97
|
+
- **Score** — every confirmed `now` finding gets a row, and the table is emitted even when there are none, with a single total row reading 0:
|
|
78
98
|
|
|
79
99
|
```
|
|
80
100
|
| # | Location | Rule | Severity | Points |
|
|
@@ -83,4 +103,4 @@ Merged by the orchestrator, written to `reviewPath`. Sections, in this order, em
|
|
|
83
103
|
| | | | **Total** | **3** |
|
|
84
104
|
```
|
|
85
105
|
|
|
86
|
-
The report's prose is written in
|
|
106
|
+
The report's prose is written in the `Report language` the target CLI returned (the project's `reportLanguage`). Paths, identifiers, rule names, and quoted code stay verbatim.
|
|
@@ -261,9 +261,9 @@ okstra config set pr-template-path "<value>" --scope global
|
|
|
261
261
|
|
|
262
262
|
If an action has an unknown `command`, `key`, or `scope`, stop and report the wizard output instead of inventing a command.
|
|
263
263
|
|
|
264
|
-
Before rendering the next phase's bundle — and between worker rounds within a phase (reverify/critic/gapverify batches), after you have collected that round's results and token usage and before you dispatch the next round — close the panes of the dispatches that finished in the prior round so they do not accumulate
|
|
264
|
+
Before rendering the next phase's bundle — and between worker rounds within a phase (reverify/critic/gapverify batches), after you have collected that round's results and token usage and before you dispatch the next round — close the panes of the dispatches that finished in the prior round so they do not accumulate: `okstra team reclaim --project-root <projectRoot> --run-manifest <RUN_MANIFEST_PATH>` closes them, records `phase-batch-cleanup panes=<n>` with the number it closed, and prints that `PROGRESS:` line last — emit it as printed and do not call `okstra lead-progress append` for it. The command reads each dispatch's recorded status, so an in-progress worker keeps its pane whichever moment you call it. It closes only the panes okstra opened and recorded — a pane the harness opened for its own teammate carries no recorded id and is not okstra's to close. `shutdown_request` alone only idles the agent and frees no pane, so it stays part of the run-end sequence for roster/token hygiene. A `cli-wrapper` run holds no pane at all and `team reclaim` refuses it, so record the checkpoint there with `okstra lead-progress append … --phase phase-batch-cleanup --field panes=0`.
|
|
265
265
|
|
|
266
|
-
Before you ask the user for any approval, clarification, or decision after workers have been dispatched, run
|
|
266
|
+
Before you ask the user for any approval, clarification, or decision after workers have been dispatched, run `okstra team reclaim … --gate` first: it closes the finished panes and prints `PROGRESS: phase-gate-cleanup panes=<n>` for you to emit, without recording a batch cleanup. Then `TaskStop` each completed worker. A `TaskStop` by itself idles the task but leaves the pane open — the `team reclaim` call is what closes it. This keeps a user gate from being shown while finished worker panes remain; in-progress dispatches keep their panes. Then follow `prompts/lead/okstra-lead-contract.md` "User confirmation before an approval blocker": read cited plan items, worker findings, and files before asking, and ask in the user's language with each option's outcome.
|
|
267
267
|
|
|
268
268
|
Build the `okstra render-bundle` invocation from `outcome.renderArgv`, passing every token verbatim and in order (including empty strings — they are intentional `use phase default` markers).
|
|
269
269
|
|
|
@@ -59,9 +59,26 @@ h3 { font-size: 15px; margin: 0; }
|
|
|
59
59
|
table { width: 100%; border-collapse: collapse; }
|
|
60
60
|
th, td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
|
|
61
61
|
th { color: var(--muted); font-weight: 600; font-size: 12px; white-space: nowrap; }
|
|
62
|
-
.wrap { display: inline-block; min-width: 220px; }
|
|
63
62
|
code.id { white-space: nowrap; word-break: normal; }
|
|
64
63
|
code { font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }
|
|
64
|
+
.children table { table-layout: fixed; }
|
|
65
|
+
.children th:nth-child(1) { width: 23%; }
|
|
66
|
+
.children th:nth-child(2) { width: 22%; }
|
|
67
|
+
.children td { padding-top: 14px; padding-bottom: 14px; overflow-wrap: anywhere; }
|
|
68
|
+
.child-ticket { display: block; margin-bottom: 4px; }
|
|
69
|
+
code.child-key { word-break: normal; }
|
|
70
|
+
.child-status { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; margin: 8px 0 0; font-size: 12px; }
|
|
71
|
+
.child-status dt { color: var(--muted); }
|
|
72
|
+
.child-status dd { margin: 0; }
|
|
73
|
+
.child-assignment { line-height: 1.65; }
|
|
74
|
+
.child-links { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 10px; font-size: 12px; }
|
|
75
|
+
.child-error { color: var(--blocked); margin: 8px 0 0; font-size: 12px; }
|
|
76
|
+
@media (max-width: 700px) {
|
|
77
|
+
.children table, .children tbody, .children tr, .children td { display: block; width: 100%; }
|
|
78
|
+
.children thead { display: none; }
|
|
79
|
+
.children tr { padding: 12px 0; border-bottom: 1px solid var(--line); }
|
|
80
|
+
.children td { padding: 6px 0; border: 0; }
|
|
81
|
+
}
|
|
65
82
|
.chip {
|
|
66
83
|
display: inline-block;
|
|
67
84
|
padding: 1px 8px;
|