@tea-agent/loop-agent 0.7.4 → 0.8.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.
Files changed (127) hide show
  1. package/AGENTS.md +143 -142
  2. package/CHANGELOG.md +148 -161
  3. package/README.md +206 -204
  4. package/bin/agent-worker.js +22 -22
  5. package/bin/loop-agent.js +21 -21
  6. package/dist/commands/init.js +518 -488
  7. package/dist/commands/loop-benchmark.js +11 -11
  8. package/dist/commands/pi-reuse-benchmark.js +16 -16
  9. package/dist/executors/cursor-executor.js +1 -1
  10. package/dist/governance/manifest-types.js +1 -1
  11. package/dist/task/runtime.js +27 -27
  12. package/dist/worker/cli.js +3 -3
  13. package/dist/worker/observability/event-store.js +2 -1
  14. package/dist/worker/observability/read-model.js +51 -13
  15. package/dist/worker/observe/paths.js +2 -2
  16. package/dist/worker/observe/routes.js +4 -3
  17. package/dist/worker/observe/static/app.js +1479 -1419
  18. package/dist/worker/observe/static/dag-layout.d.ts +31 -0
  19. package/dist/worker/observe/static/dag-layout.js +83 -0
  20. package/dist/worker/observe/static/index.html +63 -63
  21. package/dist/worker/observe/static/styles.css +722 -613
  22. package/dist/worker/pool/run-store.js +7 -8
  23. package/dist/worker/run-task/run-task.js +11 -2
  24. package/dist/worker/runner/run-ready.js +1 -1
  25. package/dist/workflows/dag/canvas-observer.js +275 -275
  26. package/docs/README.md +80 -76
  27. package/docs/agent-dag-recovery-playbook.md +184 -184
  28. package/docs/agent-dag-runner.md +42 -42
  29. package/docs/architecture/runtime-boundaries.md +162 -162
  30. package/docs/cursor-executor-usage.md +25 -25
  31. package/docs/decisions/README.md +3 -3
  32. package/docs/design/README.md +49 -49
  33. package/docs/development-principles.md +73 -73
  34. package/docs/dynamic-workflow-dag-engine-roadmap.md +1749 -1749
  35. package/docs/exec-plans/README.md +6 -6
  36. package/docs/exec-plans/active/README.md +11 -12
  37. package/docs/exec-plans/completed/README.md +35 -32
  38. package/docs/feature-workflow.md +187 -187
  39. package/docs/harness-methodology-debugging.md +153 -153
  40. package/docs/harness-methodology-tdd.md +130 -130
  41. package/docs/harness-methodology-verification.md +27 -27
  42. package/docs/init-surface.manifest.json +245 -241
  43. package/docs/loop-agent-harness.md +63 -55
  44. package/docs/production-readiness.md +96 -96
  45. package/docs/progress/README.md +3 -3
  46. package/docs/reports/README.md +9 -9
  47. package/docs/skills/README.md +6 -6
  48. package/docs/skills/vetted-skill-registry.md +26 -26
  49. package/docs/templates/adr.md +60 -60
  50. package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
  51. package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
  52. package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -117
  53. package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
  54. package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
  55. package/docs/templates/agent-dag-report.schema.json +454 -454
  56. package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
  57. package/docs/templates/agent-dag.base.json +195 -195
  58. package/docs/templates/agent-dag.final-verification.json +190 -190
  59. package/docs/templates/agent-dag.schema.json +316 -316
  60. package/docs/templates/agent-dag.supervised-implementation.json +500 -500
  61. package/docs/templates/exec-plan.md +64 -64
  62. package/docs/templates/feature-spec.md +53 -53
  63. package/docs/templates/harness.schema.json +218 -0
  64. package/docs/templates/hybrid-dag.json +193 -193
  65. package/docs/templates/init-evolution-review.md +33 -33
  66. package/docs/templates/interactive-ui-round2-experiment.md +66 -66
  67. package/docs/templates/product-line/AGENTS.md +8 -8
  68. package/docs/templates/product-line/README.md +9 -9
  69. package/docs/templates/product-line/acceptance.yaml +14 -14
  70. package/docs/templates/product-line/closeout.yaml +9 -9
  71. package/docs/templates/product-line/design.md +13 -13
  72. package/docs/templates/product-line/links.md +10 -10
  73. package/docs/templates/product-line/requirement.md +17 -17
  74. package/docs/templates/product-line/task-graph.yaml +15 -15
  75. package/docs/templates/product-line/task.yaml +65 -65
  76. package/docs/templates/product-line/test-plan.md +7 -7
  77. package/docs/templates/production-readiness-checklist.md +57 -57
  78. package/docs/templates/progress-log.md +17 -17
  79. package/docs/templates/project-start-checklist.md +9 -9
  80. package/docs/templates/qa-report.md +48 -48
  81. package/docs/templates/sprint-contract.md +29 -29
  82. package/docs/templates/worker-dogfood-evidence.md +52 -52
  83. package/docs/templates/worker-dogfood-setup.md +48 -48
  84. package/docs/verification-matrix.md +49 -49
  85. package/examples/decision-gate-agent-dag.json +123 -123
  86. package/examples/example-dag.json +51 -51
  87. package/examples/hybrid-loop-agent-dag.json +194 -194
  88. package/harness.json +73 -71
  89. package/package.json +68 -67
  90. package/scripts/check-product-line-docs.sh +22 -22
  91. package/scripts/check-task-pool-root.sh +32 -0
  92. package/skills/ai-engineering-context/SKILL.md +48 -48
  93. package/skills/code-review-core/SKILL.md +20 -20
  94. package/skills/codebase-scout/SKILL.md +19 -19
  95. package/skills/init-capability-evolution/SKILL.md +69 -69
  96. package/skills/loop-agent/SKILL.md +149 -149
  97. package/skills/loop-agent/references/README.md +67 -67
  98. package/skills/loop-agent/references/command-reference.md +432 -412
  99. package/skills/loop-agent/references/harness-policy.md +263 -263
  100. package/skills/loop-agent/references/hybrid-dag.md +216 -216
  101. package/skills/loop-agent/references/learned/README.md +21 -21
  102. package/skills/loop-agent/references/long-running-loop.md +59 -59
  103. package/skills/loop-agent/references/model-routing.md +36 -36
  104. package/skills/loop-agent/references/multi-worktree.md +54 -54
  105. package/skills/loop-agent/references/one-shot-runs.md +85 -85
  106. package/skills/loop-agent/references/orchestrator-and-interventions.md +169 -169
  107. package/skills/loop-agent/references/pi-prompt.md +23 -23
  108. package/skills/loop-agent/references/pi-subagent-assisted-mode.md +81 -81
  109. package/skills/loop-agent/references/post-implementation-and-patterns.md +44 -44
  110. package/skills/loop-agent/references/task-workflow.md +89 -89
  111. package/skills/loop-agent/references/verification-and-failure-handling.md +128 -128
  112. package/skills/requesting-code-review/SKILL.md +101 -101
  113. package/skills/requesting-code-review/code-reviewer.md +168 -168
  114. package/skills/systematic-debugging/CREATION-LOG.md +119 -119
  115. package/skills/systematic-debugging/SKILL.md +296 -296
  116. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
  117. package/skills/systematic-debugging/condition-based-waiting.md +115 -115
  118. package/skills/systematic-debugging/defense-in-depth.md +122 -122
  119. package/skills/systematic-debugging/find-polluter.sh +63 -63
  120. package/skills/systematic-debugging/root-cause-tracing.md +169 -169
  121. package/skills/systematic-debugging/test-academic.md +14 -14
  122. package/skills/systematic-debugging/test-pressure-1.md +58 -58
  123. package/skills/systematic-debugging/test-pressure-2.md +68 -68
  124. package/skills/systematic-debugging/test-pressure-3.md +69 -69
  125. package/skills/test-driven-development/SKILL.md +20 -20
  126. package/skills/verification-before-completion/SKILL.md +154 -154
  127. package/skills/webapp-testing/SKILL.md +19 -19
@@ -1,316 +1,316 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://loop-agent.local/schemas/agent-dag.schema.json",
4
- "title": "Agent DAG Spec",
5
- "type": "object",
6
- "additionalProperties": false,
7
- "required": ["version", "title", "tasks"],
8
- "properties": {
9
- "$schema": {
10
- "type": "string"
11
- },
12
- "version": {
13
- "enum": [1, 2],
14
- "default": 1
15
- },
16
- "title": {
17
- "type": "string",
18
- "minLength": 1
19
- },
20
- "objective": {
21
- "type": "string"
22
- },
23
- "successCriteria": {
24
- "type": "array",
25
- "items": { "type": "string", "minLength": 1 }
26
- },
27
- "globalConstraints": {
28
- "type": "array",
29
- "items": { "type": "string", "minLength": 1 }
30
- },
31
- "verifyStrategy": { "$ref": "#/$defs/verifyStrategy" },
32
- "defaults": {
33
- "type": "object",
34
- "additionalProperties": false,
35
- "properties": {
36
- "executor": { "$ref": "#/$defs/executor" },
37
- "model": { "type": "string" },
38
- "piBackend": {
39
- "enum": ["sdk-first", "cli-only"],
40
- "description": "Accepted metadata only. Runtime Pi backend selection is controlled by CODE_AGENT_PI_BACKEND."
41
- },
42
- "contextProfile": { "type": "string" },
43
- "skills": {
44
- "type": "array",
45
- "items": { "type": "string", "minLength": 1 }
46
- },
47
- "writePolicy": { "$ref": "#/$defs/writePolicy" }
48
- }
49
- },
50
- "skillsByRole": {
51
- "type": "object",
52
- "additionalProperties": {
53
- "type": "array",
54
- "items": { "type": "string", "minLength": 1 }
55
- }
56
- },
57
- "executorModels": {
58
- "type": "object",
59
- "description": "Executor-owned model routing template keyed by executor then complexity. Do not use legacy top-level models or defaults.model.",
60
- "additionalProperties": false,
61
- "properties": {
62
- "cursor": { "$ref": "#/$defs/complexityModelMap" },
63
- "pi": { "$ref": "#/$defs/complexityModelMap" }
64
- }
65
- },
66
- "tasks": {
67
- "type": "array",
68
- "minItems": 1,
69
- "items": { "$ref": "#/$defs/task" }
70
- }
71
- },
72
- "not": {
73
- "required": ["models"]
74
- },
75
- "$defs": {
76
- "complexity": {
77
- "enum": ["LOW", "MED", "HIGH"]
78
- },
79
- "executor": {
80
- "enum": ["cursor", "pi", "shell", "static"]
81
- },
82
- "toolProfile": {
83
- "enum": ["read-only", "write"]
84
- },
85
- "role": {
86
- "enum": ["planner", "scout", "implementer", "reviewer", "supervisor", "verifier", "closeout"]
87
- },
88
- "writePolicy": {
89
- "enum": ["read-only", "docs-only", "exclusive", "none"]
90
- },
91
- "complexityModelMap": {
92
- "type": "object",
93
- "additionalProperties": false,
94
- "properties": {
95
- "LOW": { "type": "string", "minLength": 1 },
96
- "MED": { "type": "string", "minLength": 1 },
97
- "HIGH": { "type": "string", "minLength": 1 }
98
- }
99
- },
100
- "verifyQuota": {
101
- "enum": ["1", "3", "full"]
102
- },
103
- "verifyStrategy": {
104
- "type": "object",
105
- "additionalProperties": false,
106
- "properties": {
107
- "intermediateQuota": { "$ref": "#/$defs/verifyQuota" },
108
- "finalQuota": {
109
- "const": "full",
110
- "default": "full",
111
- "description": "Final completion verification cannot be quota-reduced."
112
- },
113
- "focusedCommandSource": {
114
- "const": "adapter",
115
- "default": "adapter"
116
- }
117
- }
118
- },
119
- "shellVerifyEvidence": {
120
- "type": "object",
121
- "additionalProperties": false,
122
- "required": ["phase", "quota", "commandSource", "commandCount"],
123
- "properties": {
124
- "phase": { "enum": ["intermediate", "final"] },
125
- "quota": { "$ref": "#/$defs/verifyQuota" },
126
- "commandSource": { "enum": ["adapter", "inline"] },
127
- "commandCount": { "type": "integer", "minimum": 0 },
128
- "commandLabels": {
129
- "type": "array",
130
- "items": { "type": "string" },
131
- "default": []
132
- },
133
- "finalFullRequired": { "type": "boolean" }
134
- }
135
- },
136
- "repairArtifactGate": {
137
- "type": "object",
138
- "additionalProperties": false,
139
- "required": ["fromNodeId"],
140
- "properties": {
141
- "fromNodeId": {
142
- "type": "string",
143
- "pattern": "^[a-z][a-z0-9-]*$"
144
- }
145
- }
146
- },
147
- "shellConfig": {
148
- "type": "object",
149
- "additionalProperties": false,
150
- "properties": {
151
- "commands": {
152
- "type": "array",
153
- "items": { "type": "string", "minLength": 1 },
154
- "default": []
155
- },
156
- "preset": {
157
- "enum": ["loop-agent-standard-verify"]
158
- },
159
- "verdictGate": {
160
- "type": "object",
161
- "additionalProperties": false,
162
- "required": ["fromNodeId", "accept"],
163
- "properties": {
164
- "fromNodeId": {
165
- "type": "string",
166
- "pattern": "^[a-z][a-z0-9-]*$",
167
- "description": "Upstream node id whose canonical JSON output in the runner-injected current run directory ($HARNESS_DAG_RUN_DIR/<fromNodeId>.json) supplies the verdict line."
168
- },
169
- "accept": {
170
- "type": "array",
171
- "minItems": 1,
172
- "items": { "type": "string", "minLength": 1 },
173
- "description": "Exact assistantText/stdout verdict lines that pass the gate."
174
- },
175
- "label": {
176
- "type": "string",
177
- "minLength": 1,
178
- "description": "Optional human-readable gate label for error messages."
179
- },
180
- "lineMode": {
181
- "type": "string",
182
- "enum": ["first-non-empty", "first-verdict-line"],
183
- "default": "first-non-empty",
184
- "description": "Selects how verdict gates parse assistant output: first non-empty line (legacy) or first normalized line starting with 'VERDICT:' (common whole-line Markdown emphasis is normalized before exact accept matching)."
185
- }
186
- }
187
- },
188
- "verifyEvidence": { "$ref": "#/$defs/shellVerifyEvidence" },
189
- "repairArtifactGate": { "$ref": "#/$defs/repairArtifactGate" },
190
- "envAllowlist": {
191
- "type": "array",
192
- "items": {
193
- "type": "string",
194
- "pattern": "^[A-Z_][A-Z0-9_]*$"
195
- }
196
- },
197
- "timeoutMs": { "type": "number" },
198
- "cwd": { "type": "string", "minLength": 1 }
199
- },
200
- "anyOf": [
201
- { "required": ["commands"], "properties": { "commands": { "minItems": 1 } } },
202
- { "required": ["preset"] },
203
- { "required": ["verdictGate"] }
204
- ]
205
- },
206
- "staticConfig": {
207
- "type": "object",
208
- "additionalProperties": false,
209
- "required": ["resultMarkdown"],
210
- "properties": {
211
- "resultMarkdown": { "type": "string", "minLength": 1 },
212
- "status": { "enum": ["success", "error"] }
213
- }
214
- },
215
- "promptSource": {
216
- "type": "object",
217
- "additionalProperties": false,
218
- "required": ["type", "path", "sha256"],
219
- "properties": {
220
- "type": { "const": "markdown" },
221
- "path": { "type": "string", "minLength": 1 },
222
- "sha256": { "type": "string", "minLength": 1 }
223
- }
224
- },
225
- "task": {
226
- "type": "object",
227
- "additionalProperties": false,
228
- "required": ["id", "depends_on", "complexity"],
229
- "properties": {
230
- "id": {
231
- "type": "string",
232
- "pattern": "^[a-z][a-z0-9-]*$"
233
- },
234
- "depends_on": {
235
- "type": "array",
236
- "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
237
- "default": []
238
- },
239
- "complexity": { "$ref": "#/$defs/complexity" },
240
- "subtask_prompt": {
241
- "type": "string",
242
- "minLength": 1
243
- },
244
- "subtask_prompt_markdown": {
245
- "type": "string",
246
- "minLength": 1
247
- },
248
- "subtask_prompt_source": { "$ref": "#/$defs/promptSource" },
249
- "executor": {
250
- "$ref": "#/$defs/executor",
251
- "default": "pi"
252
- },
253
- "role": { "$ref": "#/$defs/role" },
254
- "skills": {
255
- "type": "array",
256
- "items": { "type": "string", "minLength": 1 }
257
- },
258
- "toolProfile": { "$ref": "#/$defs/toolProfile" },
259
- "writePolicy": { "$ref": "#/$defs/writePolicy" },
260
- "writeSet": {
261
- "type": "array",
262
- "items": { "type": "string", "minLength": 1 }
263
- },
264
- "piStep": {
265
- "type": "string",
266
- "minLength": 1
267
- },
268
- "shell": {
269
- "$ref": "#/$defs/shellConfig"
270
- },
271
- "static": {
272
- "$ref": "#/$defs/staticConfig"
273
- },
274
- "outputContract": {
275
- "type": "string",
276
- "minLength": 1
277
- },
278
- "allowedPaths": {
279
- "type": "array",
280
- "items": { "type": "string", "minLength": 1 },
281
- "default": []
282
- },
283
- "forbiddenPaths": {
284
- "type": "array",
285
- "items": { "type": "string", "minLength": 1 },
286
- "default": []
287
- },
288
- "decisionGate": {
289
- "type": "object",
290
- "additionalProperties": false,
291
- "required": ["enabled"],
292
- "properties": {
293
- "enabled": { "type": "boolean" },
294
- "schemaVersion": { "const": 1 },
295
- "mode": {
296
- "enum": ["record-only", "pause-on-human"],
297
- "default": "record-only"
298
- }
299
- }
300
- }
301
- },
302
- "oneOf": [
303
- {
304
- "description": "Inline prompt only; subtask_prompt_markdown must be absent.",
305
- "required": ["subtask_prompt"],
306
- "not": { "required": ["subtask_prompt_markdown"] }
307
- },
308
- {
309
- "description": "Markdown-backed prompt only; subtask_prompt must be absent until file loader resolves it.",
310
- "required": ["subtask_prompt_markdown"],
311
- "not": { "required": ["subtask_prompt"] }
312
- }
313
- ]
314
- }
315
- }
316
- }
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://loop-agent.local/schemas/agent-dag.schema.json",
4
+ "title": "Agent DAG Spec",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["version", "title", "tasks"],
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string"
11
+ },
12
+ "version": {
13
+ "enum": [1, 2],
14
+ "default": 1
15
+ },
16
+ "title": {
17
+ "type": "string",
18
+ "minLength": 1
19
+ },
20
+ "objective": {
21
+ "type": "string"
22
+ },
23
+ "successCriteria": {
24
+ "type": "array",
25
+ "items": { "type": "string", "minLength": 1 }
26
+ },
27
+ "globalConstraints": {
28
+ "type": "array",
29
+ "items": { "type": "string", "minLength": 1 }
30
+ },
31
+ "verifyStrategy": { "$ref": "#/$defs/verifyStrategy" },
32
+ "defaults": {
33
+ "type": "object",
34
+ "additionalProperties": false,
35
+ "properties": {
36
+ "executor": { "$ref": "#/$defs/executor" },
37
+ "model": { "type": "string" },
38
+ "piBackend": {
39
+ "enum": ["sdk-first", "cli-only"],
40
+ "description": "Accepted metadata only. Runtime Pi backend selection is controlled by CODE_AGENT_PI_BACKEND."
41
+ },
42
+ "contextProfile": { "type": "string" },
43
+ "skills": {
44
+ "type": "array",
45
+ "items": { "type": "string", "minLength": 1 }
46
+ },
47
+ "writePolicy": { "$ref": "#/$defs/writePolicy" }
48
+ }
49
+ },
50
+ "skillsByRole": {
51
+ "type": "object",
52
+ "additionalProperties": {
53
+ "type": "array",
54
+ "items": { "type": "string", "minLength": 1 }
55
+ }
56
+ },
57
+ "executorModels": {
58
+ "type": "object",
59
+ "description": "Executor-owned model routing template keyed by executor then complexity. Do not use legacy top-level models or defaults.model.",
60
+ "additionalProperties": false,
61
+ "properties": {
62
+ "cursor": { "$ref": "#/$defs/complexityModelMap" },
63
+ "pi": { "$ref": "#/$defs/complexityModelMap" }
64
+ }
65
+ },
66
+ "tasks": {
67
+ "type": "array",
68
+ "minItems": 1,
69
+ "items": { "$ref": "#/$defs/task" }
70
+ }
71
+ },
72
+ "not": {
73
+ "required": ["models"]
74
+ },
75
+ "$defs": {
76
+ "complexity": {
77
+ "enum": ["LOW", "MED", "HIGH"]
78
+ },
79
+ "executor": {
80
+ "enum": ["cursor", "pi", "shell", "static"]
81
+ },
82
+ "toolProfile": {
83
+ "enum": ["read-only", "write"]
84
+ },
85
+ "role": {
86
+ "enum": ["planner", "scout", "implementer", "reviewer", "supervisor", "verifier", "closeout"]
87
+ },
88
+ "writePolicy": {
89
+ "enum": ["read-only", "docs-only", "exclusive", "none"]
90
+ },
91
+ "complexityModelMap": {
92
+ "type": "object",
93
+ "additionalProperties": false,
94
+ "properties": {
95
+ "LOW": { "type": "string", "minLength": 1 },
96
+ "MED": { "type": "string", "minLength": 1 },
97
+ "HIGH": { "type": "string", "minLength": 1 }
98
+ }
99
+ },
100
+ "verifyQuota": {
101
+ "enum": ["1", "3", "full"]
102
+ },
103
+ "verifyStrategy": {
104
+ "type": "object",
105
+ "additionalProperties": false,
106
+ "properties": {
107
+ "intermediateQuota": { "$ref": "#/$defs/verifyQuota" },
108
+ "finalQuota": {
109
+ "const": "full",
110
+ "default": "full",
111
+ "description": "Final completion verification cannot be quota-reduced."
112
+ },
113
+ "focusedCommandSource": {
114
+ "const": "adapter",
115
+ "default": "adapter"
116
+ }
117
+ }
118
+ },
119
+ "shellVerifyEvidence": {
120
+ "type": "object",
121
+ "additionalProperties": false,
122
+ "required": ["phase", "quota", "commandSource", "commandCount"],
123
+ "properties": {
124
+ "phase": { "enum": ["intermediate", "final"] },
125
+ "quota": { "$ref": "#/$defs/verifyQuota" },
126
+ "commandSource": { "enum": ["adapter", "inline"] },
127
+ "commandCount": { "type": "integer", "minimum": 0 },
128
+ "commandLabels": {
129
+ "type": "array",
130
+ "items": { "type": "string" },
131
+ "default": []
132
+ },
133
+ "finalFullRequired": { "type": "boolean" }
134
+ }
135
+ },
136
+ "repairArtifactGate": {
137
+ "type": "object",
138
+ "additionalProperties": false,
139
+ "required": ["fromNodeId"],
140
+ "properties": {
141
+ "fromNodeId": {
142
+ "type": "string",
143
+ "pattern": "^[a-z][a-z0-9-]*$"
144
+ }
145
+ }
146
+ },
147
+ "shellConfig": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "properties": {
151
+ "commands": {
152
+ "type": "array",
153
+ "items": { "type": "string", "minLength": 1 },
154
+ "default": []
155
+ },
156
+ "preset": {
157
+ "enum": ["loop-agent-standard-verify"]
158
+ },
159
+ "verdictGate": {
160
+ "type": "object",
161
+ "additionalProperties": false,
162
+ "required": ["fromNodeId", "accept"],
163
+ "properties": {
164
+ "fromNodeId": {
165
+ "type": "string",
166
+ "pattern": "^[a-z][a-z0-9-]*$",
167
+ "description": "Upstream node id whose canonical JSON output in the runner-injected current run directory ($HARNESS_DAG_RUN_DIR/<fromNodeId>.json) supplies the verdict line."
168
+ },
169
+ "accept": {
170
+ "type": "array",
171
+ "minItems": 1,
172
+ "items": { "type": "string", "minLength": 1 },
173
+ "description": "Exact assistantText/stdout verdict lines that pass the gate."
174
+ },
175
+ "label": {
176
+ "type": "string",
177
+ "minLength": 1,
178
+ "description": "Optional human-readable gate label for error messages."
179
+ },
180
+ "lineMode": {
181
+ "type": "string",
182
+ "enum": ["first-non-empty", "first-verdict-line"],
183
+ "default": "first-non-empty",
184
+ "description": "Selects how verdict gates parse assistant output: first non-empty line (legacy) or first normalized line starting with 'VERDICT:' (common whole-line Markdown emphasis is normalized before exact accept matching)."
185
+ }
186
+ }
187
+ },
188
+ "verifyEvidence": { "$ref": "#/$defs/shellVerifyEvidence" },
189
+ "repairArtifactGate": { "$ref": "#/$defs/repairArtifactGate" },
190
+ "envAllowlist": {
191
+ "type": "array",
192
+ "items": {
193
+ "type": "string",
194
+ "pattern": "^[A-Z_][A-Z0-9_]*$"
195
+ }
196
+ },
197
+ "timeoutMs": { "type": "number" },
198
+ "cwd": { "type": "string", "minLength": 1 }
199
+ },
200
+ "anyOf": [
201
+ { "required": ["commands"], "properties": { "commands": { "minItems": 1 } } },
202
+ { "required": ["preset"] },
203
+ { "required": ["verdictGate"] }
204
+ ]
205
+ },
206
+ "staticConfig": {
207
+ "type": "object",
208
+ "additionalProperties": false,
209
+ "required": ["resultMarkdown"],
210
+ "properties": {
211
+ "resultMarkdown": { "type": "string", "minLength": 1 },
212
+ "status": { "enum": ["success", "error"] }
213
+ }
214
+ },
215
+ "promptSource": {
216
+ "type": "object",
217
+ "additionalProperties": false,
218
+ "required": ["type", "path", "sha256"],
219
+ "properties": {
220
+ "type": { "const": "markdown" },
221
+ "path": { "type": "string", "minLength": 1 },
222
+ "sha256": { "type": "string", "minLength": 1 }
223
+ }
224
+ },
225
+ "task": {
226
+ "type": "object",
227
+ "additionalProperties": false,
228
+ "required": ["id", "depends_on", "complexity"],
229
+ "properties": {
230
+ "id": {
231
+ "type": "string",
232
+ "pattern": "^[a-z][a-z0-9-]*$"
233
+ },
234
+ "depends_on": {
235
+ "type": "array",
236
+ "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
237
+ "default": []
238
+ },
239
+ "complexity": { "$ref": "#/$defs/complexity" },
240
+ "subtask_prompt": {
241
+ "type": "string",
242
+ "minLength": 1
243
+ },
244
+ "subtask_prompt_markdown": {
245
+ "type": "string",
246
+ "minLength": 1
247
+ },
248
+ "subtask_prompt_source": { "$ref": "#/$defs/promptSource" },
249
+ "executor": {
250
+ "$ref": "#/$defs/executor",
251
+ "default": "pi"
252
+ },
253
+ "role": { "$ref": "#/$defs/role" },
254
+ "skills": {
255
+ "type": "array",
256
+ "items": { "type": "string", "minLength": 1 }
257
+ },
258
+ "toolProfile": { "$ref": "#/$defs/toolProfile" },
259
+ "writePolicy": { "$ref": "#/$defs/writePolicy" },
260
+ "writeSet": {
261
+ "type": "array",
262
+ "items": { "type": "string", "minLength": 1 }
263
+ },
264
+ "piStep": {
265
+ "type": "string",
266
+ "minLength": 1
267
+ },
268
+ "shell": {
269
+ "$ref": "#/$defs/shellConfig"
270
+ },
271
+ "static": {
272
+ "$ref": "#/$defs/staticConfig"
273
+ },
274
+ "outputContract": {
275
+ "type": "string",
276
+ "minLength": 1
277
+ },
278
+ "allowedPaths": {
279
+ "type": "array",
280
+ "items": { "type": "string", "minLength": 1 },
281
+ "default": []
282
+ },
283
+ "forbiddenPaths": {
284
+ "type": "array",
285
+ "items": { "type": "string", "minLength": 1 },
286
+ "default": []
287
+ },
288
+ "decisionGate": {
289
+ "type": "object",
290
+ "additionalProperties": false,
291
+ "required": ["enabled"],
292
+ "properties": {
293
+ "enabled": { "type": "boolean" },
294
+ "schemaVersion": { "const": 1 },
295
+ "mode": {
296
+ "enum": ["record-only", "pause-on-human"],
297
+ "default": "record-only"
298
+ }
299
+ }
300
+ }
301
+ },
302
+ "oneOf": [
303
+ {
304
+ "description": "Inline prompt only; subtask_prompt_markdown must be absent.",
305
+ "required": ["subtask_prompt"],
306
+ "not": { "required": ["subtask_prompt_markdown"] }
307
+ },
308
+ {
309
+ "description": "Markdown-backed prompt only; subtask_prompt must be absent until file loader resolves it.",
310
+ "required": ["subtask_prompt_markdown"],
311
+ "not": { "required": ["subtask_prompt"] }
312
+ }
313
+ ]
314
+ }
315
+ }
316
+ }