@openenvelope/schema 1.0.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/LICENSE +53 -0
- package/README.md +99 -0
- package/dist/index.cjs +617 -0
- package/dist/index.d.cts +139 -0
- package/dist/index.d.ts +139 -0
- package/dist/index.js +580 -0
- package/package.json +51 -0
- package/schema.json +575 -0
package/schema.json
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://schema.openenvelope.org/team/v1.json",
|
|
4
|
+
"title": "Envelope Team Definition",
|
|
5
|
+
"description": "Schema for an Envelope AI agent team definition. Reference as $schema in your .envelope.json file.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"$schema",
|
|
9
|
+
"name",
|
|
10
|
+
"slug",
|
|
11
|
+
"version",
|
|
12
|
+
"description",
|
|
13
|
+
"visibility",
|
|
14
|
+
"agents"
|
|
15
|
+
],
|
|
16
|
+
"additionalProperties": false,
|
|
17
|
+
"properties": {
|
|
18
|
+
"$schema": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"const": "https://schema.openenvelope.org/team/v1.json",
|
|
21
|
+
"description": "Must be 'https://schema.openenvelope.org/team/v1.json'"
|
|
22
|
+
},
|
|
23
|
+
"name": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"minLength": 1,
|
|
26
|
+
"maxLength": 80,
|
|
27
|
+
"description": "Human-readable display name shown in the registry."
|
|
28
|
+
},
|
|
29
|
+
"slug": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"pattern": "^[a-z0-9-]+$",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"maxLength": 60,
|
|
34
|
+
"description": "URL-safe identifier, unique within the registry. Lowercase letters, numbers, and hyphens only."
|
|
35
|
+
},
|
|
36
|
+
"version": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$",
|
|
39
|
+
"description": "Semver string (MAJOR.MINOR.PATCH). Versions are immutable once published."
|
|
40
|
+
},
|
|
41
|
+
"description": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"minLength": 1,
|
|
44
|
+
"maxLength": 300,
|
|
45
|
+
"description": "Short description shown in the registry."
|
|
46
|
+
},
|
|
47
|
+
"category": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"enum": [
|
|
50
|
+
"customer-support",
|
|
51
|
+
"sales",
|
|
52
|
+
"marketing",
|
|
53
|
+
"finance",
|
|
54
|
+
"hr",
|
|
55
|
+
"devops",
|
|
56
|
+
"engineering",
|
|
57
|
+
"data-analysis",
|
|
58
|
+
"legal",
|
|
59
|
+
"research",
|
|
60
|
+
"content",
|
|
61
|
+
"product",
|
|
62
|
+
"security",
|
|
63
|
+
"operations",
|
|
64
|
+
"other"
|
|
65
|
+
],
|
|
66
|
+
"description": "Registry category. Teams submitted without a valid category are published under 'other'."
|
|
67
|
+
},
|
|
68
|
+
"tags": {
|
|
69
|
+
"type": "array",
|
|
70
|
+
"items": { "type": "string", "maxLength": 50 },
|
|
71
|
+
"maxItems": 20,
|
|
72
|
+
"description": "Free-form tags for search. Not yet indexed for filtering — planned for registry v2."
|
|
73
|
+
},
|
|
74
|
+
"visibility": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"enum": ["public", "team", "private"],
|
|
77
|
+
"description": "'public' — listed in registry. 'team' — org members only. 'private' — publishing API key only."
|
|
78
|
+
},
|
|
79
|
+
"pricing": {
|
|
80
|
+
"$ref": "#/$defs/Pricing"
|
|
81
|
+
},
|
|
82
|
+
"forkable": {
|
|
83
|
+
"type": "boolean",
|
|
84
|
+
"default": true,
|
|
85
|
+
"description": "Whether other builders may fork this team. Defaults to true for public teams."
|
|
86
|
+
},
|
|
87
|
+
"forkedFrom": {
|
|
88
|
+
"$ref": "#/$defs/ForkedFrom"
|
|
89
|
+
},
|
|
90
|
+
"timeout": {
|
|
91
|
+
"$ref": "#/$defs/TeamTimeout"
|
|
92
|
+
},
|
|
93
|
+
"readme": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"maxLength": 10000,
|
|
96
|
+
"description": "Long-form Markdown documentation shown on the team's registry page."
|
|
97
|
+
},
|
|
98
|
+
"icon": {
|
|
99
|
+
"type": "string",
|
|
100
|
+
"format": "uri",
|
|
101
|
+
"description": "URL of a square PNG or SVG icon (min 256x256px). Must be publicly accessible."
|
|
102
|
+
},
|
|
103
|
+
"inputs": {
|
|
104
|
+
"type": "object",
|
|
105
|
+
"additionalProperties": { "$ref": "#/$defs/IOField" },
|
|
106
|
+
"description": "Named input fields the team accepts. Accepted by the registry; schema enforcement planned for v2."
|
|
107
|
+
},
|
|
108
|
+
"outputs": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"additionalProperties": { "$ref": "#/$defs/IOField" },
|
|
111
|
+
"description": "Named output fields the team returns. Accepted by the registry; output validation planned for v2."
|
|
112
|
+
},
|
|
113
|
+
"requiredSecrets": {
|
|
114
|
+
"type": "array",
|
|
115
|
+
"items": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"pattern": "^[A-Z][A-Z0-9_]*$",
|
|
118
|
+
"description": "Uppercase with underscores. E.g. ZENDESK_API_KEY."
|
|
119
|
+
},
|
|
120
|
+
"description": "Secret names the deployer must supply at install time. Values are never in the schema."
|
|
121
|
+
},
|
|
122
|
+
"requiredVariables": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": {
|
|
125
|
+
"type": "string",
|
|
126
|
+
"pattern": "^[A-Z][A-Z0-9_]*$",
|
|
127
|
+
"description": "Uppercase with underscores. E.g. SUPPORT_EMAIL."
|
|
128
|
+
},
|
|
129
|
+
"description": "Non-secret variable names the deployer must supply at install time."
|
|
130
|
+
},
|
|
131
|
+
"changelog": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"maxLength": 2000,
|
|
134
|
+
"description": "Human-readable description of what changed in this version. Best practice: include on every publish."
|
|
135
|
+
},
|
|
136
|
+
"agents": {
|
|
137
|
+
"type": "array",
|
|
138
|
+
"minItems": 1,
|
|
139
|
+
"items": { "$ref": "#/$defs/Agent" },
|
|
140
|
+
"description": "One or more agent definitions."
|
|
141
|
+
},
|
|
142
|
+
"gates": {
|
|
143
|
+
"type": "array",
|
|
144
|
+
"items": { "$ref": "#/$defs/HumanGate" },
|
|
145
|
+
"description": "Review checkpoints between pipeline steps. All gate types in v1 are human-in-the-loop. Automated gate types are planned for v2."
|
|
146
|
+
},
|
|
147
|
+
"schedule": {
|
|
148
|
+
"$ref": "#/$defs/TeamSchedule",
|
|
149
|
+
"description": "When and how the team is triggered. Omit for on-demand teams."
|
|
150
|
+
},
|
|
151
|
+
"pipeline": {
|
|
152
|
+
"type": "array",
|
|
153
|
+
"items": { "$ref": "#/$defs/PipelineStep" },
|
|
154
|
+
"description": "Ordered sequence of pipeline steps. When present, the runtime executes steps in order rather than dispatching all agents concurrently."
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
"$defs": {
|
|
159
|
+
"TeamSchedule": {
|
|
160
|
+
"type": "object",
|
|
161
|
+
"required": ["type"],
|
|
162
|
+
"description": "Defines when the team runs. Omit for on-demand teams.",
|
|
163
|
+
"additionalProperties": false,
|
|
164
|
+
"properties": {
|
|
165
|
+
"type": {
|
|
166
|
+
"type": "string",
|
|
167
|
+
"enum": ["manual", "cron"],
|
|
168
|
+
"description": "'manual' — triggered by API or UI only. 'cron' — scheduled via cron expression."
|
|
169
|
+
},
|
|
170
|
+
"cron": {
|
|
171
|
+
"type": "string",
|
|
172
|
+
"description": "Standard 5-field cron expression (e.g. '0 9 * * 1' for every Monday at 9am UTC). Required when type is 'cron'."
|
|
173
|
+
},
|
|
174
|
+
"label": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"description": "Human-readable description of the schedule. E.g. 'Every Monday at 9am UTC'."
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
"Pricing": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"required": ["model"],
|
|
184
|
+
"description": "Omit entirely for free teams. When present, model is required.",
|
|
185
|
+
"properties": {
|
|
186
|
+
"model": {
|
|
187
|
+
"type": "string",
|
|
188
|
+
"enum": ["free", "per_run", "per_k_tokens", "subscription"],
|
|
189
|
+
"description": "'subscription' is planned — not yet available in v1."
|
|
190
|
+
},
|
|
191
|
+
"amount": {
|
|
192
|
+
"type": "number",
|
|
193
|
+
"minimum": 0,
|
|
194
|
+
"description": "Price in the specified currency. Required when model is 'per_run' or 'per_k_tokens'."
|
|
195
|
+
},
|
|
196
|
+
"currency": {
|
|
197
|
+
"type": "string",
|
|
198
|
+
"pattern": "^[A-Z]{3}$",
|
|
199
|
+
"default": "usd",
|
|
200
|
+
"description": "ISO 4217 currency code. Defaults to 'usd'."
|
|
201
|
+
},
|
|
202
|
+
"interval": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"enum": ["month", "year"],
|
|
205
|
+
"description": "Required when model is 'subscription'. Defaults to 'month'."
|
|
206
|
+
},
|
|
207
|
+
"trialDays": {
|
|
208
|
+
"type": "integer",
|
|
209
|
+
"minimum": 0,
|
|
210
|
+
"description": "Free trial length in days. Only applicable when model is 'subscription'."
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
"ForkedFrom": {
|
|
216
|
+
"type": "object",
|
|
217
|
+
"required": ["ownerSlug", "teamSlug", "version"],
|
|
218
|
+
"description": "Attribution when this team was derived from another.",
|
|
219
|
+
"properties": {
|
|
220
|
+
"ownerSlug": { "type": "string" },
|
|
221
|
+
"teamSlug": { "type": "string" },
|
|
222
|
+
"version": { "type": "string" }
|
|
223
|
+
},
|
|
224
|
+
"additionalProperties": false
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
"TeamTimeout": {
|
|
228
|
+
"type": "object",
|
|
229
|
+
"description": "Default timeout configuration for all agents in the team. Per-agent modelConfig.timeoutMs overrides this.",
|
|
230
|
+
"properties": {
|
|
231
|
+
"runMs": {
|
|
232
|
+
"type": "integer",
|
|
233
|
+
"minimum": 1000,
|
|
234
|
+
"default": 30000,
|
|
235
|
+
"description": "Maximum wall-clock time in ms for the entire run."
|
|
236
|
+
},
|
|
237
|
+
"agentMs": {
|
|
238
|
+
"type": "integer",
|
|
239
|
+
"minimum": 1000,
|
|
240
|
+
"default": 30000,
|
|
241
|
+
"description": "Maximum time in ms for a single agent invocation."
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"additionalProperties": false
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
"IOField": {
|
|
248
|
+
"type": "object",
|
|
249
|
+
"description": "An input or output field definition.",
|
|
250
|
+
"properties": {
|
|
251
|
+
"type": {
|
|
252
|
+
"type": "string",
|
|
253
|
+
"enum": ["string", "number", "boolean", "object", "array"]
|
|
254
|
+
},
|
|
255
|
+
"description": { "type": "string" },
|
|
256
|
+
"required": { "type": "boolean", "default": false },
|
|
257
|
+
"enum": {
|
|
258
|
+
"type": "array",
|
|
259
|
+
"items": { "type": "string" },
|
|
260
|
+
"description": "Restricts value to one of these options."
|
|
261
|
+
},
|
|
262
|
+
"default": {
|
|
263
|
+
"description": "Default value when the field is not supplied."
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
"Agent": {
|
|
269
|
+
"type": "object",
|
|
270
|
+
"required": ["key", "name", "title", "role"],
|
|
271
|
+
"description": "An agent within the team.",
|
|
272
|
+
"additionalProperties": false,
|
|
273
|
+
"properties": {
|
|
274
|
+
"key": {
|
|
275
|
+
"type": "string",
|
|
276
|
+
"pattern": "^[a-z0-9_-]+$",
|
|
277
|
+
"description": "Unique within the team. Used in reportsToKey references."
|
|
278
|
+
},
|
|
279
|
+
"name": {
|
|
280
|
+
"type": "string",
|
|
281
|
+
"minLength": 1,
|
|
282
|
+
"maxLength": 80,
|
|
283
|
+
"description": "Display name."
|
|
284
|
+
},
|
|
285
|
+
"title": {
|
|
286
|
+
"type": "string",
|
|
287
|
+
"minLength": 1,
|
|
288
|
+
"maxLength": 100,
|
|
289
|
+
"description": "Job title shown in the team diagram. E.g. 'Head of Support'."
|
|
290
|
+
},
|
|
291
|
+
"role": {
|
|
292
|
+
"type": "string",
|
|
293
|
+
"description": "Free-form role description. Suggested values: 'manager', 'specialist', 'analyst'. Custom values are valid and passed through unchanged."
|
|
294
|
+
},
|
|
295
|
+
"adapterType": {
|
|
296
|
+
"type": "string",
|
|
297
|
+
"enum": [
|
|
298
|
+
"http",
|
|
299
|
+
"claude_local",
|
|
300
|
+
"openai_local",
|
|
301
|
+
"codex_local",
|
|
302
|
+
"gemini_local",
|
|
303
|
+
"opencode_local",
|
|
304
|
+
"cursor_local"
|
|
305
|
+
],
|
|
306
|
+
"description": "Runtime adapter. Runtimes must support 'http'. Local adapters are optional."
|
|
307
|
+
},
|
|
308
|
+
"reportsToKey": {
|
|
309
|
+
"type": "string",
|
|
310
|
+
"pattern": "^[a-z0-9_-]+$",
|
|
311
|
+
"description": "Key of the parent agent. Omit for top-level (root) agents."
|
|
312
|
+
},
|
|
313
|
+
"capabilities": {
|
|
314
|
+
"type": "array",
|
|
315
|
+
"items": { "type": "string" },
|
|
316
|
+
"description": "Free-form capability labels. E.g. ['triage', 'escalation']."
|
|
317
|
+
},
|
|
318
|
+
"prompt": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"description": "System prompt. May reference secrets as {{SECRET_NAME}} and variables as {{VARIABLE_NAME}}."
|
|
321
|
+
},
|
|
322
|
+
"model": {
|
|
323
|
+
"type": "string",
|
|
324
|
+
"description": "LLM in 'provider:model' format. E.g. 'anthropic:claude-opus-4-5'. Use this unless you need temperature or maxTokens."
|
|
325
|
+
},
|
|
326
|
+
"modelConfig": {
|
|
327
|
+
"$ref": "#/$defs/ModelConfig"
|
|
328
|
+
},
|
|
329
|
+
"allowedHosts": {
|
|
330
|
+
"type": "array",
|
|
331
|
+
"items": { "type": "string" },
|
|
332
|
+
"description": "Simple hostname allowlist. Cannot be combined with accessPolicy."
|
|
333
|
+
},
|
|
334
|
+
"accessPolicy": {
|
|
335
|
+
"$ref": "#/$defs/AccessPolicy"
|
|
336
|
+
},
|
|
337
|
+
"metadata": {
|
|
338
|
+
"type": "object",
|
|
339
|
+
"description": "Arbitrary key-value data preserved by the registry. Not interpreted by the runtime."
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
"ModelConfig": {
|
|
345
|
+
"type": "object",
|
|
346
|
+
"required": ["provider", "model"],
|
|
347
|
+
"description": "Full LLM configuration. Alternative to the flat 'model' field — use one or the other.",
|
|
348
|
+
"additionalProperties": false,
|
|
349
|
+
"properties": {
|
|
350
|
+
"provider": {
|
|
351
|
+
"type": "string",
|
|
352
|
+
"enum": ["anthropic", "openai", "google", "mistral", "openrouter"]
|
|
353
|
+
},
|
|
354
|
+
"model": {
|
|
355
|
+
"type": "string",
|
|
356
|
+
"description": "Provider-specific model identifier."
|
|
357
|
+
},
|
|
358
|
+
"temperature": {
|
|
359
|
+
"type": "number",
|
|
360
|
+
"minimum": 0,
|
|
361
|
+
"maximum": 2,
|
|
362
|
+
"description": "0–2. Defaults to runtime default."
|
|
363
|
+
},
|
|
364
|
+
"maxTokens": {
|
|
365
|
+
"type": "integer",
|
|
366
|
+
"minimum": 1,
|
|
367
|
+
"description": "Maximum output tokens per invocation."
|
|
368
|
+
},
|
|
369
|
+
"timeoutMs": {
|
|
370
|
+
"type": "integer",
|
|
371
|
+
"minimum": 1000,
|
|
372
|
+
"description": "Per-agent timeout in ms. Overrides team.timeout.agentMs."
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
"AccessPolicy": {
|
|
378
|
+
"type": "object",
|
|
379
|
+
"required": ["accessPolicyVersion", "defaultAction"],
|
|
380
|
+
"description": "Structured outbound request rules. Use in place of allowedHosts for deny rules, path matching, or reason strings.",
|
|
381
|
+
"additionalProperties": false,
|
|
382
|
+
"properties": {
|
|
383
|
+
"accessPolicyVersion": {
|
|
384
|
+
"type": "string",
|
|
385
|
+
"const": "1",
|
|
386
|
+
"description": "Always '1'."
|
|
387
|
+
},
|
|
388
|
+
"defaultAction": {
|
|
389
|
+
"type": "string",
|
|
390
|
+
"enum": ["allow", "deny"],
|
|
391
|
+
"description": "Applied when no rule matches. 'deny' is strongly recommended for agents with a known set of integrations."
|
|
392
|
+
},
|
|
393
|
+
"rules": {
|
|
394
|
+
"type": "array",
|
|
395
|
+
"items": { "$ref": "#/$defs/AccessPolicyRule" }
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
|
|
400
|
+
"AccessPolicyRule": {
|
|
401
|
+
"type": "object",
|
|
402
|
+
"required": ["action"],
|
|
403
|
+
"description": "A single access policy rule. Rules are evaluated top-to-bottom; first match wins.",
|
|
404
|
+
"additionalProperties": false,
|
|
405
|
+
"properties": {
|
|
406
|
+
"host": {
|
|
407
|
+
"type": "string",
|
|
408
|
+
"description": "Hostname to match. Supports leading wildcard (*.domain.com). Omit to match all hosts."
|
|
409
|
+
},
|
|
410
|
+
"methods": {
|
|
411
|
+
"type": "array",
|
|
412
|
+
"items": {
|
|
413
|
+
"type": "string",
|
|
414
|
+
"enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]
|
|
415
|
+
},
|
|
416
|
+
"description": "HTTP methods to match. Omit to match all methods."
|
|
417
|
+
},
|
|
418
|
+
"pathPrefix": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"description": "URL path prefix to match. Omit to match all paths."
|
|
421
|
+
},
|
|
422
|
+
"action": {
|
|
423
|
+
"type": "string",
|
|
424
|
+
"enum": ["allow", "deny", "require_approval"],
|
|
425
|
+
"description": "'require_approval' is treated as 'deny' in v1 — reserved for v2. Definitions using it today are forward-compatible."
|
|
426
|
+
},
|
|
427
|
+
"reason": {
|
|
428
|
+
"type": "string",
|
|
429
|
+
"description": "Shown in block messages and activity logs. Strongly recommended on 'deny' rules."
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
|
|
434
|
+
"HumanGate": {
|
|
435
|
+
"type": "object",
|
|
436
|
+
"required": [
|
|
437
|
+
"name",
|
|
438
|
+
"type",
|
|
439
|
+
"afterStep",
|
|
440
|
+
"triggersStep",
|
|
441
|
+
"fields",
|
|
442
|
+
"trigger",
|
|
443
|
+
"onReject"
|
|
444
|
+
],
|
|
445
|
+
"description": "A human review checkpoint between pipeline steps.",
|
|
446
|
+
"additionalProperties": false,
|
|
447
|
+
"properties": {
|
|
448
|
+
"name": {
|
|
449
|
+
"type": "string",
|
|
450
|
+
"pattern": "^[a-z0-9-]+$",
|
|
451
|
+
"description": "Unique name within the pipeline. Used as a stable identifier in webhook payloads and audit logs."
|
|
452
|
+
},
|
|
453
|
+
"type": {
|
|
454
|
+
"type": "string",
|
|
455
|
+
"enum": [
|
|
456
|
+
"decision",
|
|
457
|
+
"content_generation",
|
|
458
|
+
"classification",
|
|
459
|
+
"action"
|
|
460
|
+
],
|
|
461
|
+
"description": "The nature of the human decision."
|
|
462
|
+
},
|
|
463
|
+
"afterStep": {
|
|
464
|
+
"type": "string",
|
|
465
|
+
"description": "Key of the pipeline step whose output produces the records waiting for review."
|
|
466
|
+
},
|
|
467
|
+
"triggersStep": {
|
|
468
|
+
"type": "string",
|
|
469
|
+
"description": "Key of the pipeline step that runs once the gate trigger condition is met."
|
|
470
|
+
},
|
|
471
|
+
"fields": {
|
|
472
|
+
"type": "array",
|
|
473
|
+
"items": { "type": "string" },
|
|
474
|
+
"minItems": 1,
|
|
475
|
+
"description": "Record field names to surface in the review UI."
|
|
476
|
+
},
|
|
477
|
+
"trigger": {
|
|
478
|
+
"type": "string",
|
|
479
|
+
"enum": ["any_approved", "all_resolved", "threshold", "scheduled"],
|
|
480
|
+
"description": "When to release the gate and run the next step."
|
|
481
|
+
},
|
|
482
|
+
"thresholdCount": {
|
|
483
|
+
"type": "integer",
|
|
484
|
+
"minimum": 1,
|
|
485
|
+
"description": "Required when trigger is 'threshold'. Number of approved records needed."
|
|
486
|
+
},
|
|
487
|
+
"onReject": {
|
|
488
|
+
"type": "string",
|
|
489
|
+
"enum": ["skip", "rerun", "escalate", "halt"],
|
|
490
|
+
"description": "What happens when a human rejects a record."
|
|
491
|
+
},
|
|
492
|
+
"recordActions": {
|
|
493
|
+
"type": "array",
|
|
494
|
+
"items": { "$ref": "#/$defs/RecordAction" },
|
|
495
|
+
"description": "Per-record actions available in the review table."
|
|
496
|
+
},
|
|
497
|
+
"timeout": {
|
|
498
|
+
"$ref": "#/$defs/GateTimeout"
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
"RecordAction": {
|
|
504
|
+
"type": "object",
|
|
505
|
+
"required": ["label", "verb", "endpointTemplate"],
|
|
506
|
+
"additionalProperties": false,
|
|
507
|
+
"properties": {
|
|
508
|
+
"label": {
|
|
509
|
+
"type": "string",
|
|
510
|
+
"description": "Button label shown in the review UI."
|
|
511
|
+
},
|
|
512
|
+
"verb": {
|
|
513
|
+
"type": "string",
|
|
514
|
+
"enum": ["approve", "skip", "reject", "reset"],
|
|
515
|
+
"description": "Machine-readable action."
|
|
516
|
+
},
|
|
517
|
+
"endpointTemplate": {
|
|
518
|
+
"type": "string",
|
|
519
|
+
"description": "API endpoint to call. Use {fieldName} interpolation for record identifiers. {installId} is injected automatically."
|
|
520
|
+
},
|
|
521
|
+
"style": {
|
|
522
|
+
"type": "string",
|
|
523
|
+
"enum": ["primary", "secondary", "danger"],
|
|
524
|
+
"description": "'primary' (green), 'secondary' (neutral), 'danger' (red)."
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
|
|
529
|
+
"GateTimeout": {
|
|
530
|
+
"type": "object",
|
|
531
|
+
"required": ["after", "behaviour"],
|
|
532
|
+
"additionalProperties": false,
|
|
533
|
+
"properties": {
|
|
534
|
+
"after": {
|
|
535
|
+
"type": "string",
|
|
536
|
+
"pattern": "^\\d+[smhd]$",
|
|
537
|
+
"description": "Duration string. E.g. '72h', '30m', '1d'."
|
|
538
|
+
},
|
|
539
|
+
"behaviour": {
|
|
540
|
+
"type": "string",
|
|
541
|
+
"enum": ["escalate", "halt", "proceed"],
|
|
542
|
+
"description": "'escalate' — route to coordinator. 'halt' — stop and notify. 'proceed' — release and continue."
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
|
|
547
|
+
"PipelineStep": {
|
|
548
|
+
"type": "object",
|
|
549
|
+
"required": ["key", "agentKey"],
|
|
550
|
+
"description": "A single step in an ordered pipeline.",
|
|
551
|
+
"additionalProperties": false,
|
|
552
|
+
"properties": {
|
|
553
|
+
"key": {
|
|
554
|
+
"type": "string",
|
|
555
|
+
"pattern": "^[a-z0-9_-]+$",
|
|
556
|
+
"description": "Unique step identifier within the pipeline."
|
|
557
|
+
},
|
|
558
|
+
"agentKey": {
|
|
559
|
+
"type": "string",
|
|
560
|
+
"pattern": "^[a-z0-9_-]+$",
|
|
561
|
+
"description": "Key of the agent that executes this step."
|
|
562
|
+
},
|
|
563
|
+
"label": {
|
|
564
|
+
"type": "string",
|
|
565
|
+
"description": "Human-readable label shown in the operator dashboard."
|
|
566
|
+
},
|
|
567
|
+
"dependsOn": {
|
|
568
|
+
"type": "array",
|
|
569
|
+
"items": { "type": "string" },
|
|
570
|
+
"description": "Keys of steps that must complete before this step runs."
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|