@suss/intent-ir 0.31.2 → 0.33.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.
@@ -0,0 +1,1476 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://suss.dev/schemas/intent-doc.schema.json",
4
+ "title": "IntentDoc",
5
+ "description": "One suss intent document, either boundary intent or a PRD, see https://github.com/nimbuscloud-ai/suss/blob/main/docs/reference/intent-format.md",
6
+ "oneOf": [
7
+ {
8
+ "type": "object",
9
+ "properties": {
10
+ "kind": {
11
+ "type": "string",
12
+ "const": "boundary",
13
+ "description": "Makes this document boundary intent for one boundary."
14
+ },
15
+ "name": {
16
+ "type": "string",
17
+ "minLength": 1,
18
+ "description": "What this document is called. A PRD scenario links to an outcome of it as <name>.<outcome-id>."
19
+ },
20
+ "purpose": {
21
+ "type": "string",
22
+ "minLength": 1,
23
+ "description": "What the boundary is for, in the author's own words."
24
+ },
25
+ "audience": {
26
+ "type": "string",
27
+ "minLength": 1,
28
+ "description": "Who calls this boundary and depends on what it does."
29
+ },
30
+ "source": {
31
+ "default": "author",
32
+ "description": "Where the document came from: somebody wrote it, suss inferred it, or suss inferred it and somebody has since curated it.",
33
+ "type": "string",
34
+ "enum": ["author", "inferred", "inferred, curated"]
35
+ },
36
+ "boundary": {
37
+ "oneOf": [
38
+ {
39
+ "type": "object",
40
+ "properties": {
41
+ "transport": {
42
+ "default": "http",
43
+ "type": "string",
44
+ "const": "http"
45
+ },
46
+ "semantics": {
47
+ "type": "string",
48
+ "const": "rest"
49
+ },
50
+ "method": {
51
+ "type": "string",
52
+ "minLength": 1,
53
+ "description": "The HTTP method the route handles."
54
+ },
55
+ "path": {
56
+ "type": "string",
57
+ "minLength": 1,
58
+ "description": "The route path, written the way the framework declares it."
59
+ },
60
+ "receives": {
61
+ "type": "object",
62
+ "properties": {
63
+ "headers": {
64
+ "type": "object",
65
+ "propertyNames": {
66
+ "type": "string",
67
+ "minLength": 1
68
+ },
69
+ "additionalProperties": {
70
+ "anyOf": [
71
+ {
72
+ "type": "object",
73
+ "properties": {
74
+ "required": {
75
+ "default": false,
76
+ "description": "Whether the boundary needs this field.",
77
+ "type": "boolean"
78
+ },
79
+ "type": {
80
+ "type": "string",
81
+ "enum": [
82
+ "string",
83
+ "integer",
84
+ "number",
85
+ "boolean",
86
+ "null",
87
+ "unknown"
88
+ ]
89
+ }
90
+ },
91
+ "required": ["type"],
92
+ "additionalProperties": false
93
+ },
94
+ {
95
+ "type": "object",
96
+ "properties": {
97
+ "required": {
98
+ "default": false,
99
+ "description": "Whether the boundary needs this field.",
100
+ "type": "boolean"
101
+ },
102
+ "type": {
103
+ "type": "string",
104
+ "const": "array"
105
+ },
106
+ "items": {
107
+ "$ref": "#/$defs/__schema0"
108
+ }
109
+ },
110
+ "required": ["type"],
111
+ "additionalProperties": false
112
+ },
113
+ {
114
+ "type": "object",
115
+ "properties": {
116
+ "required": {
117
+ "default": false,
118
+ "description": "Whether the boundary needs this field.",
119
+ "type": "boolean"
120
+ },
121
+ "type": {
122
+ "type": "string",
123
+ "const": "object"
124
+ },
125
+ "properties": {
126
+ "type": "object",
127
+ "propertyNames": {
128
+ "type": "string"
129
+ },
130
+ "additionalProperties": {
131
+ "$ref": "#/$defs/__schema0"
132
+ }
133
+ }
134
+ },
135
+ "required": ["type"],
136
+ "additionalProperties": false
137
+ },
138
+ {
139
+ "type": "object",
140
+ "properties": {
141
+ "required": {
142
+ "default": false,
143
+ "description": "Whether the boundary needs this field.",
144
+ "type": "boolean"
145
+ }
146
+ },
147
+ "additionalProperties": false
148
+ }
149
+ ]
150
+ },
151
+ "description": "The request headers the boundary depends on, by name."
152
+ },
153
+ "query": {
154
+ "type": "object",
155
+ "propertyNames": {
156
+ "type": "string",
157
+ "minLength": 1
158
+ },
159
+ "additionalProperties": {
160
+ "anyOf": [
161
+ {
162
+ "type": "object",
163
+ "properties": {
164
+ "required": {
165
+ "default": false,
166
+ "description": "Whether the boundary needs this field.",
167
+ "type": "boolean"
168
+ },
169
+ "type": {
170
+ "type": "string",
171
+ "enum": [
172
+ "string",
173
+ "integer",
174
+ "number",
175
+ "boolean",
176
+ "null",
177
+ "unknown"
178
+ ]
179
+ }
180
+ },
181
+ "required": ["type"],
182
+ "additionalProperties": false
183
+ },
184
+ {
185
+ "type": "object",
186
+ "properties": {
187
+ "required": {
188
+ "default": false,
189
+ "description": "Whether the boundary needs this field.",
190
+ "type": "boolean"
191
+ },
192
+ "type": {
193
+ "type": "string",
194
+ "const": "array"
195
+ },
196
+ "items": {
197
+ "$ref": "#/$defs/__schema0"
198
+ }
199
+ },
200
+ "required": ["type"],
201
+ "additionalProperties": false
202
+ },
203
+ {
204
+ "type": "object",
205
+ "properties": {
206
+ "required": {
207
+ "default": false,
208
+ "description": "Whether the boundary needs this field.",
209
+ "type": "boolean"
210
+ },
211
+ "type": {
212
+ "type": "string",
213
+ "const": "object"
214
+ },
215
+ "properties": {
216
+ "type": "object",
217
+ "propertyNames": {
218
+ "type": "string"
219
+ },
220
+ "additionalProperties": {
221
+ "$ref": "#/$defs/__schema0"
222
+ }
223
+ }
224
+ },
225
+ "required": ["type"],
226
+ "additionalProperties": false
227
+ },
228
+ {
229
+ "type": "object",
230
+ "properties": {
231
+ "required": {
232
+ "default": false,
233
+ "description": "Whether the boundary needs this field.",
234
+ "type": "boolean"
235
+ }
236
+ },
237
+ "additionalProperties": false
238
+ }
239
+ ]
240
+ },
241
+ "description": "The query-string parameters the boundary depends on, by name."
242
+ },
243
+ "params": {
244
+ "type": "object",
245
+ "propertyNames": {
246
+ "type": "string",
247
+ "minLength": 1
248
+ },
249
+ "additionalProperties": {
250
+ "anyOf": [
251
+ {
252
+ "type": "object",
253
+ "properties": {
254
+ "required": {
255
+ "default": false,
256
+ "description": "Whether the boundary needs this field.",
257
+ "type": "boolean"
258
+ },
259
+ "type": {
260
+ "type": "string",
261
+ "enum": [
262
+ "string",
263
+ "integer",
264
+ "number",
265
+ "boolean",
266
+ "null",
267
+ "unknown"
268
+ ]
269
+ }
270
+ },
271
+ "required": ["type"],
272
+ "additionalProperties": false
273
+ },
274
+ {
275
+ "type": "object",
276
+ "properties": {
277
+ "required": {
278
+ "default": false,
279
+ "description": "Whether the boundary needs this field.",
280
+ "type": "boolean"
281
+ },
282
+ "type": {
283
+ "type": "string",
284
+ "const": "array"
285
+ },
286
+ "items": {
287
+ "$ref": "#/$defs/__schema0"
288
+ }
289
+ },
290
+ "required": ["type"],
291
+ "additionalProperties": false
292
+ },
293
+ {
294
+ "type": "object",
295
+ "properties": {
296
+ "required": {
297
+ "default": false,
298
+ "description": "Whether the boundary needs this field.",
299
+ "type": "boolean"
300
+ },
301
+ "type": {
302
+ "type": "string",
303
+ "const": "object"
304
+ },
305
+ "properties": {
306
+ "type": "object",
307
+ "propertyNames": {
308
+ "type": "string"
309
+ },
310
+ "additionalProperties": {
311
+ "$ref": "#/$defs/__schema0"
312
+ }
313
+ }
314
+ },
315
+ "required": ["type"],
316
+ "additionalProperties": false
317
+ },
318
+ {
319
+ "type": "object",
320
+ "properties": {
321
+ "required": {
322
+ "default": false,
323
+ "description": "Whether the boundary needs this field.",
324
+ "type": "boolean"
325
+ }
326
+ },
327
+ "additionalProperties": false
328
+ }
329
+ ]
330
+ },
331
+ "description": "The path parameters the boundary depends on, by name."
332
+ },
333
+ "body": {
334
+ "anyOf": [
335
+ {
336
+ "$ref": "#/$defs/__schema0"
337
+ },
338
+ {
339
+ "type": "object",
340
+ "properties": {
341
+ "properties": {
342
+ "type": "object",
343
+ "propertyNames": {
344
+ "type": "string"
345
+ },
346
+ "additionalProperties": {
347
+ "$ref": "#/$defs/__schema0"
348
+ }
349
+ },
350
+ "required": {
351
+ "type": "array",
352
+ "items": {
353
+ "type": "string"
354
+ }
355
+ }
356
+ }
357
+ }
358
+ ],
359
+ "description": "The shape of the request body the boundary depends on."
360
+ }
361
+ },
362
+ "additionalProperties": false,
363
+ "description": "The parts of the request the boundary depends on."
364
+ }
365
+ },
366
+ "required": ["semantics", "method", "path"],
367
+ "additionalProperties": false
368
+ },
369
+ {
370
+ "type": "object",
371
+ "properties": {
372
+ "transport": {
373
+ "default": "in-process",
374
+ "type": "string"
375
+ },
376
+ "semantics": {
377
+ "type": "string",
378
+ "const": "function-call"
379
+ },
380
+ "module": {
381
+ "type": "string",
382
+ "description": "The repo-relative module path, when the boundary is a unit inside this repository."
383
+ },
384
+ "exportName": {
385
+ "type": "string",
386
+ "description": "The name the module or package exports the function under."
387
+ },
388
+ "package": {
389
+ "type": "string",
390
+ "description": "The package name, when the boundary is something a package publishes."
391
+ },
392
+ "exportPath": {
393
+ "type": "array",
394
+ "items": {
395
+ "type": "string"
396
+ },
397
+ "description": "The path to the export inside the package: the sub-path, then any nested names."
398
+ },
399
+ "receives": {
400
+ "type": "object",
401
+ "propertyNames": {
402
+ "type": "string",
403
+ "minLength": 1
404
+ },
405
+ "additionalProperties": {
406
+ "anyOf": [
407
+ {
408
+ "type": "object",
409
+ "properties": {
410
+ "required": {
411
+ "default": false,
412
+ "description": "Whether the boundary needs this field.",
413
+ "type": "boolean"
414
+ },
415
+ "type": {
416
+ "type": "string",
417
+ "enum": [
418
+ "string",
419
+ "integer",
420
+ "number",
421
+ "boolean",
422
+ "null",
423
+ "unknown"
424
+ ]
425
+ }
426
+ },
427
+ "required": ["type"],
428
+ "additionalProperties": false
429
+ },
430
+ {
431
+ "type": "object",
432
+ "properties": {
433
+ "required": {
434
+ "default": false,
435
+ "description": "Whether the boundary needs this field.",
436
+ "type": "boolean"
437
+ },
438
+ "type": {
439
+ "type": "string",
440
+ "const": "array"
441
+ },
442
+ "items": {
443
+ "$ref": "#/$defs/__schema0"
444
+ }
445
+ },
446
+ "required": ["type"],
447
+ "additionalProperties": false
448
+ },
449
+ {
450
+ "type": "object",
451
+ "properties": {
452
+ "required": {
453
+ "default": false,
454
+ "description": "Whether the boundary needs this field.",
455
+ "type": "boolean"
456
+ },
457
+ "type": {
458
+ "type": "string",
459
+ "const": "object"
460
+ },
461
+ "properties": {
462
+ "type": "object",
463
+ "propertyNames": {
464
+ "type": "string"
465
+ },
466
+ "additionalProperties": {
467
+ "$ref": "#/$defs/__schema0"
468
+ }
469
+ }
470
+ },
471
+ "required": ["type"],
472
+ "additionalProperties": false
473
+ },
474
+ {
475
+ "type": "object",
476
+ "properties": {
477
+ "required": {
478
+ "default": false,
479
+ "description": "Whether the boundary needs this field.",
480
+ "type": "boolean"
481
+ }
482
+ },
483
+ "additionalProperties": false
484
+ }
485
+ ]
486
+ },
487
+ "description": "The fields the boundary is handed, by field name. On a function-call boundary a name is a parameter, on a message bus it is a field of the message body."
488
+ }
489
+ },
490
+ "required": ["semantics"],
491
+ "additionalProperties": false
492
+ },
493
+ {
494
+ "type": "object",
495
+ "properties": {
496
+ "semantics": {
497
+ "type": "string",
498
+ "const": "message-bus"
499
+ },
500
+ "messageBus": {
501
+ "type": "string",
502
+ "enum": [
503
+ "aws_sqs",
504
+ "aws.sns",
505
+ "s3",
506
+ "eventbridge",
507
+ "aws_kinesis",
508
+ "aws_firehose",
509
+ "gcp_pubsub",
510
+ "bullmq",
511
+ "kafka",
512
+ "nats",
513
+ "cloudflare-queues",
514
+ "cloudflare-cron",
515
+ "cloudflare-tail"
516
+ ],
517
+ "description": "Which bus carries the message, in the name suss gives that bus."
518
+ },
519
+ "channel": {
520
+ "default": null,
521
+ "description": "The queue or topic the message travels on. Null when the document does not name one.",
522
+ "anyOf": [
523
+ {
524
+ "type": "string",
525
+ "minLength": 1
526
+ },
527
+ {
528
+ "type": "null"
529
+ }
530
+ ]
531
+ },
532
+ "receives": {
533
+ "type": "object",
534
+ "propertyNames": {
535
+ "type": "string",
536
+ "minLength": 1
537
+ },
538
+ "additionalProperties": {
539
+ "anyOf": [
540
+ {
541
+ "type": "object",
542
+ "properties": {
543
+ "required": {
544
+ "default": false,
545
+ "description": "Whether the boundary needs this field.",
546
+ "type": "boolean"
547
+ },
548
+ "type": {
549
+ "type": "string",
550
+ "enum": [
551
+ "string",
552
+ "integer",
553
+ "number",
554
+ "boolean",
555
+ "null",
556
+ "unknown"
557
+ ]
558
+ }
559
+ },
560
+ "required": ["type"],
561
+ "additionalProperties": false
562
+ },
563
+ {
564
+ "type": "object",
565
+ "properties": {
566
+ "required": {
567
+ "default": false,
568
+ "description": "Whether the boundary needs this field.",
569
+ "type": "boolean"
570
+ },
571
+ "type": {
572
+ "type": "string",
573
+ "const": "array"
574
+ },
575
+ "items": {
576
+ "$ref": "#/$defs/__schema0"
577
+ }
578
+ },
579
+ "required": ["type"],
580
+ "additionalProperties": false
581
+ },
582
+ {
583
+ "type": "object",
584
+ "properties": {
585
+ "required": {
586
+ "default": false,
587
+ "description": "Whether the boundary needs this field.",
588
+ "type": "boolean"
589
+ },
590
+ "type": {
591
+ "type": "string",
592
+ "const": "object"
593
+ },
594
+ "properties": {
595
+ "type": "object",
596
+ "propertyNames": {
597
+ "type": "string"
598
+ },
599
+ "additionalProperties": {
600
+ "$ref": "#/$defs/__schema0"
601
+ }
602
+ }
603
+ },
604
+ "required": ["type"],
605
+ "additionalProperties": false
606
+ },
607
+ {
608
+ "type": "object",
609
+ "properties": {
610
+ "required": {
611
+ "default": false,
612
+ "description": "Whether the boundary needs this field.",
613
+ "type": "boolean"
614
+ }
615
+ },
616
+ "additionalProperties": false
617
+ }
618
+ ]
619
+ },
620
+ "description": "The fields the boundary is handed, by field name. On a function-call boundary a name is a parameter, on a message bus it is a field of the message body."
621
+ }
622
+ },
623
+ "required": ["semantics", "messageBus"],
624
+ "additionalProperties": false
625
+ },
626
+ {
627
+ "type": "object",
628
+ "properties": {
629
+ "semantics": {
630
+ "type": "string",
631
+ "const": "storage"
632
+ },
633
+ "storageSystem": {
634
+ "default": null,
635
+ "description": "Which store this is: postgresql, aws.dynamodb, s3, and so on. Null when the document does not say which engine.",
636
+ "anyOf": [
637
+ {
638
+ "type": "string"
639
+ },
640
+ {
641
+ "type": "null"
642
+ }
643
+ ]
644
+ },
645
+ "scope": {
646
+ "default": "default",
647
+ "description": "The ORM, schema or deployment scope the container is in. A setup with one database uses default.",
648
+ "type": "string"
649
+ },
650
+ "container": {
651
+ "default": null,
652
+ "description": "The table, bucket, collection or index. Null when the document does not name one.",
653
+ "anyOf": [
654
+ {
655
+ "type": "string"
656
+ },
657
+ {
658
+ "type": "null"
659
+ }
660
+ ]
661
+ },
662
+ "accessPath": {
663
+ "default": null,
664
+ "description": "A secondary way into the container, such as a DynamoDB index or an Elasticsearch alias. Null means the container's own primary way in.",
665
+ "anyOf": [
666
+ {
667
+ "type": "string"
668
+ },
669
+ {
670
+ "type": "null"
671
+ }
672
+ ]
673
+ },
674
+ "receives": {
675
+ "type": "object",
676
+ "propertyNames": {
677
+ "type": "string",
678
+ "minLength": 1
679
+ },
680
+ "additionalProperties": {
681
+ "anyOf": [
682
+ {
683
+ "type": "object",
684
+ "properties": {
685
+ "required": {
686
+ "default": false,
687
+ "description": "Whether the boundary needs this field.",
688
+ "type": "boolean"
689
+ },
690
+ "type": {
691
+ "type": "string",
692
+ "enum": [
693
+ "string",
694
+ "integer",
695
+ "number",
696
+ "boolean",
697
+ "null",
698
+ "unknown"
699
+ ]
700
+ }
701
+ },
702
+ "required": ["type"],
703
+ "additionalProperties": false
704
+ },
705
+ {
706
+ "type": "object",
707
+ "properties": {
708
+ "required": {
709
+ "default": false,
710
+ "description": "Whether the boundary needs this field.",
711
+ "type": "boolean"
712
+ },
713
+ "type": {
714
+ "type": "string",
715
+ "const": "array"
716
+ },
717
+ "items": {
718
+ "$ref": "#/$defs/__schema0"
719
+ }
720
+ },
721
+ "required": ["type"],
722
+ "additionalProperties": false
723
+ },
724
+ {
725
+ "type": "object",
726
+ "properties": {
727
+ "required": {
728
+ "default": false,
729
+ "description": "Whether the boundary needs this field.",
730
+ "type": "boolean"
731
+ },
732
+ "type": {
733
+ "type": "string",
734
+ "const": "object"
735
+ },
736
+ "properties": {
737
+ "type": "object",
738
+ "propertyNames": {
739
+ "type": "string"
740
+ },
741
+ "additionalProperties": {
742
+ "$ref": "#/$defs/__schema0"
743
+ }
744
+ }
745
+ },
746
+ "required": ["type"],
747
+ "additionalProperties": false
748
+ },
749
+ {
750
+ "type": "object",
751
+ "properties": {
752
+ "required": {
753
+ "default": false,
754
+ "description": "Whether the boundary needs this field.",
755
+ "type": "boolean"
756
+ }
757
+ },
758
+ "additionalProperties": false
759
+ }
760
+ ]
761
+ },
762
+ "description": "The fields the boundary is handed, by field name. On a function-call boundary a name is a parameter, on a message bus it is a field of the message body."
763
+ }
764
+ },
765
+ "required": ["semantics"],
766
+ "additionalProperties": false
767
+ },
768
+ {
769
+ "type": "object",
770
+ "properties": {
771
+ "semantics": {
772
+ "type": "string",
773
+ "const": "unit-invocation"
774
+ },
775
+ "deploymentTarget": {
776
+ "type": "string",
777
+ "enum": [
778
+ "lambda",
779
+ "ecs-task",
780
+ "container",
781
+ "k8s-deployment",
782
+ "worker"
783
+ ],
784
+ "description": "What sort of deployed thing this is: a Lambda function, an ECS task's container, a plain container, a k8s deployment or an edge worker."
785
+ },
786
+ "instanceName": {
787
+ "default": null,
788
+ "description": "The name the deployment medium knows the unit by, such as a CloudFormation logical id. Null when the document does not name one.",
789
+ "anyOf": [
790
+ {
791
+ "type": "string",
792
+ "minLength": 1
793
+ },
794
+ {
795
+ "type": "null"
796
+ }
797
+ ]
798
+ },
799
+ "receives": {
800
+ "type": "object",
801
+ "propertyNames": {
802
+ "type": "string",
803
+ "minLength": 1
804
+ },
805
+ "additionalProperties": {
806
+ "anyOf": [
807
+ {
808
+ "type": "object",
809
+ "properties": {
810
+ "required": {
811
+ "default": false,
812
+ "description": "Whether the boundary needs this field.",
813
+ "type": "boolean"
814
+ },
815
+ "type": {
816
+ "type": "string",
817
+ "enum": [
818
+ "string",
819
+ "integer",
820
+ "number",
821
+ "boolean",
822
+ "null",
823
+ "unknown"
824
+ ]
825
+ }
826
+ },
827
+ "required": ["type"],
828
+ "additionalProperties": false
829
+ },
830
+ {
831
+ "type": "object",
832
+ "properties": {
833
+ "required": {
834
+ "default": false,
835
+ "description": "Whether the boundary needs this field.",
836
+ "type": "boolean"
837
+ },
838
+ "type": {
839
+ "type": "string",
840
+ "const": "array"
841
+ },
842
+ "items": {
843
+ "$ref": "#/$defs/__schema0"
844
+ }
845
+ },
846
+ "required": ["type"],
847
+ "additionalProperties": false
848
+ },
849
+ {
850
+ "type": "object",
851
+ "properties": {
852
+ "required": {
853
+ "default": false,
854
+ "description": "Whether the boundary needs this field.",
855
+ "type": "boolean"
856
+ },
857
+ "type": {
858
+ "type": "string",
859
+ "const": "object"
860
+ },
861
+ "properties": {
862
+ "type": "object",
863
+ "propertyNames": {
864
+ "type": "string"
865
+ },
866
+ "additionalProperties": {
867
+ "$ref": "#/$defs/__schema0"
868
+ }
869
+ }
870
+ },
871
+ "required": ["type"],
872
+ "additionalProperties": false
873
+ },
874
+ {
875
+ "type": "object",
876
+ "properties": {
877
+ "required": {
878
+ "default": false,
879
+ "description": "Whether the boundary needs this field.",
880
+ "type": "boolean"
881
+ }
882
+ },
883
+ "additionalProperties": false
884
+ }
885
+ ]
886
+ },
887
+ "description": "The fields the boundary is handed, by field name. On a function-call boundary a name is a parameter, on a message bus it is a field of the message body."
888
+ }
889
+ },
890
+ "required": ["semantics", "deploymentTarget"],
891
+ "additionalProperties": false
892
+ }
893
+ ],
894
+ "description": "Which boundary in the code the document is about."
895
+ },
896
+ "transitions": {
897
+ "minItems": 1,
898
+ "type": "array",
899
+ "items": {
900
+ "type": "object",
901
+ "properties": {
902
+ "id": {
903
+ "type": "string",
904
+ "minLength": 1,
905
+ "description": "The outcome's name. A PRD scenario links to it as <intent-name>.<id>."
906
+ },
907
+ "when": {
908
+ "anyOf": [
909
+ {
910
+ "type": "string",
911
+ "minLength": 1
912
+ },
913
+ {
914
+ "minItems": 1,
915
+ "type": "array",
916
+ "items": {
917
+ "anyOf": [
918
+ {
919
+ "type": "string",
920
+ "minLength": 1
921
+ },
922
+ {
923
+ "type": "object",
924
+ "properties": {
925
+ "reads": {
926
+ "type": "string",
927
+ "minLength": 1
928
+ },
929
+ "where": {
930
+ "type": "string",
931
+ "minLength": 1
932
+ },
933
+ "finds": {
934
+ "type": "string",
935
+ "enum": ["nothing", "something"]
936
+ },
937
+ "is": {
938
+ "type": "string",
939
+ "minLength": 1
940
+ },
941
+ "equals": {
942
+ "anyOf": [
943
+ {
944
+ "type": "string"
945
+ },
946
+ {
947
+ "type": "number"
948
+ },
949
+ {
950
+ "type": "boolean"
951
+ },
952
+ {
953
+ "type": "null"
954
+ }
955
+ ]
956
+ },
957
+ "has": {
958
+ "type": "string",
959
+ "minLength": 1
960
+ }
961
+ },
962
+ "required": ["reads"],
963
+ "additionalProperties": false
964
+ },
965
+ {
966
+ "type": "object",
967
+ "properties": {
968
+ "writes": {
969
+ "type": "string",
970
+ "minLength": 1
971
+ },
972
+ "where": {
973
+ "type": "string",
974
+ "minLength": 1
975
+ },
976
+ "finds": {
977
+ "type": "string",
978
+ "enum": ["nothing", "something"]
979
+ },
980
+ "is": {
981
+ "type": "string",
982
+ "minLength": 1
983
+ },
984
+ "equals": {
985
+ "anyOf": [
986
+ {
987
+ "type": "string"
988
+ },
989
+ {
990
+ "type": "number"
991
+ },
992
+ {
993
+ "type": "boolean"
994
+ },
995
+ {
996
+ "type": "null"
997
+ }
998
+ ]
999
+ },
1000
+ "has": {
1001
+ "type": "string",
1002
+ "minLength": 1
1003
+ }
1004
+ },
1005
+ "required": ["writes"],
1006
+ "additionalProperties": false
1007
+ },
1008
+ {
1009
+ "type": "object",
1010
+ "properties": {
1011
+ "invokes": {
1012
+ "type": "string",
1013
+ "minLength": 1
1014
+ },
1015
+ "where": {
1016
+ "type": "string",
1017
+ "minLength": 1
1018
+ },
1019
+ "finds": {
1020
+ "type": "string",
1021
+ "enum": ["nothing", "something"]
1022
+ },
1023
+ "is": {
1024
+ "type": "string",
1025
+ "minLength": 1
1026
+ },
1027
+ "equals": {
1028
+ "anyOf": [
1029
+ {
1030
+ "type": "string"
1031
+ },
1032
+ {
1033
+ "type": "number"
1034
+ },
1035
+ {
1036
+ "type": "boolean"
1037
+ },
1038
+ {
1039
+ "type": "null"
1040
+ }
1041
+ ]
1042
+ },
1043
+ "has": {
1044
+ "type": "string",
1045
+ "minLength": 1
1046
+ }
1047
+ },
1048
+ "required": ["invokes"],
1049
+ "additionalProperties": false
1050
+ },
1051
+ {
1052
+ "type": "object",
1053
+ "properties": {
1054
+ "input": {
1055
+ "type": "string",
1056
+ "minLength": 1
1057
+ },
1058
+ "where": {
1059
+ "type": "string",
1060
+ "minLength": 1
1061
+ },
1062
+ "finds": {
1063
+ "type": "string",
1064
+ "enum": ["nothing", "something"]
1065
+ },
1066
+ "is": {
1067
+ "type": "string",
1068
+ "minLength": 1
1069
+ },
1070
+ "equals": {
1071
+ "anyOf": [
1072
+ {
1073
+ "type": "string"
1074
+ },
1075
+ {
1076
+ "type": "number"
1077
+ },
1078
+ {
1079
+ "type": "boolean"
1080
+ },
1081
+ {
1082
+ "type": "null"
1083
+ }
1084
+ ]
1085
+ },
1086
+ "has": {
1087
+ "type": "string",
1088
+ "minLength": 1
1089
+ }
1090
+ },
1091
+ "required": ["input"],
1092
+ "additionalProperties": false
1093
+ }
1094
+ ]
1095
+ }
1096
+ }
1097
+ ],
1098
+ "description": "What has to hold for this outcome, either as a list of clauses or as one sentence."
1099
+ },
1100
+ "response": {
1101
+ "description": "This outcome sends an HTTP response.",
1102
+ "anyOf": [
1103
+ {
1104
+ "type": "object",
1105
+ "properties": {
1106
+ "status": {
1107
+ "type": "integer",
1108
+ "minimum": 100,
1109
+ "maximum": 599,
1110
+ "description": "The HTTP status code the response carries."
1111
+ },
1112
+ "body": {
1113
+ "anyOf": [
1114
+ {
1115
+ "$ref": "#/$defs/__schema0"
1116
+ },
1117
+ {
1118
+ "type": "object",
1119
+ "properties": {
1120
+ "properties": {
1121
+ "type": "object",
1122
+ "propertyNames": {
1123
+ "type": "string"
1124
+ },
1125
+ "additionalProperties": {
1126
+ "$ref": "#/$defs/__schema0"
1127
+ }
1128
+ },
1129
+ "required": {
1130
+ "type": "array",
1131
+ "items": {
1132
+ "type": "string"
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+ ],
1138
+ "description": "The shape of the response body."
1139
+ }
1140
+ },
1141
+ "required": ["status"]
1142
+ },
1143
+ {
1144
+ "type": "null"
1145
+ }
1146
+ ]
1147
+ },
1148
+ "returns": {
1149
+ "description": "This outcome returns a value to its caller.",
1150
+ "anyOf": [
1151
+ {
1152
+ "type": "object",
1153
+ "properties": {
1154
+ "body": {
1155
+ "anyOf": [
1156
+ {
1157
+ "$ref": "#/$defs/__schema0"
1158
+ },
1159
+ {
1160
+ "type": "object",
1161
+ "properties": {
1162
+ "properties": {
1163
+ "type": "object",
1164
+ "propertyNames": {
1165
+ "type": "string"
1166
+ },
1167
+ "additionalProperties": {
1168
+ "$ref": "#/$defs/__schema0"
1169
+ }
1170
+ },
1171
+ "required": {
1172
+ "type": "array",
1173
+ "items": {
1174
+ "type": "string"
1175
+ }
1176
+ }
1177
+ }
1178
+ }
1179
+ ],
1180
+ "description": "The shape of the returned value."
1181
+ }
1182
+ }
1183
+ },
1184
+ {
1185
+ "type": "null"
1186
+ }
1187
+ ]
1188
+ },
1189
+ "throws": {
1190
+ "description": "This outcome raises an error.",
1191
+ "anyOf": [
1192
+ {
1193
+ "type": "object",
1194
+ "properties": {
1195
+ "errorType": {
1196
+ "type": "string",
1197
+ "description": "The name of the error class this outcome raises."
1198
+ }
1199
+ }
1200
+ },
1201
+ {
1202
+ "type": "null"
1203
+ }
1204
+ ]
1205
+ },
1206
+ "results": {
1207
+ "minItems": 1,
1208
+ "type": "array",
1209
+ "items": {
1210
+ "anyOf": [
1211
+ {
1212
+ "type": "object",
1213
+ "properties": {
1214
+ "reads": {
1215
+ "type": "string",
1216
+ "minLength": 1
1217
+ },
1218
+ "fields": {
1219
+ "minItems": 1,
1220
+ "type": "array",
1221
+ "items": {
1222
+ "type": "string",
1223
+ "minLength": 1
1224
+ }
1225
+ },
1226
+ "by": {
1227
+ "anyOf": [
1228
+ {
1229
+ "type": "string",
1230
+ "minLength": 1
1231
+ },
1232
+ {
1233
+ "minItems": 1,
1234
+ "type": "array",
1235
+ "items": {
1236
+ "type": "string",
1237
+ "minLength": 1
1238
+ }
1239
+ }
1240
+ ]
1241
+ }
1242
+ },
1243
+ "required": ["reads"],
1244
+ "additionalProperties": false
1245
+ },
1246
+ {
1247
+ "type": "object",
1248
+ "properties": {
1249
+ "writes": {
1250
+ "type": "string",
1251
+ "minLength": 1
1252
+ },
1253
+ "fields": {
1254
+ "minItems": 1,
1255
+ "type": "array",
1256
+ "items": {
1257
+ "type": "string",
1258
+ "minLength": 1
1259
+ }
1260
+ },
1261
+ "by": {
1262
+ "anyOf": [
1263
+ {
1264
+ "type": "string",
1265
+ "minLength": 1
1266
+ },
1267
+ {
1268
+ "minItems": 1,
1269
+ "type": "array",
1270
+ "items": {
1271
+ "type": "string",
1272
+ "minLength": 1
1273
+ }
1274
+ }
1275
+ ]
1276
+ }
1277
+ },
1278
+ "required": ["writes"],
1279
+ "additionalProperties": false
1280
+ },
1281
+ {
1282
+ "type": "object",
1283
+ "properties": {
1284
+ "invokes": {
1285
+ "type": "string",
1286
+ "minLength": 1
1287
+ },
1288
+ "fields": {
1289
+ "minItems": 1,
1290
+ "type": "array",
1291
+ "items": {
1292
+ "type": "string",
1293
+ "minLength": 1
1294
+ }
1295
+ },
1296
+ "by": {
1297
+ "anyOf": [
1298
+ {
1299
+ "type": "string",
1300
+ "minLength": 1
1301
+ },
1302
+ {
1303
+ "minItems": 1,
1304
+ "type": "array",
1305
+ "items": {
1306
+ "type": "string",
1307
+ "minLength": 1
1308
+ }
1309
+ }
1310
+ ]
1311
+ }
1312
+ },
1313
+ "required": ["invokes"],
1314
+ "additionalProperties": false
1315
+ }
1316
+ ]
1317
+ },
1318
+ "description": "The effects this outcome has, written in the same verbs suss ask uses: reads, writes, invokes."
1319
+ }
1320
+ },
1321
+ "required": ["id", "when"],
1322
+ "additionalProperties": false
1323
+ },
1324
+ "description": "Every outcome the boundary can produce, one entry each."
1325
+ }
1326
+ },
1327
+ "required": [
1328
+ "kind",
1329
+ "name",
1330
+ "purpose",
1331
+ "audience",
1332
+ "boundary",
1333
+ "transitions"
1334
+ ],
1335
+ "additionalProperties": false
1336
+ },
1337
+ {
1338
+ "type": "object",
1339
+ "properties": {
1340
+ "kind": {
1341
+ "type": "string",
1342
+ "const": "prd",
1343
+ "description": "Makes this document a PRD, a set of scenarios for a feature."
1344
+ },
1345
+ "title": {
1346
+ "type": "string",
1347
+ "minLength": 1,
1348
+ "description": "What this document is called."
1349
+ },
1350
+ "purpose": {
1351
+ "type": "string",
1352
+ "minLength": 1,
1353
+ "description": "What the feature is for, in the author's own words."
1354
+ },
1355
+ "audience": {
1356
+ "type": "string",
1357
+ "minLength": 1,
1358
+ "description": "Who the feature is for."
1359
+ },
1360
+ "source": {
1361
+ "default": "author",
1362
+ "description": "Where the document came from: somebody wrote it, suss inferred it, or suss inferred it and somebody has since curated it.",
1363
+ "type": "string",
1364
+ "enum": ["author", "inferred", "inferred, curated"]
1365
+ },
1366
+ "scenarios": {
1367
+ "minItems": 1,
1368
+ "type": "array",
1369
+ "items": {
1370
+ "type": "object",
1371
+ "properties": {
1372
+ "title": {
1373
+ "type": "string",
1374
+ "minLength": 1,
1375
+ "description": "A short name for the scenario."
1376
+ },
1377
+ "when": {
1378
+ "type": "string",
1379
+ "minLength": 1,
1380
+ "description": "The condition the scenario covers, in the author's own words."
1381
+ },
1382
+ "expect": {
1383
+ "type": "string",
1384
+ "minLength": 1,
1385
+ "description": "What should happen then, in the author's own words."
1386
+ },
1387
+ "link": {
1388
+ "anyOf": [
1389
+ {
1390
+ "type": "string",
1391
+ "minLength": 1
1392
+ },
1393
+ {
1394
+ "minItems": 1,
1395
+ "type": "array",
1396
+ "items": {
1397
+ "type": "string",
1398
+ "minLength": 1
1399
+ }
1400
+ }
1401
+ ],
1402
+ "description": "The boundary-intent outcomes this scenario is about, each written <intent-name>.<outcome-id>."
1403
+ }
1404
+ },
1405
+ "required": ["when", "expect"],
1406
+ "additionalProperties": false
1407
+ },
1408
+ "description": "The situations the feature covers, one entry each."
1409
+ }
1410
+ },
1411
+ "required": ["kind", "title", "purpose", "audience", "scenarios"],
1412
+ "additionalProperties": false
1413
+ }
1414
+ ],
1415
+ "$defs": {
1416
+ "__schema0": {
1417
+ "anyOf": [
1418
+ {
1419
+ "type": "object",
1420
+ "properties": {
1421
+ "type": {
1422
+ "type": "string",
1423
+ "enum": [
1424
+ "string",
1425
+ "integer",
1426
+ "number",
1427
+ "boolean",
1428
+ "null",
1429
+ "unknown"
1430
+ ]
1431
+ }
1432
+ },
1433
+ "required": ["type"]
1434
+ },
1435
+ {
1436
+ "type": "object",
1437
+ "properties": {
1438
+ "type": {
1439
+ "type": "string",
1440
+ "const": "array"
1441
+ },
1442
+ "items": {
1443
+ "$ref": "#/$defs/__schema0"
1444
+ }
1445
+ },
1446
+ "required": ["type"]
1447
+ },
1448
+ {
1449
+ "type": "object",
1450
+ "properties": {
1451
+ "type": {
1452
+ "type": "string",
1453
+ "const": "object"
1454
+ },
1455
+ "properties": {
1456
+ "type": "object",
1457
+ "propertyNames": {
1458
+ "type": "string"
1459
+ },
1460
+ "additionalProperties": {
1461
+ "$ref": "#/$defs/__schema0"
1462
+ }
1463
+ },
1464
+ "required": {
1465
+ "type": "array",
1466
+ "items": {
1467
+ "type": "string"
1468
+ }
1469
+ }
1470
+ },
1471
+ "required": ["type"]
1472
+ }
1473
+ ]
1474
+ }
1475
+ }
1476
+ }