vetra 0.1.0.pre.alpha.4

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.
@@ -0,0 +1,941 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:vetra:ir:0.1",
4
+ "title": "Vetra Application Graph IR 0.1",
5
+ "description": "Contrato proposto pelo ADR-001. Forma estrutural; referências, tipos de literais, manifesto, digest e demais invariantes exigem validação semântica.",
6
+ "type": "object",
7
+ "properties": {
8
+ "ir_version": {"const": "0.1"},
9
+ "requires": {
10
+ "type": "array",
11
+ "items": {"enum": ["vetra.core", "vetra.live"]},
12
+ "minItems": 1,
13
+ "uniqueItems": true,
14
+ "contains": {"const": "vetra.core"}
15
+ },
16
+ "producer": {
17
+ "type": "object",
18
+ "properties": {
19
+ "name": {"const": "vetra"},
20
+ "version": {"type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"},
21
+ "ruby_version": {"type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"}
22
+ },
23
+ "required": ["name", "version", "ruby_version"],
24
+ "additionalProperties": false
25
+ },
26
+ "app": {
27
+ "type": "object",
28
+ "properties": {
29
+ "name": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
30
+ "tenant": {"$ref": "#/$defs/tenant"},
31
+ "currency": {"type": "string", "pattern": "^[A-Z]{3}$"},
32
+ "locale": {"type": "string", "minLength": 1}
33
+ },
34
+ "required": ["name", "tenant", "currency", "locale"],
35
+ "additionalProperties": false
36
+ },
37
+ "inputs": {"type": "array", "items": {"$ref": "#/$defs/input_file"}, "minItems": 1, "uniqueItems": true},
38
+ "nodes": {
39
+ "type": "array",
40
+ "items": {
41
+ "oneOf": [
42
+ {"$ref": "#/$defs/domain"},
43
+ {"$ref": "#/$defs/entity"},
44
+ {"$ref": "#/$defs/contract"},
45
+ {"$ref": "#/$defs/command"},
46
+ {"$ref": "#/$defs/query"},
47
+ {"$ref": "#/$defs/role"},
48
+ {"$ref": "#/$defs/policy"},
49
+ {"$ref": "#/$defs/capability"},
50
+ {"$ref": "#/$defs/event"},
51
+ {"$ref": "#/$defs/handler"},
52
+ {"$ref": "#/$defs/route"},
53
+ {"$ref": "#/$defs/dependency"}
54
+ ]
55
+ },
56
+ "minItems": 1,
57
+ "uniqueItems": true
58
+ },
59
+ "digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
60
+ "annotations": {"$ref": "#/$defs/annotations"}
61
+ },
62
+ "required": ["ir_version", "requires", "producer", "app", "inputs", "nodes", "digest"],
63
+ "additionalProperties": false,
64
+ "$defs": {
65
+ "domain_ref": {
66
+ "type": "object",
67
+ "properties": {"kind": {"const": "domain"}, "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"}},
68
+ "required": ["kind", "id"],
69
+ "additionalProperties": false
70
+ },
71
+ "entity_ref": {
72
+ "type": "object",
73
+ "properties": {
74
+ "kind": {"const": "entity"},
75
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
76
+ },
77
+ "required": ["kind", "id"],
78
+ "additionalProperties": false
79
+ },
80
+ "contract_ref": {
81
+ "type": "object",
82
+ "properties": {
83
+ "kind": {"const": "contract"},
84
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
85
+ },
86
+ "required": ["kind", "id"],
87
+ "additionalProperties": false
88
+ },
89
+ "command_ref": {
90
+ "type": "object",
91
+ "properties": {
92
+ "kind": {"const": "command"},
93
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
94
+ },
95
+ "required": ["kind", "id"],
96
+ "additionalProperties": false
97
+ },
98
+ "query_ref": {
99
+ "type": "object",
100
+ "properties": {
101
+ "kind": {"const": "query"},
102
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
103
+ },
104
+ "required": ["kind", "id"],
105
+ "additionalProperties": false
106
+ },
107
+ "role_ref": {
108
+ "type": "object",
109
+ "properties": {
110
+ "kind": {"const": "role"},
111
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
112
+ },
113
+ "required": ["kind", "id"],
114
+ "additionalProperties": false
115
+ },
116
+ "policy_ref": {
117
+ "type": "object",
118
+ "properties": {
119
+ "kind": {"const": "policy"},
120
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
121
+ },
122
+ "required": ["kind", "id"],
123
+ "additionalProperties": false
124
+ },
125
+ "capability_ref": {
126
+ "type": "object",
127
+ "properties": {
128
+ "kind": {"const": "capability"},
129
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
130
+ },
131
+ "required": ["kind", "id"],
132
+ "additionalProperties": false
133
+ },
134
+ "event_ref": {
135
+ "type": "object",
136
+ "properties": {
137
+ "kind": {"const": "event"},
138
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
139
+ },
140
+ "required": ["kind", "id"],
141
+ "additionalProperties": false
142
+ },
143
+ "handler_ref": {
144
+ "type": "object",
145
+ "properties": {
146
+ "kind": {"const": "handler"},
147
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
148
+ },
149
+ "required": ["kind", "id"],
150
+ "additionalProperties": false
151
+ },
152
+ "route_ref": {
153
+ "type": "object",
154
+ "properties": {
155
+ "kind": {"const": "route"},
156
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
157
+ },
158
+ "required": ["kind", "id"],
159
+ "additionalProperties": false
160
+ },
161
+ "dependency_ref": {
162
+ "type": "object",
163
+ "properties": {
164
+ "kind": {"const": "dependency"},
165
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
166
+ },
167
+ "required": ["kind", "id"],
168
+ "additionalProperties": false
169
+ },
170
+ "json_value": {
171
+ "oneOf": [
172
+ {"type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991},
173
+ {"type": "string"},
174
+ {"type": "boolean"},
175
+ {"type": "null"},
176
+ {"type": "array", "items": {"$ref": "#/$defs/json_value"}},
177
+ {"type": "object", "additionalProperties": {"$ref": "#/$defs/json_value"}}
178
+ ]
179
+ },
180
+ "reference": {
181
+ "type": "object",
182
+ "properties": {
183
+ "kind": {
184
+ "enum": [
185
+ "domain",
186
+ "entity",
187
+ "contract",
188
+ "command",
189
+ "query",
190
+ "role",
191
+ "policy",
192
+ "capability",
193
+ "event",
194
+ "handler",
195
+ "route",
196
+ "dependency"
197
+ ]
198
+ },
199
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$"}
200
+ },
201
+ "required": ["kind", "id"],
202
+ "additionalProperties": false
203
+ },
204
+ "source": {
205
+ "type": "object",
206
+ "properties": {
207
+ "path": {
208
+ "type": "string",
209
+ "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\/$)[^\\u0000-\\u001f]+$"
210
+ },
211
+ "line": {"type": "integer", "minimum": 1, "maximum": 9007199254740991}
212
+ },
213
+ "required": ["path", "line"],
214
+ "additionalProperties": false
215
+ },
216
+ "input_file": {
217
+ "type": "object",
218
+ "properties": {
219
+ "path": {
220
+ "type": "string",
221
+ "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\/$)[^\\u0000-\\u001f]+$"
222
+ },
223
+ "digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"}
224
+ },
225
+ "required": ["path", "digest"],
226
+ "additionalProperties": false
227
+ },
228
+ "tenant": {
229
+ "oneOf": [
230
+ {"type": "null"},
231
+ {
232
+ "type": "object",
233
+ "properties": {
234
+ "entity": {"$ref": "#/$defs/entity_ref"},
235
+ "field": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"}
236
+ },
237
+ "required": ["entity", "field"],
238
+ "additionalProperties": false
239
+ }
240
+ ]
241
+ },
242
+ "annotations": {
243
+ "type": "object",
244
+ "propertyNames": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"},
245
+ "additionalProperties": {"$ref": "#/$defs/json_value"}
246
+ },
247
+ "node_base": {
248
+ "type": "object",
249
+ "properties": {
250
+ "id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$"},
251
+ "kind": {
252
+ "enum": [
253
+ "domain",
254
+ "entity",
255
+ "contract",
256
+ "command",
257
+ "query",
258
+ "role",
259
+ "policy",
260
+ "capability",
261
+ "event",
262
+ "handler",
263
+ "route",
264
+ "dependency"
265
+ ]
266
+ },
267
+ "source": {"$ref": "#/$defs/source"},
268
+ "generated_from": {"$ref": "#/$defs/reference"},
269
+ "previous_ids": {
270
+ "type": "array",
271
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$"},
272
+ "minItems": 1,
273
+ "uniqueItems": true
274
+ },
275
+ "annotations": {"$ref": "#/$defs/annotations"}
276
+ },
277
+ "required": ["id", "kind", "source"]
278
+ },
279
+ "type": {
280
+ "oneOf": [
281
+ {
282
+ "type": "object",
283
+ "properties": {"name": {"enum": ["string", "text", "email", "boolean", "integer", "date", "timestamp", "json"]}},
284
+ "required": ["name"],
285
+ "additionalProperties": false
286
+ },
287
+ {
288
+ "type": "object",
289
+ "properties": {"name": {"const": "id"}, "entity": {"$ref": "#/$defs/entity_ref"}},
290
+ "required": ["name"],
291
+ "additionalProperties": false
292
+ },
293
+ {
294
+ "type": "object",
295
+ "properties": {
296
+ "name": {"const": "enum"},
297
+ "values": {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 1, "uniqueItems": true},
298
+ "groups": {
299
+ "type": "object",
300
+ "propertyNames": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
301
+ "additionalProperties": {
302
+ "type": "array",
303
+ "items": {"type": "string", "minLength": 1},
304
+ "minItems": 1,
305
+ "uniqueItems": true
306
+ }
307
+ }
308
+ },
309
+ "required": ["name", "values"],
310
+ "additionalProperties": false
311
+ },
312
+ {
313
+ "type": "object",
314
+ "properties": {
315
+ "name": {"enum": ["decimal", "money"]},
316
+ "precision": {"type": "integer", "minimum": 1, "maximum": 1000},
317
+ "scale": {"type": "integer", "minimum": 0, "maximum": 1000}
318
+ },
319
+ "required": ["name", "precision", "scale"],
320
+ "additionalProperties": false
321
+ }
322
+ ]
323
+ },
324
+ "privacy": {
325
+ "oneOf": [
326
+ {
327
+ "type": "object",
328
+ "properties": {"personal": {"const": false}},
329
+ "required": ["personal"],
330
+ "additionalProperties": false
331
+ },
332
+ {
333
+ "type": "object",
334
+ "properties": {"personal": {"const": true}, "classification": {"enum": ["personal", "sensitive"]}},
335
+ "required": ["personal", "classification"],
336
+ "additionalProperties": false
337
+ }
338
+ ]
339
+ },
340
+ "literal": {
341
+ "type": "object",
342
+ "properties": {"kind": {"const": "literal"}, "value": {"$ref": "#/$defs/json_value"}},
343
+ "required": ["kind", "value"],
344
+ "additionalProperties": false
345
+ },
346
+ "default": {
347
+ "oneOf": [
348
+ {"$ref": "#/$defs/literal"},
349
+ {
350
+ "type": "object",
351
+ "properties": {"kind": {"const": "context"}, "name": {"enum": ["current_actor", "current_tenant"]}},
352
+ "required": ["kind", "name"],
353
+ "additionalProperties": false
354
+ }
355
+ ]
356
+ },
357
+ "guard": {
358
+ "type": "object",
359
+ "properties": {
360
+ "value": {"type": "string", "minLength": 1},
361
+ "commands": {"type": "array", "items": {"$ref": "#/$defs/command_ref"}, "minItems": 1, "uniqueItems": true}
362
+ },
363
+ "required": ["value", "commands"],
364
+ "additionalProperties": false
365
+ },
366
+ "field": {
367
+ "type": "object",
368
+ "properties": {
369
+ "name": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
370
+ "type": {"$ref": "#/$defs/type"},
371
+ "required": {"type": "boolean"},
372
+ "nullable": {"type": "boolean"},
373
+ "privacy": {"$ref": "#/$defs/privacy"},
374
+ "default": {"$ref": "#/$defs/default"},
375
+ "previous_names": {
376
+ "type": "array",
377
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
378
+ "minItems": 1,
379
+ "uniqueItems": true
380
+ },
381
+ "set_by": {"type": "array", "items": {"$ref": "#/$defs/command_ref"}, "minItems": 1, "uniqueItems": true},
382
+ "guarded": {"type": "array", "items": {"$ref": "#/$defs/guard"}, "minItems": 1, "uniqueItems": true},
383
+ "normalize": {"type": "array", "items": {"enum": ["downcase"]}, "minItems": 1, "uniqueItems": true},
384
+ "generate": {
385
+ "type": "object",
386
+ "properties": {"kind": {"const": "slug"}, "from": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"}},
387
+ "required": ["kind", "from"],
388
+ "additionalProperties": false
389
+ },
390
+ "constraints": {
391
+ "type": "object",
392
+ "properties": {
393
+ "min_length": {"type": "integer", "minimum": 0, "maximum": 9007199254740991},
394
+ "max_length": {"type": "integer", "minimum": 0, "maximum": 9007199254740991},
395
+ "unique": {"type": "boolean"}
396
+ },
397
+ "required": [],
398
+ "additionalProperties": false
399
+ }
400
+ },
401
+ "required": ["name", "type", "required", "nullable", "privacy"],
402
+ "additionalProperties": false,
403
+ "allOf": [
404
+ {
405
+ "if": {"properties": {"type": {"properties": {"name": {"const": "decimal"}}}}},
406
+ "then": {
407
+ "properties": {
408
+ "default": {
409
+ "properties": {
410
+ "value": {
411
+ "oneOf": [{"type": "string", "pattern": "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$"}, {"type": "null"}]
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }
417
+ },
418
+ {
419
+ "if": {"properties": {"type": {"properties": {"name": {"const": "money"}}}}},
420
+ "then": {
421
+ "properties": {
422
+ "default": {
423
+ "properties": {
424
+ "value": {
425
+ "oneOf": [
426
+ {
427
+ "type": "object",
428
+ "properties": {
429
+ "amount": {"type": "string", "pattern": "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$"},
430
+ "currency": {"type": "string", "pattern": "^[A-Z]{3}$"}
431
+ },
432
+ "required": ["amount", "currency"],
433
+ "additionalProperties": false
434
+ },
435
+ {"type": "null"}
436
+ ]
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+ },
443
+ {
444
+ "if": {"required": ["guarded"]},
445
+ "then": {"properties": {"type": {"properties": {"name": {"const": "enum"}}}}}
446
+ }
447
+ ]
448
+ },
449
+ "relation": {
450
+ "type": "object",
451
+ "properties": {
452
+ "name": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
453
+ "kind": {"enum": ["belongs_to", "has_many", "many_to_many"]},
454
+ "target": {"$ref": "#/$defs/entity_ref"},
455
+ "same_tenant": {"type": "boolean"},
456
+ "local_fields": {
457
+ "type": "array",
458
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
459
+ "minItems": 1,
460
+ "uniqueItems": true
461
+ },
462
+ "target_fields": {
463
+ "type": "array",
464
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
465
+ "minItems": 1,
466
+ "uniqueItems": true
467
+ },
468
+ "through": {"$ref": "#/$defs/entity_ref"},
469
+ "include_on_create": {
470
+ "type": "array",
471
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
472
+ "minItems": 1,
473
+ "uniqueItems": true
474
+ }
475
+ },
476
+ "required": ["name", "kind", "target", "same_tenant", "local_fields", "target_fields"],
477
+ "additionalProperties": false
478
+ },
479
+ "operand": {
480
+ "oneOf": [
481
+ {"$ref": "#/$defs/literal"},
482
+ {
483
+ "type": "object",
484
+ "properties": {
485
+ "kind": {"enum": ["field", "actor", "input"]},
486
+ "path": {"type": "array", "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"}, "minItems": 1}
487
+ },
488
+ "required": ["kind", "path"],
489
+ "additionalProperties": false
490
+ }
491
+ ]
492
+ },
493
+ "predicate": {
494
+ "oneOf": [
495
+ {
496
+ "type": "object",
497
+ "properties": {"op": {"enum": ["true", "false"]}},
498
+ "required": ["op"],
499
+ "additionalProperties": false
500
+ },
501
+ {
502
+ "type": "object",
503
+ "properties": {
504
+ "op": {"enum": ["eq", "in"]},
505
+ "left": {"$ref": "#/$defs/operand"},
506
+ "right": {"$ref": "#/$defs/operand"}
507
+ },
508
+ "required": ["op", "left", "right"],
509
+ "additionalProperties": false
510
+ },
511
+ {
512
+ "type": "object",
513
+ "properties": {
514
+ "op": {"enum": ["and", "or"]},
515
+ "terms": {"type": "array", "items": {"$ref": "#/$defs/predicate"}, "minItems": 1}
516
+ },
517
+ "required": ["op", "terms"],
518
+ "additionalProperties": false
519
+ },
520
+ {
521
+ "type": "object",
522
+ "properties": {"op": {"const": "not"}, "term": {"$ref": "#/$defs/predicate"}},
523
+ "required": ["op", "term"],
524
+ "additionalProperties": false
525
+ },
526
+ {
527
+ "type": "object",
528
+ "properties": {
529
+ "op": {"const": "exists"},
530
+ "relation": {"type": "array", "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"}, "minItems": 1},
531
+ "where": {"$ref": "#/$defs/predicate"}
532
+ },
533
+ "required": ["op", "relation", "where"],
534
+ "additionalProperties": false
535
+ }
536
+ ]
537
+ },
538
+ "analysis": {
539
+ "type": "object",
540
+ "properties": {
541
+ "status": {"enum": ["complete", "incomplete"]},
542
+ "constants": {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 0, "uniqueItems": true},
543
+ "dynamic": {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 0, "uniqueItems": true}
544
+ },
545
+ "required": ["status", "constants", "dynamic"],
546
+ "additionalProperties": false
547
+ },
548
+ "implementation": {
549
+ "oneOf": [
550
+ {
551
+ "type": "object",
552
+ "properties": {
553
+ "kind": {"const": "builtin"},
554
+ "name": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"}
555
+ },
556
+ "required": ["kind", "name"],
557
+ "additionalProperties": false
558
+ },
559
+ {
560
+ "type": "object",
561
+ "properties": {
562
+ "kind": {"const": "ruby"},
563
+ "ref": {"type": "string", "pattern": "^[a-z][a-z0-9_.]*#call$"},
564
+ "path": {
565
+ "type": "string",
566
+ "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*\\/$)[^\\u0000-\\u001f]+$"
567
+ },
568
+ "digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
569
+ "analysis": {"$ref": "#/$defs/analysis"}
570
+ },
571
+ "required": ["kind", "ref", "path", "digest", "analysis"],
572
+ "additionalProperties": false
573
+ }
574
+ ]
575
+ },
576
+ "authorization": {
577
+ "type": "object",
578
+ "properties": {
579
+ "action": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
580
+ "entity": {"$ref": "#/$defs/entity_ref"},
581
+ "record": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"}
582
+ },
583
+ "required": ["action", "entity"],
584
+ "additionalProperties": false
585
+ },
586
+ "emission": {
587
+ "type": "object",
588
+ "properties": {
589
+ "event": {"$ref": "#/$defs/event_ref"},
590
+ "from": {"$ref": "#/$defs/entity_ref"},
591
+ "fields": {
592
+ "type": "array",
593
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
594
+ "minItems": 1,
595
+ "uniqueItems": true
596
+ }
597
+ },
598
+ "required": ["event", "from", "fields"],
599
+ "additionalProperties": false
600
+ },
601
+ "live": {
602
+ "type": "object",
603
+ "properties": {
604
+ "mode": {"enum": ["strict", "balanced"]},
605
+ "depends_on": {"type": "array", "items": {"$ref": "#/$defs/entity_ref"}, "minItems": 1, "uniqueItems": true}
606
+ },
607
+ "required": ["mode", "depends_on"],
608
+ "additionalProperties": false
609
+ },
610
+ "capability_config": {
611
+ "oneOf": [
612
+ {
613
+ "type": "object",
614
+ "properties": {
615
+ "type": {"const": "repository"},
616
+ "entity": {"$ref": "#/$defs/entity_ref"},
617
+ "access": {"enum": ["read", "read_write"]}
618
+ },
619
+ "required": ["type", "entity", "access"],
620
+ "additionalProperties": false
621
+ },
622
+ {
623
+ "type": "object",
624
+ "properties": {"type": {"const": "deterministic"}},
625
+ "required": ["type"],
626
+ "additionalProperties": false
627
+ },
628
+ {
629
+ "type": "object",
630
+ "properties": {
631
+ "type": {"const": "external"},
632
+ "idempotency_key": {"type": "boolean"},
633
+ "hosts": {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 0, "uniqueItems": true},
634
+ "timeout_ms": {"type": "integer", "minimum": 1, "maximum": 9007199254740991}
635
+ },
636
+ "required": ["type", "idempotency_key", "hosts", "timeout_ms"],
637
+ "additionalProperties": false
638
+ },
639
+ {
640
+ "type": "object",
641
+ "properties": {"type": {"const": "sql"}, "access": {"enum": ["read", "read_write"]}},
642
+ "required": ["type", "access"],
643
+ "additionalProperties": false
644
+ }
645
+ ]
646
+ },
647
+ "index": {
648
+ "type": "object",
649
+ "properties": {
650
+ "name": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
651
+ "fields": {
652
+ "type": "array",
653
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
654
+ "minItems": 1,
655
+ "uniqueItems": true
656
+ },
657
+ "unique": {"type": "boolean"},
658
+ "where": {"$ref": "#/$defs/predicate"}
659
+ },
660
+ "required": ["name", "fields", "unique"],
661
+ "additionalProperties": false
662
+ },
663
+ "http_config": {
664
+ "type": "object",
665
+ "properties": {
666
+ "method": {"enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]},
667
+ "path": {"type": "string", "pattern": "^/[^\\s]*$"}
668
+ },
669
+ "required": ["method", "path"],
670
+ "additionalProperties": false
671
+ },
672
+ "named_config": {
673
+ "type": "object",
674
+ "properties": {"name": {"type": "string", "minLength": 1}},
675
+ "required": ["name"],
676
+ "additionalProperties": false
677
+ },
678
+ "domain": {
679
+ "allOf": [
680
+ {"$ref": "#/$defs/node_base"},
681
+ {
682
+ "type": "object",
683
+ "properties": {
684
+ "kind": {"const": "domain"},
685
+ "depends_on": {
686
+ "oneOf": [
687
+ {"type": "null"},
688
+ {"type": "array", "items": {"$ref": "#/$defs/domain_ref"}, "minItems": 0, "uniqueItems": true}
689
+ ]
690
+ }
691
+ },
692
+ "required": ["kind", "depends_on"]
693
+ }
694
+ ],
695
+ "unevaluatedProperties": false
696
+ },
697
+ "entity": {
698
+ "allOf": [
699
+ {"$ref": "#/$defs/node_base"},
700
+ {
701
+ "type": "object",
702
+ "properties": {
703
+ "kind": {"const": "entity"},
704
+ "domain": {"$ref": "#/$defs/domain_ref"},
705
+ "storage": {
706
+ "type": "object",
707
+ "properties": {
708
+ "schema": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
709
+ "table": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
710
+ "primary_key": {
711
+ "type": "array",
712
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
713
+ "minItems": 1,
714
+ "uniqueItems": true
715
+ }
716
+ },
717
+ "required": ["schema", "table", "primary_key"],
718
+ "additionalProperties": false
719
+ },
720
+ "tenant": {"$ref": "#/$defs/tenant"},
721
+ "fields": {"type": "array", "items": {"$ref": "#/$defs/field"}, "minItems": 1, "uniqueItems": true},
722
+ "relations": {"type": "array", "items": {"$ref": "#/$defs/relation"}, "minItems": 0, "uniqueItems": true},
723
+ "indexes": {"type": "array", "items": {"$ref": "#/$defs/index"}, "minItems": 0, "uniqueItems": true},
724
+ "history": {"enum": ["none", "full"]},
725
+ "transitions": {
726
+ "type": "object",
727
+ "properties": {"enforce": {"enum": ["application", "db"]}},
728
+ "required": ["enforce"],
729
+ "additionalProperties": false
730
+ }
731
+ },
732
+ "required": ["kind", "domain", "storage", "tenant", "fields", "relations", "indexes", "history", "transitions"]
733
+ }
734
+ ],
735
+ "unevaluatedProperties": false
736
+ },
737
+ "contract": {
738
+ "allOf": [
739
+ {"$ref": "#/$defs/node_base"},
740
+ {
741
+ "type": "object",
742
+ "properties": {
743
+ "kind": {"const": "contract"},
744
+ "domain": {"$ref": "#/$defs/domain_ref"},
745
+ "fields": {"type": "array", "items": {"$ref": "#/$defs/field"}, "minItems": 0, "uniqueItems": true}
746
+ },
747
+ "required": ["kind", "domain", "fields"]
748
+ }
749
+ ],
750
+ "unevaluatedProperties": false
751
+ },
752
+ "command": {
753
+ "allOf": [
754
+ {"$ref": "#/$defs/node_base"},
755
+ {
756
+ "type": "object",
757
+ "properties": {
758
+ "kind": {"const": "command"},
759
+ "domain": {"$ref": "#/$defs/domain_ref"},
760
+ "input": {"$ref": "#/$defs/contract_ref"},
761
+ "output": {"$ref": "#/$defs/contract_ref"},
762
+ "authorize": {"$ref": "#/$defs/authorization"},
763
+ "uses": {"type": "array", "items": {"$ref": "#/$defs/capability_ref"}, "minItems": 0, "uniqueItems": true},
764
+ "implementation": {"$ref": "#/$defs/implementation"},
765
+ "unsafe_effect": {"type": "string", "minLength": 1},
766
+ "emits": {"type": "array", "items": {"$ref": "#/$defs/emission"}, "minItems": 0, "uniqueItems": true}
767
+ },
768
+ "required": ["kind", "domain", "input", "output", "authorize", "uses", "implementation", "emits"]
769
+ }
770
+ ],
771
+ "unevaluatedProperties": false
772
+ },
773
+ "query": {
774
+ "allOf": [
775
+ {"$ref": "#/$defs/node_base"},
776
+ {
777
+ "type": "object",
778
+ "properties": {
779
+ "kind": {"const": "query"},
780
+ "domain": {"$ref": "#/$defs/domain_ref"},
781
+ "input": {"$ref": "#/$defs/contract_ref"},
782
+ "output": {"$ref": "#/$defs/contract_ref"},
783
+ "authorize": {"$ref": "#/$defs/authorization"},
784
+ "uses": {"type": "array", "items": {"$ref": "#/$defs/capability_ref"}, "minItems": 0, "uniqueItems": true},
785
+ "implementation": {"$ref": "#/$defs/implementation"},
786
+ "unsafe_effect": {"type": "string", "minLength": 1},
787
+ "live": {"$ref": "#/$defs/live"}
788
+ },
789
+ "required": ["kind", "domain", "input", "output", "authorize", "uses", "implementation"]
790
+ }
791
+ ],
792
+ "unevaluatedProperties": false
793
+ },
794
+ "role": {
795
+ "allOf": [
796
+ {"$ref": "#/$defs/node_base"},
797
+ {
798
+ "type": "object",
799
+ "properties": {
800
+ "kind": {"const": "role"},
801
+ "domain": {"$ref": "#/$defs/domain_ref"},
802
+ "anonymous": {"type": "boolean"}
803
+ },
804
+ "required": ["kind", "domain", "anonymous"]
805
+ }
806
+ ],
807
+ "unevaluatedProperties": false
808
+ },
809
+ "policy": {
810
+ "allOf": [
811
+ {"$ref": "#/$defs/node_base"},
812
+ {
813
+ "type": "object",
814
+ "properties": {
815
+ "kind": {"const": "policy"},
816
+ "domain": {"$ref": "#/$defs/domain_ref"},
817
+ "role": {"$ref": "#/$defs/role_ref"},
818
+ "entity": {"$ref": "#/$defs/entity_ref"},
819
+ "actions": {
820
+ "type": "array",
821
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
822
+ "minItems": 1,
823
+ "uniqueItems": true
824
+ },
825
+ "fields": {
826
+ "oneOf": [
827
+ {"const": "*"},
828
+ {
829
+ "type": "array",
830
+ "items": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
831
+ "minItems": 0,
832
+ "uniqueItems": true
833
+ }
834
+ ]
835
+ },
836
+ "predicate": {"$ref": "#/$defs/predicate"},
837
+ "reads": {"type": "array", "items": {"$ref": "#/$defs/entity_ref"}, "minItems": 1, "uniqueItems": true}
838
+ },
839
+ "required": ["kind", "domain", "role", "entity", "actions", "fields", "predicate", "reads"]
840
+ }
841
+ ],
842
+ "unevaluatedProperties": false
843
+ },
844
+ "capability": {
845
+ "allOf": [
846
+ {"$ref": "#/$defs/node_base"},
847
+ {
848
+ "type": "object",
849
+ "properties": {
850
+ "kind": {"const": "capability"},
851
+ "domain": {"$ref": "#/$defs/domain_ref"},
852
+ "adapter": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"},
853
+ "retry_safe": {"type": "boolean"},
854
+ "simulation": {"enum": ["seeded", "memory", "none"]},
855
+ "config": {"$ref": "#/$defs/capability_config"}
856
+ },
857
+ "required": ["kind", "domain", "adapter", "retry_safe", "simulation", "config"]
858
+ }
859
+ ],
860
+ "unevaluatedProperties": false
861
+ },
862
+ "event": {
863
+ "allOf": [
864
+ {"$ref": "#/$defs/node_base"},
865
+ {
866
+ "type": "object",
867
+ "properties": {
868
+ "kind": {"const": "event"},
869
+ "domain": {"$ref": "#/$defs/domain_ref"},
870
+ "payload": {"$ref": "#/$defs/contract_ref"},
871
+ "version": {"type": "integer", "minimum": 1, "maximum": 9007199254740991},
872
+ "visibility": {"enum": ["internal", "public"]},
873
+ "consumer_required": {"type": "boolean"}
874
+ },
875
+ "required": ["kind", "domain", "payload", "version", "visibility", "consumer_required"]
876
+ }
877
+ ],
878
+ "unevaluatedProperties": false
879
+ },
880
+ "handler": {
881
+ "allOf": [
882
+ {"$ref": "#/$defs/node_base"},
883
+ {
884
+ "type": "object",
885
+ "properties": {
886
+ "kind": {"const": "handler"},
887
+ "domain": {"$ref": "#/$defs/domain_ref"},
888
+ "on": {"type": "array", "items": {"$ref": "#/$defs/event_ref"}, "minItems": 1, "uniqueItems": true},
889
+ "uses": {"type": "array", "items": {"$ref": "#/$defs/capability_ref"}, "minItems": 0, "uniqueItems": true},
890
+ "calls": {"type": "array", "items": {"$ref": "#/$defs/command_ref"}, "minItems": 0, "uniqueItems": true},
891
+ "idempotent_by": {"const": "event_id"},
892
+ "implementation": {"$ref": "#/$defs/implementation"},
893
+ "unsafe_effect": {"type": "string", "minLength": 1}
894
+ },
895
+ "required": ["kind", "domain", "on", "uses", "calls", "idempotent_by", "implementation"]
896
+ }
897
+ ],
898
+ "unevaluatedProperties": false
899
+ },
900
+ "route": {
901
+ "allOf": [
902
+ {"$ref": "#/$defs/node_base"},
903
+ {
904
+ "type": "object",
905
+ "properties": {
906
+ "kind": {"const": "route"},
907
+ "domain": {"$ref": "#/$defs/domain_ref"},
908
+ "surface": {"enum": ["http", "cli", "job", "webhook"]},
909
+ "target": {"oneOf": [{"$ref": "#/$defs/command_ref"}, {"$ref": "#/$defs/query_ref"}]},
910
+ "config": {"oneOf": [{"$ref": "#/$defs/http_config"}, {"$ref": "#/$defs/named_config"}]},
911
+ "idempotency": {"enum": ["optional", "required"]}
912
+ },
913
+ "required": ["kind", "domain", "surface", "target", "config", "idempotency"]
914
+ },
915
+ {
916
+ "if": {"properties": {"surface": {"enum": ["http", "webhook"]}}},
917
+ "then": {"properties": {"config": {"$ref": "#/$defs/http_config"}}},
918
+ "else": {"properties": {"config": {"$ref": "#/$defs/named_config"}}}
919
+ }
920
+ ],
921
+ "unevaluatedProperties": false
922
+ },
923
+ "dependency": {
924
+ "allOf": [
925
+ {"$ref": "#/$defs/node_base"},
926
+ {
927
+ "type": "object",
928
+ "properties": {
929
+ "kind": {"const": "dependency"},
930
+ "domain": {"$ref": "#/$defs/domain_ref"},
931
+ "name": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$"},
932
+ "version": {"type": "string", "minLength": 1},
933
+ "trust": {"enum": ["trusted", "restricted", "outside_guarantee", "unclassified"]}
934
+ },
935
+ "required": ["kind", "domain", "name", "version", "trust"]
936
+ }
937
+ ],
938
+ "unevaluatedProperties": false
939
+ }
940
+ }
941
+ }