@deksden-com/dd-flow-cli 0.3.1 → 0.4.1

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 (43) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +25 -9
  3. package/dist/build-info.json +5 -5
  4. package/dist/cli/help.js +58 -32
  5. package/dist/cli/run-cli.js +282 -50
  6. package/dist/domain/entity-ids.js +4 -4
  7. package/dist/domain/flow-contract.js +502 -36
  8. package/dist/domain/validation.js +34 -0
  9. package/dist/protocol/local-files.js +8 -6
  10. package/dist/schemas/code-stage-report.schema.json +197 -2
  11. package/dist/schemas/flow-contract.schema.json +126 -0
  12. package/dist/schemas/flow-run-index-v3.schema.json +203 -0
  13. package/dist/schemas/flow-run-index.schema.json +22 -2
  14. package/dist/schemas/flow-run.schema.json +36 -0
  15. package/dist/schemas/merge-stage-report.schema.json +213 -2
  16. package/dist/schemas/plan-stage-report.schema.json +156 -2
  17. package/dist/schemas/release-impact.schema.json +16 -0
  18. package/dist/services/audit.js +3 -3
  19. package/dist/services/branch-context.js +266 -0
  20. package/dist/services/canon.js +0 -1
  21. package/dist/services/cleanup.js +6 -6
  22. package/dist/services/cli-operation-classifier.js +1 -1
  23. package/dist/services/compatibility-preflight.js +8 -77
  24. package/dist/services/dashboard.js +48 -11
  25. package/dist/services/engines.js +123 -13
  26. package/dist/services/hooks.js +6 -6
  27. package/dist/services/ids.js +40 -49
  28. package/dist/services/merge-queue.js +240 -20
  29. package/dist/services/merge-worker.js +12 -4
  30. package/dist/services/migrations.js +64 -0
  31. package/dist/services/plans.js +23 -16
  32. package/dist/services/projects.js +2 -2
  33. package/dist/services/prompts.js +322 -0
  34. package/dist/services/protocols.js +78 -42
  35. package/dist/services/run-projection.js +80 -0
  36. package/dist/services/runs.js +360 -22
  37. package/dist/services/schema-validation.js +35 -12
  38. package/dist/services/sessions.js +81 -3
  39. package/dist/services/status.js +32 -1
  40. package/dist/services/usage.js +233 -0
  41. package/dist/services/worktrees.js +24 -19
  42. package/dist/storage/database.js +223 -9
  43. package/package.json +1 -1
@@ -73,10 +73,44 @@ function validatePlanItem(input, index) {
73
73
  owner: requireString(item.owner, `items[${index}].owner`),
74
74
  summary: typeof item.summary === "string" ? item.summary : "",
75
75
  evidence: item.evidence,
76
+ ...(item.semantic_spine ? { semantic_spine: validateSemanticSpine(item.semantic_spine, id) } : {}),
77
+ ...(item.execution_context ? { execution_context: validateExecutionContext(item.execution_context, id) } : {}),
76
78
  ...(typeof item.block_reason === "string" ? { block_reason: item.block_reason } : {}),
77
79
  ...(typeof item.user_required === "boolean" ? { user_required: item.user_required } : {})
78
80
  };
79
81
  }
82
+ function validateExecutionContext(input, itemId) {
83
+ const context = requireRecord(input, `Plan item ${itemId} execution_context`);
84
+ return {
85
+ prompt_profile: requireString(context.prompt_profile, `Plan item ${itemId} execution_context.prompt_profile`),
86
+ required_read: requireStringArray(context.required_read, `Plan item ${itemId} execution_context.required_read`),
87
+ discovery_boundary: requireStringArray(context.discovery_boundary, `Plan item ${itemId} execution_context.discovery_boundary`),
88
+ write_scope: requireStringArray(context.write_scope, `Plan item ${itemId} execution_context.write_scope`),
89
+ checks: requireStringArray(context.checks, `Plan item ${itemId} execution_context.checks`)
90
+ };
91
+ }
92
+ function validateSemanticSpine(input, itemId) {
93
+ const spine = requireRecord(input, `Plan item ${itemId} semantic_spine`);
94
+ return {
95
+ user_outcome: requireString(spine.user_outcome, `Plan item ${itemId} semantic_spine.user_outcome`),
96
+ component_responsibility: requireString(spine.component_responsibility, `Plan item ${itemId} semantic_spine.component_responsibility`),
97
+ must_preserve: requireStringArray(spine.must_preserve, `Plan item ${itemId} semantic_spine.must_preserve`),
98
+ non_goals: requireStringArray(spine.non_goals, `Plan item ${itemId} semantic_spine.non_goals`),
99
+ acceptance_contribution: requireString(spine.acceptance_contribution, `Plan item ${itemId} semantic_spine.acceptance_contribution`)
100
+ };
101
+ }
102
+ function requireRecord(value, label) {
103
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
104
+ throw new AppError("validation", `${label} must be an object`, 2);
105
+ }
106
+ return value;
107
+ }
108
+ function requireStringArray(value, label) {
109
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || entry.length === 0)) {
110
+ throw new AppError("validation", `${label} must be a string array`, 2);
111
+ }
112
+ return value;
113
+ }
80
114
  function requireString(value, label) {
81
115
  if (typeof value !== "string" || value.length === 0) {
82
116
  throw new AppError("validation", `${label} must be a non-empty string`, 2);
@@ -6,6 +6,10 @@ import { ensureDir, planJsonPath, protocolDir, stateJsonPath } from "../storage/
6
6
  export function ensureProtocolFiles(input) {
7
7
  const storageRoot = input.storageRoot ?? input.projectRoot;
8
8
  const dir = protocolDir(storageRoot, input.protocolId);
9
+ const currentFlowContract = loadProjectFlowContract(input.projectRoot);
10
+ const statePath = stateJsonPath(storageRoot, input.protocolId);
11
+ const existing = readStateIfExists(statePath);
12
+ const flowContract = existing?.flow_contract ?? currentFlowContract;
9
13
  ensureDir(dir);
10
14
  const summaryPath = path.join(dir, "summary.md");
11
15
  if (!fs.existsSync(summaryPath)) {
@@ -25,9 +29,6 @@ export function ensureProtocolFiles(input) {
25
29
  ""
26
30
  ].join("\n"));
27
31
  }
28
- const statePath = stateJsonPath(storageRoot, input.protocolId);
29
- const existing = readStateIfExists(statePath);
30
- const flowContract = existing?.flow_contract ?? loadProjectFlowContract(input.projectRoot);
31
32
  const state = existing ??
32
33
  {
33
34
  schema_version: schemaVersion,
@@ -62,14 +63,15 @@ export function ensureProtocolFiles(input) {
62
63
  return { ...state, flow_contract: flowContract, updated_at: input.now };
63
64
  }
64
65
  export function ensureRuntimeProtocolFiles(input) {
66
+ const currentFlowContract = loadProjectFlowContract(input.projectRoot);
67
+ const statePath = path.join(input.runtimeDir, "state.json");
68
+ const existing = readStateIfExists(statePath);
69
+ const flowContract = existing?.flow_contract ?? currentFlowContract;
65
70
  ensureDir(input.runtimeDir);
66
71
  const metadataPath = path.join(input.runtimeDir, "metadata.json");
67
72
  if (!fs.existsSync(metadataPath)) {
68
73
  fs.writeFileSync(metadataPath, `${JSON.stringify({ protocol_id: input.protocolId, handshake_id: input.handshakeId, project_root: input.projectRoot }, null, 2)}\n`);
69
74
  }
70
- const statePath = path.join(input.runtimeDir, "state.json");
71
- const existing = readStateIfExists(statePath);
72
- const flowContract = existing?.flow_contract ?? loadProjectFlowContract(input.projectRoot);
73
75
  const state = existing ??
74
76
  {
75
77
  schema_version: schemaVersion,
@@ -1,9 +1,18 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "dd-flow/code-stage-report@1",
3
+ "$id": "dd-flow/code-stage-report@2",
4
4
  "title": "Code stage report data",
5
5
  "type": "object",
6
6
  "additionalProperties": true,
7
+ "allOf": [
8
+ {
9
+ "if": {
10
+ "properties": { "schema_id": { "const": "dd-flow/code-stage-report@2" } },
11
+ "required": ["schema_id"]
12
+ },
13
+ "then": { "required": ["flow_flags"] }
14
+ }
15
+ ],
7
16
  "required": [
8
17
  "schema_id",
9
18
  "run",
@@ -20,11 +29,12 @@
20
29
  "defs"
21
30
  ],
22
31
  "properties": {
23
- "schema_id": { "const": "dd-flow/code-stage-report@1" },
32
+ "schema_id": { "enum": ["dd-flow/code-stage-report@1", "dd-flow/code-stage-report@2"] },
24
33
  "run": { "$ref": "#/definitions/run" },
25
34
  "stage": { "$ref": "#/definitions/stage" },
26
35
  "project": { "$ref": "#/definitions/namedEntity" },
27
36
  "subject": { "$ref": "#/definitions/namedEntity" },
37
+ "flow_flags": { "$ref": "#/definitions/flowFlags" },
28
38
  "overall": { "$ref": "#/definitions/overall" },
29
39
  "breadcrumbs": {
30
40
  "type": "array",
@@ -42,6 +52,24 @@
42
52
  "type": "array",
43
53
  "items": { "$ref": "#/definitions/fileRef" }
44
54
  },
55
+ "policy_context": { "$ref": "#/definitions/policyContext" },
56
+ "sdlc_contours": { "$ref": "#/definitions/sdlcContours" },
57
+ "knowledge_candidates": {
58
+ "type": "object",
59
+ "additionalProperties": true,
60
+ "properties": {
61
+ "source_candidates": { "type": "string" },
62
+ "total": { "type": "integer", "minimum": 0 },
63
+ "implemented": { "type": "integer", "minimum": 0 },
64
+ "documented_during_code": { "type": "integer", "minimum": 0 },
65
+ "already_documented": { "type": "integer", "minimum": 0 },
66
+ "task_local_only": { "type": "integer", "minimum": 0 },
67
+ "deferred_as_DEF": { "type": "integer", "minimum": 0 },
68
+ "needs_user_confirmation": { "type": "integer", "minimum": 0 },
69
+ "not_applicable": { "type": "integer", "minimum": 0 },
70
+ "summary": { "type": "string" }
71
+ }
72
+ },
45
73
  "checks": {
46
74
  "type": "array",
47
75
  "items": { "$ref": "#/definitions/check" }
@@ -58,6 +86,35 @@
58
86
  }
59
87
  }
60
88
  },
89
+ "review_gates": {
90
+ "type": "array",
91
+ "items": { "$ref": "#/definitions/reviewGate" }
92
+ },
93
+ "design_aspect_traceability": {
94
+ "type": "object",
95
+ "additionalProperties": true,
96
+ "properties": {
97
+ "source": { "type": "string" },
98
+ "verdict": { "type": "string" },
99
+ "summary": { "type": "string" },
100
+ "implemented_seeds": { "type": "array" },
101
+ "deviations": { "type": "array" },
102
+ "gaps": { "type": "array" }
103
+ }
104
+ },
105
+ "testing_system": {
106
+ "type": "object",
107
+ "additionalProperties": true,
108
+ "properties": {
109
+ "source": { "type": "string" },
110
+ "verdict": { "type": "string" },
111
+ "summary": { "type": "string" },
112
+ "commands": { "type": "array" },
113
+ "datasets": { "type": "array" },
114
+ "gaps": { "type": "array" }
115
+ }
116
+ },
117
+ "aspect_coverage": { "$ref": "#/definitions/aspectCoverage" },
61
118
  "defs": {
62
119
  "type": "array",
63
120
  "items": { "$ref": "#/definitions/deferral" }
@@ -176,6 +233,144 @@
176
233
  "status": { "type": "string", "minLength": 1 },
177
234
  "summary": { "type": "string", "minLength": 1 }
178
235
  }
236
+ },
237
+ "reviewGate": {
238
+ "type": "object",
239
+ "additionalProperties": true,
240
+ "required": ["id", "label", "stage", "applicability", "verdict", "summary"],
241
+ "properties": {
242
+ "id": { "type": "string", "minLength": 1 },
243
+ "label": { "type": "string", "minLength": 1 },
244
+ "stage": { "type": "string", "minLength": 1 },
245
+ "applicability": { "type": "string", "minLength": 1 },
246
+ "verdict": { "type": "string", "minLength": 1 },
247
+ "summary": { "type": "string", "minLength": 1 },
248
+ "evidence": {
249
+ "type": "array",
250
+ "items": { "type": "string", "minLength": 1 }
251
+ }
252
+ }
253
+ },
254
+ "aspectCoverage": {
255
+ "type": "object",
256
+ "additionalProperties": true,
257
+ "required": ["source", "verdict", "summary"],
258
+ "properties": {
259
+ "source": { "type": "string", "minLength": 1 },
260
+ "verdict": { "type": "string", "minLength": 1 },
261
+ "summary": { "type": "string", "minLength": 1 },
262
+ "counts": {
263
+ "type": "object",
264
+ "additionalProperties": true,
265
+ "properties": {
266
+ "applicable": { "type": "integer", "minimum": 0 },
267
+ "not_applicable": { "type": "integer", "minimum": 0 },
268
+ "unknown": { "type": "integer", "minimum": 0 },
269
+ "covered": { "type": "integer", "minimum": 0 },
270
+ "blocked": { "type": "integer", "minimum": 0 },
271
+ "deferred": { "type": "integer", "minimum": 0 }
272
+ }
273
+ },
274
+ "artifacts": {
275
+ "type": "array",
276
+ "items": { "type": "string", "minLength": 1 }
277
+ }
278
+ }
279
+ },
280
+ "sdlcContours": {
281
+ "type": "object",
282
+ "additionalProperties": true,
283
+ "properties": {
284
+ "summary": { "type": "string" },
285
+ "contours": {
286
+ "type": "array",
287
+ "items": { "$ref": "#/definitions/sdlcContour" }
288
+ },
289
+ "policy_migration": { "type": "string" },
290
+ "next_delivery_action": { "type": "string" }
291
+ }
292
+ },
293
+ "sdlcContour": {
294
+ "type": "object",
295
+ "additionalProperties": true,
296
+ "required": ["name", "applicability_status", "gate_status", "summary"],
297
+ "properties": {
298
+ "name": { "type": "string", "minLength": 1 },
299
+ "applicability_status": { "type": "string", "minLength": 1 },
300
+ "verification_state": { "type": "string" },
301
+ "closure_state": { "type": "string" },
302
+ "gate_status": { "type": "string", "minLength": 1 },
303
+ "target_stage": { "type": "string" },
304
+ "delivery_target": { "type": "string" },
305
+ "summary": { "type": "string", "minLength": 1 },
306
+ "reason": { "type": "string" },
307
+ "evidence": { "type": "string" },
308
+ "next_action": { "type": "string" }
309
+ }
310
+ },
311
+ "policyContext": {
312
+ "type": "object",
313
+ "additionalProperties": true,
314
+ "required": ["sources", "git", "checks", "delivery", "gaps"],
315
+ "properties": {
316
+ "sources": { "type": "object", "additionalProperties": true },
317
+ "git": {
318
+ "type": "object",
319
+ "additionalProperties": true,
320
+ "properties": {
321
+ "workspace_route": { "type": "string" },
322
+ "delivery_strategy": {
323
+ "type": "string",
324
+ "enum": ["direct_commit", "direct_commit_push", "feature_merge", "pull_request", "merge_queue", "squash_merge", "rebase_ff", "release_branch", "external_handoff", "local_only", "no_git"]
325
+ },
326
+ "fixation_required": { "type": "boolean" },
327
+ "result_evidence_required": { "type": "array", "items": { "type": "string" } },
328
+ "actual_workspace_route": { "type": "string" },
329
+ "route_match": { "type": "boolean" }
330
+ }
331
+ },
332
+ "checks": { "type": "object", "additionalProperties": true },
333
+ "delivery": { "type": "object", "additionalProperties": true },
334
+ "gaps": { "type": "object", "additionalProperties": true }
335
+ }
336
+ },
337
+ "flowFlags": {
338
+ "type": "object",
339
+ "additionalProperties": false,
340
+ "required": ["flow_kind", "snapshot_revision", "resolution_status", "values", "snapshot_checksum"],
341
+ "properties": {
342
+ "contract": { "type": "object", "additionalProperties": true },
343
+ "flow_kind": { "type": "string", "minLength": 1 },
344
+ "preset": { "type": "object", "additionalProperties": true },
345
+ "snapshot_revision": { "type": "integer", "minimum": 1 },
346
+ "resolution_status": { "type": "string", "enum": ["valid", "legacy_incomplete", "reconciliation_required"] },
347
+ "values": { "type": "object", "additionalProperties": { "$ref": "#/definitions/flagValue" } },
348
+ "snapshot_checksum": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
349
+ "floors_applied": { "type": "array", "items": { "type": "string" } },
350
+ "resolved_at": { "type": "string", "format": "date-time" }
351
+ }
352
+ },
353
+ "flagValue": {
354
+ "type": "object",
355
+ "additionalProperties": false,
356
+ "required": ["value", "value_type", "owner", "source", "rationale", "resolved_at"],
357
+ "properties": {
358
+ "value": {},
359
+ "value_type": { "type": "string", "minLength": 1 },
360
+ "owner": { "type": "string", "minLength": 1 },
361
+ "source": {
362
+ "type": "object",
363
+ "additionalProperties": false,
364
+ "required": ["kind", "ref"],
365
+ "properties": {
366
+ "kind": { "type": "string", "minLength": 1 },
367
+ "ref": { "type": "string", "minLength": 1 },
368
+ "revision": { "type": ["integer", "null"] }
369
+ }
370
+ },
371
+ "rationale": { "type": "string", "minLength": 1 },
372
+ "resolved_at": { "type": "string", "format": "date-time" }
373
+ }
179
374
  }
180
375
  }
181
376
  }
@@ -0,0 +1,126 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "dd-flow/flow-contract@3",
4
+ "title": "dd-flow canonical flow contract",
5
+ "description": "Structural contract for the complete flow-contract.json catalog. Dynamic cross-key relationships are validated by the shared CLI normalizer.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["id", "version", "capabilities", "stages", "transitions", "readiness", "merge_queue", "defaults", "legacy_aliases", "flow_flags"],
9
+ "properties": {
10
+ "id": {"type":"string","pattern":"^dd-flow-canonical-[0-9]{4}-[0-9]{2}$"},
11
+ "version": {"const":3},
12
+ "capabilities": {"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1}},
13
+ "stages": {"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/definitions/stage"}},
14
+ "transitions": {"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/definitions/stringArray"}},
15
+ "entrypoints": {"type":"object","additionalProperties":{"$ref":"#/definitions/entrypoint"}},
16
+ "readiness": {"$ref":"#/definitions/readiness"},
17
+ "merge_queue": {"$ref":"#/definitions/mergeQueue"},
18
+ "defaults": {"$ref":"#/definitions/defaults"},
19
+ "auto_policy": {"$ref":"#/definitions/autoPolicy"},
20
+ "legacy_aliases": {"$ref":"#/definitions/stringMap"},
21
+ "route_aliases": {"$ref":"#/definitions/stringMap"},
22
+ "flow_flags": {"$ref":"#/definitions/flowFlags"}
23
+ },
24
+ "definitions": {
25
+ "nonEmptyString": {"type":"string","minLength":1},
26
+ "stringArray": {"type":"array","uniqueItems":true,"items":{"$ref":"#/definitions/nonEmptyString"}},
27
+ "stringMap": {"type":"object","additionalProperties":{"$ref":"#/definitions/nonEmptyString"}},
28
+ "flagScalar": {"type":["string","number","boolean","null"]},
29
+ "flagMap": {"type":"object","additionalProperties":{"$ref":"#/definitions/flagScalar"}},
30
+ "stage": {
31
+ "type":"object","additionalProperties":false,"required":["terminal"],
32
+ "properties":{"terminal":{"type":"boolean"},"report_enabled":{"type":"boolean"}}
33
+ },
34
+ "entrypoint": {
35
+ "type":"object","additionalProperties":false,
36
+ "properties": {
37
+ "stage":{"$ref":"#/definitions/nonEmptyString"},
38
+ "logical_stages":{"$ref":"#/definitions/stringArray"},
39
+ "creates_protocol":{"type":"boolean"},
40
+ "purpose":{"$ref":"#/definitions/nonEmptyString"},
41
+ "mode":{"$ref":"#/definitions/nonEmptyString"}
42
+ },
43
+ "anyOf":[{"required":["stage"]},{"required":["logical_stages"]}]
44
+ },
45
+ "readiness": {
46
+ "type":"object","additionalProperties":false,"required":["command","allowed_from","target_stage"],
47
+ "properties":{"command":{"const":"ready-for-merge"},"allowed_from":{"$ref":"#/definitions/stringArray"},"target_stage":{"$ref":"#/definitions/nonEmptyString"}}
48
+ },
49
+ "mergeQueue": {
50
+ "type":"object","additionalProperties":false,"required":["complete"],
51
+ "properties":{"complete":{"type":"object","additionalProperties":false,"required":["target_stage","next_action"],"properties":{"target_stage":{"$ref":"#/definitions/nonEmptyString"},"next_action":{"$ref":"#/definitions/nonEmptyString"}}}}
52
+ },
53
+ "defaults": {
54
+ "type":"object","additionalProperties":false,"required":["registered_next_action"],
55
+ "properties": {
56
+ "registered_next_action":{"$ref":"#/definitions/nonEmptyString"},
57
+ "ordinary_protocol_flow_kind":{"$ref":"#/definitions/nonEmptyString"},
58
+ "normal_stage_layout":{"$ref":"#/definitions/stringArray"},
59
+ "legacy_coding_stage_layout":{"$ref":"#/definitions/stringArray"}
60
+ }
61
+ },
62
+ "autoPolicy": {
63
+ "type":"object","additionalProperties":false,
64
+ "properties": {
65
+ "ready_for_code_auto":{"$ref":"#/definitions/nonEmptyString"},
66
+ "ready_for_code_after_user_review":{"$ref":"#/definitions/nonEmptyString"},
67
+ "home_config_path":{"$ref":"#/definitions/nonEmptyString"},
68
+ "snapshot_authority":{"$ref":"#/definitions/nonEmptyString"},
69
+ "legacy_profile_projection":{"$ref":"#/definitions/nonEmptyString"}
70
+ }
71
+ },
72
+ "flowFlags": {
73
+ "type":"object","additionalProperties":false,
74
+ "required":["source_precedence","definitions","presets","flows","mandatory_floors"],
75
+ "properties": {
76
+ "source_precedence": {
77
+ "type":"array","minItems":1,"uniqueItems":true,
78
+ "items":{"enum":["flow_default","preset","task_profile","protocol_override","run_override","escalation","compatibility_alias"]}
79
+ },
80
+ "definitions": {"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/definitions/flagDefinition"}},
81
+ "presets": {"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/definitions/flagMap"}},
82
+ "flows": {"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/definitions/flowFlagConsumer"}},
83
+ "mandatory_floors": {"type":"array","items":{"$ref":"#/definitions/mandatoryFloor"}},
84
+ "reduction_matrix": {"type":"object","additionalProperties":{"$ref":"#/definitions/reductionEntry"}},
85
+ "consumer_matrix": {"type":"object","additionalProperties":{"$ref":"#/definitions/stringArray"}}
86
+ }
87
+ },
88
+ "flagDefinition": {
89
+ "type":"object","additionalProperties":false,"required":["type","owner","description"],
90
+ "properties": {
91
+ "type":{"enum":["boolean","enum","number","string"]},
92
+ "values":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/definitions/flagScalar"}},
93
+ "owner":{"$ref":"#/definitions/nonEmptyString"},
94
+ "description":{"$ref":"#/definitions/nonEmptyString"}
95
+ },
96
+ "allOf":[
97
+ {"if":{"properties":{"type":{"const":"enum"}},"required":["type"]},"then":{"required":["values"]}},
98
+ {"if":{"properties":{"type":{"enum":["boolean","number","string"]}},"required":["type"]},"then":{"not":{"required":["values"]}}}
99
+ ]
100
+ },
101
+ "flowFlagConsumer": {
102
+ "type":"object","additionalProperties":false,"required":["default_preset","supported","defaults"],
103
+ "properties": {
104
+ "default_preset":{"$ref":"#/definitions/nonEmptyString"},
105
+ "supported":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/definitions/nonEmptyString"}},
106
+ "defaults":{"type":"object","additionalProperties":false,"required":["preset"],"properties":{"preset":{"$ref":"#/definitions/nonEmptyString"}}}
107
+ }
108
+ },
109
+ "mandatoryFloor": {
110
+ "type":"object","additionalProperties":false,"required":["when","values","reason"],
111
+ "properties": {
112
+ "when":{"type":"object","minProperties":1,"additionalProperties":{"$ref":"#/definitions/stringArray"}},
113
+ "values":{"$ref":"#/definitions/flagMap"},
114
+ "reason":{"$ref":"#/definitions/nonEmptyString"}
115
+ }
116
+ },
117
+ "reductionEntry": {
118
+ "type":"object","additionalProperties":false,"required":["skips","keeps","reduced_artifact_status"],
119
+ "properties": {
120
+ "skips":{"$ref":"#/definitions/stringArray"},
121
+ "keeps":{"$ref":"#/definitions/stringArray"},
122
+ "reduced_artifact_status":{"$ref":"#/definitions/nonEmptyString"}
123
+ }
124
+ }
125
+ }
126
+ }