vinta-ai-workflows 0.7.0-alpha9 → 0.7.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/CHANGELOG.md +473 -621
- package/README.md +33 -19
- package/package.json +4 -1
- package/schemas/README.md +11 -3
- package/schemas/ai-models.v1.schema.json +5 -0
- package/schemas/interview-answers.v1.schema.json +122 -0
- package/schemas/interview-round.v1.schema.json +346 -0
- package/schemas/plan-review.v1.schema.json +342 -0
- package/schemas/postmortem.v1.schema.json +848 -3
- package/schemas/prs-context-comments.v1.schema.json +1 -1
- package/schemas/prs-context-frontmatter.v1.schema.json +18 -7
- package/schemas/vinta-ai-workflows-config.v1.schema.json +677 -18
- package/schemas/workflow.v1.schema.json +616 -26
- package/skills/vinta-analyze-codebase/SKILL.md +5 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +154 -31
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/README.md +1 -1
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/django/notes.md +36 -1
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/README.md +85 -0
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/lib-template.sh +160 -0
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/prepare-template.sh +250 -0
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/teardown-template.sh +96 -0
- package/skills/vinta-derive-skills/SKILL.md +23 -15
- package/skills/vinta-derive-skills/resources/dependency-license-block.md +8 -9
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md +1 -1
- package/skills/vinta-derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md +3 -3
- package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +21 -2
- package/skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md +3 -3
- package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/SKILL.md +121 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/docs/D4-concurrency.md +28 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/round-01.json +60 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md +1 -1
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh +34 -7
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +363 -142
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml +19 -13
- package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +39 -21
- package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md +8 -6
- package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-review-loop/SKILL.md +181 -0
- package/skills/vinta-derive-skills/resources/plan-execution/README.md +40 -7
- package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +14 -35
- package/skills/vinta-derive-skills/resources/plan-execution/partials/commit-strategy/stacked.md +21 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/dispatched-agent.md +31 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +67 -6
- package/skills/vinta-derive-skills/resources/plan-execution/partials/maestro-live-run.md +44 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +9 -3
- package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +95 -50
- package/skills/vinta-derive-skills/resources/plan-execution/partials/pr-context.md +4 -2
- package/skills/vinta-derive-skills/resources/plan-execution/partials/relay-questions.md +13 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/review-loop.md +81 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +86 -17
- package/skills/vinta-derive-skills/resources/plan-execution/shell/amend-plan-template.md +35 -16
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +12 -1
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +49 -33
- package/skills/vinta-derive-skills/resources/plan-execution/shell/integrate-phase-template.md +2 -1
- package/skills/vinta-derive-skills/resources/plan-execution/shell/review-phase-template.md +19 -27
- package/skills/vinta-derive-skills/resources/prs-context-template.md +5 -4
- package/skills/vinta-derive-skills/resources/systematic-debugging-mcp-tools.md +1 -1
- package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +8 -8
- package/skills/vinta-derive-skills/resources/write-unit-test-packs/stacks/django.md +4 -1
- package/skills/vinta-derive-skills/resources/write-unit-test-template.md +3 -0
- package/skills/vinta-derive-subagents/SKILL.md +25 -9
- package/skills/vinta-install-ai-tools-setup/SKILL.md +29 -2
- package/skills/vinta-migrate-plans-specs/SKILL.md +7 -7
- package/skills/vinta-sync-ai-tools/SKILL.md +19 -2
- package/skills/vinta-update-project-skills/SKILL.md +1 -0
- package/skills/vinta-write-agents-md/SKILL.md +10 -6
- package/skills/vinta-write-agents-md/resources/asking-the-human.md +56 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +0 -101
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://github.com/vintasoftware/vinta-ai-workflows/schemas/postmortem.v1.schema.json",
|
|
4
4
|
"title": "vinta-ai-maestro plan post-mortem",
|
|
5
|
-
"description": "What one finished `vinta-ai-maestro` run learned about the plan that produced it: dependencies that were never used, dependencies discovered missing, same-wave phases that conflicted,
|
|
5
|
+
"description": "What one finished `vinta-ai-maestro` run learned about the plan that produced it: dependencies that were never used, dependencies discovered missing, same-wave phases that conflicted, phases whose duration diverged from their wave, what each gate cost, and changes the run made to its own plan while it ran. Ids, waves, paths, durations and counts only. Lives at `.vinta-ai-maestro/runs/<run-id>/postmortem.json` in a target project, emitted by `vinta-ai-maestro` after a run ends and read by `plan-feature` when planning the next feature in the same repo. GENERATED from packages/vinta-ai-maestro/src/postmortem/postmortem.ts — edit there, not here. See schemas/README.md for versioning rules.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
8
|
"$schema": {
|
|
@@ -169,6 +169,14 @@
|
|
|
169
169
|
"maximum": 9007199254740991,
|
|
170
170
|
"description": "The wave whose merge produced the conflict."
|
|
171
171
|
},
|
|
172
|
+
"where": {
|
|
173
|
+
"description": "`wave`: the wave merge. `base`: building a phase’s `integ-` base out of its dependencies, a wave earlier. Absent on post-mortems written before base conflicts were counted.",
|
|
174
|
+
"type": "string",
|
|
175
|
+
"enum": [
|
|
176
|
+
"base",
|
|
177
|
+
"wave"
|
|
178
|
+
]
|
|
179
|
+
},
|
|
172
180
|
"nodes": {
|
|
173
181
|
"minItems": 2,
|
|
174
182
|
"type": "array",
|
|
@@ -191,6 +199,37 @@
|
|
|
191
199
|
"minimum": 0,
|
|
192
200
|
"maximum": 9007199254740991,
|
|
193
201
|
"description": "Conflict-fixer rounds the resolution took. High is a strong split signal."
|
|
202
|
+
},
|
|
203
|
+
"reverted_deletions": {
|
|
204
|
+
"description": "Paths where the resolution kept lines one side had deleted — a fixer keeping “both sides”, or the `append_only` union driver. Flagged, not refused: check each deletion reached the branch. Absent when there were none.",
|
|
205
|
+
"type": "array",
|
|
206
|
+
"items": {
|
|
207
|
+
"type": "object",
|
|
208
|
+
"properties": {
|
|
209
|
+
"path": {
|
|
210
|
+
"type": "string",
|
|
211
|
+
"maxLength": 500
|
|
212
|
+
},
|
|
213
|
+
"node": {
|
|
214
|
+
"type": "string",
|
|
215
|
+
"maxLength": 200,
|
|
216
|
+
"description": "The phase whose deletion was reverted, or the branch standing in when no phase on that side touched the path."
|
|
217
|
+
},
|
|
218
|
+
"lines": {
|
|
219
|
+
"type": "integer",
|
|
220
|
+
"minimum": 1,
|
|
221
|
+
"maximum": 9007199254740991,
|
|
222
|
+
"description": "Lines that side deleted and the resolution kept. A count, never the lines."
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"required": [
|
|
226
|
+
"path",
|
|
227
|
+
"node",
|
|
228
|
+
"lines"
|
|
229
|
+
],
|
|
230
|
+
"additionalProperties": false,
|
|
231
|
+
"description": "A deletion a merge resolution undid. Identifiers and a count only."
|
|
232
|
+
}
|
|
194
233
|
}
|
|
195
234
|
},
|
|
196
235
|
"required": [
|
|
@@ -203,6 +242,73 @@
|
|
|
203
242
|
"description": "Two same-wave phases that actually fought over the same code at integration."
|
|
204
243
|
}
|
|
205
244
|
},
|
|
245
|
+
"gate_costs": {
|
|
246
|
+
"type": "array",
|
|
247
|
+
"items": {
|
|
248
|
+
"type": "object",
|
|
249
|
+
"properties": {
|
|
250
|
+
"gate": {
|
|
251
|
+
"type": "string",
|
|
252
|
+
"minLength": 1,
|
|
253
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
254
|
+
},
|
|
255
|
+
"runs": {
|
|
256
|
+
"type": "integer",
|
|
257
|
+
"minimum": 1,
|
|
258
|
+
"maximum": 9007199254740991,
|
|
259
|
+
"description": "Verdicts recorded for this gate, over every phase and every fix round."
|
|
260
|
+
},
|
|
261
|
+
"cached_runs": {
|
|
262
|
+
"type": "integer",
|
|
263
|
+
"minimum": 0,
|
|
264
|
+
"maximum": 9007199254740991,
|
|
265
|
+
"description": "Of those, the ones the result cache served. They cost this run nothing."
|
|
266
|
+
},
|
|
267
|
+
"ran_ms": {
|
|
268
|
+
"type": "integer",
|
|
269
|
+
"minimum": 0,
|
|
270
|
+
"maximum": 9007199254740991,
|
|
271
|
+
"description": "Summed runtime of the verdicts the run actually paid for — the runner’s own measurement, not the distance between two journal rows. Cache hits are excluded."
|
|
272
|
+
},
|
|
273
|
+
"slowest_ms": {
|
|
274
|
+
"type": "integer",
|
|
275
|
+
"minimum": 0,
|
|
276
|
+
"maximum": 9007199254740991,
|
|
277
|
+
"description": "The slowest single paid run. What a `timeout_s` is set against."
|
|
278
|
+
},
|
|
279
|
+
"cache_saved_ms": {
|
|
280
|
+
"type": "integer",
|
|
281
|
+
"minimum": 0,
|
|
282
|
+
"maximum": 9007199254740991,
|
|
283
|
+
"description": "Summed runtime of the cache hits: what those gates cost the last time they really ran. An estimate of time saved, never additive with `ran_ms`."
|
|
284
|
+
},
|
|
285
|
+
"failed_runs": {
|
|
286
|
+
"type": "integer",
|
|
287
|
+
"minimum": 0,
|
|
288
|
+
"maximum": 9007199254740991,
|
|
289
|
+
"description": "Verdicts that came back red."
|
|
290
|
+
},
|
|
291
|
+
"timed_out_runs": {
|
|
292
|
+
"type": "integer",
|
|
293
|
+
"minimum": 0,
|
|
294
|
+
"maximum": 9007199254740991,
|
|
295
|
+
"description": "Verdicts killed at `timeout_s`. The most expensive kind of run there is."
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
"required": [
|
|
299
|
+
"gate",
|
|
300
|
+
"runs",
|
|
301
|
+
"cached_runs",
|
|
302
|
+
"ran_ms",
|
|
303
|
+
"slowest_ms",
|
|
304
|
+
"cache_saved_ms",
|
|
305
|
+
"failed_runs",
|
|
306
|
+
"timed_out_runs"
|
|
307
|
+
],
|
|
308
|
+
"additionalProperties": false,
|
|
309
|
+
"description": "What one gate cost the run. A plan is sized against this: the gate that dominates `ran_ms` is the one whose pool capacity decides the wall clock, and a gate whose `runs` far exceeds its phases is a fix loop re-paying for the same suite."
|
|
310
|
+
}
|
|
311
|
+
},
|
|
206
312
|
"duration_divergences": {
|
|
207
313
|
"type": "array",
|
|
208
314
|
"items": {
|
|
@@ -254,13 +360,740 @@
|
|
|
254
360
|
"additionalProperties": false,
|
|
255
361
|
"description": "A phase whose real duration was wildly out of line with its wave placement — which is exactly what makes the next plan’s parallelism estimate wrong."
|
|
256
362
|
}
|
|
363
|
+
},
|
|
364
|
+
"critical_path": {
|
|
365
|
+
"anyOf": [
|
|
366
|
+
{
|
|
367
|
+
"type": "object",
|
|
368
|
+
"properties": {
|
|
369
|
+
"nodes": {
|
|
370
|
+
"type": "array",
|
|
371
|
+
"items": {
|
|
372
|
+
"type": "object",
|
|
373
|
+
"properties": {
|
|
374
|
+
"node": {
|
|
375
|
+
"type": "string",
|
|
376
|
+
"minLength": 1,
|
|
377
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
378
|
+
},
|
|
379
|
+
"wave": {
|
|
380
|
+
"type": "integer",
|
|
381
|
+
"minimum": -9007199254740991,
|
|
382
|
+
"maximum": 9007199254740991
|
|
383
|
+
},
|
|
384
|
+
"span_ms": {
|
|
385
|
+
"type": "integer",
|
|
386
|
+
"minimum": 0,
|
|
387
|
+
"maximum": 9007199254740991
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
"required": [
|
|
391
|
+
"node",
|
|
392
|
+
"wave",
|
|
393
|
+
"span_ms"
|
|
394
|
+
],
|
|
395
|
+
"additionalProperties": false
|
|
396
|
+
},
|
|
397
|
+
"description": "The chain in the order it ran, each with the time it was running."
|
|
398
|
+
},
|
|
399
|
+
"span_ms": {
|
|
400
|
+
"type": "integer",
|
|
401
|
+
"minimum": 0,
|
|
402
|
+
"maximum": 9007199254740991,
|
|
403
|
+
"description": "The chain’s total. The floor this graph could reach."
|
|
404
|
+
},
|
|
405
|
+
"share_of_elapsed": {
|
|
406
|
+
"type": "number",
|
|
407
|
+
"minimum": 0,
|
|
408
|
+
"maximum": 1,
|
|
409
|
+
"description": "How much of the run’s wall clock this one chain accounts for."
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
"required": [
|
|
413
|
+
"nodes",
|
|
414
|
+
"span_ms",
|
|
415
|
+
"share_of_elapsed"
|
|
416
|
+
],
|
|
417
|
+
"additionalProperties": false,
|
|
418
|
+
"description": "The dependency chain that decided how long the run took. A plan is re-drawn against this: shortening any other phase changes nothing, and the only way to a faster run is a shallower graph or a cheaper phase on this list."
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"type": "null"
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
"idle_capacity": {
|
|
426
|
+
"anyOf": [
|
|
427
|
+
{
|
|
428
|
+
"type": "object",
|
|
429
|
+
"properties": {
|
|
430
|
+
"lane_capacity": {
|
|
431
|
+
"type": "integer",
|
|
432
|
+
"minimum": 1,
|
|
433
|
+
"maximum": 9007199254740991,
|
|
434
|
+
"description": "Lanes the plan asked to be provisioned."
|
|
435
|
+
},
|
|
436
|
+
"peak_concurrency": {
|
|
437
|
+
"type": "integer",
|
|
438
|
+
"minimum": 0,
|
|
439
|
+
"maximum": 9007199254740991,
|
|
440
|
+
"description": "The most phases that were ever running at once. The width the graph reached."
|
|
441
|
+
},
|
|
442
|
+
"lane_ms_provisioned": {
|
|
443
|
+
"type": "integer",
|
|
444
|
+
"minimum": 0,
|
|
445
|
+
"maximum": 9007199254740991
|
|
446
|
+
},
|
|
447
|
+
"lane_ms_used": {
|
|
448
|
+
"type": "integer",
|
|
449
|
+
"minimum": 0,
|
|
450
|
+
"maximum": 9007199254740991,
|
|
451
|
+
"description": "Summed phase spans — one lane each, while running."
|
|
452
|
+
},
|
|
453
|
+
"idle_share": {
|
|
454
|
+
"type": "number",
|
|
455
|
+
"minimum": 0,
|
|
456
|
+
"maximum": 1,
|
|
457
|
+
"description": "Provisioned lane time no phase occupied."
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
"required": [
|
|
461
|
+
"lane_capacity",
|
|
462
|
+
"peak_concurrency",
|
|
463
|
+
"lane_ms_provisioned",
|
|
464
|
+
"lane_ms_used",
|
|
465
|
+
"idle_share"
|
|
466
|
+
],
|
|
467
|
+
"additionalProperties": false,
|
|
468
|
+
"description": "What the run paid for and did not use. A lane is a worktree, a forked database and a desk for a crew member, and a plan that is never as wide as its lane count bought all three for nothing — which is a fact about the graph, not about the machine."
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"type": "null"
|
|
472
|
+
}
|
|
473
|
+
]
|
|
474
|
+
},
|
|
475
|
+
"interventions": {
|
|
476
|
+
"type": "array",
|
|
477
|
+
"items": {
|
|
478
|
+
"type": "object",
|
|
479
|
+
"properties": {
|
|
480
|
+
"amendment": {
|
|
481
|
+
"type": "integer",
|
|
482
|
+
"minimum": 1,
|
|
483
|
+
"maximum": 9007199254740991,
|
|
484
|
+
"description": "The amendment ordinal, matching the run’s `workflow_amended` history."
|
|
485
|
+
},
|
|
486
|
+
"at_ms": {
|
|
487
|
+
"type": "integer",
|
|
488
|
+
"minimum": -9007199254740991,
|
|
489
|
+
"maximum": 9007199254740991,
|
|
490
|
+
"description": "When the run amended itself."
|
|
491
|
+
},
|
|
492
|
+
"target": {
|
|
493
|
+
"type": "string",
|
|
494
|
+
"minLength": 1,
|
|
495
|
+
"description": "What it changed, as the ledger keys it — `gate:<id>` or `node:<id>`."
|
|
496
|
+
},
|
|
497
|
+
"effect": {
|
|
498
|
+
"type": "string",
|
|
499
|
+
"enum": [
|
|
500
|
+
"cheaper",
|
|
501
|
+
"dearer",
|
|
502
|
+
"unchanged",
|
|
503
|
+
"unmeasured"
|
|
504
|
+
],
|
|
505
|
+
"description": "`cheaper` / `dearer` / `unchanged` compare the gate’s mean uncached duration before and after. `unmeasured` means the journal cannot answer — a phase-level change, or a gate with no runs on one side of the amendment."
|
|
506
|
+
},
|
|
507
|
+
"before_ms": {
|
|
508
|
+
"description": "Mean uncached duration of this gate before the amendment. Absent when unmeasured.",
|
|
509
|
+
"type": "integer",
|
|
510
|
+
"minimum": -9007199254740991,
|
|
511
|
+
"maximum": 9007199254740991
|
|
512
|
+
},
|
|
513
|
+
"after_ms": {
|
|
514
|
+
"description": "The same, after. Absent when unmeasured.",
|
|
515
|
+
"type": "integer",
|
|
516
|
+
"minimum": -9007199254740991,
|
|
517
|
+
"maximum": 9007199254740991
|
|
518
|
+
},
|
|
519
|
+
"runs_before": {
|
|
520
|
+
"type": "integer",
|
|
521
|
+
"minimum": 0,
|
|
522
|
+
"maximum": 9007199254740991
|
|
523
|
+
},
|
|
524
|
+
"runs_after": {
|
|
525
|
+
"type": "integer",
|
|
526
|
+
"minimum": 0,
|
|
527
|
+
"maximum": 9007199254740991
|
|
528
|
+
},
|
|
529
|
+
"record_ref": {
|
|
530
|
+
"type": "string",
|
|
531
|
+
"description": "Where the run coordinator’s own account of this change lives, relative to the run directory: its conversation. The reasoning, the evidence and the commands are prose about a repository and stay there; this artifact carries what can be counted."
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
"required": [
|
|
535
|
+
"amendment",
|
|
536
|
+
"at_ms",
|
|
537
|
+
"target",
|
|
538
|
+
"effect",
|
|
539
|
+
"record_ref"
|
|
540
|
+
],
|
|
541
|
+
"additionalProperties": false,
|
|
542
|
+
"description": "One amendment a run made to itself, and what happened to the thing it changed. The effect is a comparison of measured durations, not a claim of cause: a gate that got cheaper across an amendment did so while other things were also changing."
|
|
543
|
+
},
|
|
544
|
+
"description": "Amendments the run made to itself (§9.2), oldest first. Empty means it made none, which is a fact rather than a gap: `workflow_amended` rows say who wrote them. Changes a person made are in `operations`."
|
|
545
|
+
},
|
|
546
|
+
"failure_causes": {
|
|
547
|
+
"description": "Failed attempts grouped by cause, most expensive first.",
|
|
548
|
+
"type": "array",
|
|
549
|
+
"items": {
|
|
550
|
+
"type": "object",
|
|
551
|
+
"properties": {
|
|
552
|
+
"reason": {
|
|
553
|
+
"type": "string",
|
|
554
|
+
"maxLength": 300,
|
|
555
|
+
"description": "The scheduler’s recorded reason, verbatim up to 300 characters."
|
|
556
|
+
},
|
|
557
|
+
"setup": {
|
|
558
|
+
"type": "boolean",
|
|
559
|
+
"description": "Whether these attempts failed before any agent ran — provisioning, a base merge, a checkout. The machinery’s failure rather than the work’s, and the kind a plan cannot fix but a project configuration can."
|
|
560
|
+
},
|
|
561
|
+
"attempts": {
|
|
562
|
+
"type": "integer",
|
|
563
|
+
"minimum": 1,
|
|
564
|
+
"maximum": 9007199254740991,
|
|
565
|
+
"description": "Attempts that failed with this reason, across every phase."
|
|
566
|
+
},
|
|
567
|
+
"nodes": {
|
|
568
|
+
"minItems": 1,
|
|
569
|
+
"type": "array",
|
|
570
|
+
"items": {
|
|
571
|
+
"type": "string",
|
|
572
|
+
"minLength": 1,
|
|
573
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
574
|
+
},
|
|
575
|
+
"description": "The phases it hit."
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
"required": [
|
|
579
|
+
"reason",
|
|
580
|
+
"setup",
|
|
581
|
+
"attempts",
|
|
582
|
+
"nodes"
|
|
583
|
+
],
|
|
584
|
+
"additionalProperties": false,
|
|
585
|
+
"description": "One cause of failed attempts, and what it cost: the run’s retries, grouped."
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
"crew_substitutions": {
|
|
589
|
+
"type": "array",
|
|
590
|
+
"items": {
|
|
591
|
+
"type": "object",
|
|
592
|
+
"properties": {
|
|
593
|
+
"node": {
|
|
594
|
+
"type": "string",
|
|
595
|
+
"minLength": 1,
|
|
596
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
597
|
+
},
|
|
598
|
+
"planned": {
|
|
599
|
+
"type": "string",
|
|
600
|
+
"minLength": 1,
|
|
601
|
+
"description": "The member the plan named."
|
|
602
|
+
},
|
|
603
|
+
"planned_tier": {
|
|
604
|
+
"description": "Their tier. Absent on rows written before it was recorded.",
|
|
605
|
+
"type": "integer",
|
|
606
|
+
"minimum": -9007199254740991,
|
|
607
|
+
"maximum": 9007199254740991
|
|
608
|
+
},
|
|
609
|
+
"member": {
|
|
610
|
+
"type": "string",
|
|
611
|
+
"minLength": 1,
|
|
612
|
+
"description": "Who ran it instead."
|
|
613
|
+
},
|
|
614
|
+
"tier": {
|
|
615
|
+
"type": "integer",
|
|
616
|
+
"minimum": -9007199254740991,
|
|
617
|
+
"maximum": 9007199254740991
|
|
618
|
+
},
|
|
619
|
+
"model": {
|
|
620
|
+
"description": "The model that member ran on, from the roster.",
|
|
621
|
+
"type": "string"
|
|
622
|
+
},
|
|
623
|
+
"reason": {
|
|
624
|
+
"type": "string",
|
|
625
|
+
"enum": [
|
|
626
|
+
"peer_busy",
|
|
627
|
+
"warm_session",
|
|
628
|
+
"spare_crew"
|
|
629
|
+
],
|
|
630
|
+
"description": "`peer_busy`: the planned member was working. `warm_session`: promoted to reuse an open session. `spare_crew`: the planned member was working, and a spare was taken on in their image."
|
|
631
|
+
},
|
|
632
|
+
"attempts": {
|
|
633
|
+
"type": "integer",
|
|
634
|
+
"minimum": 1,
|
|
635
|
+
"maximum": 9007199254740991,
|
|
636
|
+
"description": "Attempts this member took the phase for."
|
|
637
|
+
},
|
|
638
|
+
"above_plan": {
|
|
639
|
+
"type": "boolean",
|
|
640
|
+
"description": "Whether this ran at a higher tier than the plan named — dearer than budgeted."
|
|
641
|
+
},
|
|
642
|
+
"node_cost_usd": {
|
|
643
|
+
"description": "What the whole phase cost, every attempt and member included, when its harness reported cost.",
|
|
644
|
+
"type": "number",
|
|
645
|
+
"minimum": 0
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
"required": [
|
|
649
|
+
"node",
|
|
650
|
+
"planned",
|
|
651
|
+
"member",
|
|
652
|
+
"tier",
|
|
653
|
+
"reason",
|
|
654
|
+
"attempts",
|
|
655
|
+
"above_plan"
|
|
656
|
+
],
|
|
657
|
+
"additionalProperties": false,
|
|
658
|
+
"description": "A phase run by somebody other than the member its plan named."
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
"operations": {
|
|
662
|
+
"type": "object",
|
|
663
|
+
"properties": {
|
|
664
|
+
"amendments": {
|
|
665
|
+
"type": "array",
|
|
666
|
+
"items": {
|
|
667
|
+
"type": "object",
|
|
668
|
+
"properties": {
|
|
669
|
+
"amendment": {
|
|
670
|
+
"type": "integer",
|
|
671
|
+
"minimum": 1,
|
|
672
|
+
"maximum": 9007199254740991
|
|
673
|
+
},
|
|
674
|
+
"at_ms": {
|
|
675
|
+
"type": "integer",
|
|
676
|
+
"minimum": -9007199254740991,
|
|
677
|
+
"maximum": 9007199254740991
|
|
678
|
+
},
|
|
679
|
+
"author": {
|
|
680
|
+
"type": "string",
|
|
681
|
+
"enum": [
|
|
682
|
+
"operator",
|
|
683
|
+
"monitor",
|
|
684
|
+
"coordinator",
|
|
685
|
+
"config",
|
|
686
|
+
"scheduler"
|
|
687
|
+
]
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
"required": [
|
|
691
|
+
"amendment",
|
|
692
|
+
"at_ms",
|
|
693
|
+
"author"
|
|
694
|
+
],
|
|
695
|
+
"additionalProperties": false
|
|
696
|
+
},
|
|
697
|
+
"description": "Every change to the run’s definition while it ran, whoever made it."
|
|
698
|
+
},
|
|
699
|
+
"node_operations": {
|
|
700
|
+
"type": "array",
|
|
701
|
+
"items": {
|
|
702
|
+
"type": "object",
|
|
703
|
+
"properties": {
|
|
704
|
+
"node": {
|
|
705
|
+
"type": "string",
|
|
706
|
+
"minLength": 1,
|
|
707
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
708
|
+
},
|
|
709
|
+
"op": {
|
|
710
|
+
"type": "string",
|
|
711
|
+
"enum": [
|
|
712
|
+
"add_context",
|
|
713
|
+
"redirect",
|
|
714
|
+
"pause",
|
|
715
|
+
"resume",
|
|
716
|
+
"abort",
|
|
717
|
+
"fresh",
|
|
718
|
+
"interrupt",
|
|
719
|
+
"reassign",
|
|
720
|
+
"step",
|
|
721
|
+
"retry"
|
|
722
|
+
]
|
|
723
|
+
},
|
|
724
|
+
"by": {
|
|
725
|
+
"type": "string",
|
|
726
|
+
"enum": [
|
|
727
|
+
"operator",
|
|
728
|
+
"coordinator"
|
|
729
|
+
]
|
|
730
|
+
},
|
|
731
|
+
"count": {
|
|
732
|
+
"type": "integer",
|
|
733
|
+
"minimum": 1,
|
|
734
|
+
"maximum": 9007199254740991
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
"required": [
|
|
738
|
+
"node",
|
|
739
|
+
"op",
|
|
740
|
+
"by",
|
|
741
|
+
"count"
|
|
742
|
+
],
|
|
743
|
+
"additionalProperties": false
|
|
744
|
+
},
|
|
745
|
+
"description": "Steering, pauses, aborts and dropped sessions, per phase."
|
|
746
|
+
},
|
|
747
|
+
"questions": {
|
|
748
|
+
"type": "object",
|
|
749
|
+
"properties": {
|
|
750
|
+
"asked": {
|
|
751
|
+
"type": "integer",
|
|
752
|
+
"minimum": 0,
|
|
753
|
+
"maximum": 9007199254740991
|
|
754
|
+
},
|
|
755
|
+
"by_operator": {
|
|
756
|
+
"type": "integer",
|
|
757
|
+
"minimum": 0,
|
|
758
|
+
"maximum": 9007199254740991
|
|
759
|
+
},
|
|
760
|
+
"unattended": {
|
|
761
|
+
"type": "integer",
|
|
762
|
+
"minimum": 0,
|
|
763
|
+
"maximum": 9007199254740991,
|
|
764
|
+
"description": "Answered by a `--retry-after` timer."
|
|
765
|
+
},
|
|
766
|
+
"by_coordinator": {
|
|
767
|
+
"type": "integer",
|
|
768
|
+
"minimum": 0,
|
|
769
|
+
"maximum": 9007199254740991
|
|
770
|
+
},
|
|
771
|
+
"unanswered": {
|
|
772
|
+
"type": "integer",
|
|
773
|
+
"minimum": 0,
|
|
774
|
+
"maximum": 9007199254740991
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
"required": [
|
|
778
|
+
"asked",
|
|
779
|
+
"by_operator",
|
|
780
|
+
"unattended",
|
|
781
|
+
"by_coordinator",
|
|
782
|
+
"unanswered"
|
|
783
|
+
],
|
|
784
|
+
"additionalProperties": false,
|
|
785
|
+
"description": "Every question a phase was parked on, and who answered it."
|
|
786
|
+
},
|
|
787
|
+
"exec_runs": {
|
|
788
|
+
"type": "array",
|
|
789
|
+
"items": {
|
|
790
|
+
"type": "object",
|
|
791
|
+
"properties": {
|
|
792
|
+
"target": {
|
|
793
|
+
"type": "string",
|
|
794
|
+
"minLength": 1
|
|
795
|
+
},
|
|
796
|
+
"by": {
|
|
797
|
+
"type": "string",
|
|
798
|
+
"enum": [
|
|
799
|
+
"operator",
|
|
800
|
+
"coordinator"
|
|
801
|
+
]
|
|
802
|
+
},
|
|
803
|
+
"count": {
|
|
804
|
+
"type": "integer",
|
|
805
|
+
"minimum": 1,
|
|
806
|
+
"maximum": 9007199254740991
|
|
807
|
+
},
|
|
808
|
+
"failed": {
|
|
809
|
+
"type": "integer",
|
|
810
|
+
"minimum": 0,
|
|
811
|
+
"maximum": 9007199254740991
|
|
812
|
+
}
|
|
813
|
+
},
|
|
814
|
+
"required": [
|
|
815
|
+
"target",
|
|
816
|
+
"by",
|
|
817
|
+
"count",
|
|
818
|
+
"failed"
|
|
819
|
+
],
|
|
820
|
+
"additionalProperties": false
|
|
821
|
+
},
|
|
822
|
+
"description": "Commands run by hand in a lane or the integration worktree (`vinta-ai-maestro exec`)."
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
"required": [
|
|
826
|
+
"amendments",
|
|
827
|
+
"node_operations",
|
|
828
|
+
"questions",
|
|
829
|
+
"exec_runs"
|
|
830
|
+
],
|
|
831
|
+
"additionalProperties": false,
|
|
832
|
+
"description": "What was done to the run while it ran, by a person or its coordinator. Repairs made outside maestro — a wave branch rebuilt in another checkout — leave no record and are not counted."
|
|
833
|
+
},
|
|
834
|
+
"cross_phase_failures": {
|
|
835
|
+
"type": "array",
|
|
836
|
+
"items": {
|
|
837
|
+
"type": "object",
|
|
838
|
+
"properties": {
|
|
839
|
+
"wave": {
|
|
840
|
+
"type": "integer",
|
|
841
|
+
"minimum": 1,
|
|
842
|
+
"maximum": 9007199254740991
|
|
843
|
+
},
|
|
844
|
+
"gate": {
|
|
845
|
+
"type": "string",
|
|
846
|
+
"minLength": 1,
|
|
847
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
848
|
+
},
|
|
849
|
+
"members": {
|
|
850
|
+
"minItems": 1,
|
|
851
|
+
"type": "array",
|
|
852
|
+
"items": {
|
|
853
|
+
"type": "string",
|
|
854
|
+
"minLength": 1,
|
|
855
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
856
|
+
},
|
|
857
|
+
"description": "The phases merged in that wave."
|
|
858
|
+
},
|
|
859
|
+
"at_ms": {
|
|
860
|
+
"type": "integer",
|
|
861
|
+
"minimum": -9007199254740991,
|
|
862
|
+
"maximum": 9007199254740991
|
|
863
|
+
},
|
|
864
|
+
"exit_code": {
|
|
865
|
+
"type": "integer",
|
|
866
|
+
"minimum": -9007199254740991,
|
|
867
|
+
"maximum": 9007199254740991
|
|
868
|
+
}
|
|
869
|
+
},
|
|
870
|
+
"required": [
|
|
871
|
+
"wave",
|
|
872
|
+
"gate",
|
|
873
|
+
"members",
|
|
874
|
+
"at_ms",
|
|
875
|
+
"exit_code"
|
|
876
|
+
],
|
|
877
|
+
"additionalProperties": false,
|
|
878
|
+
"description": "A gate that every phase passed on its own branch and that failed on the merged wave: two of `members` (or one of them and an earlier wave) disagree. The evidence of a missing dependency or a missing contract test that `missing_dependencies`’ ordering cannot see."
|
|
879
|
+
}
|
|
880
|
+
},
|
|
881
|
+
"unattended_decisions": {
|
|
882
|
+
"type": "object",
|
|
883
|
+
"properties": {
|
|
884
|
+
"answers": {
|
|
885
|
+
"type": "array",
|
|
886
|
+
"items": {
|
|
887
|
+
"type": "object",
|
|
888
|
+
"properties": {
|
|
889
|
+
"node": {
|
|
890
|
+
"type": "string",
|
|
891
|
+
"minLength": 1,
|
|
892
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
893
|
+
},
|
|
894
|
+
"at_ms": {
|
|
895
|
+
"type": "integer",
|
|
896
|
+
"minimum": -9007199254740991,
|
|
897
|
+
"maximum": 9007199254740991
|
|
898
|
+
},
|
|
899
|
+
"category": {
|
|
900
|
+
"type": "string",
|
|
901
|
+
"enum": [
|
|
902
|
+
"retry",
|
|
903
|
+
"agent_question",
|
|
904
|
+
"plan_question",
|
|
905
|
+
"merge_commit",
|
|
906
|
+
"other"
|
|
907
|
+
],
|
|
908
|
+
"description": "`retry`: a failed attempt retried or stopped. `agent_question`: a design question the agent stopped to ask, given its recommended options. `plan_question`: a pipeline question such as an exhausted review budget, given the plan’s `unattended_answer`. `merge_commit`: a merge commit git refused."
|
|
909
|
+
},
|
|
910
|
+
"by": {
|
|
911
|
+
"type": "string",
|
|
912
|
+
"enum": [
|
|
913
|
+
"unattended",
|
|
914
|
+
"coordinator"
|
|
915
|
+
]
|
|
916
|
+
},
|
|
917
|
+
"answer": {
|
|
918
|
+
"anyOf": [
|
|
919
|
+
{
|
|
920
|
+
"type": "string",
|
|
921
|
+
"maxLength": 200
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
"type": "number"
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
"type": "boolean"
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
"type": "null"
|
|
931
|
+
}
|
|
932
|
+
],
|
|
933
|
+
"description": "The answer’s value: a choice, or an agent question’s picked option indices as JSON."
|
|
934
|
+
},
|
|
935
|
+
"waited_ms": {
|
|
936
|
+
"description": "How long the question stood unanswered.",
|
|
937
|
+
"type": "integer",
|
|
938
|
+
"minimum": 0,
|
|
939
|
+
"maximum": 9007199254740991
|
|
940
|
+
}
|
|
941
|
+
},
|
|
942
|
+
"required": [
|
|
943
|
+
"node",
|
|
944
|
+
"at_ms",
|
|
945
|
+
"category",
|
|
946
|
+
"by",
|
|
947
|
+
"answer"
|
|
948
|
+
],
|
|
949
|
+
"additionalProperties": false
|
|
950
|
+
},
|
|
951
|
+
"description": "Questions a `--retry-after` timer or the run coordinator answered, oldest first."
|
|
952
|
+
},
|
|
953
|
+
"coordinator_actions": {
|
|
954
|
+
"type": "array",
|
|
955
|
+
"items": {
|
|
956
|
+
"type": "object",
|
|
957
|
+
"properties": {
|
|
958
|
+
"at_ms": {
|
|
959
|
+
"type": "integer",
|
|
960
|
+
"minimum": -9007199254740991,
|
|
961
|
+
"maximum": 9007199254740991
|
|
962
|
+
},
|
|
963
|
+
"node": {
|
|
964
|
+
"type": "string",
|
|
965
|
+
"minLength": 1,
|
|
966
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
967
|
+
},
|
|
968
|
+
"action": {
|
|
969
|
+
"type": "string",
|
|
970
|
+
"enum": [
|
|
971
|
+
"add_context",
|
|
972
|
+
"redirect",
|
|
973
|
+
"pause",
|
|
974
|
+
"abort",
|
|
975
|
+
"fresh",
|
|
976
|
+
"amend",
|
|
977
|
+
"exec",
|
|
978
|
+
"gate_cache_invalidate",
|
|
979
|
+
"interrupt",
|
|
980
|
+
"reassign",
|
|
981
|
+
"retry",
|
|
982
|
+
"step"
|
|
983
|
+
]
|
|
984
|
+
},
|
|
985
|
+
"target": {
|
|
986
|
+
"description": "An amendment’s targets, an `exec` target or a gate id.",
|
|
987
|
+
"type": "string",
|
|
988
|
+
"maxLength": 500
|
|
989
|
+
}
|
|
990
|
+
},
|
|
991
|
+
"required": [
|
|
992
|
+
"at_ms",
|
|
993
|
+
"action"
|
|
994
|
+
],
|
|
995
|
+
"additionalProperties": false
|
|
996
|
+
},
|
|
997
|
+
"description": "What the coordinator did on its own, oldest first. Its reasons are in its conversation and, for steering, in the phase’s decisions — not here."
|
|
998
|
+
},
|
|
999
|
+
"reverted_deletions": {
|
|
1000
|
+
"description": "Merge resolutions that kept lines a phase deliberately deleted, oldest first: flagged, not refused. Unused code breaks no gate, so check each deletion reached the branch. Absent when there were none, and on post-mortems written before it was checked.",
|
|
1001
|
+
"type": "array",
|
|
1002
|
+
"items": {
|
|
1003
|
+
"type": "object",
|
|
1004
|
+
"properties": {
|
|
1005
|
+
"at_ms": {
|
|
1006
|
+
"type": "integer",
|
|
1007
|
+
"minimum": -9007199254740991,
|
|
1008
|
+
"maximum": 9007199254740991
|
|
1009
|
+
},
|
|
1010
|
+
"node": {
|
|
1011
|
+
"type": "string",
|
|
1012
|
+
"maxLength": 200,
|
|
1013
|
+
"description": "The phase whose deletion was reverted, or the branch standing in when no phase on that side touched the path."
|
|
1014
|
+
},
|
|
1015
|
+
"path": {
|
|
1016
|
+
"type": "string",
|
|
1017
|
+
"maxLength": 500
|
|
1018
|
+
},
|
|
1019
|
+
"lines": {
|
|
1020
|
+
"type": "integer",
|
|
1021
|
+
"minimum": 1,
|
|
1022
|
+
"maximum": 9007199254740991,
|
|
1023
|
+
"description": "Lines that side deleted and the resolution kept. A count, never the lines."
|
|
1024
|
+
},
|
|
1025
|
+
"branch": {
|
|
1026
|
+
"type": "string",
|
|
1027
|
+
"description": "The branch the merge was made on."
|
|
1028
|
+
},
|
|
1029
|
+
"fix_rounds": {
|
|
1030
|
+
"type": "integer",
|
|
1031
|
+
"minimum": 0,
|
|
1032
|
+
"maximum": 9007199254740991,
|
|
1033
|
+
"description": "Conflict-fixer rounds the resolution took; 0 is git’s own merge, the `append_only` union driver."
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
"required": [
|
|
1037
|
+
"at_ms",
|
|
1038
|
+
"node",
|
|
1039
|
+
"path",
|
|
1040
|
+
"lines",
|
|
1041
|
+
"branch",
|
|
1042
|
+
"fix_rounds"
|
|
1043
|
+
],
|
|
1044
|
+
"additionalProperties": false
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
},
|
|
1048
|
+
"required": [
|
|
1049
|
+
"answers",
|
|
1050
|
+
"coordinator_actions"
|
|
1051
|
+
],
|
|
1052
|
+
"additionalProperties": false,
|
|
1053
|
+
"description": "Every decision made with nobody watching. A plan whose run decided much on its own left those choices to chance: a design question answered unattended belonged in the plan."
|
|
1054
|
+
},
|
|
1055
|
+
"failed_chores": {
|
|
1056
|
+
"description": "Chores that did not do their job, oldest first. Empty means every chore that ran succeeded.",
|
|
1057
|
+
"type": "array",
|
|
1058
|
+
"items": {
|
|
1059
|
+
"type": "object",
|
|
1060
|
+
"properties": {
|
|
1061
|
+
"node": {
|
|
1062
|
+
"type": "string",
|
|
1063
|
+
"minLength": 1,
|
|
1064
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
1065
|
+
},
|
|
1066
|
+
"chore": {
|
|
1067
|
+
"type": "string",
|
|
1068
|
+
"minLength": 1,
|
|
1069
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
1070
|
+
},
|
|
1071
|
+
"at_ms": {
|
|
1072
|
+
"type": "integer",
|
|
1073
|
+
"minimum": -9007199254740991,
|
|
1074
|
+
"maximum": 9007199254740991,
|
|
1075
|
+
"description": "When its last turn on that phase failed."
|
|
1076
|
+
}
|
|
1077
|
+
},
|
|
1078
|
+
"required": [
|
|
1079
|
+
"node",
|
|
1080
|
+
"chore",
|
|
1081
|
+
"at_ms"
|
|
1082
|
+
],
|
|
1083
|
+
"additionalProperties": false,
|
|
1084
|
+
"description": "A chore whose last turn on a phase failed — the turn broke, or its report said `Status: FAILURE`. The phase is merged regardless (`on_failure: continue`), so whatever the chore was meant to leave, a review canvas or a PR comment, is missing from it."
|
|
1085
|
+
}
|
|
257
1086
|
}
|
|
258
1087
|
},
|
|
259
1088
|
"required": [
|
|
260
1089
|
"unused_dependencies",
|
|
261
1090
|
"missing_dependencies",
|
|
262
1091
|
"wave_conflicts",
|
|
263
|
-
"
|
|
1092
|
+
"gate_costs",
|
|
1093
|
+
"duration_divergences",
|
|
1094
|
+
"critical_path",
|
|
1095
|
+
"idle_capacity",
|
|
1096
|
+
"interventions"
|
|
264
1097
|
],
|
|
265
1098
|
"additionalProperties": false
|
|
266
1099
|
},
|
|
@@ -272,9 +1105,12 @@
|
|
|
272
1105
|
"kind": {
|
|
273
1106
|
"type": "string",
|
|
274
1107
|
"enum": [
|
|
1108
|
+
"blocking_cause_unrecorded",
|
|
275
1109
|
"dependency_use_unrecorded",
|
|
276
1110
|
"gate_result_unrecorded",
|
|
277
|
-
"
|
|
1111
|
+
"gate_durations_unrecorded",
|
|
1112
|
+
"integration_record_unavailable",
|
|
1113
|
+
"intervention_effect_unmeasured"
|
|
278
1114
|
]
|
|
279
1115
|
},
|
|
280
1116
|
"needs": {
|
|
@@ -316,6 +1152,15 @@
|
|
|
316
1152
|
"minLength": 1,
|
|
317
1153
|
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
318
1154
|
}
|
|
1155
|
+
},
|
|
1156
|
+
"gates": {
|
|
1157
|
+
"description": "The gates the gap applies to.",
|
|
1158
|
+
"type": "array",
|
|
1159
|
+
"items": {
|
|
1160
|
+
"type": "string",
|
|
1161
|
+
"minLength": 1,
|
|
1162
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
1163
|
+
}
|
|
319
1164
|
}
|
|
320
1165
|
},
|
|
321
1166
|
"required": [
|