okstra 0.123.0 → 0.125.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 -0
- package/docs/architecture/storage-model.md +3 -1
- package/docs/architecture.md +16 -2
- package/docs/cli.md +3 -1
- package/docs/for-ai/README.md +41 -35
- package/docs/for-ai/skills/okstra-brief-gen.md +105 -105
- package/docs/for-ai/skills/okstra-container-build.md +61 -61
- package/docs/for-ai/skills/okstra-graphify.md +64 -0
- package/docs/for-ai/skills/okstra-inspect.md +87 -86
- package/docs/for-ai/skills/okstra-manager.md +32 -32
- package/docs/for-ai/skills/okstra-memory.md +49 -50
- package/docs/for-ai/skills/okstra-pr-gen.md +48 -0
- package/docs/for-ai/skills/okstra-rollup.md +58 -58
- package/docs/for-ai/skills/okstra-run.md +95 -95
- package/docs/for-ai/skills/okstra-schedule-gen.md +106 -106
- package/docs/for-ai/skills/okstra-setup.md +63 -64
- package/docs/for-ai/skills/okstra-user-response.md +48 -0
- package/docs/performance-improvement-plan-v2.md +6 -6
- package/docs/pr-template-usage.md +34 -34
- package/docs/project-structure-overview.md +91 -70
- package/docs/task-process/README.md +33 -33
- package/docs/task-process/common-flow.md +26 -26
- package/docs/task-process/error-analysis.md +20 -21
- package/docs/task-process/final-verification.md +41 -41
- package/docs/task-process/implementation-planning.md +33 -33
- package/docs/task-process/implementation.md +38 -38
- package/docs/task-process/release-handoff.md +46 -46
- package/docs/task-process/requirements-discovery.md +22 -23
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/antigravity-worker.md +4 -4
- package/runtime/agents/workers/claude-worker.md +2 -2
- package/runtime/agents/workers/codex-worker.md +4 -4
- package/runtime/agents/workers/report-writer-worker.md +4 -4
- package/runtime/bin/lib/okstra/usage.sh +1 -1
- package/runtime/prompts/coding-preflight/frameworks/node-server.md +1 -1
- package/runtime/prompts/launch.template.md +1 -1
- package/runtime/prompts/lead/convergence.md +10 -20
- package/runtime/prompts/lead/okstra-lead-contract.md +15 -17
- package/runtime/prompts/lead/plan-body-verification.md +18 -18
- package/runtime/prompts/lead/report-writer.md +46 -44
- package/runtime/prompts/lead/team-contract.md +11 -122
- package/runtime/prompts/profiles/_common-contract.md +15 -22
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +1 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +28 -2
- package/runtime/prompts/profiles/error-analysis.md +2 -2
- package/runtime/prompts/profiles/final-verification.md +1 -1
- package/runtime/prompts/profiles/implementation-planning.md +13 -13
- package/runtime/prompts/profiles/implementation.md +2 -1
- package/runtime/prompts/profiles/improvement-discovery.md +1 -1
- package/runtime/prompts/profiles/release-handoff.md +3 -3
- package/runtime/prompts/profiles/requirements-discovery.md +17 -18
- package/runtime/python/okstra_ctl/models.py +4 -2
- package/runtime/python/okstra_ctl/run.py +8 -2
- package/runtime/python/okstra_ctl/stage_fix_carry.py +112 -0
- package/runtime/schemas/final-report-v1.0.schema.json +6 -6
- package/runtime/skills/_fragments/bash-invocation-rule.md +1 -0
- package/runtime/skills/_fragments/preflight-outdated-cli.md +1 -0
- package/runtime/skills/_fragments/python-bootstrap-note.md +1 -0
- package/runtime/skills/okstra-brief-gen/SKILL.md +117 -122
- package/runtime/skills/okstra-container-build/SKILL.md +24 -14
- package/runtime/skills/okstra-graphify/SKILL.md +12 -4
- package/runtime/skills/okstra-inspect/SKILL.md +39 -747
- package/runtime/skills/okstra-inspect/facets/cost.md +84 -0
- package/runtime/skills/okstra-inspect/facets/error-zip.md +41 -0
- package/runtime/skills/okstra-inspect/facets/errors.md +69 -0
- package/runtime/skills/okstra-inspect/facets/history.md +90 -0
- package/runtime/skills/okstra-inspect/facets/logs.md +89 -0
- package/runtime/skills/okstra-inspect/facets/recap.md +96 -0
- package/runtime/skills/okstra-inspect/facets/report.md +61 -0
- package/runtime/skills/okstra-inspect/facets/status.md +145 -0
- package/runtime/skills/okstra-inspect/facets/time.md +56 -0
- package/runtime/skills/okstra-manager/SKILL.md +1 -1
- package/runtime/skills/okstra-memory/SKILL.md +3 -3
- package/runtime/skills/okstra-pr-gen/SKILL.md +3 -3
- package/runtime/skills/okstra-rollup/SKILL.md +12 -6
- package/runtime/skills/okstra-run/SKILL.md +49 -88
- package/runtime/skills/okstra-schedule-gen/SKILL.md +36 -30
- package/runtime/skills/okstra-setup/SKILL.md +1 -1
- package/runtime/skills/okstra-setup/references/project-config.md +17 -16
- package/runtime/skills/okstra-usage/SKILL.md +5 -2
- package/runtime/skills/okstra-user-response/SKILL.md +15 -3
- package/runtime/templates/prd/brief.template.md +92 -92
- package/runtime/templates/project-docs/task-index.template.md +1 -1
- package/runtime/templates/reports/error-analysis-input.template.md +1 -1
- package/runtime/templates/reports/fan-out-unit.template.md +6 -6
- package/runtime/templates/reports/final-verification-input.template.md +6 -6
- package/runtime/templates/reports/implementation-input.template.md +1 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
- package/runtime/templates/reports/improvement-discovery-input.template.md +1 -1
- package/runtime/templates/reports/quick-input.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +1 -1
- package/runtime/templates/reports/schedule.template.md +22 -22
- package/runtime/templates/reports/task-brief.template.md +3 -3
- package/runtime/templates/reports/user-response.template.md +20 -20
- package/runtime/templates/worker-prompt-preamble.md +111 -13
- package/runtime/validators/validate-schedule.py +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Every subsequent `okstra <subcmd>` call self-bootstraps its Python path, so this skill never needs `okstra paths --shell` / `export PYTHONPATH=...`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-brief-gen
|
|
3
|
-
description: Use when the user wants to generate a task brief file for okstra from a requirements document, an existing markdown file, an issue-tracker ticket (Linear / Jira / GitHub / Notion), a link URL, conversation context, or short user input. Produces the markdown brief consumed by `okstra-run` Step 5 (task-brief). Trigger words include "okstra brief", "make a brief", "brief
|
|
3
|
+
description: Use when the user wants to generate a task brief file for okstra from a requirements document, an existing markdown file, an issue-tracker ticket (Linear / Jira / GitHub / Notion), a link URL, conversation context, or short user input. Produces the markdown brief consumed by `okstra-run` Step 5 (task-brief). Trigger words include "okstra brief", "make a brief", "generate a brief", "make a brief from requirements", "make an okstra input", "write a task brief", "brief from this ticket", "brief from this link".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# okstra-brief-gen
|
|
@@ -10,13 +10,12 @@ Generate a single `task brief` markdown file under the okstra project domain
|
|
|
10
10
|
[`okstra-run`](../okstra-run/SKILL.md) as `--task-brief`.
|
|
11
11
|
|
|
12
12
|
**Purpose — pre-discovery artifact.** A brief is the **pre-discovery** stage
|
|
13
|
-
of an okstra task: it absorbs domain alignment, codebase evidence
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
provenance does not change the output contract.
|
|
13
|
+
of an okstra task: it absorbs domain alignment, codebase evidence, and
|
|
14
|
+
reporter intent so the downstream expert phases (`requirements-discovery` /
|
|
15
|
+
`error-analysis` / `implementation-planning`) run with **zero fill-in
|
|
16
|
+
questions** to the operator. It is written from a domain reporter's report
|
|
17
|
+
(PM, CS, ops, QA, end-user, …) **or** by a developer — provenance does not
|
|
18
|
+
change the output contract.
|
|
20
19
|
|
|
21
20
|
This is a **labelled-handoff** to the next phase, built on two
|
|
22
21
|
non-negotiables:
|
|
@@ -24,19 +23,19 @@ non-negotiables:
|
|
|
24
23
|
- **Verbatim-preserving capture** — the reporter's words are kept
|
|
25
24
|
byte-for-byte under `Source Material`. Format-only transformations
|
|
26
25
|
(e.g. Jira ADF → Markdown) and codebase cross-references are mechanical
|
|
27
|
-
and reversible
|
|
28
|
-
|
|
26
|
+
and reversible, recorded with the `format-conversion` and `evidence-link`
|
|
27
|
+
Augmentation labels.
|
|
29
28
|
- **Labelled interpretation** — anywhere the skill resolves a reporter
|
|
30
|
-
word to a project-canonical term or infers
|
|
31
|
-
|
|
32
|
-
`
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
word to a project-canonical term or infers meaning not literally stated,
|
|
30
|
+
the addition lives in `Augmentation` with the `terminology-mapping` or
|
|
31
|
+
`intent-inference` label. Unlabelled augmentation is forbidden — the
|
|
32
|
+
label is what makes the interpretation auditable and (for
|
|
33
|
+
`intent-inference`) verifiable against the reporter.
|
|
35
34
|
|
|
36
35
|
A brief still does NOT write a PRD, decompose work into vertical slices,
|
|
37
|
-
or decide modules
|
|
38
|
-
(`requirements-discovery`, `implementation-planning`)
|
|
39
|
-
|
|
36
|
+
or decide modules — those belong to later cross-verification phases
|
|
37
|
+
(`requirements-discovery`, `implementation-planning`) and would conflict
|
|
38
|
+
with anything decided here.
|
|
40
39
|
|
|
41
40
|
## Intended chain
|
|
42
41
|
|
|
@@ -67,7 +66,7 @@ okstra-brief-gen (error-feedback variant)
|
|
|
67
66
|
|
|
68
67
|
- The user pastes / points at a requirements doc, support ticket, bug report,
|
|
69
68
|
or rough description and wants to start the okstra pipeline.
|
|
70
|
-
- The user asks to "make a brief", "okstra
|
|
69
|
+
- The user asks to "make a brief", "make an okstra input", "generate a brief", etc.
|
|
71
70
|
- A previous okstra task produced findings the user wants to convert into a
|
|
72
71
|
new follow-up task's brief.
|
|
73
72
|
|
|
@@ -82,21 +81,17 @@ okstra-brief-gen (error-feedback variant)
|
|
|
82
81
|
|
|
83
82
|
## Artifact-home rule (okstra-wide)
|
|
84
83
|
|
|
85
|
-
**All okstra-generated artifacts live under `<PROJECT_ROOT>/.okstra
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Paths outside `<PROJECT_ROOT>/.okstra/**` are not okstra
|
|
98
|
-
memory. This skill reads them only when the reporter explicitly cited them
|
|
99
|
-
as source material, and never writes them. Decision files (when raised by
|
|
84
|
+
**All okstra-generated artifacts live under `<PROJECT_ROOT>/.okstra/`** —
|
|
85
|
+
briefs, run manifests, reports, worker results, status, sessions, and any
|
|
86
|
+
other run output. All writes by this skill stay inside `.okstra/`. When
|
|
87
|
+
domain alignment (Step 3b / Step 4.5) yields a user-approved glossary
|
|
88
|
+
change, it is written to `<PROJECT_ROOT>/.okstra/glossary.md` (okstra's
|
|
89
|
+
internal glossary; created if absent, else appended to a `## Glossary`
|
|
90
|
+
section).
|
|
91
|
+
|
|
92
|
+
Paths outside `<PROJECT_ROOT>/.okstra/**` are not okstra memory. This skill
|
|
93
|
+
reads them only when the reporter explicitly cited them as source material,
|
|
94
|
+
and never writes them. Decision files (when raised by
|
|
100
95
|
`implementation-planning`) also live inside okstra's subtree at
|
|
101
96
|
`<PROJECT_ROOT>/.okstra/decisions/<NNNN>-<slug>.md`.
|
|
102
97
|
|
|
@@ -108,9 +103,8 @@ as source material, and never writes them. Decision files (when raised by
|
|
|
108
103
|
(single / parent) or
|
|
109
104
|
`<PROJECT_ROOT>/.okstra/briefs/<task-group>/sub/<ticket-id>-<file-title>.md`
|
|
110
105
|
(tracker child ticket; at depth N, `sub/` is nested N times) — output
|
|
111
|
-
location for this skill. `<ticket-id>`
|
|
112
|
-
|
|
113
|
-
auto-slugified from the tracker title, otherwise from user input.
|
|
106
|
+
location for this skill. See Step 2b for `<ticket-id>` / `<file-title>`
|
|
107
|
+
resolution.
|
|
114
108
|
- okstra-internal glossary (write target of Step 4.5):
|
|
115
109
|
`<PROJECT_ROOT>/.okstra/glossary.md`. Created if absent.
|
|
116
110
|
- okstra-internal decisions (write target of `implementation-planning`
|
|
@@ -119,13 +113,23 @@ as source material, and never writes them. Decision files (when raised by
|
|
|
119
113
|
|
|
120
114
|
## Step 0: Preflight
|
|
121
115
|
|
|
122
|
-
Every Bash command in this skill is a **separate Bash tool call
|
|
116
|
+
Every Bash command in this skill is a **separate Bash tool call**.
|
|
117
|
+
|
|
118
|
+
<!-- BEGIN FRAGMENT: bash-invocation-rule -->
|
|
119
|
+
Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
|
|
120
|
+
<!-- END FRAGMENT: bash-invocation-rule -->
|
|
123
121
|
|
|
124
122
|
```bash
|
|
125
123
|
okstra preflight --runtime claude-code --json
|
|
126
124
|
```
|
|
127
125
|
|
|
128
|
-
Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string into the steps below. `ok: false` (or `okstra` not on `PATH` at all) → tell the user: "okstra not set up — run `/okstra-setup` first." Then stop.
|
|
126
|
+
Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string into the steps below. `ok: false` (or `okstra` not on `PATH` at all) → tell the user: "okstra not set up — run `/okstra-setup` first." Then stop.
|
|
127
|
+
|
|
128
|
+
<!-- BEGIN FRAGMENT: preflight-outdated-cli -->
|
|
129
|
+
If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
|
|
130
|
+
<!-- END FRAGMENT: preflight-outdated-cli -->
|
|
131
|
+
|
|
132
|
+
Do **not** try `npx -y okstra@latest ...` as a fallback.
|
|
129
133
|
|
|
130
134
|
## Step 1: Choose input source
|
|
131
135
|
|
|
@@ -135,9 +139,9 @@ Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string in
|
|
|
135
139
|
|
|
136
140
|
- **Label**: `"Brief variant?"`
|
|
137
141
|
- **Options**:
|
|
138
|
-
1. `Reporter input` — reporter
|
|
139
|
-
2. `Codebase scan` —
|
|
140
|
-
3. `Error feedback` (`error-feedback`) —
|
|
142
|
+
1. `Reporter input` — absorb the reporter's utterance / ticket / link / free text verbatim. The existing 4-source flow.
|
|
143
|
+
2. `Codebase scan` — take only the codebase scope + lens priorities and generate the input for the `improvement-discovery` phase.
|
|
144
|
+
3. `Error feedback` (`error-feedback`) — convert one frequent cluster from the `.zip` produced by `okstra error-zip` into an `error-analysis` brief (for okstra self-repair).
|
|
141
145
|
|
|
142
146
|
### 1.A. Reporter input (variant 1)
|
|
143
147
|
|
|
@@ -171,28 +175,24 @@ in Source Material.
|
|
|
171
175
|
Order of operations:
|
|
172
176
|
|
|
173
177
|
0. **Task-group precondition (REQUIRED before any recursion)** — if the
|
|
174
|
-
tracker fetch may yield child tickets (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
would either stall mid-collection or invent a placeholder group.
|
|
178
|
+
tracker fetch may yield child tickets (always possible until the first
|
|
179
|
+
fetch proves otherwise), acquire `task_group` first by running Step 2a
|
|
180
|
+
now; when Step 2a is re-entered later it MUST reuse this value without
|
|
181
|
+
asking again. Why: sub-step 6's recursion records descendant brief paths
|
|
182
|
+
under `<task-group>/sub.../`, which cannot be formed until `task_group`
|
|
183
|
+
is known — without this preflight the walk stalls or invents a
|
|
184
|
+
placeholder group.
|
|
182
185
|
|
|
183
186
|
**Sequential, never batched.** Run Step 2a as its **own**
|
|
184
|
-
`AskUserQuestion` call
|
|
185
|
-
**separate** call
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
before the ticket (it scopes where this ticket's brief — and any
|
|
190
|
-
sub-ticket briefs — are written).
|
|
187
|
+
`AskUserQuestion` call, then ask sub-step 1's ticket question in a
|
|
188
|
+
**separate** call — never combine the task-group and ticket-ref
|
|
189
|
+
questions into one. When you relay this preflight, tell the user in one
|
|
190
|
+
line *why* task group comes first (it scopes where this ticket's brief —
|
|
191
|
+
and any sub-ticket briefs — are written).
|
|
191
192
|
1. `AskUserQuestion` (free text):
|
|
192
193
|
`"Ticket key or URL (e.g. LIN-1234, PROJ-42, https://linear.app/..., https://your.atlassian.net/browse/...)"` →
|
|
193
194
|
`ticket_ref`. Issue this only **after** Step 2a's task-group answer is in
|
|
194
|
-
hand
|
|
195
|
-
question.
|
|
195
|
+
hand (per sub-step 0's sequential rule).
|
|
196
196
|
2. Auto-detect the tracker by URL host or key prefix (`linear.app` → Linear,
|
|
197
197
|
`atlassian.net` or `JIRA_*` pattern → Jira, `github.com/.../issues/` →
|
|
198
198
|
GitHub, `notion.so` → Notion). If detection fails, ask once more via
|
|
@@ -288,32 +288,32 @@ If the user picked `Codebase scan`, gather the codebase-scan-specific inputs:
|
|
|
288
288
|
|
|
289
289
|
Validation (before Step 4 sharpening):
|
|
290
290
|
|
|
291
|
-
- `scan_scope`
|
|
292
|
-
- `priority_lenses`
|
|
293
|
-
- `candidate_cap`
|
|
291
|
+
- Confirm that each path in `scan_scope` actually exists inside `<PROJECT_ROOT>` via `ls` — if not, correct it with a single question.
|
|
292
|
+
- Confirm that `priority_lenses` is a subset (1–4) of `LENSES` in `~/.okstra/lib/python/okstra_ctl/improvement_lenses.py` — on violation, show the enum + re-select. Final enforcement is done by Step 6.6 `validate-brief` (`check_codebase_scope`).
|
|
293
|
+
- Confirm that `candidate_cap` is an integer in 1–12.
|
|
294
294
|
|
|
295
295
|
Once validation passes, jump to Step 2 (task key).
|
|
296
296
|
|
|
297
|
-
### 1.C. Error feedback (`error-feedback`, variant 3) — okstra
|
|
297
|
+
### 1.C. Error feedback (`error-feedback`, variant 3) — for okstra self-repair
|
|
298
298
|
|
|
299
|
-
If the user picked `Error feedback`, the input is a `.zip` produced by `okstra error-zip --out <path>`.
|
|
299
|
+
If the user picked `Error feedback`, the input is a `.zip` produced by `okstra error-zip --out <path>`. This variant selects one frequent error cluster and converts it into an `error-analysis` brief, and **the repair target is the okstra repo itself**.
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
Input: the `.zip` produced by `okstra error-zip`. Ask the user for the zip path (if a path was received earlier, propose reusing it as `Recommended:`).
|
|
302
302
|
|
|
303
|
-
1. zip
|
|
304
|
-
`AskUserQuestion` (single-select,
|
|
305
|
-
1. top-1
|
|
306
|
-
2. top-2
|
|
307
|
-
3.
|
|
308
|
-
2.
|
|
309
|
-
3. frontmatter `scope`
|
|
310
|
-
4.
|
|
311
|
-
5.
|
|
303
|
+
1. Read the zip's `report.md`, show the frequent-cluster table to the user, and have them pick **one cluster**.
|
|
304
|
+
`AskUserQuestion` (single-select, `Specify manually` always last):
|
|
305
|
+
1. top-1 cluster (highest frequency) — marked `Recommended:`.
|
|
306
|
+
2. top-2 cluster.
|
|
307
|
+
3. `Specify manually` — the user names a cluster directly from the table.
|
|
308
|
+
2. Quote the chosen cluster's anonymized records into the brief's `## Source Material` — from `errors/anonymized.jsonl` inside the zip, pull only the `clusterId` records **matching the chosen cluster number (the `#` in `report.md`'s table)**, and move their errorType · command · exitCode · phase · agent · representative message into a table/list. (`#` ↔ `clusterId` is a 1:1 mapping, and even the same errorType+phase+agent counts as a separate cluster when the normalized message differs — do not merge them.)
|
|
309
|
+
3. Leave frontmatter `scope` as reporter-input — because this variant carries anonymized error records verbatim in `## Source Material`, it belongs to the reporter-input family, so omit the `scope` key (⇒ `reporter-input`). Do not use the codebase-scan-only keys (`priority-lenses`·`scan-scope`, etc.). Send the next-phase signal via Step 6's `Recommended next phase: error-analysis` header line (do not create a separate frontmatter key). In the body, state the repair target explicitly: "this error is a signal of an okstra runtime/prompt/wrapper/permission-seed defect, and the repair target is the okstra source (`prompts/`·`agents/`·`scripts/`·`templates/`)."
|
|
310
|
+
4. Keep the **single cluster = single failure condition** principle — do not mix heterogeneous errorTypes into one brief (the `error-analysis` symptom-lock requirement). To also fix another cluster, make a separate brief per cluster.
|
|
311
|
+
5. At the end of the generated brief, write the next step inline: "run this brief from the okstra repo with `okstra-run --task-type error-analysis`."
|
|
312
312
|
|
|
313
313
|
Validation (before Step 4 sharpening):
|
|
314
314
|
|
|
315
|
-
- zip
|
|
316
|
-
-
|
|
315
|
+
- Confirm the zip path actually exists and contains `report.md` + `errors/anonymized.jsonl` — if not, correct it with a single question.
|
|
316
|
+
- Confirm the chosen cluster is a single errorType — if multiple errorTypes are mixed, keep only one with a single question.
|
|
317
317
|
|
|
318
318
|
Once validation passes, jump to Step 2 (task key).
|
|
319
319
|
|
|
@@ -334,34 +334,33 @@ okstra task-list
|
|
|
334
334
|
Parse the JSON `tasks[]` array. The `taskGroup` field is a **raw display
|
|
335
335
|
name, not a slug** — `slugify` each value (lowercase + non-alphanumeric →
|
|
336
336
|
`-`) and **dedupe by slug** so case/format variants collapse (e.g.
|
|
337
|
-
`uploadFont` and `uploadfont` are one group, not two). Order
|
|
338
|
-
|
|
339
|
-
|
|
337
|
+
`uploadFont` and `uploadfont` are one group, not two). Order distinct slugs
|
|
338
|
+
by most-recent `updatedAt` and take the **2 most-recent** as recommendations,
|
|
339
|
+
shown in slug form.
|
|
340
340
|
|
|
341
341
|
`AskUserQuestion` (single-select):
|
|
342
342
|
|
|
343
343
|
- **Label**: `"Task group?"`
|
|
344
|
-
- **Options** (recommendations first,
|
|
344
|
+
- **Options** (recommendations first, `Enter directly` always last):
|
|
345
345
|
1. (and 2.) each recommended existing group, most-recent first —
|
|
346
|
-
label `<group> (
|
|
347
|
-
3.
|
|
346
|
+
label `<group> (existing)` (e.g. `uploadfont (existing)`).
|
|
347
|
+
3. `Enter directly` — free-text for a new or other group.
|
|
348
348
|
|
|
349
349
|
When the user picks an existing group, use its value verbatim. When they
|
|
350
|
-
pick
|
|
350
|
+
pick `Enter directly`, take a free-text value via a follow-up question.
|
|
351
351
|
|
|
352
352
|
If `okstra task-list` returns an empty `tasks[]` (no prior tasks), skip the
|
|
353
353
|
picker and ask one free-text question:
|
|
354
354
|
`"Task group (e.g. backend-api, INV-1234, refactor)"` → `task_group`.
|
|
355
355
|
|
|
356
356
|
Slug rule: same as `okstra-run` Step 3 — slugify, must have at least one
|
|
357
|
-
alphanumeric character. **Always slugify the chosen value**, whether
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
`slugify(frontmatter task-group)`.
|
|
357
|
+
alphanumeric character. **Always slugify the chosen value**, whether from an
|
|
358
|
+
existing-group selection or `Enter directly` — the `taskGroup` from `okstra
|
|
359
|
+
task-list` is a raw display name, so picking one verbatim would create a
|
|
360
|
+
non-standard directory (e.g. `briefs/uploadFont/`). The on-disk directory
|
|
361
|
+
segment (`briefs/<task-group>/`) and the frontmatter `task-group` are both
|
|
362
|
+
the slugified form, and `validate-brief.py` (Step 6.6) rejects any brief
|
|
363
|
+
whose directory segment differs from `slugify(frontmatter task-group)`.
|
|
365
364
|
|
|
366
365
|
If `task_group` was already collected by Step 1b sub-step 0 (tracker
|
|
367
366
|
preflight), reuse that value silently — do NOT ask again.
|
|
@@ -482,10 +481,9 @@ on a project-internal concrete object whenever possible.
|
|
|
482
481
|
`Read` / `Grep` to locate the concrete file path (relative to
|
|
483
482
|
`<PROJECT_ROOT>`) and the canonical symbol name. Record the resolution
|
|
484
483
|
under `Augmentation > Domain alignment` with the `evidence-link` label,
|
|
485
|
-
and link the absolute path from `Related Artifacts
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
object.
|
|
484
|
+
and link the absolute path from `Related Artifacts` — this keeps the brief
|
|
485
|
+
portable across downstream workers (Claude / Codex / Antigravity) in
|
|
486
|
+
separate worktrees that must point at the same object.
|
|
489
487
|
- **Conversion-block signal** — when a reporter statement cannot be
|
|
490
488
|
mapped to project vocabulary even after codebase exploration (e.g. the
|
|
491
489
|
reporter names a UI element that does not exist by that name, or
|
|
@@ -549,22 +547,22 @@ or to a `> augmented: <label>` blockquote inside the required section, so
|
|
|
549
547
|
it is clear that the content is the skill's / user's added interpretation
|
|
550
548
|
rather than the original source.
|
|
551
549
|
|
|
552
|
-
### codebase-scan variant
|
|
550
|
+
### codebase-scan variant-specific sharpening rules (improvement-discovery)
|
|
553
551
|
|
|
554
|
-
|
|
552
|
+
These 5 rules apply only to `scope: codebase` briefs. The budget expands from the default 6 → **8**.
|
|
555
553
|
|
|
556
|
-
1. **scan-scope
|
|
557
|
-
2.
|
|
558
|
-
3. **priority-lenses
|
|
559
|
-
4. **out-of-scope
|
|
560
|
-
5. **lens
|
|
554
|
+
1. **scan-scope path existence check.** Confirm each path via `ls` / `Read`. If missing, correct it with a single question (offer the nearest path candidate as `Recommended:`).
|
|
555
|
+
2. **Ambiguous path narrowing.** Narrow abstract paths like `"backend"`, `"payment module"` down to one or more concrete directories. Guess codebase-first, then confirm with a single question.
|
|
556
|
+
3. **priority-lenses whitelist check.** Confirm it is a subset of `LENSES` in `~/.okstra/lib/python/okstra_ctl/improvement_lenses.py`. If out-of-enum, offer the nearest in-enum value as `Recommended:`.
|
|
557
|
+
4. **out-of-scope consistency.** Confirm each path in `out-of-scope` is a subset of `scan-scope`. If a path is unrelated, remove it with a single question or absorb it into scan-scope.
|
|
558
|
+
5. **One line of lens-priority rationale.** If the brief body lacks a line on *why* each priority lens takes precedence in this scope, offer the result of a first codebase pass as `Recommended:` and ask one question.
|
|
561
559
|
|
|
562
|
-
stop conditions (codebase-scan
|
|
560
|
+
stop conditions (codebase-scan-specific additions):
|
|
563
561
|
|
|
564
|
-
- `scan-scope`
|
|
565
|
-
- `priority-lenses`
|
|
562
|
+
- Every path in `scan-scope` exists in the codebase
|
|
563
|
+
- `priority-lenses` is a valid enum subset (1–4 of them)
|
|
566
564
|
|
|
567
|
-
|
|
565
|
+
When both of the above conditions hold, sharpening may end even if budget remains.
|
|
568
566
|
|
|
569
567
|
### Augmentation labels (REQUIRED — no unlabelled augmentation)
|
|
570
568
|
|
|
@@ -577,7 +575,7 @@ labels. Unlabelled augmentation is rejected as half-formed translation.
|
|
|
577
575
|
| `evidence-link` | Cross-reference / file path / symbol resolved from the source against the actual codebase. Pure fact, verified by `Read` / `Grep`. | Trust without verification. |
|
|
578
576
|
| `format-conversion` | Format-only transform (Jira ADF → Markdown, HTML → Markdown, etc.). Semantics unchanged. | Trust without verification. |
|
|
579
577
|
| `terminology-mapping` | Reporter's word mapped to an okstra-canonical term from Step 3b. | Verify against `.okstra/glossary.md`; if mismatch, treat as a clarification candidate. |
|
|
580
|
-
| `intent-inference` | Reporter did NOT literally state this — the skill inferred meaning from context (e.g. classifying "
|
|
578
|
+
| `intent-inference` | Reporter did NOT literally state this — the skill inferred meaning from context (e.g. classifying "sometimes it doesn't work" as "intermittent failure on a specific path"). Qualitative only — **never** invent quantitative thresholds (numbers, latencies, percentages, counts). | **Verify with the reporter before acting.** Auto-mirrored into `Open Questions`. |
|
|
581
579
|
|
|
582
580
|
**Inline form** — `> augmented: intent-inference — <one line>`.
|
|
583
581
|
**Section form** — `- intent-inference: <one line>` under `Augmentation`.
|
|
@@ -585,12 +583,11 @@ labels. Unlabelled augmentation is rejected as half-formed translation.
|
|
|
585
583
|
### Auto-mirroring rule
|
|
586
584
|
|
|
587
585
|
Every `intent-inference` entry must have a paired entry in `Open Questions`
|
|
588
|
-
with the prefix `intent-check:` describing what the reporter must confirm
|
|
589
|
-
|
|
590
|
-
visible (
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
unverified translation.
|
|
586
|
+
with the prefix `intent-check:` describing what the reporter must confirm —
|
|
587
|
+
the inference stays visible (Augmentation) and its verification need stays
|
|
588
|
+
visible (Open Questions). If a downstream worker resolves the inference
|
|
589
|
+
without going back to the reporter, the `intent-check:` row stays open as a
|
|
590
|
+
record of unverified translation.
|
|
594
591
|
|
|
595
592
|
`terminology-mapping` and `conversion-block:` follow the same dual-record
|
|
596
593
|
discipline (Augmentation observation ↔ `Open Questions` `terminology:` /
|
|
@@ -906,15 +903,13 @@ started.
|
|
|
906
903
|
- **No template author-guidance in the artifact body.** The Step 5
|
|
907
904
|
template carries author guidance in HTML comments (`<!-- ... -->`);
|
|
908
905
|
**strip every such comment when writing the brief** — the final artifact
|
|
909
|
-
contains zero `<!-- ... -->` blocks
|
|
910
|
-
regions, but a clean artifact is the contract
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
replaced with the reporter's actual content; replace those placeholders,
|
|
917
|
-
do not leave them in.
|
|
906
|
+
contains zero `<!-- ... -->` blocks (the validator ignores comment
|
|
907
|
+
regions, but a clean artifact is the contract). Section headings stay
|
|
908
|
+
clean — never copy parenthetical reviewer notes onto the heading (e.g.
|
|
909
|
+
emit `## Source Material`, not `## Source Material (verbatim — do not
|
|
910
|
+
modify)`). Placeholder prose inside angle brackets (`<Background / scope
|
|
911
|
+
/ why now…>`) is NOT a comment — it is scaffolding to replace with the
|
|
912
|
+
reporter's actual content, not to leave in.
|
|
918
913
|
- If the tracker MCP is not connected, do not guess — ask the user to paste
|
|
919
914
|
the body or skip the source.
|
|
920
915
|
- If a URL fetch fails or hits an auth wall, do not guess — ask for a
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-container-build
|
|
3
3
|
description: |
|
|
4
|
-
Use to bring up, inspect, or tear down the okstra user-test container runtime for an implementation task — the docker-compose group okstra deploys from a task's worktree so a human can poke at the running build. Trigger words include "okstra container", "okstra container up", "okstra container down", "
|
|
4
|
+
Use to bring up, inspect, or tear down the okstra user-test container runtime for an implementation task — the docker-compose group okstra deploys from a task's worktree so a human can poke at the running build. Trigger words include "okstra container", "okstra container up", "okstra container down", "bring up the container", "spin up the container", "tear down the container", "container status", "container logs", "user-test environment", "user test environment", "docker compose up please", "spin up this task in a container", "stop the watcher", "stop watcher", "stop monitoring".
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# OKSTRA Container Build
|
|
@@ -18,35 +18,45 @@ Single entry point for the okstra user-test container runtime. okstra provisions
|
|
|
18
18
|
|
|
19
19
|
## Step 0: Preflight (shared)
|
|
20
20
|
|
|
21
|
-
Before any sub-command
|
|
21
|
+
Before any sub-command:
|
|
22
|
+
|
|
23
|
+
<!-- BEGIN FRAGMENT: bash-invocation-rule -->
|
|
24
|
+
Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
|
|
25
|
+
<!-- END FRAGMENT: bash-invocation-rule -->
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
28
|
okstra preflight --runtime claude-code --json
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string and pass it as `--project-root <projectRoot>` to every `okstra container` call below. `ok: false` → tell the user to run `/okstra-setup` first, then stop.
|
|
31
|
+
Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string and pass it as `--project-root <projectRoot>` to every `okstra container` call below. `ok: false` → tell the user to run `/okstra-setup` first, then stop.
|
|
32
|
+
|
|
33
|
+
<!-- BEGIN FRAGMENT: preflight-outdated-cli -->
|
|
34
|
+
If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
|
|
35
|
+
<!-- END FRAGMENT: preflight-outdated-cli -->
|
|
28
36
|
|
|
29
37
|
Docker itself must be installed and running for `up`/`status`/`down` to work. If a sub-command fails with a docker connection error, tell the user to start Docker (Desktop / daemon) and retry — do not try to start docker yourself.
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
<!-- BEGIN FRAGMENT: python-bootstrap-note -->
|
|
40
|
+
Every subsequent `okstra <subcmd>` call self-bootstraps its Python path, so this skill never needs `okstra paths --shell` / `export PYTHONPATH=...`.
|
|
41
|
+
<!-- END FRAGMENT: python-bootstrap-note -->
|
|
32
42
|
|
|
33
43
|
## Step 1: Dispatch by intent
|
|
34
44
|
|
|
35
45
|
Classify the user's request into one sub-command using the sub-command table above.
|
|
36
46
|
|
|
37
|
-
- Clear verbs route directly: "
|
|
38
|
-
- If the request is ambiguous (e.g. "okstra container
|
|
47
|
+
- Clear verbs route directly: "bring up/deploy/up" → `up`; "status" → `status`; "logs" → `logs`; "stop watcher/stop-watcher" → `stop-watcher`; "tear down/down" → `down`.
|
|
48
|
+
- If the request is ambiguous (e.g. "take a look at the okstra container"), present a numbered picker. Recommend the 1–2 most likely facets first, and make the **last option always "Enter directly"** so the user can name any facet:
|
|
39
49
|
|
|
40
50
|
```
|
|
41
|
-
|
|
42
|
-
1. status —
|
|
43
|
-
2. up —
|
|
44
|
-
3.
|
|
51
|
+
What would you like to do?
|
|
52
|
+
1. status — check running containers / watcher state (recommended)
|
|
53
|
+
2. up — bring up this task's containers
|
|
54
|
+
3. Enter directly (one of up / status / logs / stop-watcher / down)
|
|
45
55
|
```
|
|
46
56
|
|
|
47
|
-
The full facet list is the `Sub-command | What it does` table above — never hide a facet; if the user picks "
|
|
57
|
+
The full facet list is the `Sub-command | What it does` table above — never hide a facet; if the user picks "Enter directly", let them name any row.
|
|
48
58
|
|
|
49
|
-
When the user chains multiple facets in one message (e.g. "
|
|
59
|
+
When the user chains multiple facets in one message (e.g. "bring it up, then show me the status"), execute them sequentially — Step 0 runs once, each sub-command section runs once.
|
|
50
60
|
|
|
51
61
|
Every sub-command needs a **task-key** (`<project-id>:<task-group>:<task-id>`) — the container group is bound to one implementation task's worktree. Resolve it the same way across sub-commands:
|
|
52
62
|
|
|
@@ -61,8 +71,8 @@ Every sub-command needs a **task-key** (`<project-id>:<task-group>:<task-id>`)
|
|
|
61
71
|
Brings up the task's container group: integrates the implementation stages into the task worktree, synthesizes the compose env override, runs `docker compose up -d`, polls healthchecks, and attaches a tmux watcher pane.
|
|
62
72
|
|
|
63
73
|
**Preconditions** (state them if unmet, do not guess):
|
|
64
|
-
- The task must be an `implementation` task whose worktree is registered in `~/.okstra/worktrees/registry.json`. If `up` fails with "task worktree
|
|
65
|
-
- The worktree root must contain a `docker-compose.yml`. If `up` fails with "
|
|
74
|
+
- The task must be an `implementation` task whose worktree is registered in `~/.okstra/worktrees/registry.json`. If `up` fails with "task worktree is not in the registry" → the task has no implementation worktree yet; tell the user to run the `implementation` phase first.
|
|
75
|
+
- The worktree root must contain a `docker-compose.yml`. If `up` fails with "there is no ... at the worktree root" → no compose file shipped with this task; surface the message verbatim.
|
|
66
76
|
- Every stage declared in the approved plan's Stage Map must be `done`. `up` integrates the whole task, so a partially-finished task (e.g. only stage 1 of 3 done) is refused rather than deployed as if complete (gate in `stage_targets.py`, shared with whole-task `final-verification`). If `up` fails with `final-verification(whole-task): stage N not done — run implementation --stage N first`, surface that message verbatim and tell the user to finish the named stage via the `implementation` phase with `--stage N`.
|
|
67
77
|
|
|
68
78
|
Run:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-graphify
|
|
3
3
|
description: >-
|
|
4
|
-
Use when the user wants to build, query, or navigate a knowledge graph over an okstra project's own `.okstra/` memory — its reports, decision records, and glossary. Turns that docs corpus into a persistent graph with community detection and an honest EXTRACTED/INFERRED/AMBIGUOUS audit trail, then answers cross-document questions the flat files can't. Trigger phrases include "okstra graphify", "graph the .okstra docs", "build okstra knowledge graph", "query okstra graph", "what connects to X in the okstra docs", "okstra graph
|
|
4
|
+
Use when the user wants to build, query, or navigate a knowledge graph over an okstra project's own `.okstra/` memory — its reports, decision records, and glossary. Turns that docs corpus into a persistent graph with community detection and an honest EXTRACTED/INFERRED/AMBIGUOUS audit trail, then answers cross-document questions the flat files can't. Trigger phrases include "okstra graphify", "graph the .okstra docs", "build okstra knowledge graph", "query okstra graph", "what connects to X in the okstra docs", "build the okstra graph", "graph the decision records". NOT for graphing arbitrary code or non-okstra folders (that is the standalone /graphify), and NOT for single-task inspection (okstra-inspect) or rollups (okstra-rollup).
|
|
5
5
|
trigger: /okstra-graphify
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -22,7 +22,11 @@ Only `.okstra/**/*.md` (final reports, `decisions/*.md`, `glossary.md`, briefs)
|
|
|
22
22
|
|
|
23
23
|
## Step 0: Preflight (shared)
|
|
24
24
|
|
|
25
|
-
Before any sub-command
|
|
25
|
+
Before any sub-command:
|
|
26
|
+
|
|
27
|
+
<!-- BEGIN FRAGMENT: bash-invocation-rule -->
|
|
28
|
+
Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
|
|
29
|
+
<!-- END FRAGMENT: bash-invocation-rule -->
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
32
|
okstra preflight --runtime claude-code --json
|
|
@@ -30,13 +34,17 @@ okstra preflight --runtime claude-code --json
|
|
|
30
34
|
|
|
31
35
|
Parse the stdout JSON:
|
|
32
36
|
- `ok: true` → carry `projectRoot` as a literal string; it is the `--project-root` value for every sub-command below.
|
|
33
|
-
- `ok: false` → before concluding "no setup", ask whether the user pointed at a specific project directory. If so, re-run `okstra preflight --runtime claude-code --cwd <that-dir> --json`. Only if this **also** returns `ok:false` do you tell the user: "this project has no okstra setup. Run `/okstra-setup` first." Then stop.
|
|
37
|
+
- `ok: false` → before concluding "no setup", ask whether the user pointed at a specific project directory. If so, re-run `okstra preflight --runtime claude-code --cwd <that-dir> --json`. Only if this **also** returns `ok:false` do you tell the user: "this project has no okstra setup. Run `/okstra-setup` first." Then stop.
|
|
38
|
+
|
|
39
|
+
<!-- BEGIN FRAGMENT: preflight-outdated-cli -->
|
|
40
|
+
If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
|
|
41
|
+
<!-- END FRAGMENT: preflight-outdated-cli -->
|
|
34
42
|
|
|
35
43
|
Every `okstra graphify` call below passes `--project-root <projectRoot>` — `--project-root` is REQUIRED and there is no cwd injection; a bare `okstra graphify build` fails with a usage error.
|
|
36
44
|
|
|
37
45
|
## Step 1: Dispatch by intent
|
|
38
46
|
|
|
39
|
-
Classify the request into one sub-command using the table above. If ambiguous ("okstra graph
|
|
47
|
+
Classify the request into one sub-command using the table above. If ambiguous ("show me the okstra graph"), ask which — enumerate the full sub-command table as a numbered text list and let the user pick. `build` is the prerequisite for `query`/`path`/`explain`/`wiki`/`mcp`; if the user asks to query before a graph exists, the CLI will fail cleanly with `no graph … Run \`okstra graphify build\` first` — run `build` first.
|
|
40
48
|
|
|
41
49
|
---
|
|
42
50
|
|