okstra 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/SKILL.md +12 -3
- package/runtime/agents/workers/claude-worker.md +7 -5
- package/runtime/agents/workers/codex-worker.md +23 -16
- package/runtime/agents/workers/gemini-worker.md +23 -16
- package/runtime/prompts/launch.template.md +15 -0
- package/runtime/prompts/profiles/error-analysis.md +2 -1
- package/runtime/prompts/profiles/final-verification.md +2 -1
- package/runtime/prompts/profiles/implementation-planning.md +2 -1
- package/runtime/prompts/profiles/requirements-discovery.md +2 -1
- package/runtime/python/okstra_ctl/paths.py +16 -0
- package/runtime/python/okstra_ctl/render.py +10 -0
- package/runtime/skills/okstra-team-contract/SKILL.md +18 -3
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
package/runtime/agents/SKILL.md
CHANGED
|
@@ -175,12 +175,21 @@ Spawn **analysis workers only** in the same turn (Phase 4 in Teams mode; Phase 5
|
|
|
175
175
|
|
|
176
176
|
The no-`team_name` fallback (Phase 5) is only legal when team-state's `teamCreate.status` is `"error"` for this run. If `teamCreate` is missing or `attempted: false`, the correct action when an Agent dispatch is rejected for a missing team is to GO BACK to Phase 3 and call `TeamCreate` — never to strip `team_name` and continue.
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
### Errors log path wiring (BLOCKING)
|
|
179
|
+
|
|
180
|
+
The launch prompt's `## Run Logs (error-log wiring)` section gives Lead the resolved absolute paths for the run-level errors log and every per-worker sidecar. When Lead constructs each worker's dispatch prompt body, Lead MUST inject the matching two header lines verbatim:
|
|
181
|
+
|
|
182
|
+
- `**Errors log path:** <absolute run-level errors log path from launch prompt>`
|
|
183
|
+
- `**Errors sidecar path:** <absolute per-worker sidecar path matching the dispatched worker>`
|
|
184
|
+
|
|
185
|
+
Workers are contractually required to extract these two lines and abort with `<WORKER>_ERRORS_PATH_MISSING` if either is absent (see each worker definition's "Path extraction (BLOCKING)" block). Omitting these headers reproduces the historical bug class where every run's `errors-<task-type>-<seq>.jsonl` stayed empty because workers had only template placeholders to work from.
|
|
186
|
+
|
|
187
|
+
After each worker terminates (any terminal status), if its errors sidecar exists, dump it to the run error log using the same resolved paths from the launch prompt:
|
|
179
188
|
|
|
180
189
|
```bash
|
|
181
190
|
python3 scripts/okstra-error-log.py append-from-worker \
|
|
182
|
-
--sidecar <sidecar> \
|
|
183
|
-
--out <
|
|
191
|
+
--sidecar <absolute-sidecar-path-from-launch-prompt> \
|
|
192
|
+
--out <absolute-errors-log-path-from-launch-prompt> \
|
|
184
193
|
--task-key <taskKey> --agent <agent> --agent-role <role> --model <model>
|
|
185
194
|
```
|
|
186
195
|
|
|
@@ -92,13 +92,15 @@ If you find yourself thinking "let me double-check section 3" or "I should read
|
|
|
92
92
|
|
|
93
93
|
This agent is responsible for recording its own tool failures via `scripts/okstra-error-log.py`:
|
|
94
94
|
|
|
95
|
-
**
|
|
95
|
+
**Path extraction (BLOCKING).** Before recording anything, extract the absolute sidecar path from the lead's dispatch prompt body:
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
runs/<task-type>/worker-results/claude-worker-errors-<task-type>-<seq>.json
|
|
99
|
-
```
|
|
97
|
+
- `**Errors sidecar path:** <abs-path>` — this worker's per-run sidecar JSON.
|
|
100
98
|
|
|
101
|
-
|
|
99
|
+
If the header line is absent from the dispatch prompt, return `CLAUDE_WORKER_ERRORS_PATH_MISSING: lead prompt did not include **Errors sidecar path:** header` without proceeding. Do NOT synthesize the path from `runs/<task-type>/...` — that template syntax is documentation only and historically led to silent log loss.
|
|
100
|
+
|
|
101
|
+
**Tool failure (worker-reported)** — if `Write` of the prompt history file, `mkdir`, any MCP call, or any other pre-/in-analysis tool call fails (non-zero exit, exception, or empty result where data was required), append a `tool-failure` entry to the worker errors sidecar at the absolute path extracted from the `**Errors sidecar path:**` header. If the file does not exist, create it with `{"schemaVersion": 1, "errors": []}` then append.
|
|
102
|
+
|
|
103
|
+
The sidecar follows the schema in `skills/okstra-team-contract/SKILL.md` (Optional errors sidecar). Lead will dump it to the run error log after this subagent terminates.
|
|
102
104
|
|
|
103
105
|
There is NO `cli-failure` category for this worker — Claude worker has no external CLI to invoke. Treat MCP errors and Bash errors uniformly as `tool-failure`.
|
|
104
106
|
|
|
@@ -148,19 +148,26 @@ This contract mirrors the `okstra-team-contract` skill's Worker Output Contract
|
|
|
148
148
|
The wrapper agent (this Codex worker subagent) is responsible for recording
|
|
149
149
|
two kinds of errors via `scripts/okstra-error-log.py`:
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
`tool-failure` entry to the worker errors sidecar at:
|
|
151
|
+
**Path extraction (BLOCKING).** Before recording anything, extract the
|
|
152
|
+
following two absolute paths verbatim from the lead's dispatch prompt body:
|
|
154
153
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
```
|
|
154
|
+
- `**Errors log path:** <abs-path>` — the run-level errors JSONL.
|
|
155
|
+
- `**Errors sidecar path:** <abs-path>` — this worker's per-run sidecar JSON.
|
|
158
156
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
If either header line is absent from the dispatch prompt, return
|
|
158
|
+
`CODEX_ERRORS_PATH_MISSING: lead prompt did not include **Errors log path:** / **Errors sidecar path:** headers`
|
|
159
|
+
without proceeding. Do NOT synthesize the path from `<runDir>/logs/...` —
|
|
160
|
+
historical bug class: workers writing to a literally-named template path
|
|
161
|
+
and the run-level error log staying empty.
|
|
162
|
+
|
|
163
|
+
1. **Wrapper-internal tool failure (worker-reported)** — if `Write` of the
|
|
164
|
+
prompt history file, `mkdir`, or any pre-CLI tool call fails, append a
|
|
165
|
+
`tool-failure` entry to the worker errors sidecar at the absolute path
|
|
166
|
+
extracted from the `**Errors sidecar path:**` header. If the file does
|
|
167
|
+
not exist, create it with `{"schemaVersion": 1, "errors": []}` then
|
|
168
|
+
append. The sidecar follows the schema in
|
|
169
|
+
`skills/okstra-team-contract/SKILL.md` (Optional errors sidecar). Lead
|
|
170
|
+
will dump it to the run error log after this subagent terminates.
|
|
164
171
|
|
|
165
172
|
2. **CLI failure (lead-observed)** — if the wrapper's final `BashOutput`
|
|
166
173
|
reports a non-zero `exit_code`, the 30-minute polling cap is hit, or the
|
|
@@ -171,7 +178,7 @@ two kinds of errors via `scripts/okstra-error-log.py`:
|
|
|
171
178
|
|
|
172
179
|
```bash
|
|
173
180
|
python3 scripts/okstra-error-log.py append-observed \
|
|
174
|
-
--out "<
|
|
181
|
+
--out "<absolute-errors-log-path-from-lead-prompt>" \
|
|
175
182
|
--task-key "<task-key>" \
|
|
176
183
|
--phase "<phase>" \
|
|
177
184
|
--agent codex-worker --agent-role worker \
|
|
@@ -184,10 +191,10 @@ two kinds of errors via `scripts/okstra-error-log.py`:
|
|
|
184
191
|
--stderr-excerpt-file "<captured-stderr-path or omit>"
|
|
185
192
|
```
|
|
186
193
|
|
|
187
|
-
The lead prompt provides
|
|
188
|
-
the prompt history path. If any of these are
|
|
189
|
-
to the worker errors sidecar instead —
|
|
190
|
-
failure.
|
|
194
|
+
The lead prompt provides `**Errors log path:**`, `<task-key>`, and
|
|
195
|
+
`<phase>` alongside the prompt history path. If any of these are
|
|
196
|
+
missing, fall back to logging to the worker errors sidecar instead —
|
|
197
|
+
never silently swallow a CLI failure.
|
|
191
198
|
|
|
192
199
|
Do not record a `cli-failure` for `CODEX_NOT_INSTALLED` returns — that is a
|
|
193
200
|
pre-flight terminal status, not a runtime CLI error.
|
|
@@ -148,19 +148,26 @@ This contract mirrors the `okstra-team-contract` skill's Worker Output Contract
|
|
|
148
148
|
The wrapper agent (this Gemini worker subagent) is responsible for recording
|
|
149
149
|
two kinds of errors via `scripts/okstra-error-log.py`:
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
`tool-failure` entry to the worker errors sidecar at:
|
|
151
|
+
**Path extraction (BLOCKING).** Before recording anything, extract the
|
|
152
|
+
following two absolute paths verbatim from the lead's dispatch prompt body:
|
|
154
153
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
```
|
|
154
|
+
- `**Errors log path:** <abs-path>` — the run-level errors JSONL.
|
|
155
|
+
- `**Errors sidecar path:** <abs-path>` — this worker's per-run sidecar JSON.
|
|
158
156
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
If either header line is absent from the dispatch prompt, return
|
|
158
|
+
`GEMINI_ERRORS_PATH_MISSING: lead prompt did not include **Errors log path:** / **Errors sidecar path:** headers`
|
|
159
|
+
without proceeding. Do NOT synthesize the path from `<runDir>/logs/...` —
|
|
160
|
+
historical bug class: workers writing to a literally-named template path
|
|
161
|
+
and the run-level error log staying empty.
|
|
162
|
+
|
|
163
|
+
1. **Wrapper-internal tool failure (worker-reported)** — if `Write` of the
|
|
164
|
+
prompt history file, `mkdir`, or any pre-CLI tool call fails, append a
|
|
165
|
+
`tool-failure` entry to the worker errors sidecar at the absolute path
|
|
166
|
+
extracted from the `**Errors sidecar path:**` header. If the file does
|
|
167
|
+
not exist, create it with `{"schemaVersion": 1, "errors": []}` then
|
|
168
|
+
append. The sidecar follows the schema in
|
|
169
|
+
`skills/okstra-team-contract/SKILL.md` (Optional errors sidecar). Lead
|
|
170
|
+
will dump it to the run error log after this subagent terminates.
|
|
164
171
|
|
|
165
172
|
2. **CLI failure (lead-observed)** — if the wrapper's final `BashOutput`
|
|
166
173
|
reports a non-zero `exit_code`, the 30-minute polling cap is hit, or the
|
|
@@ -171,7 +178,7 @@ two kinds of errors via `scripts/okstra-error-log.py`:
|
|
|
171
178
|
|
|
172
179
|
```bash
|
|
173
180
|
python3 scripts/okstra-error-log.py append-observed \
|
|
174
|
-
--out "<
|
|
181
|
+
--out "<absolute-errors-log-path-from-lead-prompt>" \
|
|
175
182
|
--task-key "<task-key>" \
|
|
176
183
|
--phase "<phase>" \
|
|
177
184
|
--agent gemini-worker --agent-role worker \
|
|
@@ -184,10 +191,10 @@ two kinds of errors via `scripts/okstra-error-log.py`:
|
|
|
184
191
|
--stderr-excerpt-file "<captured-stderr-path or omit>"
|
|
185
192
|
```
|
|
186
193
|
|
|
187
|
-
The lead prompt provides
|
|
188
|
-
the prompt history path. If any of these are
|
|
189
|
-
to the worker errors sidecar instead —
|
|
190
|
-
failure.
|
|
194
|
+
The lead prompt provides `**Errors log path:**`, `<task-key>`, and
|
|
195
|
+
`<phase>` alongside the prompt history path. If any of these are
|
|
196
|
+
missing, fall back to logging to the worker errors sidecar instead —
|
|
197
|
+
never silently swallow a CLI failure.
|
|
191
198
|
|
|
192
199
|
Do not record a `cli-failure` for `GEMINI_NOT_INSTALLED` returns — that is a
|
|
193
200
|
pre-flight terminal status, not a runtime CLI error.
|
|
@@ -46,6 +46,21 @@ Invoke the `okstra` skill now. Read the manifests below for all task metadata, p
|
|
|
46
46
|
- Final status: `{{FINAL_STATUS_RELATIVE_PATH}}`
|
|
47
47
|
- Validator: `{{RUN_VALIDATOR_RELATIVE_PATH}}`
|
|
48
48
|
|
|
49
|
+
## Run Logs (error-log wiring)
|
|
50
|
+
|
|
51
|
+
- Run-level errors log (absolute): `{{RUN_ERRORS_LOG_PATH}}`
|
|
52
|
+
- Run-level errors log (relative): `{{RUN_ERRORS_LOG_RELATIVE_PATH}}`
|
|
53
|
+
- Worker error sidecars (absolute):
|
|
54
|
+
- Claude worker: `{{CLAUDE_WORKER_ERRORS_SIDECAR_PATH}}`
|
|
55
|
+
- Codex worker: `{{CODEX_WORKER_ERRORS_SIDECAR_PATH}}`
|
|
56
|
+
- Gemini worker: `{{GEMINI_WORKER_ERRORS_SIDECAR_PATH}}`
|
|
57
|
+
- Report writer worker: `{{REPORT_WRITER_WORKER_ERRORS_SIDECAR_PATH}}`
|
|
58
|
+
- When dispatching any worker you MUST inject **two header lines** into the dispatch prompt body so the worker subagent can record errors without guessing paths:
|
|
59
|
+
- `**Errors log path:** <absolute run-level errors log path>`
|
|
60
|
+
- `**Errors sidecar path:** <absolute per-worker sidecar path matching the dispatched worker>`
|
|
61
|
+
- These lines are the canonical contract — worker subagents extract them verbatim and pass them to `okstra-error-log.py append-observed --out ...` (run-level cli-failure / contract-violation events) and to their internal sidecar writes (worker-reported tool-failure events) respectively.
|
|
62
|
+
- After each worker terminates, dump its sidecar into the run-level errors log via `python3 scripts/okstra-error-log.py append-from-worker --sidecar <sidecar-path> --out <run-errors-log-path> --task-key {{TASK_KEY}} --agent <worker-id> --agent-role worker --model <assigned-model-execution-value>` (per `okstra-team-contract` Worker Output Contract).
|
|
63
|
+
|
|
49
64
|
## Executor Worktree
|
|
50
65
|
|
|
51
66
|
- Status: `{{EXECUTOR_WORKTREE_STATUS}}`
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
- Required workers:
|
|
5
5
|
- claude
|
|
6
6
|
- codex
|
|
7
|
-
- gemini
|
|
8
7
|
- report-writer
|
|
8
|
+
- Optional workers (opt-in via `--workers`):
|
|
9
|
+
- gemini — when added to the roster it joins the analyser set; omitted by default
|
|
9
10
|
{{INCLUDE:_common-contract.md}}
|
|
10
11
|
- Primary focus areas:
|
|
11
12
|
- symptom and trigger clarification
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
- Required workers:
|
|
5
5
|
- claude
|
|
6
6
|
- codex
|
|
7
|
-
- gemini
|
|
8
7
|
- report-writer
|
|
8
|
+
- Optional workers (opt-in via `--workers`):
|
|
9
|
+
- gemini — when added to the roster it joins the analyser set; omitted by default
|
|
9
10
|
{{INCLUDE:_common-contract.md}}
|
|
10
11
|
- Primary focus areas:
|
|
11
12
|
- requirement coverage
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
- Required workers:
|
|
5
5
|
- claude
|
|
6
6
|
- codex
|
|
7
|
-
- gemini
|
|
8
7
|
- report-writer
|
|
8
|
+
- Optional workers (opt-in via `--workers`):
|
|
9
|
+
- gemini — when added to the roster it joins the analyser set; omitted by default
|
|
9
10
|
{{INCLUDE:_common-contract.md}}
|
|
10
11
|
- Pre-planning context exploration (mandatory before option drafting):
|
|
11
12
|
- read the task brief, related-task briefs, and any cited spec / design doc end-to-end
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
- Required workers:
|
|
5
5
|
- claude
|
|
6
6
|
- codex
|
|
7
|
-
- gemini
|
|
8
7
|
- report-writer
|
|
8
|
+
- Optional workers (opt-in via `--workers`):
|
|
9
|
+
- gemini — when added to the roster it joins the analyser set; omitted by default
|
|
9
10
|
{{INCLUDE:_common-contract.md}}
|
|
10
11
|
- Primary focus areas:
|
|
11
12
|
- classify the work as bugfix, feature, improvement, refactor, or ops-change
|
|
@@ -143,6 +143,12 @@ def compute_run_paths(
|
|
|
143
143
|
gemini_worker_result = worker_results / f"gemini-worker{suffixes['worker_results']}.md"
|
|
144
144
|
report_writer_worker_result = worker_results / f"report-writer-worker{suffixes['worker_results']}.md"
|
|
145
145
|
|
|
146
|
+
run_errors_log = run_logs / f"errors-{task_type_segment}-{seqs['state']}.jsonl"
|
|
147
|
+
claude_worker_errors_sidecar = worker_results / f"claude-worker-errors{suffixes['worker_results']}.json"
|
|
148
|
+
codex_worker_errors_sidecar = worker_results / f"codex-worker-errors{suffixes['worker_results']}.json"
|
|
149
|
+
gemini_worker_errors_sidecar = worker_results / f"gemini-worker-errors{suffixes['worker_results']}.json"
|
|
150
|
+
report_writer_worker_errors_sidecar = worker_results / f"report-writer-worker-errors{suffixes['worker_results']}.json"
|
|
151
|
+
|
|
146
152
|
run_validator_script = workspace_root / "validators" / "validate-run.py"
|
|
147
153
|
|
|
148
154
|
abs_paths = {
|
|
@@ -193,6 +199,11 @@ def compute_run_paths(
|
|
|
193
199
|
"CODEX_WORKER_RESULT_FILE": str(codex_worker_result),
|
|
194
200
|
"GEMINI_WORKER_RESULT_FILE": str(gemini_worker_result),
|
|
195
201
|
"REPORT_WRITER_WORKER_RESULT_FILE": str(report_writer_worker_result),
|
|
202
|
+
"RUN_ERRORS_LOG_FILE": str(run_errors_log),
|
|
203
|
+
"CLAUDE_WORKER_ERRORS_SIDECAR_FILE": str(claude_worker_errors_sidecar),
|
|
204
|
+
"CODEX_WORKER_ERRORS_SIDECAR_FILE": str(codex_worker_errors_sidecar),
|
|
205
|
+
"GEMINI_WORKER_ERRORS_SIDECAR_FILE": str(gemini_worker_errors_sidecar),
|
|
206
|
+
"REPORT_WRITER_WORKER_ERRORS_SIDECAR_FILE": str(report_writer_worker_errors_sidecar),
|
|
196
207
|
"RUN_VALIDATOR_SCRIPT": str(run_validator_script),
|
|
197
208
|
"RUN_MANIFEST_FILENAME": run_manifest_file.name,
|
|
198
209
|
"RUN_PROMPT_SNAPSHOT_FILENAME": run_prompt_snapshot.name,
|
|
@@ -245,6 +256,11 @@ def compute_run_paths(
|
|
|
245
256
|
("CODEX_WORKER_RESULT_RELATIVE_PATH", codex_worker_result),
|
|
246
257
|
("GEMINI_WORKER_RESULT_RELATIVE_PATH", gemini_worker_result),
|
|
247
258
|
("REPORT_WRITER_WORKER_RESULT_RELATIVE_PATH", report_writer_worker_result),
|
|
259
|
+
("RUN_ERRORS_LOG_RELATIVE_PATH", run_errors_log),
|
|
260
|
+
("CLAUDE_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", claude_worker_errors_sidecar),
|
|
261
|
+
("CODEX_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", codex_worker_errors_sidecar),
|
|
262
|
+
("GEMINI_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", gemini_worker_errors_sidecar),
|
|
263
|
+
("REPORT_WRITER_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", report_writer_worker_errors_sidecar),
|
|
248
264
|
("LATEST_RUN_RELATIVE_PATH", run_dir),
|
|
249
265
|
]
|
|
250
266
|
rel_paths = {key: _rel(project_root, target) for key, target in rel_pairs}
|
|
@@ -1078,6 +1078,16 @@ def render_template_file(template_path: str, output_path: str, ctx: dict) -> Non
|
|
|
1078
1078
|
"{{CODEX_WORKER_RESULT_RELATIVE_PATH}}": ctx.get("CODEX_WORKER_RESULT_RELATIVE_PATH", ""),
|
|
1079
1079
|
"{{GEMINI_WORKER_RESULT_RELATIVE_PATH}}": ctx.get("GEMINI_WORKER_RESULT_RELATIVE_PATH", ""),
|
|
1080
1080
|
"{{REPORT_WRITER_WORKER_RESULT_RELATIVE_PATH}}": ctx.get("REPORT_WRITER_WORKER_RESULT_RELATIVE_PATH", ""),
|
|
1081
|
+
"{{RUN_ERRORS_LOG_PATH}}": ctx.get("RUN_ERRORS_LOG_FILE", ""),
|
|
1082
|
+
"{{RUN_ERRORS_LOG_RELATIVE_PATH}}": ctx.get("RUN_ERRORS_LOG_RELATIVE_PATH", ""),
|
|
1083
|
+
"{{CLAUDE_WORKER_ERRORS_SIDECAR_PATH}}": ctx.get("CLAUDE_WORKER_ERRORS_SIDECAR_FILE", ""),
|
|
1084
|
+
"{{CLAUDE_WORKER_ERRORS_SIDECAR_RELATIVE_PATH}}": ctx.get("CLAUDE_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", ""),
|
|
1085
|
+
"{{CODEX_WORKER_ERRORS_SIDECAR_PATH}}": ctx.get("CODEX_WORKER_ERRORS_SIDECAR_FILE", ""),
|
|
1086
|
+
"{{CODEX_WORKER_ERRORS_SIDECAR_RELATIVE_PATH}}": ctx.get("CODEX_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", ""),
|
|
1087
|
+
"{{GEMINI_WORKER_ERRORS_SIDECAR_PATH}}": ctx.get("GEMINI_WORKER_ERRORS_SIDECAR_FILE", ""),
|
|
1088
|
+
"{{GEMINI_WORKER_ERRORS_SIDECAR_RELATIVE_PATH}}": ctx.get("GEMINI_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", ""),
|
|
1089
|
+
"{{REPORT_WRITER_WORKER_ERRORS_SIDECAR_PATH}}": ctx.get("REPORT_WRITER_WORKER_ERRORS_SIDECAR_FILE", ""),
|
|
1090
|
+
"{{REPORT_WRITER_WORKER_ERRORS_SIDECAR_RELATIVE_PATH}}": ctx.get("REPORT_WRITER_WORKER_ERRORS_SIDECAR_RELATIVE_PATH", ""),
|
|
1081
1091
|
"{{LEAD_MODEL}}": lead_model,
|
|
1082
1092
|
"{{LEAD_MODEL_EXECUTION_VALUE}}": lead_model_execution,
|
|
1083
1093
|
"{{CLAUDE_WORKER_MODEL}}": ctx.get("CLAUDE_WORKER_MODEL_DISPLAY", ""),
|
|
@@ -263,12 +263,27 @@ Schema:
|
|
|
263
263
|
```
|
|
264
264
|
|
|
265
265
|
Workers MUST omit `source` / `recordedAt` / `agent` / `agentRole` / `model` /
|
|
266
|
-
`taskKey`. Claude lead fills those in when dumping the sidecar to
|
|
267
|
-
`runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl`
|
|
268
|
-
`scripts/okstra-error-log.py append-from-worker`.
|
|
266
|
+
`taskKey`. Claude lead fills those in when dumping the sidecar to the
|
|
267
|
+
run-level errors log (`runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl`)
|
|
268
|
+
via `scripts/okstra-error-log.py append-from-worker`.
|
|
269
269
|
|
|
270
270
|
Workers MUST use only `errorType: "tool-failure"` in the **sidecar file**.
|
|
271
271
|
|
|
272
|
+
**Path delivery contract (BLOCKING).** Workers do NOT synthesize the
|
|
273
|
+
run-level errors log path or their sidecar path from the
|
|
274
|
+
`runs/<task-type>/...` template syntax. Both absolute paths are delivered
|
|
275
|
+
by Lead via two dispatch-prompt header lines:
|
|
276
|
+
|
|
277
|
+
- `**Errors log path:** <absolute path>` — run-level JSONL (`okstra-error-log.py append-observed --out ...`)
|
|
278
|
+
- `**Errors sidecar path:** <absolute path>` — per-worker JSON (`{ "schemaVersion": 1, "errors": [...] }`)
|
|
279
|
+
|
|
280
|
+
Lead obtains both paths from the launch prompt's `## Run Logs (error-log
|
|
281
|
+
wiring)` section (resolved by the okstra runtime via `paths.py`). If Lead
|
|
282
|
+
omits either header, the worker MUST return `<WORKER>_ERRORS_PATH_MISSING`
|
|
283
|
+
without proceeding — this is the contractual replacement for the previous
|
|
284
|
+
"derive from template placeholders" behavior, which silently produced
|
|
285
|
+
empty run-level error logs in production.
|
|
286
|
+
|
|
272
287
|
- `cli-failure` events are recorded by the wrapper subagent itself (Codex / Gemini), but **directly to the run-level error log** via `okstra-error-log.py append-observed --error-type cli-failure ...` — NOT via the sidecar. The sidecar is an in-process tool-failure channel only.
|
|
273
288
|
- **Wrapper invocation arity.** Both `okstra-codex-exec.sh` and `okstra-gemini-exec.sh` accept four positional arguments: `<project-root> <model> <prompt-path> [<worktree-path>]`. The fourth (worktree) argument is **mandatory for implementation phase** and optional otherwise. For codex it becomes `--add-dir <worktree>` (sandbox write access); for gemini it is appended to `--include-directories`. Omitting it during implementation causes the codex sandbox to reject every Edit/Write targeting the worktree with EPERM. Workers extract the path from the `**Worktree:**` / `EXECUTOR_WORKTREE_PATH` / `cwd for every mutating command:` line in the lead prompt.
|
|
274
289
|
- **Background dispatch + polling contract (Codex / Gemini wrappers).** Both wrapper subagents MUST dispatch `okstra-codex-exec.sh` / `okstra-gemini-exec.sh` via `Bash(run_in_background: true)` and poll with `BashOutput(bash_id)` on a 60-second cadence, capped at 30 minutes (1800s). The legacy "single foreground `Bash` with 120000ms timeout" rule is retired — it forced workers into ad-hoc background dispatch that lost stdout and silently broke Phase 5 synthesis. The new rule applies in **every phase** (analysis runs typically complete in 1–2 polls, so there is no regression for short jobs). Recording responsibilities:
|