okstra 0.127.0 → 0.129.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/docs/architecture/storage-model.md +23 -3
- package/docs/architecture.md +28 -1
- package/docs/cli.md +9 -0
- package/docs/project-structure-overview.md +17 -7
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/antigravity-worker.md +3 -3
- package/runtime/agents/workers/claude-worker.md +4 -4
- package/runtime/agents/workers/codex-worker.md +3 -3
- package/runtime/agents/workers/report-writer-worker.md +5 -5
- package/runtime/prompts/lead/adapters/claude-code.md +2 -1
- package/runtime/prompts/lead/adapters/codex.md +1 -0
- package/runtime/prompts/lead/adapters/external.md +1 -0
- package/runtime/prompts/lead/convergence.md +45 -83
- package/runtime/prompts/lead/okstra-lead-contract.md +12 -8
- package/runtime/prompts/lead/report-writer.md +3 -2
- package/runtime/prompts/lead/team-contract.md +19 -9
- package/runtime/prompts/profiles/_common-contract.md +1 -1
- package/runtime/prompts/profiles/error-analysis.md +1 -1
- package/runtime/prompts/profiles/final-verification.md +10 -6
- package/runtime/prompts/profiles/implementation-planning.md +5 -0
- package/runtime/prompts/profiles/improvement-discovery.md +11 -1
- package/runtime/prompts/profiles/requirements-discovery.md +8 -1
- package/runtime/python/okstra_ctl/analysis_packet.py +14 -15
- package/runtime/python/okstra_ctl/codex_dispatch.py +51 -80
- package/runtime/python/okstra_ctl/context_cost.py +82 -7
- package/runtime/python/okstra_ctl/convergence.py +223 -0
- package/runtime/python/okstra_ctl/convergence_engine.py +1152 -0
- package/runtime/python/okstra_ctl/convergence_migration.py +184 -0
- package/runtime/python/okstra_ctl/convergence_store.py +85 -0
- package/runtime/python/okstra_ctl/dispatch_core.py +60 -1
- package/runtime/python/okstra_ctl/improvement_assignment.py +61 -0
- package/runtime/python/okstra_ctl/log_report.py +44 -5
- package/runtime/python/okstra_ctl/path_hints.py +28 -1
- package/runtime/python/okstra_ctl/paths.py +10 -1
- package/runtime/python/okstra_ctl/render.py +78 -11
- package/runtime/python/okstra_ctl/run.py +66 -2
- package/runtime/python/okstra_ctl/wizard.py +15 -4
- package/runtime/python/okstra_ctl/work_categories.py +37 -0
- package/runtime/python/okstra_ctl/worker_prompt_body.py +107 -0
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +316 -0
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +109 -10
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +158 -0
- package/runtime/templates/implementation-worker-preamble.md +51 -0
- package/runtime/templates/operating-standard.md +4 -4
- package/runtime/templates/report-writer-prompt-preamble.md +37 -0
- package/runtime/templates/worker-error-contract.md +46 -0
- package/runtime/templates/worker-prompt-preamble.md +28 -227
- package/runtime/validators/lib/fixtures.sh +27 -12
- package/runtime/validators/validate-run.py +228 -45
- package/src/cli-registry.mjs +7 -0
- package/src/commands/execute/convergence.mjs +34 -0
- package/src/commands/inspect/log-report.mjs +5 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Report Writer Prompt Preamble (canonical)
|
|
2
|
+
|
|
3
|
+
This file is the audience-specific contract for `report-writer`. Read it end-to-end. Before work, also read the shared file named by `**Worker Error Contract Path:**`; error rules live only there.
|
|
4
|
+
|
|
5
|
+
## Operating standard (read before any output)
|
|
6
|
+
|
|
7
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
8
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
9
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
10
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
11
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
12
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
13
|
+
|
|
14
|
+
## Required reading
|
|
15
|
+
|
|
16
|
+
Read every input enumerated by the Phase 6 dispatch end-to-end: task/analysis inputs, worker results, convergence state, the instruction-set-local `final-report-template.md`, and the task-type excerpt `final-report-schema.json`. Do not pull the full repository template or schema when the scoped instruction-set copies are provided.
|
|
17
|
+
|
|
18
|
+
Write Reading Confirmation to the report-writer audit sidecar, not the rendered final report. Resolve `.okstra/**` paths against `**Project Root:**`.
|
|
19
|
+
|
|
20
|
+
## Report authoring handoff
|
|
21
|
+
|
|
22
|
+
- Author the data.json at `**Result Path:**` and the audit file at `**Worker Result Path:**`.
|
|
23
|
+
- Follow the task-type schema excerpt and Phase 6 report-writer contract. Do not perform independent analysis, edit source code, or load implementation coding-preflight resources.
|
|
24
|
+
- Invoke `okstra render-final-report <Result Path>` after writing data.json and verify the markdown sibling exists before returning.
|
|
25
|
+
- Preserve source item IDs, convergence classifications, round history, and unresolved dissent; do not recompute them from intuition.
|
|
26
|
+
|
|
27
|
+
## Anchor headers
|
|
28
|
+
|
|
29
|
+
The generated prompt selects this file through `**Worker Preamble Path:**` and includes `**Worker Error Contract Path:**`, error paths, and read scope. It never includes `**Coding preflight pack:**`.
|
|
30
|
+
|
|
31
|
+
## Return message to the lead
|
|
32
|
+
|
|
33
|
+
Begin the inline return with the exact `**Model:** Report writer worker, <modelExecutionValue>` line from the prompt, followed by the artifact status. Never invent or abbreviate the model.
|
|
34
|
+
|
|
35
|
+
## Writing style
|
|
36
|
+
|
|
37
|
+
Use concise reader-facing prose and honor the report language. Keep identifiers, paths, symbols, model names, CLI flags, and status tokens in English. Translate meaning rather than dictionary words.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Worker Error Contract (canonical)
|
|
2
|
+
|
|
3
|
+
This audience-neutral file is the single source of truth for every initial worker's error path, sidecar schema, and write protocol. Read it end-to-end from `**Worker Error Contract Path:**` before work.
|
|
4
|
+
|
|
5
|
+
## Error reporting
|
|
6
|
+
|
|
7
|
+
Record a tool call only when its failure blocked the step you intended. A non-zero exit code is NOT by itself a failure to record. Do not record an entry when:
|
|
8
|
+
|
|
9
|
+
- a search/probe exits non-zero solely because it found no matches and work proceeds unaffected;
|
|
10
|
+
- an optional / expected-absent path is absent and detecting absence was the purpose;
|
|
11
|
+
- output was truncated but a later read covered the content end-to-end.
|
|
12
|
+
|
|
13
|
+
If the non-zero exit changed nothing about what you could do next, it is normal. When in doubt, record the real blocker: under-recording a real blocker is worse than one noisy entry.
|
|
14
|
+
|
|
15
|
+
If the sidecar does not exist when a real failure occurs, create `{"schemaVersion": 1, "errors": []}` and append one entry.
|
|
16
|
+
|
|
17
|
+
### Entry schema
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"ts": "<ISO 8601 UTC>",
|
|
22
|
+
"phase": "<current okstra phase>",
|
|
23
|
+
"errorType": "tool-failure",
|
|
24
|
+
"command": "<failed command/tool signature>",
|
|
25
|
+
"commandKind": "bash | tool:Read | tool:Edit | mcp | ...",
|
|
26
|
+
"exitCode": null,
|
|
27
|
+
"durationMs": null,
|
|
28
|
+
"message": "<one-line human summary>",
|
|
29
|
+
"stderrExcerpt": null,
|
|
30
|
+
"context": null
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Rules
|
|
35
|
+
|
|
36
|
+
- Do not add `source`, `recordedAt`, `agent`, `agentRole`, `model`, or `taskKey`; the lead supplies them when merging the sidecar.
|
|
37
|
+
- The sidecar accepts only `errorType: "tool-failure"`. CLI wrappers write `cli-failure` directly to the run log; the lead records `contract-violation`.
|
|
38
|
+
- Continue after recording unless the failure makes the task impossible.
|
|
39
|
+
|
|
40
|
+
### Path extraction (BLOCKING)
|
|
41
|
+
|
|
42
|
+
Extract `**Errors log path:**` and `**Errors sidecar path:**` verbatim from the dispatch prompt. If either is absent, return the worker-specific `<SENTINEL_PREFIX>_ERRORS_PATH_MISSING` sentinel and stop. Never synthesize a path from a run-directory pattern.
|
|
43
|
+
|
|
44
|
+
## Path anchoring
|
|
45
|
+
|
|
46
|
+
Every `.okstra/...` path is anchored at `**Project Root:**`, never at cwd. A task or stage worktree does **not** contain the project's `.okstra/` directory. Mutating project commands may use `**Worktree:**`, but okstra artifact reads and error writes use absolute paths resolved from Project Root. If a relative read fails in a worktree, re-anchor it to `<Project Root>` instead of retrying the same path.
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
# Worker Prompt Preamble (canonical)
|
|
1
|
+
# Analysis Worker Prompt Preamble (canonical)
|
|
2
2
|
|
|
3
|
-
This file is the
|
|
4
|
-
|
|
5
|
-
It replaces the previous practice of inlining ~80 lines of identical boilerplate into every worker prompt body.
|
|
3
|
+
This file is the audience-specific contract for initial `analysis` workers. Read it end-to-end from the path selected by the dispatch prompt. Before doing work, also read the shared file named by `**Worker Error Contract Path:**`; that file is the only source for error-sidecar rules.
|
|
6
4
|
|
|
7
5
|
## Operating standard (read before any output)
|
|
8
6
|
|
|
@@ -14,251 +12,54 @@ Work like a senior engineer who owns this result, not a commentator on it.
|
|
|
14
12
|
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
15
13
|
- Hold your own line — reason from your independent angle; do not drift toward the other workers' likely answers or echo the user. Triangulation fails if your view isn't genuinely yours.
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
## Required reading (analysis workers + report-writer worker)
|
|
20
|
-
|
|
21
|
-
You are required to read every primary input file enumerated by the dispatcher (the lead's prompt lists them under `[Required reading]`) from the very first character to the very last character before you produce any analysis output. Skimming, partial reads, jumping to a single section, or relying on prior knowledge of a similar file's structure is not acceptable. Source files listed as fallback/evidence paths are read on demand when you need to verify a citation, resolve ambiguity, or inspect material the packet says it omitted.
|
|
22
|
-
|
|
23
|
-
### Audience-scoped enumeration (performance optimization — mandatory)
|
|
15
|
+
## Required reading
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
| Recipient | Files included in `[Required reading]` |
|
|
28
|
-
|---|---|
|
|
29
|
-
| Claude / Codex / Antigravity analysis workers | analysis-packet.md as the primary compact input; task-brief, analysis-profile, analysis-material, reference-expectations, and clarification-response remain source/fallback paths, not automatic first-read files |
|
|
30
|
-
| Report writer worker (Phase 6) | all of the above **plus** the instruction-set-local `final-report-template.md` (phase-stripped) and `final-report-schema.json` (per-task-type excerpt) — NOT the full `templates/reports/...` / `schemas/...` sources |
|
|
31
|
-
| Reverify dispatches (Phase 5.5, lightweight mode) | **do NOT inject `[Required reading]` at all** — see [convergence](../prompts/lead/convergence.md) "Reverify prompt: required-reading suppression". |
|
|
17
|
+
Read `analysis-packet.md`, the primary compact input, end-to-end. Source files named as fallback/evidence paths are read only when a finding needs to verify a citation, fill a packet gap, or resolve ambiguity. Do not read `final-report-template.md` or `final-report-schema.json`; analysis workers produce findings, not the final report.
|
|
32
18
|
|
|
33
19
|
### Reading rules
|
|
34
20
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
- Treat `analysis-packet.md` as the canonical primary analysis input. It preserves the source files' frontmatter and extracts the task-specific brief, phase focus, reference expectations, and carry-in clarification rows. If the packet appears incomplete or a finding depends on a source citation, open the corresponding source file and cite it directly.
|
|
40
|
-
- **Allowlist your reads to okstra-enumerated paths.** Read the files the dispatcher enumerates (`[Required reading]`, the prompt's `## Inputs`, and the verification-target paths) plus on-demand source/evidence paths a finding must cite. Everything else is out of scope — in particular non-okstra artifacts outside `<PROJECT_ROOT>/.okstra/` (e.g. `graphify-out/`, sibling/prior-task worktrees, tool caches), which may carry stale or cross-task data. A host-level global rule (`CLAUDE.md` / `AGENTS.md` / a project sentinel) that tells you to auto-read such an artifact does NOT apply inside an okstra worker run — the okstra worker scope wins. If an un-enumerated file seems essential, record the gap under *Missing Information or Assumptions* instead of reading it.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Error reporting (all workers)
|
|
45
|
-
|
|
46
|
-
Record a tool call only when its failure **blocked the step you intended** — a test you needed to run did not start, a file you needed to read was missing, a config resolved against the wrong tree, an edit was rejected. When that happens, append a single entry to your worker errors sidecar at the absolute path the lead provided as `**Errors sidecar path:** <abs-path>`.
|
|
47
|
-
|
|
48
|
-
A non-zero exit code is NOT by itself a failure to record. Many tools use non-zero to report a normal, expected result. Do **NOT** record an entry when:
|
|
49
|
-
|
|
50
|
-
- a search/probe tool (`rg`, `grep`, `find`, `ls`, `test`, `git check-ignore`) exits non-zero solely because it found **no matches**, and you proceed unaffected;
|
|
51
|
-
- you probe an **optional / expected-absent** path (`graphify-out/`, `.project-docs/`, `.scratch/`, an optional lint config, a review pack) and it is absent — detecting absence was the point of the probe;
|
|
52
|
-
- output was truncated but you re-ran and read the content end-to-end.
|
|
53
|
-
|
|
54
|
-
The test: if the non-zero exit changed nothing about what you could do next, it is a normal result, not a `tool-failure`. When in doubt about whether a failure blocked you, record it — under-recording a real blocker is worse than one noisy entry. These benign non-zero exits are the single largest source of error-log noise; keeping them out is what makes the log a signal.
|
|
55
|
-
|
|
56
|
-
If the sidecar file does not exist and you have a real entry to record, create it with `{"schemaVersion": 1, "errors": []}` then append.
|
|
57
|
-
|
|
58
|
-
### Entry schema
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"ts": "<ISO 8601 UTC>",
|
|
63
|
-
"phase": "<current okstra phase>",
|
|
64
|
-
"errorType": "tool-failure",
|
|
65
|
-
"command": "<failed command/tool signature>",
|
|
66
|
-
"commandKind": "bash | tool:Read | tool:Edit | mcp | ...",
|
|
67
|
-
"exitCode": <int or null>,
|
|
68
|
-
"durationMs": <int or null>,
|
|
69
|
-
"message": "<one-line human summary>",
|
|
70
|
-
"stderrExcerpt": "<first ~2KB of stderr, or null>",
|
|
71
|
-
"context": { ... or null }
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Rules
|
|
76
|
-
|
|
77
|
-
- Do NOT include `source` / `recordedAt` / `agent` / `agentRole` / `model` / `taskKey` — the lead fills those in when dumping the sidecar to the run-level errors log via `okstra-error-log.py append-from-worker`.
|
|
78
|
-
- Do NOT use `errorType` values other than `"tool-failure"` in the sidecar. `cli-failure` events are recorded by CLI wrapper agents (codex / antigravity) directly to the run-level errors log, not via the sidecar. `contract-violation` events are recorded by the lead after inspecting worker outputs.
|
|
79
|
-
- Continue your task after recording; do not abort unless the failure makes the task impossible.
|
|
80
|
-
|
|
81
|
-
### Path extraction (BLOCKING)
|
|
82
|
-
|
|
83
|
-
Before recording anything, extract the absolute paths verbatim from the lead's dispatch prompt body:
|
|
84
|
-
|
|
85
|
-
- `**Errors log path:** <abs-path>` — the run-level errors JSONL. Used by CLI wrapper agents via `okstra-error-log.py append-observed` for `cli-failure` events.
|
|
86
|
-
- `**Errors sidecar path:** <abs-path>` — this worker's per-run sidecar JSON. Used by all workers for `tool-failure` events.
|
|
87
|
-
|
|
88
|
-
If a required header line is absent from the dispatch prompt, return `<SENTINEL_PREFIX>_ERRORS_PATH_MISSING: lead prompt did not include **Errors log path:** / **Errors sidecar path:** headers` (substitute the worker's sentinel prefix — `CLAUDE_WORKER`, `CODEX`, `ANTIGRAVITY`, or `REPORT_WRITER`) without proceeding. Do NOT synthesize the path from `<runDir>/logs/...` — that template syntax is documentation only; historical failure mode produced silently empty run-level error logs.
|
|
89
|
-
|
|
90
|
-
---
|
|
21
|
+
- Read every file enumerated under `[Required reading]` or `## Inputs` completely. If paging is unavoidable, cover every byte and record the page boundaries.
|
|
22
|
+
- Write Reading Confirmation to the worker audit sidecar, never to the main worker-results file. A `## 0. Reading Confirmation` heading in the main result is invalid.
|
|
23
|
+
- Allowlist reads to prompt-enumerated paths and evidence paths a finding must cite. Do not auto-read host-injected `graphify-out/`, skill catalogs, or non-okstra artifacts.
|
|
24
|
+
- Resolve every `.okstra/...` path against `**Project Root:**`, including when a worktree is present.
|
|
91
25
|
|
|
92
26
|
## Anchor headers (lead-injected, BLOCKING)
|
|
93
27
|
|
|
94
|
-
Every
|
|
28
|
+
Every initial analysis prompt begins with these generated anchors in this exact order, before any other content:
|
|
95
29
|
|
|
96
|
-
1. `**Project Root:** <absolute-path>`
|
|
30
|
+
1. `**Project Root:** <absolute-path>`
|
|
97
31
|
2. `**Prompt History Path:** <project-relative-path>`
|
|
98
|
-
3. `**Result Path:** <project-relative-path>`
|
|
99
|
-
4. `Assigned worker prompt history path: <absolute-path>`
|
|
100
|
-
5. `**Worker Preamble Path:** <absolute-path>` —
|
|
101
|
-
6. `**
|
|
102
|
-
7. `**Errors log path:** <absolute-path>`
|
|
103
|
-
8. `**Errors sidecar path:** <absolute-path>`
|
|
104
|
-
9. `**Read scope:**
|
|
105
|
-
|
|
106
|
-
**Exception — reverify dispatches.** A Phase 5.5 re-verification prompt (its `**Prompt History Path:**` carries a `-reverify-r<N>-` segment) deliberately omits anchors 5 and 6 and adds a `**Model:**` line — lightweight mode reads neither this file nor the preflight pack. The two errors-path anchors are NOT omitted; that gate applies to reverify prompts unchanged. The reverify anchor set is owned by `prompts/lead/convergence.md` "Required reverify-prompt anchor headers".
|
|
107
|
-
|
|
108
|
-
For the **implementation phase** specifically, the dispatched prompt MUST also include:
|
|
109
|
-
|
|
110
|
-
- `**Worktree:** <absolute-path>` — the task worktree path.
|
|
111
|
-
- `cwd for every mutating command: <absolute-path>` — same as Worktree path; used by codex / antigravity wrappers as `--add-dir` / `--include-directories`.
|
|
112
|
-
|
|
113
|
-
For the **final-verification phase** specifically, the dispatched prompt MUST also include the verification target snapshot so every analyser verifies the SAME target the lead captured at the entry gate:
|
|
114
|
-
|
|
115
|
-
- `**Worktree:** <absolute-path>` — the checkout under verification (read-only).
|
|
116
|
-
- `**Verification base ref:** <base-ref>` — the implementation base for the diff.
|
|
117
|
-
- `**Verification diff stat:** <git diff --stat output>` — the captured diff-stat that bounds the verification scope.
|
|
118
|
-
|
|
119
|
-
For the **improvement-discovery phase** specifically, the dispatched prompt MUST also include the resolved-scope log the lead wrote during Phase 1.5, so workers key off an explicit absolute path instead of re-deriving the run directory:
|
|
120
|
-
|
|
121
|
-
- `**Phase 1.5 Grilling Log:** <absolute-path>` — the lead's Phase 1.5 reflect-back log (`<RUN_DIR>/state/phase-1.5-grilling.md`, written before dispatch). Its `Resolved scope` / `Resolved lenses` blocks are the authoritative scope and lens definition for this run. Read the file at this absolute path; do NOT re-derive it from `<RUN_DIR>`, and do NOT re-interpret the brief's raw `scan-scope` / `priority-lenses`. The presence of this anchor is itself the signal that this is an improvement-discovery run — no separate task-type detection is required.
|
|
122
|
-
|
|
123
|
-
### Path anchoring (BLOCKING — the single largest source of worker tool-failures)
|
|
124
|
-
|
|
125
|
-
Every `.okstra/...` path is anchored at `**Project Root:**`, **never** at your cwd. When your run has a worktree (`**Worktree:**` is present), your cwd is that worktree — and the stage/task worktree does **not** contain the project's `.okstra/` directory. So a bare `Read`/`cat .okstra/tasks/...` from cwd resolves inside the worktree and fails "no such file". This is the same trap whether the path came from the prompt, a manifest field, a prior report's citation, or your own reasoning.
|
|
126
|
-
|
|
127
|
-
- Resolve any project-relative path (`.okstra/...`, `<Result Path>`, `<Prompt History Path>`, a prior-report `path:line` citation) against `**Project Root:**`: `<Project Root>/.okstra/...`. Never use the bare relative form.
|
|
128
|
-
- Mutating build/test commands still run from the worktree cwd (`cd <Worktree> && ...`) — but reads of okstra artifacts (`.okstra/**`) always go through `<Project Root>`, even while cwd is the worktree.
|
|
129
|
-
- If a `.okstra/...` read fails "no such file / does not exist in the worktree", do not retry the same relative path — re-anchor it to `<Project Root>` and read the absolute path.
|
|
32
|
+
3. `**Result Path:** <project-relative-path>`
|
|
33
|
+
4. `Assigned worker prompt history path: <absolute-path>`
|
|
34
|
+
5. `**Worker Preamble Path:** <absolute-path>` — selects this analysis preamble.
|
|
35
|
+
6. `**Worker Error Contract Path:** <absolute-path>` — shared by every initial audience.
|
|
36
|
+
7. `**Errors log path:** <absolute-path>`
|
|
37
|
+
8. `**Errors sidecar path:** <absolute-path>`
|
|
38
|
+
9. `**Read scope:** <allowlist>`
|
|
130
39
|
|
|
131
|
-
|
|
40
|
+
`final-verification` additionally carries its six verification-target anchors. `improvement-discovery` carries `**Phase 1.5 Grilling Log:**`. Reverify prompts are lightweight and do not use this preamble.
|
|
132
41
|
|
|
133
|
-
## Worker output sections
|
|
42
|
+
## Worker output sections
|
|
134
43
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
### Result Frontmatter (mandatory, precedes Section 1)
|
|
138
|
-
|
|
139
|
-
Every worker result file MUST begin with a YAML frontmatter block. For analysis workers, values are sourced from `analysis-packet.md` frontmatter; fall back to `analysis-material.md` or `task-brief.md` only if the packet is missing a field. Report-writer can use `analysis-material.md` / `task-brief.md` as before. Copy values verbatim; do NOT regenerate them. Only `workerId` and `title` are worker-specific.
|
|
140
|
-
|
|
141
|
-
```yaml
|
|
142
|
-
---
|
|
143
|
-
title: OKSTRA <Worker Role> Result - <task-key>
|
|
144
|
-
id: "<task-key with ':' replaced by '-'>"
|
|
145
|
-
aliases: ["<id>-<task-type>"]
|
|
146
|
-
tags: ["worker-result", "<task-type>"]
|
|
147
|
-
taskType: "<task-type>"
|
|
148
|
-
workerId: "<claude|codex|antigravity|report-writer>"
|
|
149
|
-
task-id: "<task-id>"
|
|
150
|
-
task-group: "<task-group>"
|
|
151
|
-
project-id: "<project-id>"
|
|
152
|
-
date: <YYYY-MM-DD>
|
|
153
|
-
---
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Concrete example for a `claude-worker` result on task-key `fontsninja-classifier-v2:DEV-9388:DEV-9429` and task-type `implementation`:
|
|
157
|
-
|
|
158
|
-
```yaml
|
|
159
|
-
---
|
|
160
|
-
title: OKSTRA Claude Worker Result - fontsninja-classifier-v2:DEV-9388:DEV-9429
|
|
161
|
-
id: "fontsninja-classifier-v2-DEV-9388-DEV-9429"
|
|
162
|
-
aliases: ["fontsninja-classifier-v2-DEV-9388-DEV-9429-implementation"]
|
|
163
|
-
tags: ["worker-result", "implementation"]
|
|
164
|
-
taskType: "implementation"
|
|
165
|
-
workerId: "claude"
|
|
166
|
-
task-id: "DEV-9429"
|
|
167
|
-
task-group: "DEV-9388"
|
|
168
|
-
project-id: "fontsninja-classifier-v2"
|
|
169
|
-
date: 2026-05-15
|
|
170
|
-
---
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Rules:
|
|
174
|
-
- `id` is the run's `task-key` with `:` replaced by `-`. It is a scalar string, NOT an array.
|
|
175
|
-
- `aliases` is a YAML array containing a single value `"<id>-<task-type>"`.
|
|
176
|
-
- `taskType` mirrors the run's task type (`requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`, `final-verification`, `release-handoff`).
|
|
177
|
-
- `workerId` identifies which worker produced the file. Required values: `claude` / `codex` / `antigravity` / `report-writer`.
|
|
178
|
-
- Other fields (`task-id`, `task-group`, `project-id`, `date`) MUST match the input files' frontmatter exactly. If the input frontmatter is missing or unreadable, the worker MUST record a `tool-failure` and stop instead of guessing.
|
|
179
|
-
|
|
180
|
-
The same frontmatter contract applies to the `Report writer worker`'s final-report file — the report-writer copies these values from its inputs and only swaps `workerId` to `report-writer`.
|
|
181
|
-
|
|
182
|
-
### Worker Result Header Standard
|
|
183
|
-
|
|
184
|
-
Every worker result file under `worker-results/` must begin with a standardized header:
|
|
185
|
-
|
|
186
|
-
```markdown
|
|
187
|
-
# <Role> Analysis — <task-key>
|
|
188
|
-
|
|
189
|
-
**Target:** <path or scope> <!-- OPTIONAL: include when the run is scoped to a specific file/module -->
|
|
190
|
-
**Model:** <Role>, <AI model>
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Task-type and date are **not** repeated in this human header — the YAML frontmatter (`taskType`, `date`) is the single source for both (and the copy Obsidian indexes). The `Target:` line is optional — include it when the run is scoped to a specific path or module, omit it for whole-project runs; when present, place it between the title and the `Model:` line.
|
|
194
|
-
|
|
195
|
-
Example (Codex / Report-writer headers are identical modulo the role name and model id):
|
|
196
|
-
|
|
197
|
-
```markdown
|
|
198
|
-
# Claude Worker Analysis — jobs:tasks:8852
|
|
199
|
-
|
|
200
|
-
**Target:** server/auth.ts
|
|
201
|
-
**Model:** Claude worker, opus
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Use the actual model identifier recorded in team-state (never invent a model ID — read it from `resultContract.requiredWorkerRoles[*].modelExecutionValue` or the tool response metadata).
|
|
205
|
-
|
|
206
|
-
The header is followed by the standard worker output contract sections (Findings, Missing Information, etc.).
|
|
207
|
-
|
|
208
|
-
### Section ordering
|
|
209
|
-
|
|
210
|
-
A successful worker result must include the following sections in this exact order, beneath the frontmatter block:
|
|
44
|
+
Every analysis result starts with YAML frontmatter containing the task identity and `workerId`, followed by a header with the actual `**Model:**` value. Then emit these sections in exact order:
|
|
211
45
|
|
|
212
46
|
1. Findings
|
|
213
47
|
2. Missing Information or Assumptions
|
|
214
48
|
3. Safe or Reasonable Areas
|
|
215
49
|
4. Uncertain Points
|
|
216
50
|
5. Recommended Next Actions
|
|
217
|
-
6.
|
|
218
|
-
|
|
219
|
-
Every item in sections 1–5 (and any section 6) MUST carry a worker-internal item ID unique within the file. Lead synthesis preserves these as `<worker>:<item-id>` in `Source items (worker:item)` columns.
|
|
220
|
-
|
|
221
|
-
**Sections 1–5 are the common core.** Every analysis worker (Claude / Codex / Antigravity) MUST cover the same set of dimensions in sections 1–5 — feasibility, requirement interpretation, hidden assumptions, alternatives, and execution risk — regardless of which model is producing the result. The point of running three models is to triangulate the same answer space, not to partition it. A worker that produces "Findings" populated only with items from its own lens (e.g. Codex only listing implementation-feasibility findings) is in breach of contract; convergence will treat coverage gaps as `verification-error`.
|
|
222
|
-
|
|
223
|
-
**Section 6 is the only legal home for specialization.** When the worker has a depth-of-perspective contribution that genuinely sits outside the common core (e.g. a Codex-specific stack-trace decomposition, a Claude-specific assumption-chain teardown, a Antigravity-specific alternative-architecture sketch), put it there. Lead and convergence treat Section 6 as additive context, not as input to consensus measurement.
|
|
224
|
-
|
|
225
|
-
Code evidence must include file paths and line numbers.
|
|
226
|
-
|
|
227
|
-
### Ticket Tagging (mandatory for sections 1–5)
|
|
228
|
-
|
|
229
|
-
Every item in sections 1–5 MUST be tagged with the ticket(s) it relates to. This applies whenever the run's task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`.
|
|
230
|
-
|
|
231
|
-
- **Table-form items**: include a `Ticket ID` column. The column is placed immediately after the row-ID column (e.g. after `F-001`, `M-001`).
|
|
232
|
-
- **Bullet / numbered-list items**: prepend `[TICKETID: <id>]` to the item title, immediately after the row ID and before the body text. Example: `- F-001 [TICKETID: TICKET-123] — <summary> (path:line)`.
|
|
233
|
-
- **Section headers in the final report** (e.g. `### 5.5.3 Recommended Option`): append `[TICKETID: <id>]` to the header when the section is scoped to a specific ticket. Headers that span all tickets in the run omit the tag.
|
|
234
|
-
|
|
235
|
-
Ticket ID fill rule (in order):
|
|
236
|
-
|
|
237
|
-
1. Use the `Issue / Ticket` value from the run's input template.
|
|
238
|
-
2. If empty, fall back to the `Task ID` value (no prefix; write `8852` not `task:8852`).
|
|
239
|
-
3. If both are absent, write `unknown`. This is allowed but signals an input-template defect — the worker SHOULD also record a `Missing Information` item noting the absent identifier.
|
|
240
|
-
4. When a single item maps to multiple tickets, separate them with commas: `TICKET-123, TICKET-456`. Ticket IDs containing commas are not supported.
|
|
241
|
-
|
|
242
|
-
Workers MUST apply these rules to every item in sections 1–5. Lead and report-writer MUST preserve the tagging when carrying worker findings into the final report.
|
|
243
|
-
|
|
244
|
-
For phases other than the four listed above (e.g. `release-handoff`, `final-verification`), ticket tagging is optional.
|
|
51
|
+
6. Specialization Lens (optional, additive only)
|
|
245
52
|
|
|
246
|
-
|
|
53
|
+
Every item has a worker-local ID and file:line evidence where code evidence exists. Sections 1–5 are the common core: feasibility, requirement interpretation, hidden assumptions, alternatives, and execution risk. Section 6 is the only legal home for specialization and is not consensus input.
|
|
247
54
|
|
|
248
|
-
|
|
55
|
+
### Ticket Tagging
|
|
249
56
|
|
|
250
|
-
|
|
251
|
-
**Model:** <Role>, <modelExecutionValue>
|
|
252
|
-
```
|
|
57
|
+
For `requirements-discovery`, `error-analysis`, and `implementation-planning`, tag every section 1–5 item with its related ticket. Use `Issue / Ticket`, fall back to Task ID, then `unknown`; comma-separate multiple tickets.
|
|
253
58
|
|
|
254
|
-
|
|
59
|
+
## Return message to the lead
|
|
255
60
|
|
|
256
|
-
|
|
61
|
+
Begin the inline return with the model identity copied verbatim from the `**Model:** <Role>, <modelExecutionValue>` line in the prompt, followed by the status summary. Never invent or abbreviate the model.
|
|
257
62
|
|
|
258
|
-
|
|
63
|
+
## Writing style
|
|
259
64
|
|
|
260
|
-
|
|
261
|
-
- Do NOT render a technical term as its literal dictionary noun. Use the term a developer actually says:
|
|
262
|
-
- `authoritative` → render it by its domain sense — "the value that takes precedence" / "the canonical value" — never by the bare dictionary noun for "authority".
|
|
263
|
-
- e.g. "overlays this row as authoritative" → phrase it as "overwrites this row as the definitive value", never as a word-for-word "authority" calque.
|
|
264
|
-
- Self-check before emitting any Korean sentence: if it reads like an awkward word-for-word translation, rewrite it by meaning. Confident-but-unreadable direct translation is a defect.
|
|
65
|
+
Translate meaning rather than dictionary words. Keep identifiers, paths, symbols, model names, CLI flags, and status tokens in English. Rewrite awkward word-for-word Korean before returning.
|
|
@@ -123,12 +123,20 @@ if not prompt_relative:
|
|
|
123
123
|
|
|
124
124
|
prompt_path = project_root / prompt_relative
|
|
125
125
|
prompt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
126
|
+
artifacts = task_manifest.get("artifacts", {})
|
|
127
|
+
analysis_packet_path = (
|
|
128
|
+
str(artifacts.get("analysisPacketPath", "")).strip()
|
|
129
|
+
if isinstance(artifacts, dict)
|
|
130
|
+
else ""
|
|
131
|
+
)
|
|
126
132
|
prompt_path.write_text(
|
|
127
133
|
"\n".join(
|
|
128
134
|
[
|
|
129
|
-
|
|
130
|
-
"",
|
|
135
|
+
"**Worker Error Contract Path:** /okstra/templates/worker-error-contract.md",
|
|
131
136
|
f"Assigned worker prompt history path: {prompt_relative}",
|
|
137
|
+
f"- Primary analysis packet: `{analysis_packet_path}`",
|
|
138
|
+
"",
|
|
139
|
+
"# Initial Analysis Prompt",
|
|
132
140
|
f"Task Key: {task_manifest.get('taskKey', '')}",
|
|
133
141
|
"Validation fixture prompt body.",
|
|
134
142
|
]
|
|
@@ -213,17 +221,24 @@ for worker in team_state.get("workers", []):
|
|
|
213
221
|
if prompt_relative and worker_id != omitted_worker_id:
|
|
214
222
|
prompt_path = project_root / prompt_relative
|
|
215
223
|
prompt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
216
|
-
|
|
217
|
-
"
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"Validation fixture prompt body.",
|
|
224
|
-
]
|
|
224
|
+
prompt_lines = [
|
|
225
|
+
"**Worker Error Contract Path:** /okstra/templates/worker-error-contract.md",
|
|
226
|
+
f"Assigned worker prompt history path: {prompt_relative}",
|
|
227
|
+
]
|
|
228
|
+
if worker_id != "report-writer":
|
|
229
|
+
prompt_lines.append(
|
|
230
|
+
f"- Primary analysis packet: `{run_manifest.get('analysisPacketPath', '')}`"
|
|
225
231
|
)
|
|
226
|
-
|
|
232
|
+
prompt_lines.extend([
|
|
233
|
+
"",
|
|
234
|
+
"# Initial Analysis Prompt",
|
|
235
|
+
f"Task Key: {task_manifest.get('taskKey', '')}",
|
|
236
|
+
"Validation fixture prompt body.",
|
|
237
|
+
])
|
|
238
|
+
else:
|
|
239
|
+
prompt_lines.extend(["", "# Report Writer Prompt"])
|
|
240
|
+
prompt_path.write_text(
|
|
241
|
+
"\n".join(prompt_lines) + "\n"
|
|
227
242
|
)
|
|
228
243
|
|
|
229
244
|
result_relative = str(worker.get("resultPath", "")).strip()
|