maestro-flow 0.4.16 → 0.4.18

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.
Files changed (105) hide show
  1. package/.agents/skills/maestro/SKILL.md +1 -1
  2. package/.agents/skills/maestro-analyze/SKILL.md +5 -0
  3. package/.agents/skills/maestro-blueprint/SKILL.md +5 -0
  4. package/.agents/skills/maestro-brainstorm/SKILL.md +5 -0
  5. package/.agents/skills/maestro-init/SKILL.md +1 -1
  6. package/.agents/skills/maestro-next/SKILL.md +219 -0
  7. package/.agents/skills/maestro-ralph-beta/SKILL.md +893 -0
  8. package/.agy/skills/maestro/SKILL.md +1 -1
  9. package/.agy/skills/maestro-analyze/SKILL.md +5 -0
  10. package/.agy/skills/maestro-blueprint/SKILL.md +5 -0
  11. package/.agy/skills/maestro-brainstorm/SKILL.md +5 -0
  12. package/.agy/skills/maestro-init/SKILL.md +1 -1
  13. package/.agy/skills/maestro-next/SKILL.md +215 -0
  14. package/.agy/skills/maestro-ralph-beta/SKILL.md +889 -0
  15. package/.claude/commands/maestro-analyze.md +5 -0
  16. package/.claude/commands/maestro-blueprint.md +5 -0
  17. package/.claude/commands/maestro-brainstorm.md +5 -0
  18. package/.claude/commands/maestro-init.md +1 -1
  19. package/.claude/commands/maestro-next.md +217 -0
  20. package/.claude/commands/maestro-ralph-beta.md +891 -0
  21. package/.claude/commands/maestro.md +1 -1
  22. package/.codex/skills/learn-decompose/SKILL.md +34 -3
  23. package/.codex/skills/learn-retro/SKILL.md +31 -1
  24. package/.codex/skills/learn-second-opinion/SKILL.md +34 -4
  25. package/.codex/skills/maestro-analyze/SKILL.md +44 -5
  26. package/.codex/skills/maestro-blueprint/SKILL.md +5 -0
  27. package/.codex/skills/maestro-brainstorm/SKILL.md +46 -0
  28. package/.codex/skills/maestro-execute/SKILL.md +61 -5
  29. package/.codex/skills/maestro-milestone-audit/SKILL.md +64 -13
  30. package/.codex/skills/maestro-milestone-complete/SKILL.md +12 -0
  31. package/.codex/skills/maestro-plan/SKILL.md +36 -1
  32. package/.codex/skills/maestro-player/SKILL.md +25 -6
  33. package/.codex/skills/maestro-ralph/SKILL.md +108 -81
  34. package/.codex/skills/maestro-ralph-beta/SKILL.md +891 -0
  35. package/.codex/skills/maestro-ralph-execute/SKILL.md +244 -0
  36. package/.codex/skills/maestro-roadmap/SKILL.md +35 -4
  37. package/.codex/skills/maestro-ui-codify/SKILL.md +38 -10
  38. package/.codex/skills/maestro-verify/SKILL.md +40 -5
  39. package/.codex/skills/manage-codebase-rebuild/SKILL.md +52 -5
  40. package/.codex/skills/manage-issue-discover/SKILL.md +106 -15
  41. package/.codex/skills/quality-auto-test/SKILL.md +70 -16
  42. package/.codex/skills/quality-debug/SKILL.md +139 -28
  43. package/.codex/skills/quality-refactor/SKILL.md +61 -11
  44. package/.codex/skills/quality-review/SKILL.md +45 -9
  45. package/.codex/skills/quality-test/SKILL.md +58 -3
  46. package/.codex/skills/security-audit/SKILL.md +38 -0
  47. package/.codex/skills/spec-map/SKILL.md +65 -8
  48. package/.codex/skills/team-coordinate/SKILL.md +28 -11
  49. package/.codex/skills/team-coordinate/specs/role-catalog.md +20 -0
  50. package/.codex/skills/team-lifecycle-v4/SKILL.md +23 -7
  51. package/.codex/skills/team-lifecycle-v4/instructions/agent-instruction.md +20 -0
  52. package/.codex/skills/team-quality-assurance/SKILL.md +40 -2
  53. package/.codex/skills/team-review/SKILL.md +42 -2
  54. package/.codex/skills/team-tech-debt/SKILL.md +45 -2
  55. package/.codex/skills/team-testing/SKILL.md +42 -2
  56. package/dashboard/dist-server/dashboard/src/server/wiki/search.d.ts +6 -4
  57. package/dashboard/dist-server/dashboard/src/server/wiki/search.js +50 -8
  58. package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
  59. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.d.ts +32 -0
  60. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +294 -0
  61. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
  62. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +1 -0
  63. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +35 -1
  64. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
  65. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js +235 -0
  66. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js.map +1 -1
  67. package/dist/src/commands/install-backend.d.ts.map +1 -1
  68. package/dist/src/commands/install-backend.js +23 -4
  69. package/dist/src/commands/install-backend.js.map +1 -1
  70. package/dist/src/commands/ralph.d.ts.map +1 -1
  71. package/dist/src/commands/ralph.js +3 -1
  72. package/dist/src/commands/ralph.js.map +1 -1
  73. package/dist/src/ralph/cmd-check.js +1 -1
  74. package/dist/src/ralph/cmd-check.js.map +1 -1
  75. package/dist/src/ralph/cmd-complete.js +1 -1
  76. package/dist/src/ralph/cmd-complete.js.map +1 -1
  77. package/dist/src/ralph/cmd-next.d.ts.map +1 -1
  78. package/dist/src/ralph/cmd-next.js +56 -5
  79. package/dist/src/ralph/cmd-next.js.map +1 -1
  80. package/dist/src/ralph/cmd-session.js +2 -2
  81. package/dist/src/ralph/cmd-session.js.map +1 -1
  82. package/dist/src/ralph/cmd-skills.d.ts +2 -0
  83. package/dist/src/ralph/cmd-skills.d.ts.map +1 -1
  84. package/dist/src/ralph/cmd-skills.js +11 -4
  85. package/dist/src/ralph/cmd-skills.js.map +1 -1
  86. package/dist/src/ralph/skill-scanner.d.ts +7 -2
  87. package/dist/src/ralph/skill-scanner.d.ts.map +1 -1
  88. package/dist/src/ralph/skill-scanner.js +39 -24
  89. package/dist/src/ralph/skill-scanner.js.map +1 -1
  90. package/dist/src/ralph/status-schema.d.ts +2 -0
  91. package/dist/src/ralph/status-schema.d.ts.map +1 -1
  92. package/dist/src/ralph/status-store.d.ts +8 -1
  93. package/dist/src/ralph/status-store.d.ts.map +1 -1
  94. package/dist/src/ralph/status-store.js +12 -2
  95. package/dist/src/ralph/status-store.js.map +1 -1
  96. package/dist/src/tools/store-knowhow.d.ts.map +1 -1
  97. package/dist/src/tools/store-knowhow.js +51 -64
  98. package/dist/src/tools/store-knowhow.js.map +1 -1
  99. package/dist/src/utils/update-notices.js +12 -0
  100. package/dist/src/utils/update-notices.js.map +1 -1
  101. package/package.json +1 -1
  102. package/templates/config.json +21 -33
  103. package/workflows/finish-work.md +119 -0
  104. package/workflows/init.md +11 -11
  105. package/workflows/milestone-complete.md +23 -1
@@ -216,33 +216,69 @@ Filter master `tasks.csv` for `wave == 1 AND status == pending` → write `wave-
216
216
  spawn_agents_on_csv({
217
217
  csv_path: `${sessionFolder}/wave-1.csv`,
218
218
  id_column: "id",
219
- instruction: buildReviewInstruction(sessionFolder), // agent: ~/.codex/agents/workflow-reviewer.toml
219
+ instruction: REVIEW_DIMENSION_INSTRUCTION, // see "Dimension Worker Contract" below
220
220
  max_concurrency: maxConcurrency,
221
221
  max_runtime_seconds: 3600,
222
222
  output_csv_path: `${sessionFolder}/wave-1-results.csv`,
223
223
  output_schema: {
224
224
  type: "object",
225
225
  properties: {
226
- id: { type: "string" },
227
- result_status: { type: "string", enum: ["completed", "failed"] },
228
- findings: { type: "string" },
229
- severity_counts: { type: "string" },
230
- top_issues: { type: "string" },
231
- error: { type: "string" }
226
+ id: { type: "string" },
227
+ result_status: { type: "string", enum: ["completed", "failed"] },
228
+ findings: { type: "string", maxLength: 500 },
229
+ severity_counts: { type: "string", description: "JSON object string {critical, high, medium, low}" },
230
+ top_issues: { type: "string", description: "JSON array string of top issues with file:line" },
231
+ error: { type: "string" }
232
232
  },
233
233
  required: ["id", "result_status", "findings"]
234
234
  }
235
235
  })
236
236
  ```
237
237
 
238
- Merge `wave-1-results.csv` into master `tasks.csv` (map `result_status` → master `status` column), then delete both `wave-1.csv` and `wave-1-results.csv`.
238
+ Merge `wave-1-results.csv` into master `tasks.csv` (map `result_status` → master `status` column; copy `findings`, `severity_counts`, `top_issues`, `error`), then delete both `wave-1.csv` and `wave-1-results.csv`.
239
+
240
+ #### Dimension Worker Contract (REVIEW_DIMENSION_INSTRUCTION)
241
+
242
+ ```
243
+ You are a code reviewer for ONE dimension (correctness/security/performance/maintainability/...). Your dimension, scope, and standards come from your CSV row.
244
+
245
+ REQUIRED STEPS:
246
+ 1. Read shared discoveries: {sessionFolder}/discoveries.ndjson
247
+ 2. Read specs loaded by orchestrator (review category) for severity calibration
248
+ 3. Scan code in scope using Read/Grep/Glob (read-only)
249
+ 4. Classify each issue: critical / high / medium / low with file:line refs
250
+ 5. Append cross-cutting patterns to discoveries.ndjson
251
+ 6. Call report_agent_job_result EXACTLY ONCE
252
+
253
+ TERMINATION CONTRACT (mandatory — NO worker may end without calling report_agent_job_result):
254
+ - Success → result_status=completed (severity_counts may be all-zero if clean)
255
+ - Timeout → near max_runtime_seconds, STOP and report completed with partial findings
256
+ - Failure → unrecoverable read/parse error → result_status=failed
257
+ - NEVER skip report_agent_job_result.
258
+
259
+ OUTPUT (must match output_schema):
260
+ {
261
+ "id": "<your row id>",
262
+ "result_status": "completed" | "failed",
263
+ "findings": "<one-sentence dimension summary, max 500 chars>",
264
+ "severity_counts": "<JSON object string: {critical:N, high:N, medium:N, low:N}>",
265
+ "top_issues": "<JSON array string: [{title, severity, location, recommendation}...]>",
266
+ "error": "<message if failed, else empty>"
267
+ }
268
+
269
+ CONSTRAINTS:
270
+ - Every issue MUST have a concrete file:line reference. No speculation.
271
+ - Do NOT modify source. This is review only.
272
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv, review.json (orchestrator owns those).
273
+ - Do NOT call spawn_agents_on_csv (no recursion).
274
+ ```
239
275
 
240
276
  #### Wave 2: Aggregation + Deep-Dive
241
277
 
242
278
  Filter master `tasks.csv` for `wave == 2 AND status == pending`. If all wave 1 tasks failed, skip aggregation.
243
279
 
244
280
  Build `prev_context` from wave 1 findings (format: `[Task N: Title] summary...` per task).
245
- Write `wave-2.csv` with `prev_context` column → execute `spawn_agents_on_csv` → merge results into master `tasks.csv` (map `result_status` → master `status` column) → delete both `wave-2.csv` and `wave-2-results.csv`.
281
+ Write `wave-2.csv` with `prev_context` column → execute `spawn_agents_on_csv` with `REVIEW_AGGREGATION_INSTRUCTION` (same termination contract; output_schema returns `result_status` enum [completed|failed], findings, plus `verdict` enum [PASS|WARN|BLOCK]) → merge results into master `tasks.csv` (map `result_status` → master `status` column) → delete both `wave-2.csv` and `wave-2-results.csv`.
246
282
 
247
283
  ### Phase 3: Results Aggregation
248
284
 
@@ -183,10 +183,65 @@ On issue: auto-create in `.workflow/issues/issues.jsonl`:
183
183
  ### A_DIAGNOSE_GAPS
184
184
 
185
185
  1. Cluster gaps by component/module/feature
186
- 2. Build diagnosis.csv: one row per gap with target_files, source_context
187
- 3. `spawn_agents_on_csv` for parallel diagnosis
186
+ 2. Build diagnosis.csv with `status="pending"` per row, target_files, source_context
187
+ 3. Filter `status=="pending"` -> write diagnosis-wave.csv -> `spawn_agents_on_csv` for parallel diagnosis with the contract below
188
188
  4. **Diagnosis agent**: Find root cause (not symptom), suggest fix direction, list affected files. Do NOT modify files. Reference issue_id for traceability.
189
- 5. Merge results: update uat.md gaps with root_cause, fix_direction, affected_files
189
+ 5. Merge results: map `result_status` master `status`; copy `root_cause`, `fix_direction`, `affected_files`; update uat.md gaps
190
+
191
+ **output_schema**:
192
+
193
+ ```json
194
+ {
195
+ "type": "object",
196
+ "properties": {
197
+ "id": { "type": "string" },
198
+ "result_status": { "type": "string", "enum": ["completed", "failed", "blocked"] },
199
+ "root_cause": { "type": "string", "maxLength": 500 },
200
+ "fix_direction": { "type": "string" },
201
+ "affected_files": { "type": "string", "description": "Semicolon-separated file:line refs" },
202
+ "findings": { "type": "string", "maxLength": 500 },
203
+ "error": { "type": "string" }
204
+ },
205
+ "required": ["id", "result_status", "root_cause", "findings"]
206
+ }
207
+ ```
208
+
209
+ **Diagnosis Worker Instruction** (embed in spawn instruction):
210
+ ```
211
+ You are a UAT gap diagnostician. ONE gap row is assigned to you.
212
+
213
+ INPUT: id, target_files, source_context, issue_id, gap description
214
+
215
+ REQUIRED STEPS:
216
+ 1. Read target_files + source_context (read-only)
217
+ 2. Trace symptom backward through call chain to root cause
218
+ 3. Identify fix direction (high-level — orchestrator hands off to maestro-plan)
219
+ 4. List affected files with file:line refs
220
+ 5. Call report_agent_job_result EXACTLY ONCE
221
+
222
+ TERMINATION CONTRACT (mandatory):
223
+ - Success → result_status=completed with root_cause + fix_direction populated
224
+ - Failure → result_status=failed (cannot read files, parse error)
225
+ - Blocked → result_status=blocked (insufficient context to diagnose; orchestrator may re-cluster)
226
+ - Timeout → near max_runtime_seconds → result_status=blocked with error="timeout"
227
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
228
+
229
+ OUTPUT (must match output_schema):
230
+ {
231
+ "id": "<your row id>",
232
+ "result_status": "completed" | "failed" | "blocked",
233
+ "root_cause": "<concrete root cause with file:line, max 500 chars>",
234
+ "fix_direction": "<high-level fix strategy, NOT code>",
235
+ "affected_files": "<semicolon-separated file:line refs>",
236
+ "findings": "<one-sentence summary>",
237
+ "error": "<message if not completed>"
238
+ }
239
+
240
+ CONSTRAINTS:
241
+ - Read-only. Do NOT modify source files.
242
+ - Do NOT write to uat.md, diagnosis.csv, issues.jsonl (orchestrator owns those).
243
+ - Do NOT call spawn_agents_on_csv (no recursion).
244
+ ```
190
245
 
191
246
  ### A_GAP_FIX_LOOP
192
247
 
@@ -59,6 +59,38 @@ Use `Grep` for pattern matching (e.g., `eval(`, `exec(`, `innerHTML`, `dangerous
59
59
  For `standard` and `deep` tiers, use `spawn_agents_on_csv` to parallelize OWASP category scans
60
60
  across multiple agents, one agent per 2-3 categories.
61
61
 
62
+ **spawn_agents_on_csv contract** (OWASP scan):
63
+ - CSV columns: `id, title, owasp_categories, scope_glob, deps, wave, status` (initial `status="pending"`); filter `wave==1 AND status=="pending"` before writing wave-1.csv.
64
+ - `output_schema`:
65
+
66
+ ```json
67
+ {
68
+ "type": "object",
69
+ "properties": {
70
+ "id": { "type": "string" },
71
+ "result_status": { "type": "string", "enum": ["completed", "failed"] },
72
+ "findings": { "type": "string", "maxLength": 500 },
73
+ "severity_counts": { "type": "string", "description": "JSON: {critical, high, medium, low}" },
74
+ "top_issues": { "type": "string", "description": "JSON array: [{title, severity, file:line, cwe}]" },
75
+ "error": { "type": "string" }
76
+ },
77
+ "required": ["id", "result_status", "findings"]
78
+ }
79
+ ```
80
+
81
+ - Merge: `result_status` → master `status`; copy `findings`, `severity_counts`, `top_issues`, `error`.
82
+ - **Termination contract** (embed in instruction):
83
+ ```
84
+ You MUST call report_agent_job_result EXACTLY ONCE before exiting.
85
+ - Success → result_status=completed (severity_counts may be zero if clean)
86
+ - Failure → result_status=failed with error message
87
+ - Timeout → near max_runtime_seconds → result_status=completed with partial top_issues (do not fail the wave for timeout)
88
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
89
+ - Every issue MUST include file:line and CWE reference. No speculation.
90
+ - Read-only. Do NOT modify source.
91
+ Do NOT write to tasks.csv, wave-*.csv, results.csv. Do NOT call spawn_agents_on_csv (no recursion).
92
+ ```
93
+
62
94
  **Phase 3: Dependency Audit** (all tiers)
63
95
 
64
96
  ```bash
@@ -107,6 +139,12 @@ For each critical module identified in Phase 1:
107
139
  For `deep` tier, use `spawn_agents_on_csv` to parallelize STRIDE analysis across critical modules,
108
140
  one agent per module. Use `request_user_input` to confirm critical module list before spawning.
109
141
 
142
+ **STRIDE spawn contract**:
143
+ - CSV columns: `id, module_path, threats_to_assess, deps, wave, status` (initial `status="pending"`); filter `wave==2 AND status=="pending"`.
144
+ - Same `output_schema` as the OWASP spawn above, but `top_issues` JSON items use shape `{stride_category, threat, severity, file:line, mitigation}`.
145
+ - Same termination contract as the OWASP spawn above (mandatory `report_agent_job_result`, read-only, no recursion, timeout → partial findings, etc.).
146
+ - Merge: `result_status` → master `status`; copy `findings`, `severity_counts`, `top_issues`, `error`.
147
+
110
148
  **Phase 7: Git History Archaeology** (deep only)
111
149
 
112
150
  ```bash
@@ -61,10 +61,10 @@ $spec-map --continue "20260318-map-auth"
61
61
 
62
62
  ```csv
63
63
  id,title,description,focus_area,output_file,deps,context_from,wave,status,findings,error
64
- "1","Tech Stack Analysis","Analyze languages, frameworks, dependencies, build system, package managers, runtime configuration. Scan package.json, build configs, CI/CD files.","full","tech-stack.md","","","1","","",""
65
- "2","Architecture Analysis","Analyze project structure, module boundaries, layer architecture, data flow patterns, entry points, API surface. Map directory tree and import graph.","full","architecture.md","","","1","","",""
66
- "3","Features Analysis","Inventory user-facing capabilities, API endpoints, CLI commands, UI components, background jobs, integrations. Map to source locations.","full","features.md","","","1","","",""
67
- "4","Cross-cutting Concerns","Analyze error handling patterns, logging strategy, authentication/authorization, configuration management, testing approach, observability.","full","concerns.md","","","1","","",""
64
+ "1","Tech Stack Analysis","Analyze languages, frameworks, dependencies, build system, package managers, runtime configuration. Scan package.json, build configs, CI/CD files.","full","tech-stack.md","","","1","pending","",""
65
+ "2","Architecture Analysis","Analyze project structure, module boundaries, layer architecture, data flow patterns, entry points, API surface. Map directory tree and import graph.","full","architecture.md","","","1","pending","",""
66
+ "3","Features Analysis","Inventory user-facing capabilities, API endpoints, CLI commands, UI components, background jobs, integrations. Map to source locations.","full","features.md","","","1","pending","",""
67
+ "4","Cross-cutting Concerns","Analyze error handling patterns, logging strategy, authentication/authorization, configuration management, testing approach, observability.","full","concerns.md","","","1","pending","",""
68
68
  ```
69
69
 
70
70
  **Columns**:
@@ -79,9 +79,11 @@ id,title,description,focus_area,output_file,deps,context_from,wave,status,findin
79
79
  | `deps` | Input | Empty (all independent) |
80
80
  | `context_from` | Input | Empty (no cross-task context) |
81
81
  | `wave` | Computed | Always 1 (single wave) |
82
- | `status` | Output | pending/completed/failed/skipped |
83
- | `findings` | Output | Analysis summary (max 500 chars) |
84
- | `error` | Output | Error if failed |
82
+ | `status` | Lifecycle | `pending` (initial) → `completed`/`failed`/`skipped` (set by merge step from worker's `result_status`) |
83
+ | `findings` | Lifecycle | Analysis summary (max 500 chars; merged from worker output) |
84
+ | `error` | Lifecycle | Error if failed (merged) |
85
+
86
+ **Column separation rule**: Wave CSV (input to `spawn_agents_on_csv`) contains Input columns only. Workers return Output columns exclusively via `output_schema` using `result_status` (NOT `status`). Merge maps `result_status` → master `status`.
85
87
 
86
88
  </csv_schema>
87
89
 
@@ -106,7 +108,62 @@ Generate 4 mapper rows. If focus area specified, scope descriptions to that area
106
108
 
107
109
  ### Phase 2: Wave Execution
108
110
 
109
- Single wave -- all 4 mappers via `spawn_agents_on_csv` (max_concurrency: 4, 3600s timeout). Each agent returns: id, status (completed/failed), findings, error.
111
+ Single wave -- all 4 mappers via `spawn_agents_on_csv`:
112
+
113
+ ```javascript
114
+ spawn_agents_on_csv({
115
+ csv_path: `${sessionFolder}/wave-1.csv`, // only rows where status == "pending"
116
+ id_column: "id",
117
+ instruction: MAPPER_INSTRUCTION, // see "Mapper Worker Contract" below
118
+ max_concurrency: 4,
119
+ max_runtime_seconds: 3600,
120
+ output_csv_path: `${sessionFolder}/wave-1-results.csv`,
121
+ output_schema: {
122
+ type: "object",
123
+ properties: {
124
+ id: { type: "string" },
125
+ result_status: { type: "string", enum: ["completed", "failed"] },
126
+ findings: { type: "string", maxLength: 500 },
127
+ error: { type: "string" }
128
+ },
129
+ required: ["id", "result_status", "findings"]
130
+ }
131
+ })
132
+ ```
133
+
134
+ Merge: write `master.status = result_status`, copy `findings` and `error`. Delete `wave-1.csv` and `wave-1-results.csv`.
135
+
136
+ #### Mapper Worker Contract (MAPPER_INSTRUCTION)
137
+
138
+ ```
139
+ You are a codebase mapper for ONE dimension. Your assigned focus_area, description, and output_file come from your CSV row.
140
+
141
+ REQUIRED STEPS:
142
+ 1. Read shared discoveries: {sessionFolder}/discoveries.ndjson (may be empty)
143
+ 2. Scan codebase using Read/Grep/Glob within your focus_area
144
+ 3. Synthesize findings into the analysis sections required by your description
145
+ 4. Append reusable discoveries (tech_stack / code_pattern / integration_point / convention) to discoveries.ndjson
146
+ 5. Call report_agent_job_result EXACTLY ONCE
147
+
148
+ TERMINATION CONTRACT (mandatory — NO worker may end without calling report_agent_job_result):
149
+ - Success path → result_status = completed
150
+ - Timeout path → if approaching max_runtime_seconds, STOP and report failed with error="timeout (partial findings)"
151
+ - Failure path → on unrecoverable error, report failed with error message
152
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
153
+
154
+ OUTPUT (return via report_agent_job_result; must match output_schema):
155
+ {
156
+ "id": "<your row id>",
157
+ "result_status": "completed" | "failed",
158
+ "findings": "<analysis summary, max 500 chars — orchestrator uses this to write {output_file}>",
159
+ "error": "<message if failed, else empty>"
160
+ }
161
+
162
+ CONSTRAINTS:
163
+ - Read-only. Do NOT write to .workflow/codebase/ — orchestrator writes output files from your findings in Phase 3.
164
+ - Do NOT write to tasks.csv, wave-*.csv, or results.csv.
165
+ - Do NOT call spawn_agents_on_csv (no recursion).
166
+ ```
110
167
 
111
168
  ### Phase 3: Write Output Files
112
169
 
@@ -303,18 +303,22 @@ Extract qualifying rows from master CSV. Add `prev_context` column.
303
303
 
304
304
  ```javascript
305
305
  spawn_agents_on_csv({
306
- csv_path: `${sessionFolder}/wave-${N}.csv`,
306
+ csv_path: `${sessionFolder}/wave-${N}.csv`, // only rows where wave==N AND status=="pending"
307
307
  id_column: "id",
308
- instruction: /* see Instruction Builder section below */,
308
+ instruction: TEAM_COORDINATE_INSTRUCTION, // see "Instruction Builder" section below
309
309
  max_concurrency: maxConcurrency,
310
310
  max_runtime_seconds: 3600,
311
311
  output_csv_path: `${sessionFolder}/wave-${N}-results.csv`,
312
312
  output_schema: {
313
- id, // mandatory: links to master CSV
314
- result_status, // mandatory: completed | failed | blocked
315
- findings, // key findings (max 500 chars)
316
- files_modified, // semicolon-separated paths
317
- error // error message if not completed
313
+ type: "object",
314
+ properties: {
315
+ id: { type: "string" },
316
+ result_status: { type: "string", enum: ["completed", "failed", "blocked"] },
317
+ findings: { type: "string", maxLength: 500 },
318
+ files_modified: { type: "string", description: "Semicolon-separated paths" },
319
+ error: { type: "string" }
320
+ },
321
+ required: ["id", "result_status", "findings"]
318
322
  }
319
323
  })
320
324
  ```
@@ -409,12 +413,25 @@ Append findings as NDJSON lines:
409
413
  {"ts":"<ISO>","worker":"<TASK-ID>","type":"<TYPE>","data":{...}}
410
414
  Types: code_pattern, integration_point, convention, blocker, key_finding, decision
411
415
 
416
+ ## Termination Contract (MANDATORY)
417
+ You MUST call report_agent_job_result EXACTLY ONCE before exiting. NO exceptions.
418
+ - Success path → result_status=completed after verification passes
419
+ - Failure path → unrecoverable error (build fails, scope unclear, contract violation) → result_status=failed with error message
420
+ - Blocked path → cannot proceed without upstream fix → result_status=blocked with error explaining what is needed
421
+ - Timeout path → approaching max_runtime_seconds → revert partial unsafe work, report blocked with error="timeout"
422
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
423
+
412
424
  ## Output
413
- Return via output_schema:
414
- - result_status: completed | failed | blocked
425
+ Return via output_schema (matches schema declared in spawn call):
426
+ - id: your CSV row id (mandatory)
427
+ - result_status: completed | failed | blocked (mandatory)
415
428
  - findings: key findings summary (max 500 chars, be specific and actionable)
416
- - files_modified: semicolon-separated paths of created/modified files
417
- - error: error message if result_status is not completed
429
+ - files_modified: semicolon-separated paths of created/modified files (empty if none)
430
+ - error: error message if result_status is not completed (empty otherwise)
431
+
432
+ ## Hard Constraints
433
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv (orchestrator owns those).
434
+ - Do NOT call spawn_agents_on_csv (no recursion).
418
435
  ```
419
436
 
420
437
  </actions>
@@ -80,6 +80,26 @@ All agents — regardless of dynamically assigned role — MUST follow these tra
80
80
  - 2 retries exhausted → report `failed` with evidence
81
81
  - NEVER skip verification and report completed
82
82
 
83
+ ### Termination Contract (MANDATORY)
84
+
85
+ Every spawned worker MUST call `report_agent_job_result` EXACTLY ONCE before exiting. NO exceptions:
86
+
87
+ | Path | Action |
88
+ |------|--------|
89
+ | Success | `result_status=completed` after verification passes |
90
+ | Failure | `result_status=failed` with error message (build error, file write failure, unrecoverable tool error) |
91
+ | Blocked | `result_status=blocked` when upstream missing OR retries exhausted |
92
+ | Timeout | Approaching `max_runtime_seconds` → revert partial unsafe work → `result_status=blocked` with error="timeout" |
93
+
94
+ - NEVER continue indefinitely.
95
+ - NEVER exit silently.
96
+ - NEVER omit `report_agent_job_result`.
97
+
98
+ ### Hard Constraints
99
+
100
+ - Do NOT write to `tasks.csv`, `wave-*.csv`, `results.csv` — orchestrator owns those.
101
+ - Do NOT call `spawn_agents_on_csv` (no recursion).
102
+
83
103
  ## 6. Quality Scoring
84
104
 
85
105
  | Result | Score | Action |
@@ -302,19 +302,23 @@ Extract wave N rows + add `prev_context` column.
302
302
 
303
303
  ```javascript
304
304
  spawn_agents_on_csv({
305
- csv_path: `${sessionFolder}/wave-${N}.csv`,
305
+ csv_path: `${sessionFolder}/wave-${N}.csv`, // only rows where wave==N AND status=="pending"
306
306
  id_column: "id",
307
307
  instruction: buildLifecycleInstruction(sessionFolder, skillRoot),
308
308
  max_concurrency: maxConcurrency,
309
309
  max_runtime_seconds: 3600,
310
310
  output_csv_path: `${sessionFolder}/wave-${N}-results.csv`,
311
311
  output_schema: {
312
- id,
313
- result_status, // completed | failed | blocked
314
- findings, // key findings (max 500 chars)
315
- files_modified, // semicolon-separated paths
316
- quality_score, // 0-100
317
- error // error message
312
+ type: "object",
313
+ properties: {
314
+ id: { type: "string" },
315
+ result_status: { type: "string", enum: ["completed", "failed", "blocked"] },
316
+ findings: { type: "string", maxLength: 500 },
317
+ files_modified: { type: "string", description: "Semicolon-separated paths" },
318
+ quality_score: { type: "string", description: "0-100" },
319
+ error: { type: "string" }
320
+ },
321
+ required: ["id", "result_status", "findings"]
318
322
  }
319
323
  })
320
324
  ```
@@ -363,6 +367,18 @@ For roles with commands/ subdirectory, load the relevant command file based on y
363
367
  3. Retry on verification failure (max 2 retries)
364
368
  4. Report blocked if still failing after retries
365
369
 
370
+ ## Termination Contract (MANDATORY)
371
+ You MUST call report_agent_job_result EXACTLY ONCE before exiting. NO exceptions.
372
+ - Success → result_status=completed after all verifications pass
373
+ - Failure → result_status=failed with error message (build error, file write fail)
374
+ - Blocked → result_status=blocked when upstream missing OR after retries exhausted
375
+ - Timeout → near max_runtime_seconds → revert partial unsafe work → result_status=blocked, error="timeout"
376
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
377
+
378
+ ## Hard Constraints
379
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv (orchestrator owns those).
380
+ - Do NOT call spawn_agents_on_csv (no recursion).
381
+
366
382
  ## Discovery Protocol
367
383
  Write task output to {sessionFolder}/discoveries/{task_id}.json:
368
384
  {
@@ -811,6 +811,24 @@ All roles read/write `{session}/discoveries.ndjson`:
811
811
 
812
812
  ---
813
813
 
814
+ ## Termination Contract (MANDATORY for ALL roles)
815
+
816
+ Every spawned worker — regardless of role — MUST call `report_agent_job_result` EXACTLY ONCE before exiting. NO exceptions:
817
+
818
+ | Path | Action |
819
+ |------|--------|
820
+ | Success | `status=completed` after verification passes |
821
+ | Failure | `status=failed` with error message (unrecoverable error) |
822
+ | Blocked | `status=failed` (no separate "blocked" enum here — use error message to explain blockage) |
823
+ | Timeout | Approaching `max_runtime_seconds` → revert partial unsafe work → `status=failed` with error="timeout" |
824
+
825
+ Rules:
826
+ - NEVER continue indefinitely.
827
+ - NEVER exit silently.
828
+ - NEVER omit `report_agent_job_result`.
829
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv — orchestrator owns those.
830
+ - Do NOT call `spawn_agents_on_csv` (no recursion).
831
+
814
832
  ## Output Format
815
833
 
816
834
  All roles use `report_agent_job_result` with this schema:
@@ -825,3 +843,5 @@ All roles use `report_agent_job_result` with this schema:
825
843
  "error": ""
826
844
  }
827
845
  ```
846
+
847
+ Note: spawn output_schema in SKILL.md uses `result_status` (not `status`). The orchestrator's merge step maps `result_status` → master `status`. Workers report via `report_agent_job_result` which the harness converts to the CSV result row — the field key here (`status`) is the worker-facing field name documented for this skill family.
@@ -178,10 +178,48 @@ Session: {sessionFolder}
178
178
  Discovery board: {sessionFolder}/discoveries.ndjson
179
179
  Previous context: 'prev_context' column
180
180
 
181
- ## Output
182
- result_status, findings, files_modified, coverage_score (QARUN only), error
181
+ ## Termination Contract (MANDATORY)
182
+ You MUST call report_agent_job_result EXACTLY ONCE before exiting. NO exceptions.
183
+ - Success → result_status=completed
184
+ - Failure → result_status=failed with error message
185
+ - Blocked → result_status=blocked when upstream missing
186
+ - Timeout → near max_runtime_seconds → result_status=blocked, error="timeout"
187
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
188
+
189
+ ## Output (must match output_schema)
190
+ {
191
+ "id": "<your CSV row id>",
192
+ "result_status": "completed" | "failed" | "blocked",
193
+ "findings": "<key findings, max 500 chars>",
194
+ "files_modified": "<semicolon-separated paths or empty>",
195
+ "coverage_score": "<0-100 or empty>" (QARUN only),
196
+ "error": "<message if not completed>"
197
+ }
198
+
199
+ ## Hard Constraints
200
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv (orchestrator owns those).
201
+ - Do NOT call spawn_agents_on_csv (no recursion).
183
202
  ```
184
203
 
204
+ ### Spawn output_schema
205
+
206
+ ```json
207
+ {
208
+ "type": "object",
209
+ "properties": {
210
+ "id": { "type": "string" },
211
+ "result_status": { "type": "string", "enum": ["completed", "failed", "blocked"] },
212
+ "findings": { "type": "string", "maxLength": 500 },
213
+ "files_modified": { "type": "string" },
214
+ "coverage_score": { "type": "string" },
215
+ "error": { "type": "string" }
216
+ },
217
+ "required": ["id", "result_status", "findings"]
218
+ }
219
+ ```
220
+
221
+ Merge maps `result_status` → master `status`.
222
+
185
223
  </actions>
186
224
  </state_machine>
187
225
 
@@ -172,10 +172,50 @@ Discovery board: {sessionFolder}/discoveries.ndjson
172
172
  Previous context: 'prev_context' column
173
173
  Dimensions: {skillRoot}/specs/dimensions.md
174
174
 
175
- ## Output
176
- result_status, findings, files_modified, finding_count, verdict (REV only), error
175
+ ## Termination Contract (MANDATORY)
176
+ You MUST call report_agent_job_result EXACTLY ONCE before exiting. NO exceptions.
177
+ - Success → result_status=completed after scan/review/fix completes
178
+ - Failure → result_status=failed with error message
179
+ - Blocked → result_status=blocked when upstream missing
180
+ - Timeout → near max_runtime_seconds → result_status=blocked, error="timeout"
181
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
182
+
183
+ ## Output (must match output_schema)
184
+ {
185
+ "id": "<your CSV row id>",
186
+ "result_status": "completed" | "failed" | "blocked",
187
+ "findings": "<key findings, max 500 chars>",
188
+ "files_modified": "<semicolon-separated paths or empty>",
189
+ "finding_count": "<integer or empty>",
190
+ "verdict": "PASS" | "WARN" | "BLOCK" | "" (REV only),
191
+ "error": "<message if not completed>"
192
+ }
193
+
194
+ ## Hard Constraints
195
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv (orchestrator owns those).
196
+ - Do NOT call spawn_agents_on_csv (no recursion).
177
197
  ```
178
198
 
199
+ ### Spawn output_schema
200
+
201
+ ```json
202
+ {
203
+ "type": "object",
204
+ "properties": {
205
+ "id": { "type": "string" },
206
+ "result_status": { "type": "string", "enum": ["completed", "failed", "blocked"] },
207
+ "findings": { "type": "string", "maxLength": 500 },
208
+ "files_modified": { "type": "string" },
209
+ "finding_count": { "type": "string" },
210
+ "verdict": { "type": "string", "enum": ["PASS", "WARN", "BLOCK", ""] },
211
+ "error": { "type": "string" }
212
+ },
213
+ "required": ["id", "result_status", "findings"]
214
+ }
215
+ ```
216
+
217
+ Merge maps `result_status` → master `status`.
218
+
179
219
  </actions>
180
220
  </state_machine>
181
221
 
@@ -187,10 +187,53 @@ Session: {sessionFolder}
187
187
  Discovery board: {sessionFolder}/discoveries.ndjson
188
188
  Previous context: 'prev_context' column
189
189
 
190
- ## Output
191
- result_status, findings, files_modified, debt_count, regression_detected (TDVAL), error
190
+ ## Termination Contract (MANDATORY)
191
+ You MUST call report_agent_job_result EXACTLY ONCE before exiting. NO exceptions.
192
+ - Success → result_status=completed after verification
193
+ - Failure → result_status=failed with error message
194
+ - Blocked → cannot proceed without upstream fix → result_status=blocked
195
+ - Timeout → near max_runtime_seconds → revert partial unsafe work → result_status=blocked, error="timeout"
196
+ - NEVER continue indefinitely. NEVER exit silently. NEVER omit the call.
197
+
198
+ ## Output (must match output_schema)
199
+ Return JSON:
200
+ {
201
+ "id": "<your CSV row id>",
202
+ "result_status": "completed" | "failed" | "blocked",
203
+ "findings": "<key findings, max 500 chars>",
204
+ "files_modified": "<semicolon-separated paths or empty>",
205
+ "debt_count": <integer or empty>,
206
+ "regression_detected": "true" | "false" | "" (TDVAL only),
207
+ "error": "<message if not completed>"
208
+ }
209
+
210
+ ## Hard Constraints
211
+ - Do NOT write to tasks.csv, wave-*.csv, results.csv (orchestrator owns those).
212
+ - Do NOT call spawn_agents_on_csv (no recursion).
192
213
  ```
193
214
 
215
+ ### Spawn output_schema
216
+
217
+ When the coordinator dispatches a wave via `spawn_agents_on_csv`, it MUST use the strict JSON Schema:
218
+
219
+ ```json
220
+ {
221
+ "type": "object",
222
+ "properties": {
223
+ "id": { "type": "string" },
224
+ "result_status": { "type": "string", "enum": ["completed", "failed", "blocked"] },
225
+ "findings": { "type": "string", "maxLength": 500 },
226
+ "files_modified": { "type": "string" },
227
+ "debt_count": { "type": "string" },
228
+ "regression_detected": { "type": "string", "enum": ["true", "false", ""] },
229
+ "error": { "type": "string" }
230
+ },
231
+ "required": ["id", "result_status", "findings"]
232
+ }
233
+ ```
234
+
235
+ Merge maps `result_status` → master `status`.
236
+
194
237
  </actions>
195
238
  </state_machine>
196
239