okstra 0.82.1 → 0.83.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.kr.md +7 -6
- package/README.md +6 -6
- package/docs/kr/architecture.md +8 -7
- package/docs/kr/cli.md +2 -2
- package/docs/kr/performance-improvement-plan-v2.md +14 -14
- package/docs/project-structure-overview.md +7 -8
- package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +504 -0
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +342 -0
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +258 -0
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +387 -0
- package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +749 -0
- package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +828 -0
- package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +490 -0
- package/docs/task-process/README.md +1 -1
- package/docs/task-process/error-analysis.md +1 -1
- package/docs/task-process/final-verification.md +1 -1
- package/docs/task-process/implementation-planning.md +1 -1
- package/docs/task-process/implementation.md +1 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/docs/task-process/requirements-discovery.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/TODO.md +2 -0
- package/runtime/agents/workers/claude-worker.md +8 -8
- package/runtime/agents/workers/codex-worker.md +8 -8
- package/runtime/agents/workers/gemini-worker.md +8 -8
- package/runtime/agents/workers/report-writer-worker.md +2 -2
- package/runtime/bin/lib/okstra/globals.sh +0 -1
- package/runtime/bin/okstra-wrapper-status.py +1 -1
- package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/languages/python.md +2 -2
- package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/languages/rust.md +1 -1
- package/runtime/{skills/okstra-coding-preflight/SKILL.md → prompts/coding-preflight/overview.md} +27 -38
- package/runtime/prompts/launch.template.md +5 -3
- package/runtime/{skills/okstra-context-loader/SKILL.md → prompts/lead/context-loader.md} +7 -14
- package/runtime/{skills/okstra-convergence/SKILL.md → prompts/lead/convergence.md} +12 -19
- package/runtime/{agents/SKILL.md → prompts/lead/okstra-lead-contract.md} +53 -59
- package/runtime/{skills/okstra-report-writer/SKILL.md → prompts/lead/report-writer.md} +12 -19
- package/runtime/{skills/okstra-team-contract/SKILL.md → prompts/lead/team-contract.md} +13 -19
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +2 -2
- package/runtime/prompts/profiles/_common-contract.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +2 -2
- package/runtime/prompts/profiles/_implementation-verifier.md +2 -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 +4 -4
- package/runtime/prompts/profiles/requirements-discovery.md +2 -2
- package/runtime/python/okstra_ctl/codex_dispatch.py +12 -61
- package/runtime/python/okstra_ctl/context_cost.py +14 -11
- package/runtime/python/okstra_ctl/dispatch_core.py +36 -13
- package/runtime/python/okstra_ctl/paths.py +27 -1
- package/runtime/python/okstra_ctl/render.py +62 -8
- package/runtime/python/okstra_ctl/run.py +5 -5
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +126 -0
- package/runtime/python/okstra_token_usage/claude.py +1 -1
- package/runtime/python/okstra_token_usage/collect.py +1 -1
- package/runtime/templates/reports/task-brief.template.md +2 -2
- package/runtime/templates/worker-prompt-preamble.md +2 -2
- package/runtime/validators/lib/validate-assets.sh +12 -4
- package/runtime/validators/validate-run.py +3 -3
- package/runtime/validators/validate_session_conformance.py +11 -11
- package/src/install.mjs +95 -81
- package/src/skill-catalog.mjs +35 -0
- package/src/uninstall.mjs +5 -0
- /package/runtime/{skills/okstra-coding-preflight/architecture → prompts/coding-preflight/architectures}/hexagonal.md +0 -0
- /package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/clean-code.md +0 -0
- /package/runtime/{skills/okstra-coding-preflight/languages/nodejs.md → prompts/coding-preflight/frameworks/node-server.md} +0 -0
- /package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/languages/java.md +0 -0
- /package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/languages/javascript-typescript.md +0 -0
- /package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/languages/kotlin.md +0 -0
- /package/runtime/{skills/okstra-coding-preflight → prompts/coding-preflight}/languages/sql.md +0 -0
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
# Worker Prompt Header Error Contract Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Make worker prompt header rendering failures surface through dispatcher-native `DispatchError` boundaries instead of leaking helper-local exception types or tracebacks.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Keep `worker_prompt_headers.py` as the single renderer for the eight team-contract anchor headers, but give it a domain-specific exception type. Each dispatcher boundary (`codex_dispatch.py`, `dispatch_core.py`) converts that shared exception into its own public `DispatchError`, preserving existing CLI/error contracts. No graphify/plugin refresh work is included; the user explicitly excluded that external-plugin failure.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python 3.11+, `pytest`, existing Okstra dispatcher modules under `scripts/okstra_ctl/`, npm build/check wrappers.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Current Evidence
|
|
14
|
+
|
|
15
|
+
- `scripts/okstra_ctl/worker_prompt_headers.py` renders the worker anchor headers in one shared helper.
|
|
16
|
+
- The helper currently raises raw `ValueError` from `_run_seq()` and `_require_string()` when required manifest fields are missing.
|
|
17
|
+
- `scripts/okstra_ctl/codex_dispatch.py` catches only its local `DispatchError` in `main()`, so a malformed manifest can bypass the clean CLI error path.
|
|
18
|
+
- `scripts/okstra_ctl/dispatch_core.py` already uses local `DispatchError` for malformed dispatch inputs, but `_materialize_prompt_if_missing()` delegates directly to `worker_prompt_headers()` without wrapping helper failures.
|
|
19
|
+
- The only remaining issue in scope is this exception-boundary gap. The graphify update failure is intentionally out of scope.
|
|
20
|
+
|
|
21
|
+
## File Structure
|
|
22
|
+
|
|
23
|
+
- Modify: `scripts/okstra_ctl/worker_prompt_headers.py`
|
|
24
|
+
- Responsibility: render deterministic worker prompt anchor headers.
|
|
25
|
+
- Add: `WorkerPromptHeaderError` for malformed manifest/context input.
|
|
26
|
+
- Change: `_run_seq()` and `_require_string()` raise `WorkerPromptHeaderError`.
|
|
27
|
+
|
|
28
|
+
- Modify: `scripts/okstra_ctl/codex_dispatch.py`
|
|
29
|
+
- Responsibility: Codex CLI-wrapper dispatch boundary.
|
|
30
|
+
- Change: import `WorkerPromptHeaderError` and convert it to Codex-local `DispatchError` in `_base_prompt_headers()`.
|
|
31
|
+
|
|
32
|
+
- Modify: `scripts/okstra_ctl/dispatch_core.py`
|
|
33
|
+
- Responsibility: backend-neutral deterministic worker dispatch.
|
|
34
|
+
- Change: import `WorkerPromptHeaderError` and convert it to dispatch-core-local `DispatchError` in `_materialize_prompt_if_missing()`.
|
|
35
|
+
|
|
36
|
+
- Modify: `tests/test_worker_prompt_headers.py`
|
|
37
|
+
- Responsibility: shared header renderer regression tests.
|
|
38
|
+
- Add: helper raises `WorkerPromptHeaderError` for malformed fallback manifest input.
|
|
39
|
+
|
|
40
|
+
- Modify: `tests/test_codex_dispatch.py`
|
|
41
|
+
- Responsibility: Codex dispatcher regression tests.
|
|
42
|
+
- Add: `_base_prompt_headers()` wraps shared header errors as Codex `DispatchError`.
|
|
43
|
+
|
|
44
|
+
- Modify: `tests/test_dispatch_core.py`
|
|
45
|
+
- Responsibility: backend-neutral dispatcher regression tests.
|
|
46
|
+
- Add: `_materialize_prompt_if_missing()` wraps shared header errors as dispatch-core `DispatchError` and does not create a prompt file on failure.
|
|
47
|
+
|
|
48
|
+
- Modify: `CHANGES.md`
|
|
49
|
+
- Responsibility: user-visible behavior log.
|
|
50
|
+
- Add: clean dispatcher error behavior entry under `2026-06-15` after the current dispatch entry.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Task 1: Add Shared Header Error Type
|
|
55
|
+
|
|
56
|
+
**Files:**
|
|
57
|
+
- Modify: `scripts/okstra_ctl/worker_prompt_headers.py`
|
|
58
|
+
- Test: `tests/test_worker_prompt_headers.py`
|
|
59
|
+
|
|
60
|
+
- [ ] **Step 1: Write the failing helper regression test**
|
|
61
|
+
|
|
62
|
+
Add `pytest` to the test imports and import the new exception type:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import pytest
|
|
66
|
+
|
|
67
|
+
from okstra_ctl.worker_prompt_headers import ( # noqa: E402
|
|
68
|
+
WorkerPromptHeaderError,
|
|
69
|
+
worker_prompt_headers,
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Append this test to `tests/test_worker_prompt_headers.py`:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
def test_worker_prompt_headers_raise_contract_error_for_missing_manifest_fields(
|
|
77
|
+
tmp_path: Path,
|
|
78
|
+
) -> None:
|
|
79
|
+
with pytest.raises(WorkerPromptHeaderError, match="teamStatePath"):
|
|
80
|
+
worker_prompt_headers(
|
|
81
|
+
project_root=tmp_path / "project",
|
|
82
|
+
prompt_rel=".okstra/run/prompts/codex.md",
|
|
83
|
+
result_rel=".okstra/run/worker-results/codex.md",
|
|
84
|
+
worker_id="codex",
|
|
85
|
+
manifest={},
|
|
86
|
+
active_context={},
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- [ ] **Step 2: Run the helper test and verify it fails for the intended reason**
|
|
91
|
+
|
|
92
|
+
Run:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python3 -m pytest tests/test_worker_prompt_headers.py::test_worker_prompt_headers_raise_contract_error_for_missing_manifest_fields -q
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Expected: FAIL because `WorkerPromptHeaderError` is not importable yet, or because the helper still raises `ValueError`.
|
|
99
|
+
|
|
100
|
+
- [ ] **Step 3: Implement `WorkerPromptHeaderError` in the shared helper**
|
|
101
|
+
|
|
102
|
+
In `scripts/okstra_ctl/worker_prompt_headers.py`, add this class after the imports:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
class WorkerPromptHeaderError(Exception):
|
|
106
|
+
"""Raised when worker prompt anchor headers cannot be rendered."""
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Replace `_run_seq()` with:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
def _run_seq(manifest: Mapping[str, Any]) -> str:
|
|
113
|
+
seqs = manifest.get("runSequencesByCategory")
|
|
114
|
+
if not isinstance(seqs, Mapping):
|
|
115
|
+
raise WorkerPromptHeaderError("run manifest has no runSequencesByCategory object")
|
|
116
|
+
return _require_string(seqs, "manifests")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Replace `_require_string()` with:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
def _require_string(payload: Mapping[str, Any], key: str) -> str:
|
|
123
|
+
value = payload.get(key)
|
|
124
|
+
if not isinstance(value, str) or not value.strip():
|
|
125
|
+
raise WorkerPromptHeaderError(f"missing required string field: {key}")
|
|
126
|
+
return value
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- [ ] **Step 4: Run the helper regression test and verify it passes**
|
|
130
|
+
|
|
131
|
+
Run:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
python3 -m pytest tests/test_worker_prompt_headers.py::test_worker_prompt_headers_raise_contract_error_for_missing_manifest_fields -q
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Expected: PASS.
|
|
138
|
+
|
|
139
|
+
- [ ] **Step 5: Run all shared helper tests**
|
|
140
|
+
|
|
141
|
+
Run:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
python3 -m pytest tests/test_worker_prompt_headers.py -q
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Expected: PASS for all tests in `tests/test_worker_prompt_headers.py`.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### Task 2: Wrap Codex Dispatcher Header Errors
|
|
152
|
+
|
|
153
|
+
**Files:**
|
|
154
|
+
- Modify: `scripts/okstra_ctl/codex_dispatch.py`
|
|
155
|
+
- Test: `tests/test_codex_dispatch.py`
|
|
156
|
+
|
|
157
|
+
- [ ] **Step 1: Write the failing Codex boundary regression test**
|
|
158
|
+
|
|
159
|
+
Extend the `tests/test_codex_dispatch.py` import from `okstra_ctl.codex_dispatch` to include `_base_prompt_headers`:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from okstra_ctl.codex_dispatch import ( # noqa: E402
|
|
163
|
+
DispatchError,
|
|
164
|
+
_base_prompt_headers,
|
|
165
|
+
build_dispatch_plan,
|
|
166
|
+
dispatch_plan,
|
|
167
|
+
)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Append this test near the other prompt-generation tests:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
def test_base_prompt_headers_wraps_worker_header_errors() -> None:
|
|
174
|
+
with pytest.raises(DispatchError, match="teamStatePath"):
|
|
175
|
+
_base_prompt_headers(
|
|
176
|
+
project_root=Path("/project"),
|
|
177
|
+
manifest={},
|
|
178
|
+
active_context={},
|
|
179
|
+
worker_id="codex",
|
|
180
|
+
prompt_rel=".okstra/run/prompts/codex.md",
|
|
181
|
+
result_rel=".okstra/run/worker-results/codex.md",
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- [ ] **Step 2: Run the Codex regression test and verify it fails for the intended reason**
|
|
186
|
+
|
|
187
|
+
Run:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python3 -m pytest tests/test_codex_dispatch.py::test_base_prompt_headers_wraps_worker_header_errors -q
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Expected: FAIL because `_base_prompt_headers()` raises `WorkerPromptHeaderError` instead of Codex `DispatchError`.
|
|
194
|
+
|
|
195
|
+
- [ ] **Step 3: Convert shared header errors to Codex `DispatchError`**
|
|
196
|
+
|
|
197
|
+
In `scripts/okstra_ctl/codex_dispatch.py`, replace the worker header import with:
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from .worker_prompt_headers import WorkerPromptHeaderError, worker_prompt_headers
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Replace `_base_prompt_headers()` with:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
def _base_prompt_headers(
|
|
207
|
+
*,
|
|
208
|
+
project_root: Path,
|
|
209
|
+
manifest: Mapping[str, Any],
|
|
210
|
+
active_context: Mapping[str, Any],
|
|
211
|
+
worker_id: str,
|
|
212
|
+
prompt_rel: str,
|
|
213
|
+
result_rel: str,
|
|
214
|
+
) -> list[str]:
|
|
215
|
+
try:
|
|
216
|
+
return worker_prompt_headers(
|
|
217
|
+
project_root=project_root,
|
|
218
|
+
prompt_rel=prompt_rel,
|
|
219
|
+
result_rel=result_rel,
|
|
220
|
+
worker_id=worker_id,
|
|
221
|
+
manifest=manifest,
|
|
222
|
+
active_context=active_context,
|
|
223
|
+
)
|
|
224
|
+
except WorkerPromptHeaderError as exc:
|
|
225
|
+
raise DispatchError(str(exc)) from exc
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- [ ] **Step 4: Run the Codex regression test and verify it passes**
|
|
229
|
+
|
|
230
|
+
Run:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
python3 -m pytest tests/test_codex_dispatch.py::test_base_prompt_headers_wraps_worker_header_errors -q
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Expected: PASS.
|
|
237
|
+
|
|
238
|
+
- [ ] **Step 5: Smoke-test the Codex boundary exception type**
|
|
239
|
+
|
|
240
|
+
Run:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
python3 - <<'PY'
|
|
244
|
+
from pathlib import Path
|
|
245
|
+
import sys
|
|
246
|
+
|
|
247
|
+
sys.path.insert(0, "scripts")
|
|
248
|
+
|
|
249
|
+
from okstra_ctl.codex_dispatch import DispatchError, _base_prompt_headers
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
_base_prompt_headers(
|
|
253
|
+
project_root=Path("/project"),
|
|
254
|
+
manifest={},
|
|
255
|
+
active_context={},
|
|
256
|
+
worker_id="codex",
|
|
257
|
+
prompt_rel=".okstra/run/prompts/codex.md",
|
|
258
|
+
result_rel=".okstra/run/worker-results/codex.md",
|
|
259
|
+
)
|
|
260
|
+
except DispatchError as exc:
|
|
261
|
+
print(type(exc).__name__, str(exc))
|
|
262
|
+
else:
|
|
263
|
+
raise SystemExit("expected DispatchError")
|
|
264
|
+
PY
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Expected output:
|
|
268
|
+
|
|
269
|
+
```text
|
|
270
|
+
DispatchError missing required string field: teamStatePath
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### Task 3: Wrap Backend-Neutral Dispatcher Header Errors
|
|
276
|
+
|
|
277
|
+
**Files:**
|
|
278
|
+
- Modify: `scripts/okstra_ctl/dispatch_core.py`
|
|
279
|
+
- Test: `tests/test_dispatch_core.py`
|
|
280
|
+
|
|
281
|
+
- [ ] **Step 1: Write the failing dispatch-core regression test**
|
|
282
|
+
|
|
283
|
+
Add `pytest` to `tests/test_dispatch_core.py` imports:
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
import pytest
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Append this test to `tests/test_dispatch_core.py`:
|
|
290
|
+
|
|
291
|
+
```python
|
|
292
|
+
def test_materialize_prompt_wraps_worker_header_errors(tmp_path: Path) -> None:
|
|
293
|
+
prompt_path = tmp_path / "project" / "prompts" / "claude-worker-prompt.md"
|
|
294
|
+
|
|
295
|
+
with pytest.raises(dispatch_core.DispatchError, match="teamStatePath"):
|
|
296
|
+
dispatch_core._materialize_prompt_if_missing(
|
|
297
|
+
prompt_path=prompt_path,
|
|
298
|
+
prompt_rel="prompts/claude-worker-prompt.md",
|
|
299
|
+
worker_id="claude",
|
|
300
|
+
result_rel="worker-results/claude.md",
|
|
301
|
+
project_root=tmp_path / "project",
|
|
302
|
+
manifest={},
|
|
303
|
+
active_context={},
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
assert not prompt_path.exists()
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
- [ ] **Step 2: Run the dispatch-core regression test and verify it fails for the intended reason**
|
|
310
|
+
|
|
311
|
+
Run:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
python3 -m pytest tests/test_dispatch_core.py::test_materialize_prompt_wraps_worker_header_errors -q
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Expected: FAIL because `_materialize_prompt_if_missing()` raises `WorkerPromptHeaderError` instead of dispatch-core `DispatchError`.
|
|
318
|
+
|
|
319
|
+
- [ ] **Step 3: Convert shared header errors to dispatch-core `DispatchError`**
|
|
320
|
+
|
|
321
|
+
In `scripts/okstra_ctl/dispatch_core.py`, replace the worker header import with:
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
from .worker_prompt_headers import WorkerPromptHeaderError, worker_prompt_headers
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Replace `_materialize_prompt_if_missing()` with:
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
def _materialize_prompt_if_missing(
|
|
331
|
+
*,
|
|
332
|
+
prompt_path: Path,
|
|
333
|
+
prompt_rel: str,
|
|
334
|
+
worker_id: str,
|
|
335
|
+
result_rel: str,
|
|
336
|
+
project_root: Path,
|
|
337
|
+
manifest: Mapping[str, Any],
|
|
338
|
+
active_context: Mapping[str, Any],
|
|
339
|
+
) -> None:
|
|
340
|
+
if prompt_path.is_file():
|
|
341
|
+
return
|
|
342
|
+
prompt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
343
|
+
try:
|
|
344
|
+
headers = worker_prompt_headers(
|
|
345
|
+
project_root=project_root,
|
|
346
|
+
prompt_rel=prompt_rel,
|
|
347
|
+
result_rel=result_rel,
|
|
348
|
+
worker_id=worker_id,
|
|
349
|
+
manifest=manifest,
|
|
350
|
+
active_context=active_context,
|
|
351
|
+
)
|
|
352
|
+
except WorkerPromptHeaderError as exc:
|
|
353
|
+
raise DispatchError(str(exc)) from exc
|
|
354
|
+
prompt_path.write_text("\n".join([*headers, ""]), encoding="utf-8")
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
- [ ] **Step 4: Run the dispatch-core regression test and verify it passes**
|
|
358
|
+
|
|
359
|
+
Run:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
python3 -m pytest tests/test_dispatch_core.py::test_materialize_prompt_wraps_worker_header_errors -q
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Expected: PASS.
|
|
366
|
+
|
|
367
|
+
- [ ] **Step 5: Run all backend-neutral dispatch prompt tests**
|
|
368
|
+
|
|
369
|
+
Run:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
python3 -m pytest tests/test_dispatch_core.py -q
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Expected: PASS for all tests in `tests/test_dispatch_core.py`.
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
### Task 4: Verify Integration and Update User-Facing Log
|
|
380
|
+
|
|
381
|
+
**Files:**
|
|
382
|
+
- Modify: `CHANGES.md`
|
|
383
|
+
- Verify: `tests/test_worker_prompt_headers.py`, `tests/test_codex_dispatch.py`, `tests/test_dispatch_core.py`, `tests/test_docs_runtime_contract.py`, generated `runtime/`
|
|
384
|
+
|
|
385
|
+
- [ ] **Step 1: Run the focused regression suite**
|
|
386
|
+
|
|
387
|
+
Run:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
python3 -m pytest tests/test_worker_prompt_headers.py tests/test_codex_dispatch.py::test_base_prompt_headers_wraps_worker_header_errors tests/test_dispatch_core.py::test_materialize_prompt_wraps_worker_header_errors -q
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Expected: PASS for the shared helper test file and both new dispatcher boundary tests.
|
|
394
|
+
|
|
395
|
+
- [ ] **Step 2: Run the prompt/dispatch contract suite**
|
|
396
|
+
|
|
397
|
+
Run:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
python3 -m pytest tests/test_worker_prompt_headers.py tests/test_codex_dispatch.py tests/test_dispatch_core.py tests/test_docs_runtime_contract.py -q
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Expected: PASS for all prompt, dispatch, and runtime-contract tests.
|
|
404
|
+
|
|
405
|
+
- [ ] **Step 3: Update `CHANGES.md` under `## 2026-06-15`**
|
|
406
|
+
|
|
407
|
+
Insert this entry after the current `fix(dispatch): worker 프롬프트가 coding-preflight 팩 경로를 앵커 헤더로 직접 수신` section:
|
|
408
|
+
|
|
409
|
+
```markdown
|
|
410
|
+
### fix(dispatch): worker prompt header 오류를 dispatcher 경계에서 정규화
|
|
411
|
+
|
|
412
|
+
- **배경**: worker prompt anchor header 렌더러를 공유 모듈로 추출한 뒤 malformed fallback manifest 가 renderer 내부 예외를 그대로 노출할 수 있었다. Codex CLI dispatcher 는 `DispatchError` 만 clean error 로 처리하므로 helper 예외가 그대로 올라오면 traceback 형태로 보일 위험이 있었다.
|
|
413
|
+
- **해결**: shared renderer 는 `WorkerPromptHeaderError` 를 던지고, Codex dispatcher 와 backend-neutral dispatch core 는 이를 각자의 `DispatchError` 로 변환한다. 정상 header 렌더링 경로와 기존 deterministic prompt materialization 은 그대로 유지한다.
|
|
414
|
+
- 사용자 영향: 잘못된 run manifest/context 로 fallback worker prompt 를 만들 수 없는 경우에도 내부 helper 예외나 traceback 대신 dispatcher 의 일관된 오류 메시지로 실패한다.
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
- [ ] **Step 4: Refresh runtime build output**
|
|
418
|
+
|
|
419
|
+
Run:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
npm run build
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Expected: exit code 0 and build sync completion, including `scripts/`, `prompts/`, `skills/`, `agents/`, `templates/`, and `validators/` sources.
|
|
426
|
+
|
|
427
|
+
- [ ] **Step 5: Run the full project check**
|
|
428
|
+
|
|
429
|
+
Run:
|
|
430
|
+
|
|
431
|
+
```bash
|
|
432
|
+
npm run check
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Expected: exit code 0. JavaScript tests, Python tests, and `validators/validate-workflow.sh` all pass.
|
|
436
|
+
|
|
437
|
+
- [ ] **Step 6: Smoke-test runtime import after build**
|
|
438
|
+
|
|
439
|
+
Run:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
python3 - <<'PY'
|
|
443
|
+
from pathlib import Path
|
|
444
|
+
import sys
|
|
445
|
+
|
|
446
|
+
sys.path.insert(0, "runtime/scripts")
|
|
447
|
+
|
|
448
|
+
from okstra_ctl.codex_dispatch import DispatchError, _base_prompt_headers
|
|
449
|
+
|
|
450
|
+
try:
|
|
451
|
+
_base_prompt_headers(
|
|
452
|
+
project_root=Path("/project"),
|
|
453
|
+
manifest={},
|
|
454
|
+
active_context={},
|
|
455
|
+
worker_id="codex",
|
|
456
|
+
prompt_rel=".okstra/run/prompts/codex.md",
|
|
457
|
+
result_rel=".okstra/run/worker-results/codex.md",
|
|
458
|
+
)
|
|
459
|
+
except DispatchError as exc:
|
|
460
|
+
print(type(exc).__name__, str(exc))
|
|
461
|
+
else:
|
|
462
|
+
raise SystemExit("expected DispatchError")
|
|
463
|
+
PY
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Expected output:
|
|
467
|
+
|
|
468
|
+
```text
|
|
469
|
+
DispatchError missing required string field: teamStatePath
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
- [ ] **Step 7: Commit the finished fix**
|
|
473
|
+
|
|
474
|
+
Run:
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
git add scripts/okstra_ctl/worker_prompt_headers.py scripts/okstra_ctl/codex_dispatch.py scripts/okstra_ctl/dispatch_core.py tests/test_worker_prompt_headers.py tests/test_codex_dispatch.py tests/test_dispatch_core.py CHANGES.md
|
|
478
|
+
git commit -m "fix(dispatch): normalize worker prompt header errors"
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Expected: one conventional commit containing source changes, regression tests, and the user-facing behavior log. `runtime/` stays generated and is not hand-edited.
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## Self-Review Checklist
|
|
485
|
+
|
|
486
|
+
- [ ] The plan covers the only remaining in-scope issue: shared header renderer exceptions leaking past dispatcher error boundaries.
|
|
487
|
+
- [ ] The graphify update failure is excluded because the user classified it as an external plugin issue.
|
|
488
|
+
- [ ] No compatibility shim or duplicate renderer is introduced; `worker_prompt_headers.py` remains the single header-rendering implementation.
|
|
489
|
+
- [ ] Tests assert observable behavior: public exception type at the dispatcher boundary and absence of a partial prompt file on dispatch-core failure.
|
|
490
|
+
- [ ] `CHANGES.md` states the user impact and the mechanism that enforces the cleaner failure mode.
|
|
@@ -57,7 +57,7 @@ flowchart TD
|
|
|
57
57
|
| phase boundary | [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py) |
|
|
58
58
|
| task worktree | [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py) |
|
|
59
59
|
| worker roster parser | [`scripts/okstra_ctl/workers.py`](../../scripts/okstra_ctl/workers.py) |
|
|
60
|
-
| lead operating contract | [`
|
|
60
|
+
| lead operating contract | [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md) |
|
|
61
61
|
| phase profiles | [`prompts/profiles/`](../../prompts/profiles/) |
|
|
62
62
|
| final report shape | [`templates/reports/final-report.template.md`](../../templates/reports/final-report.template.md) |
|
|
63
63
|
|
|
@@ -97,5 +97,5 @@ final report는 다음을 담아야 한다.
|
|
|
97
97
|
- [`templates/reports/error-analysis-input.template.md`](../../templates/reports/error-analysis-input.template.md)
|
|
98
98
|
- [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py)
|
|
99
99
|
- [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py)
|
|
100
|
-
- [`
|
|
100
|
+
- [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md)
|
|
101
101
|
|
|
@@ -164,4 +164,4 @@ source edit, follow-up fix, scope expansion은 전부 금지다. 결함을 발
|
|
|
164
164
|
- [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
|
|
165
165
|
- [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py)
|
|
166
166
|
- [`scripts/okstra_ctl/render.py`](../../scripts/okstra_ctl/render.py)
|
|
167
|
-
- [`
|
|
167
|
+
- [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md)
|
|
@@ -124,5 +124,5 @@ flowchart TD
|
|
|
124
124
|
- [`templates/reports/final-report.template.md`](../../templates/reports/final-report.template.md)
|
|
125
125
|
- [`scripts/okstra_ctl/render.py`](../../scripts/okstra_ctl/render.py)
|
|
126
126
|
- [`validators/validate-run.py`](../../validators/validate-run.py)
|
|
127
|
-
- [`
|
|
127
|
+
- [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md)
|
|
128
128
|
|
|
@@ -145,5 +145,5 @@ flowchart TD
|
|
|
145
145
|
- [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py)
|
|
146
146
|
- [`validators/validate-implementation-plan-stages.py`](../../validators/validate-implementation-plan-stages.py)
|
|
147
147
|
- [`scripts/okstra_ctl/qa_commands.py`](../../scripts/okstra_ctl/qa_commands.py)
|
|
148
|
-
- [`
|
|
148
|
+
- [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md)
|
|
149
149
|
|
|
@@ -62,7 +62,7 @@ sequenceDiagram
|
|
|
62
62
|
P-->>W: lead prompt for current session
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
profile에 `Required workers:` block이 없고 `run.py`도 `release-handoff`에서는 worker override를 비운다. 따라서 `
|
|
65
|
+
profile에 `Required workers:` block이 없고 `run.py`도 `release-handoff`에서는 worker override를 비운다. 따라서 `prompts/lead/okstra-lead-contract.md`의 일반 TeamCreate / convergence / report-writer 흐름을 타지 않는 것이 의도된 동작이다.
|
|
66
66
|
|
|
67
67
|
## 4. entry gate
|
|
68
68
|
|
|
@@ -79,7 +79,7 @@ flowchart TD
|
|
|
79
79
|
R --> P7[Phase 7 token usage, validate, persist]
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
`requirements-discovery`는 convergence default가 1 round다. 이 예외는 `render._build_convergence_block()`와 `
|
|
82
|
+
`requirements-discovery`는 convergence default가 1 round다. 이 예외는 `render._build_convergence_block()`와 `prompts/lead/okstra-lead-contract.md` 모두에서 명시된다.
|
|
83
83
|
|
|
84
84
|
## 5. 산출물과 routing
|
|
85
85
|
|
|
@@ -111,5 +111,5 @@ Non-goal은 source edit, plan authoring, build, deployment다.
|
|
|
111
111
|
- [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
|
|
112
112
|
- [`scripts/okstra_ctl/workflow.py`](../../scripts/okstra_ctl/workflow.py)
|
|
113
113
|
- [`prompts/profiles/requirements-discovery.md`](../../prompts/profiles/requirements-discovery.md)
|
|
114
|
-
- [`
|
|
114
|
+
- [`prompts/lead/okstra-lead-contract.md`](../../prompts/lead/okstra-lead-contract.md)
|
|
115
115
|
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
package/runtime/agents/TODO.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
이 파일은 okstra 워크플로우의 워커 종료 / Phase 4 대기 시간 개선 작업, 그리고 워커 설정 일관성 감사(2026-05-03)에서 도출됐지만 단일 라운드에서 안전하게 처리할 수 없어 별도 라운드로 미룬 항목을 기록한다.
|
|
4
4
|
|
|
5
|
+
> Historical note: entries before 2026-06-15 may reference the former internal-skill layout; current lead contracts live under `prompts/lead/` and current coding-preflight resources live under `prompts/coding-preflight/`.
|
|
6
|
+
|
|
5
7
|
---
|
|
6
8
|
|
|
7
9
|
## 항목 C2 — Worker-results 경로 표준 결정 [해결됨, 2026-05-03]
|
|
@@ -45,7 +45,7 @@ Unlike the Codex / Gemini workers, you are an in-process Claude subagent — you
|
|
|
45
45
|
|
|
46
46
|
4. Anchor all file operations to the absolute `Project Root` from the lead prompt. Use absolute paths — do NOT rely on inherited cwd. Never use `cd` to change directory.
|
|
47
47
|
- **Executor exception (implementation phase only):** when this worker is dispatched as the `Executor` and the lead prompt provides an `EXECUTOR_WORKTREE_PATH` that differs from the session's inherited cwd, cwd-sensitive Bash commands (`cargo *`, `npm *`, `pnpm *`, `bun *`, `pytest`, `make *`, `go *`, language-toolchain test/build commands) MUST be prefixed with `cd <EXECUTOR_WORKTREE_PATH> && ` in the same Bash invocation — e.g. `cd /Users/.../worktrees/foo && cargo test -p bar`. Do NOT wrap the whole thing in `bash -lc "..."` or `bash -c "..."`; pass the chained command directly to the Bash tool so the leading `cd` token remains visible to the permission layer. The `cd` is scoped to the single Bash subshell and does not mutate the session's shell state, so this does not conflict with the "never use cd" rule above (which prevents the worker from drifting the session cwd across calls).
|
|
48
|
-
- **Executor coding-conventions preflight (BLOCKING, before your first `Edit` / `Write`):** when dispatched as the `Executor`, you MUST run the coding-conventions preflight defined in the executor sidecar (`prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") before writing any code
|
|
48
|
+
- **Executor coding-conventions preflight (BLOCKING, before your first `Edit` / `Write`):** when dispatched as the `Executor`, you MUST run the coding-conventions preflight defined in the executor sidecar (`prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") before writing any code. Use this worker prompt's `**Coding preflight pack:**` anchor header; read that pack's `overview.md` and `clean-code.md`, then follow the routed pack's language → framework → architecture stages, iterating every rule and loading every matching resource (for example `frameworks/node-server.md` and `architectures/hexagonal.md` when their conditions match). The preflight pack is a runtime resource, not an auto-invoked skill; read the files via the Read tool by absolute path.
|
|
49
49
|
- **Verifier QA-gate exception:** verifier roles MAY use the same `cd <WORKTREE> && <cmd>` shape when executing project-declared `qaCommands` (lint / format / typecheck / test) from `project.json`, since those commands are cwd-sensitive by nature. Outside the QA gate, verifiers still read with absolute paths only — do NOT use `cd` for file inspection.
|
|
50
50
|
- **No extra chaining beyond `cd && cmd`:** the permission matcher only allows the exact two-segment shape `cd <PATH> && <single-command>`. Do NOT append additional pipes, semicolons, redirects, or `&&` chains — e.g. `cd ... && cargo test ... 2>&1 | tail -20; echo "exit:$?"` will trigger a permission prompt every dispatch because the trailing `| tail`, `; echo`, and `2>&1` tokens disqualify the prefix match against `Bash(cargo:*)`. Let Claude Code capture the full stdout/stderr and exit code natively — do not post-process with `tail`, `head`, or `echo "exit:$?"`. If output truncation is genuinely needed, run the command first and read the result in a separate tool call.
|
|
51
51
|
|
|
@@ -68,7 +68,7 @@ Before producing any output, you MUST:
|
|
|
68
68
|
|
|
69
69
|
When returning results, start the file with a YAML frontmatter block, then organize the body into the following sections in this exact order.
|
|
70
70
|
|
|
71
|
-
**Frontmatter (mandatory)** — set `workerId: "claude"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the primary input (`analysis-packet.md`; fall back to `analysis-material.md` only if the packet is missing a field). Full schema and a concrete example live in the `
|
|
71
|
+
**Frontmatter (mandatory)** — set `workerId: "claude"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the primary input (`analysis-packet.md`; fall back to `analysis-material.md` only if the packet is missing a field). Full schema and a concrete example live in the team-contract resource (`prompts/lead/team-contract.md`) "Result Frontmatter" subsection.
|
|
72
72
|
|
|
73
73
|
1. **Findings** - what you identified
|
|
74
74
|
2. **Missing Information or Assumptions** - gaps in the analysis
|
|
@@ -80,15 +80,15 @@ Include file paths and line numbers when discussing code evidence.
|
|
|
80
80
|
|
|
81
81
|
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Use the leading column for table-form items (`F-001`, `M-001`, `S-001`, `U-001`, `R-001` per section) or a `[<ID>]` prefix for bullet/numbered items. The ID shape is your choice but it MUST appear — the lead's §6.1 / §6.2 / §2.1 synthesis preserves these IDs in its `Source items (worker:item)` column to keep cross-worker traceability intact. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
|
|
82
82
|
|
|
83
|
-
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `
|
|
83
|
+
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the team-contract resource (`prompts/lead/team-contract.md`) Ticket Tagging section.
|
|
84
84
|
|
|
85
|
-
This contract mirrors the `
|
|
85
|
+
This contract mirrors the team-contract resource (`prompts/lead/team-contract.md`) Worker Output Contract — that resource is the authoritative source if the two ever diverge.
|
|
86
86
|
|
|
87
87
|
## Stop Condition (BLOCKING)
|
|
88
88
|
|
|
89
|
-
When Lead dispatches you with `team_name` (Teams mode), its `Agent()` call returns `Spawned successfully` **immediately** and does NOT block on your completion — Lead detects your completion by self-scheduled polling of your worker-results file (see `
|
|
89
|
+
When Lead dispatches you with `team_name` (Teams mode), its `Agent()` call returns `Spawned successfully` **immediately** and does NOT block on your completion — Lead detects your completion by self-scheduled polling of your worker-results file (see `team-contract` "Worker-completion detection (self-scheduled polling)"). Therefore you MUST write your worker-results file at the canonical Result Path before returning: that file's appearance is the ONLY completion signal Lead uses. Lingering after your worker-results file is on disk extends Phase 4 wall-clock time for the entire run and delays convergence. Be deliberate about stopping.
|
|
90
90
|
|
|
91
|
-
After your `Write` to the assigned worker-results file (path provided by Lead as `**Result Path:**` — the canonical anchor header defined in `
|
|
91
|
+
After your `Write` to the assigned worker-results file (path provided by Lead as `**Result Path:**` — the canonical anchor header defined in `team-contract` "Worker Prompt Composition" — or derived under `runs/<task-type>/worker-results/claude-worker-<task-type>-<seq>.md`) succeeds:
|
|
92
92
|
|
|
93
93
|
1. Return your final assistant message **immediately**. Begin every return with your model identity, copied verbatim from the `**Model:** Claude worker, <modelExecutionValue>` line in your dispatch prompt (per Worker Preamble → "Return message to the lead"), then the status line — for an analysis dispatch:
|
|
94
94
|
```
|
|
@@ -114,7 +114,7 @@ If the header line is absent from the dispatch prompt, return `CLAUDE_WORKER_ERR
|
|
|
114
114
|
|
|
115
115
|
**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.
|
|
116
116
|
|
|
117
|
-
The sidecar follows the schema in `
|
|
117
|
+
The sidecar follows the schema in `prompts/lead/team-contract.md` (Optional errors sidecar). Lead will dump it to the run error log after this subagent terminates.
|
|
118
118
|
|
|
119
119
|
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`.
|
|
120
120
|
|
|
@@ -122,7 +122,7 @@ There is NO `cli-failure` category for this worker — Claude worker has no exte
|
|
|
122
122
|
|
|
123
123
|
- Return error messages as-is on failure.
|
|
124
124
|
- Do not summarize or modify your own analysis output beyond the structured sections above.
|
|
125
|
-
- Sections 1–5 are the common core — same dimensions for every analysis worker. Your specialization (broad reasoning depth, hidden-assumption surfacing, execution-risk decomposition) only enters Section 6 if you have additive content beyond the core. See `
|
|
125
|
+
- Sections 1–5 are the common core — same dimensions for every analysis worker. Your specialization (broad reasoning depth, hidden-assumption surfacing, execution-risk decomposition) only enters Section 6 if you have additive content beyond the core. See `prompts/lead/team-contract.md` "Worker Output Contract" for the authoritative split.
|
|
126
126
|
|
|
127
127
|
## Stage evidence emission (BLOCKING, implementation task only)
|
|
128
128
|
|