@intentius/chant 0.83.0 → 0.85.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.
Files changed (66) hide show
  1. package/dist/cli/main.d.ts.map +1 -1
  2. package/dist/cli/mcp/resource-handlers.d.ts +2 -1
  3. package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
  4. package/dist/cli/mcp/server.d.ts +1 -0
  5. package/dist/cli/mcp/server.d.ts.map +1 -1
  6. package/dist/cli/mcp/tools/composites.d.ts +44 -0
  7. package/dist/cli/mcp/tools/composites.d.ts.map +1 -0
  8. package/dist/cli/mcp/tools/search.d.ts.map +1 -1
  9. package/dist/cli/registry.d.ts +6 -0
  10. package/dist/cli/registry.d.ts.map +1 -1
  11. package/dist/components/cli-support.d.ts +4 -0
  12. package/dist/components/cli-support.d.ts.map +1 -1
  13. package/dist/composite.d.ts +6 -0
  14. package/dist/composite.d.ts.map +1 -1
  15. package/dist/lexicon.d.ts +44 -0
  16. package/dist/lexicon.d.ts.map +1 -1
  17. package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
  18. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  19. package/dist/workspace/composites.d.ts +139 -0
  20. package/dist/workspace/composites.d.ts.map +1 -0
  21. package/dist/workspace/graph-cli.d.ts +16 -1
  22. package/dist/workspace/graph-cli.d.ts.map +1 -1
  23. package/dist/workspace/intent-cli.d.ts +21 -0
  24. package/dist/workspace/intent-cli.d.ts.map +1 -0
  25. package/dist/workspace/intent-joins.d.ts +121 -0
  26. package/dist/workspace/intent-joins.d.ts.map +1 -0
  27. package/dist/workspace/intent.d.ts +310 -0
  28. package/dist/workspace/intent.d.ts.map +1 -0
  29. package/dist/workspace/member-commands.d.ts +7 -2
  30. package/dist/workspace/member-commands.d.ts.map +1 -1
  31. package/dist/workspace/reason-codes.d.ts +29 -0
  32. package/dist/workspace/reason-codes.d.ts.map +1 -1
  33. package/dist/workspace/records.d.ts +7 -1
  34. package/dist/workspace/records.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/src/cli/handlers/graph.ts +4 -0
  37. package/src/cli/main.test.ts +20 -0
  38. package/src/cli/main.ts +18 -0
  39. package/src/cli/mcp/resource-handlers.ts +17 -0
  40. package/src/cli/mcp/server.test.ts +140 -4
  41. package/src/cli/mcp/server.ts +5 -1
  42. package/src/cli/mcp/tools/composites.ts +98 -0
  43. package/src/cli/mcp/tools/search.ts +47 -5
  44. package/src/cli/registry.ts +6 -0
  45. package/src/components/cli-support.test.ts +16 -0
  46. package/src/components/cli-support.ts +8 -2
  47. package/src/composite.ts +9 -0
  48. package/src/lexicon.ts +47 -0
  49. package/src/workspace/__fixtures__/contract-repo.ts +17 -0
  50. package/src/workspace/composites.schema.json +471 -0
  51. package/src/workspace/composites.test.ts +244 -0
  52. package/src/workspace/composites.ts +295 -0
  53. package/src/workspace/graph-cli.ts +39 -3
  54. package/src/workspace/intent-cli.ts +119 -0
  55. package/src/workspace/intent-joins.ts +210 -0
  56. package/src/workspace/intent.schema.json +1141 -0
  57. package/src/workspace/intent.test.ts +566 -0
  58. package/src/workspace/intent.ts +999 -0
  59. package/src/workspace/member-commands.ts +11 -5
  60. package/src/workspace/read-contract.test.ts +46 -3
  61. package/src/workspace/reason-codes.test.ts +39 -2
  62. package/src/workspace/reason-codes.ts +40 -0
  63. package/src/workspace/records-contract.test.ts +22 -2
  64. package/src/workspace/records.schema.json +2 -2
  65. package/src/workspace/records.test.ts +93 -0
  66. package/src/workspace/records.ts +55 -11
@@ -0,0 +1,1141 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/chant/schemas/workspace/intent/v1/intent.schema.json",
4
+ "title": "chant workspace graph --intent output",
5
+ "description": "What `chant workspace graph --intent <region> --json` prints: the intent graph over one region of a workspace (#2651, #2650 section C1, #2524 D8 and D15). The region, the commits that touched it, the decisions whose constrains cover it and their supersession chains, the artifacts those decisions pin, the units, contracts and evidence a plugin joins to the commits, the member links of the region's member, and findings as nodes with closed codes. chant emits it and a reader such as hud draws it. Readers ignore fields and node or edge kinds they do not know; a field is only ever added within a version. The finding, reason and error codes are closed lists. Contract version 1 is written by chant 0.81.0 and newer, and this document was added to it by #2651; a chant without --intent refuses the flag. Every code is in the one closed list of `reason-codes.ts`.",
6
+ "oneOf": [
7
+ {
8
+ "$ref": "#/$defs/result"
9
+ },
10
+ {
11
+ "$ref": "#/$defs/failure"
12
+ }
13
+ ],
14
+ "$defs": {
15
+ "result": {
16
+ "description": "The region was read. Exit code 0, or 1 when a plugin failed; the document is printed either way.",
17
+ "type": "object",
18
+ "required": [
19
+ "$schema",
20
+ "contract",
21
+ "chant",
22
+ "at",
23
+ "workspace",
24
+ "region",
25
+ "history",
26
+ "kinds",
27
+ "nodes",
28
+ "edges",
29
+ "reasons",
30
+ "summary"
31
+ ],
32
+ "properties": {
33
+ "$schema": {
34
+ "const": "https://intentius.io/chant/schemas/workspace/intent/v1/intent.schema.json"
35
+ },
36
+ "contract": {
37
+ "const": 1
38
+ },
39
+ "chant": {
40
+ "type": "string",
41
+ "description": "The chant that wrote the document."
42
+ },
43
+ "at": {
44
+ "type": [
45
+ "string",
46
+ "null"
47
+ ],
48
+ "pattern": "^[0-9a-f]{40,64}$",
49
+ "description": "The full commit id read with --at, or null for the working tree. History is read from this commit, or from HEAD for the working tree."
50
+ },
51
+ "workspace": {
52
+ "type": "object",
53
+ "required": [
54
+ "name",
55
+ "root"
56
+ ],
57
+ "properties": {
58
+ "name": {
59
+ "type": "string"
60
+ },
61
+ "root": {
62
+ "type": "string",
63
+ "description": "The workspace root relative to the git root, \".\" for the git root."
64
+ }
65
+ }
66
+ },
67
+ "region": {
68
+ "type": "string",
69
+ "description": "The id of the region node."
70
+ },
71
+ "history": {
72
+ "type": "object",
73
+ "required": [
74
+ "rev",
75
+ "follows",
76
+ "shallow"
77
+ ],
78
+ "properties": {
79
+ "rev": {
80
+ "type": [
81
+ "string",
82
+ "null"
83
+ ],
84
+ "pattern": "^[0-9a-f]{40,64}$",
85
+ "description": "The commit the history was read from, or null when the repository has no commits."
86
+ },
87
+ "follows": {
88
+ "enum": [
89
+ "line-range",
90
+ "file",
91
+ "directory"
92
+ ],
93
+ "description": "line-range: git log -L over the region's lines. file: git log --follow over the file. directory: git log over the directory."
94
+ },
95
+ "shallow": {
96
+ "type": "boolean",
97
+ "description": "Whether the repository is a shallow clone. When true, reasons holds intent-history-shallow."
98
+ }
99
+ }
100
+ },
101
+ "error": false,
102
+ "kinds": {
103
+ "type": "array",
104
+ "description": "Each --kind file, in order: its name, the record kind it reads, if any, and the form of its commitJoins export, if any.",
105
+ "items": {
106
+ "type": "object",
107
+ "required": [
108
+ "file",
109
+ "records",
110
+ "joins"
111
+ ],
112
+ "properties": {
113
+ "file": {
114
+ "type": "string",
115
+ "description": "From the repository root."
116
+ },
117
+ "name": {
118
+ "type": "string",
119
+ "description": "The kind's name: the record kind's name, or the file's name without .kind.mjs for a plugin with no records. A plugin's findings use it as their namespace, plugin:<name>:<code> (#2656). Added within version 1, so an older document may lack it."
120
+ },
121
+ "records": {
122
+ "type": [
123
+ "string",
124
+ "null"
125
+ ],
126
+ "description": "The record kind's name, or null for a plugin with no records."
127
+ },
128
+ "joins": {
129
+ "enum": [
130
+ "function",
131
+ "data",
132
+ null
133
+ ]
134
+ }
135
+ }
136
+ }
137
+ },
138
+ "nodes": {
139
+ "type": "array",
140
+ "description": "In walk order: the region, its files and member, the commits newest first with the units, contracts and evidence joined to them, the decisions and their evidence entries, the artifacts, the links, and the findings.",
141
+ "items": {
142
+ "$ref": "#/$defs/node"
143
+ }
144
+ },
145
+ "edges": {
146
+ "type": "array",
147
+ "items": {
148
+ "$ref": "#/$defs/edge"
149
+ }
150
+ },
151
+ "reasons": {
152
+ "type": "array",
153
+ "description": "Parts of the walk that could not be read. The rest of the document stands.",
154
+ "items": {
155
+ "$ref": "#/$defs/reason"
156
+ }
157
+ },
158
+ "summary": {
159
+ "type": "object",
160
+ "required": [
161
+ "commits",
162
+ "decisions",
163
+ "artifacts",
164
+ "findings"
165
+ ],
166
+ "properties": {
167
+ "commits": {
168
+ "type": "integer",
169
+ "minimum": 0
170
+ },
171
+ "decisions": {
172
+ "type": "integer",
173
+ "minimum": 0
174
+ },
175
+ "artifacts": {
176
+ "type": "integer",
177
+ "minimum": 0
178
+ },
179
+ "findings": {
180
+ "type": "integer",
181
+ "minimum": 0
182
+ }
183
+ }
184
+ }
185
+ }
186
+ },
187
+ "node": {
188
+ "oneOf": [
189
+ {
190
+ "$ref": "#/$defs/region"
191
+ },
192
+ {
193
+ "$ref": "#/$defs/file"
194
+ },
195
+ {
196
+ "$ref": "#/$defs/member"
197
+ },
198
+ {
199
+ "$ref": "#/$defs/commit"
200
+ },
201
+ {
202
+ "$ref": "#/$defs/joined"
203
+ },
204
+ {
205
+ "$ref": "#/$defs/decision"
206
+ },
207
+ {
208
+ "$ref": "#/$defs/artifact"
209
+ },
210
+ {
211
+ "$ref": "#/$defs/link"
212
+ },
213
+ {
214
+ "$ref": "#/$defs/finding"
215
+ }
216
+ ]
217
+ },
218
+ "lineRange": {
219
+ "type": "object",
220
+ "required": [
221
+ "start",
222
+ "end"
223
+ ],
224
+ "properties": {
225
+ "start": {
226
+ "type": "integer",
227
+ "minimum": 1
228
+ },
229
+ "end": {
230
+ "type": "integer",
231
+ "minimum": 0
232
+ }
233
+ }
234
+ },
235
+ "region": {
236
+ "description": "The region the walk starts from. Its id is region:<path> with :<start>-<end> for a line range.",
237
+ "type": "object",
238
+ "required": [
239
+ "id",
240
+ "kind",
241
+ "path",
242
+ "lines",
243
+ "member",
244
+ "at",
245
+ "type",
246
+ "generated",
247
+ "node"
248
+ ],
249
+ "properties": {
250
+ "id": {
251
+ "type": "string",
252
+ "pattern": "^region:"
253
+ },
254
+ "kind": {
255
+ "const": "region"
256
+ },
257
+ "path": {
258
+ "type": "string",
259
+ "description": "From the workspace root, \".\" for the root itself."
260
+ },
261
+ "lines": {
262
+ "oneOf": [
263
+ {
264
+ "type": "null"
265
+ },
266
+ {
267
+ "$ref": "#/$defs/lineRange"
268
+ }
269
+ ],
270
+ "description": "The line range asked for, in the file as read, or null for the whole path."
271
+ },
272
+ "member": {
273
+ "type": [
274
+ "string",
275
+ "null"
276
+ ],
277
+ "description": "The member whose directory holds the path, or null."
278
+ },
279
+ "at": {
280
+ "type": [
281
+ "string",
282
+ "null"
283
+ ],
284
+ "pattern": "^[0-9a-f]{40,64}$"
285
+ },
286
+ "type": {
287
+ "enum": [
288
+ "file",
289
+ "dir"
290
+ ]
291
+ },
292
+ "generated": {
293
+ "type": [
294
+ "boolean",
295
+ "null"
296
+ ],
297
+ "description": "For a file, whether it is generated (#2524 D14): declared in a member's generated entries, or one core registers. Null for a directory."
298
+ },
299
+ "node": {
300
+ "type": [
301
+ "string",
302
+ "null"
303
+ ],
304
+ "description": "The graph node id the region was given as, whose sourceLoc it is, or null."
305
+ }
306
+ }
307
+ },
308
+ "file": {
309
+ "description": "A file under a directory region.",
310
+ "type": "object",
311
+ "required": [
312
+ "id",
313
+ "kind",
314
+ "path",
315
+ "member",
316
+ "generated"
317
+ ],
318
+ "properties": {
319
+ "id": {
320
+ "type": "string",
321
+ "pattern": "^file:"
322
+ },
323
+ "kind": {
324
+ "const": "file"
325
+ },
326
+ "path": {
327
+ "type": "string"
328
+ },
329
+ "member": {
330
+ "type": [
331
+ "string",
332
+ "null"
333
+ ]
334
+ },
335
+ "generated": {
336
+ "type": "boolean"
337
+ }
338
+ }
339
+ },
340
+ "member": {
341
+ "description": "The region's member, and each member a link joins it to.",
342
+ "type": "object",
343
+ "required": [
344
+ "id",
345
+ "kind",
346
+ "name",
347
+ "dir",
348
+ "memberKind"
349
+ ],
350
+ "properties": {
351
+ "id": {
352
+ "type": "string",
353
+ "pattern": "^member:"
354
+ },
355
+ "kind": {
356
+ "const": "member"
357
+ },
358
+ "name": {
359
+ "type": "string",
360
+ "description": "Joins to members[].name in ls and graph."
361
+ },
362
+ "dir": {
363
+ "type": "string"
364
+ },
365
+ "memberKind": {
366
+ "type": "string"
367
+ }
368
+ }
369
+ },
370
+ "commit": {
371
+ "description": "A commit that touched the region. Linked from the region by a touched-by edge, and to each decision whose path window it falls in by a within edge.",
372
+ "type": "object",
373
+ "required": [
374
+ "id",
375
+ "kind",
376
+ "sha",
377
+ "subject",
378
+ "author",
379
+ "date",
380
+ "trailers",
381
+ "pullRequest",
382
+ "signature",
383
+ "lines"
384
+ ],
385
+ "properties": {
386
+ "id": {
387
+ "type": "string",
388
+ "pattern": "^commit:"
389
+ },
390
+ "kind": {
391
+ "const": "commit"
392
+ },
393
+ "sha": {
394
+ "type": "string",
395
+ "pattern": "^[0-9a-f]{40,64}$"
396
+ },
397
+ "subject": {
398
+ "type": "string"
399
+ },
400
+ "author": {
401
+ "type": "object",
402
+ "required": [
403
+ "name",
404
+ "email"
405
+ ],
406
+ "properties": {
407
+ "name": {
408
+ "type": "string"
409
+ },
410
+ "email": {
411
+ "type": "string"
412
+ }
413
+ }
414
+ },
415
+ "date": {
416
+ "type": "string",
417
+ "description": "Author date, ISO 8601."
418
+ },
419
+ "trailers": {
420
+ "type": "object",
421
+ "description": "Every trailer git parses from the message, keyed as written. Core gives no key a meaning; a kind's commitJoins may.",
422
+ "additionalProperties": {
423
+ "type": "array",
424
+ "items": {
425
+ "type": "string"
426
+ }
427
+ }
428
+ },
429
+ "pullRequest": {
430
+ "type": [
431
+ "integer",
432
+ "null"
433
+ ],
434
+ "description": "The number in a (#n) that ends the subject, as a squash merge writes it, or null."
435
+ },
436
+ "signature": {
437
+ "type": "object",
438
+ "required": [
439
+ "level",
440
+ "reason"
441
+ ],
442
+ "properties": {
443
+ "level": {
444
+ "enum": [
445
+ "attested",
446
+ "attested-unverifiable-here",
447
+ "adopted",
448
+ "unattested"
449
+ ],
450
+ "description": "The commit's provenance level, judged by the signers at base as records judges a record (#2547)."
451
+ },
452
+ "reason": {
453
+ "type": "string"
454
+ },
455
+ "principal": {
456
+ "type": "string"
457
+ }
458
+ }
459
+ },
460
+ "lines": {
461
+ "oneOf": [
462
+ {
463
+ "type": "null"
464
+ },
465
+ {
466
+ "type": "array",
467
+ "items": {
468
+ "$ref": "#/$defs/lineRange"
469
+ }
470
+ }
471
+ ],
472
+ "description": "For a line-range region, the ranges the commit changed within it, numbered in the commit's own version of the file. Null otherwise."
473
+ },
474
+ "state": {
475
+ "enum": [
476
+ "decided",
477
+ "decided-by-window",
478
+ "undecided",
479
+ null
480
+ ],
481
+ "description": "How the decisions constraining the region by path relate to the commit (#2656). decided: it falls inside a decision's window and that decision's own unit made it. decided-by-window: it falls inside a window, and it is not the decision's own work, so the person judges it. undecided: outside every window, with the finding intent-commit-undecided. null: no record kind was read. Added within version 1, so an older document may lack it."
482
+ }
483
+ }
484
+ },
485
+ "joined": {
486
+ "description": "A unit of work, contract or piece of evidence from a plugin (#2650 C13), or an evidence entry of a decision that has a URL.",
487
+ "type": "object",
488
+ "required": [
489
+ "id",
490
+ "kind",
491
+ "ref",
492
+ "plugin",
493
+ "data"
494
+ ],
495
+ "properties": {
496
+ "id": {
497
+ "type": "string",
498
+ "pattern": "^(unit|contract|evidence):"
499
+ },
500
+ "kind": {
501
+ "enum": [
502
+ "unit",
503
+ "contract",
504
+ "evidence"
505
+ ]
506
+ },
507
+ "ref": {
508
+ "type": "string",
509
+ "description": "The plugin's own id, or the URL of a decision's evidence entry."
510
+ },
511
+ "plugin": {
512
+ "type": [
513
+ "string",
514
+ "null"
515
+ ],
516
+ "description": "The kind file whose commitJoins supplied it, from the repository root, or null for a decision's evidence entry."
517
+ },
518
+ "data": {
519
+ "type": "object",
520
+ "description": "The fields the plugin gave besides the id, such as a unit's role, scope, base_commit, context_hash and outcome, or a contract's sha, status and criteria. For a decision's evidence entry: title, url, path, as_of and sha256."
521
+ }
522
+ }
523
+ },
524
+ "decision": {
525
+ "description": "A record whose constrains cover the region, or one in the supersession chain of such a record. Its id is record:<kind>/<id>.",
526
+ "type": "object",
527
+ "required": [
528
+ "id",
529
+ "kind",
530
+ "recordKind",
531
+ "record",
532
+ "path",
533
+ "title",
534
+ "state",
535
+ "closed",
536
+ "valid",
537
+ "reasons",
538
+ "provenance",
539
+ "decided_by",
540
+ "decided_on",
541
+ "reviews",
542
+ "supersededBy",
543
+ "supersedes",
544
+ "constrains"
545
+ ],
546
+ "properties": {
547
+ "id": {
548
+ "type": "string",
549
+ "pattern": "^record:"
550
+ },
551
+ "kind": {
552
+ "const": "decision"
553
+ },
554
+ "recordKind": {
555
+ "type": "string"
556
+ },
557
+ "record": {
558
+ "type": "string",
559
+ "description": "The record's id; joins to records[].id in graph --kind and records."
560
+ },
561
+ "path": {
562
+ "type": "string",
563
+ "description": "The record file, from the repository root."
564
+ },
565
+ "title": {
566
+ "type": [
567
+ "string",
568
+ "null"
569
+ ]
570
+ },
571
+ "state": {
572
+ "type": [
573
+ "string",
574
+ "null"
575
+ ]
576
+ },
577
+ "closed": {
578
+ "type": "boolean",
579
+ "description": "Whether the record kind lists the state as closed, such as ratified."
580
+ },
581
+ "valid": {
582
+ "type": "boolean"
583
+ },
584
+ "reasons": {
585
+ "type": "array",
586
+ "items": {
587
+ "type": "object",
588
+ "required": [
589
+ "code",
590
+ "message"
591
+ ],
592
+ "properties": {
593
+ "code": {
594
+ "enum": [
595
+ "record-unparseable",
596
+ "record-schema-invalid",
597
+ "record-id-duplicate",
598
+ "record-supersedes-unknown",
599
+ "record-supersedes-conflict"
600
+ ]
601
+ },
602
+ "message": {
603
+ "type": "string"
604
+ }
605
+ }
606
+ }
607
+ },
608
+ "provenance": {
609
+ "type": "object",
610
+ "required": [
611
+ "level",
612
+ "commit",
613
+ "reason"
614
+ ],
615
+ "properties": {
616
+ "level": {
617
+ "enum": [
618
+ "attested",
619
+ "attested-unverifiable-here",
620
+ "adopted",
621
+ "unattested"
622
+ ]
623
+ },
624
+ "commit": {
625
+ "type": [
626
+ "string",
627
+ "null"
628
+ ],
629
+ "pattern": "^[0-9a-f]{40,64}$"
630
+ },
631
+ "reason": {
632
+ "type": "string"
633
+ }
634
+ }
635
+ },
636
+ "decided_by": {
637
+ "type": [
638
+ "string",
639
+ "null"
640
+ ]
641
+ },
642
+ "decided_on": {
643
+ "type": [
644
+ "string",
645
+ "null"
646
+ ]
647
+ },
648
+ "reviews": {
649
+ "type": "object",
650
+ "required": [
651
+ "agree",
652
+ "dissent",
653
+ "abstain",
654
+ "openConcerns"
655
+ ],
656
+ "properties": {
657
+ "agree": {
658
+ "type": "integer",
659
+ "minimum": 0
660
+ },
661
+ "dissent": {
662
+ "type": "integer",
663
+ "minimum": 0
664
+ },
665
+ "abstain": {
666
+ "type": "integer",
667
+ "minimum": 0
668
+ },
669
+ "openConcerns": {
670
+ "type": "integer",
671
+ "minimum": 0
672
+ }
673
+ },
674
+ "description": "Verdict counts. openConcerns counts dissents with neither addressed_by nor withdrawn_on."
675
+ },
676
+ "supersededBy": {
677
+ "type": [
678
+ "string",
679
+ "null"
680
+ ],
681
+ "description": "Derived as records derives it: the id of the record whose supersedes link replaces this one."
682
+ },
683
+ "supersedes": {
684
+ "type": "array",
685
+ "items": {
686
+ "type": "string"
687
+ },
688
+ "description": "The ids this record's supersedes links name."
689
+ },
690
+ "constrains": {
691
+ "type": "array",
692
+ "description": "The entries that cover the region, with their granularity. Empty for a decision in the graph only through a supersession chain or a path below a directory region.",
693
+ "items": {
694
+ "type": "object",
695
+ "required": [
696
+ "entry",
697
+ "granularity"
698
+ ],
699
+ "properties": {
700
+ "entry": {
701
+ "type": "string"
702
+ },
703
+ "granularity": {
704
+ "enum": [
705
+ "path",
706
+ "member",
707
+ "contract",
708
+ "issue"
709
+ ]
710
+ }
711
+ }
712
+ }
713
+ }
714
+ }
715
+ },
716
+ "artifact": {
717
+ "description": "A workspace file a decision in the graph pins. Artifacts reach the region only through decisions (#2549).",
718
+ "type": "object",
719
+ "required": [
720
+ "id",
721
+ "kind",
722
+ "path",
723
+ "anchor",
724
+ "pinnedSha256",
725
+ "currentSha256",
726
+ "pinState"
727
+ ],
728
+ "properties": {
729
+ "id": {
730
+ "type": "string",
731
+ "pattern": "^artifact:"
732
+ },
733
+ "kind": {
734
+ "const": "artifact"
735
+ },
736
+ "path": {
737
+ "type": "string",
738
+ "description": "From the workspace root the pinning record kind resolves pins in."
739
+ },
740
+ "anchor": {
741
+ "type": [
742
+ "string",
743
+ "null"
744
+ ]
745
+ },
746
+ "pinnedSha256": {
747
+ "type": [
748
+ "string",
749
+ "null"
750
+ ],
751
+ "pattern": "^[0-9a-f]{64}$",
752
+ "description": "The hash a current decision pins, or null when none does."
753
+ },
754
+ "currentSha256": {
755
+ "type": [
756
+ "string",
757
+ "null"
758
+ ],
759
+ "pattern": "^[0-9a-f]{64}$",
760
+ "description": "The file's hash in the tree read, or null when it is missing or nothing hashed it."
761
+ },
762
+ "pinState": {
763
+ "enum": [
764
+ "pinned",
765
+ "drifted",
766
+ "missing",
767
+ "stale",
768
+ "unpinned"
769
+ ],
770
+ "description": "The state of a current decision's pin (the worst, when several pin it): pinned, drifted, missing or stale as records reports it. unpinned when only superseded decisions pin it, or the evidence entry has no hash."
771
+ }
772
+ }
773
+ },
774
+ "link": {
775
+ "description": "A member link that touches the region's member.",
776
+ "type": "object",
777
+ "required": [
778
+ "id",
779
+ "kind",
780
+ "row"
781
+ ],
782
+ "properties": {
783
+ "id": {
784
+ "type": "string",
785
+ "pattern": "^link:"
786
+ },
787
+ "kind": {
788
+ "const": "link"
789
+ },
790
+ "row": {
791
+ "type": "object",
792
+ "required": [
793
+ "consumer",
794
+ "kind",
795
+ "origin",
796
+ "resolves",
797
+ "status",
798
+ "reason"
799
+ ],
800
+ "description": "A declared member link row of the region's member, resolved in source as workspace check resolves it (#2539).",
801
+ "properties": {
802
+ "consumer": {
803
+ "type": "string"
804
+ },
805
+ "kind": {
806
+ "type": "string"
807
+ },
808
+ "origin": {
809
+ "type": "string"
810
+ },
811
+ "resolves": {
812
+ "type": "string"
813
+ },
814
+ "status": {
815
+ "type": "string"
816
+ },
817
+ "reason": {
818
+ "type": [
819
+ "string",
820
+ "null"
821
+ ]
822
+ }
823
+ }
824
+ }
825
+ }
826
+ },
827
+ "finding": {
828
+ "description": "A gap the walk found. Findings are nodes so a reader can draw them and a test can assert them; the tool asks, and never answers. A plugin's commitJoins may add findings of its own, with a code in its namespace (#2656).",
829
+ "type": "object",
830
+ "required": [
831
+ "id",
832
+ "kind",
833
+ "code",
834
+ "message",
835
+ "concerns"
836
+ ],
837
+ "properties": {
838
+ "id": {
839
+ "type": "string",
840
+ "pattern": "^finding:"
841
+ },
842
+ "kind": {
843
+ "const": "finding"
844
+ },
845
+ "code": {
846
+ "anyOf": [
847
+ {
848
+ "enum": [
849
+ "intent-commit-undecided",
850
+ "intent-commit-bare",
851
+ "intent-pin-drifted",
852
+ "intent-pin-missing",
853
+ "intent-artifact-unpinned",
854
+ "intent-decision-superseded-live",
855
+ "intent-decision-provisional",
856
+ "intent-constraint-coarse",
857
+ "intent-constraint-lost",
858
+ "intent-evidence-unpinned",
859
+ "intent-trailer-unverified",
860
+ "intent-region-unconstrained"
861
+ ]
862
+ },
863
+ {
864
+ "type": "string",
865
+ "pattern": "^plugin:[^:\\s]+:[a-z0-9]+(-[a-z0-9]+)*$",
866
+ "description": "A plugin's own code, plugin:<name>:<code>, where <name> is the kind's name in kinds. Outside the closed list: the plugin owns its namespace."
867
+ }
868
+ ]
869
+ },
870
+ "message": {
871
+ "type": "string"
872
+ },
873
+ "concerns": {
874
+ "type": "array",
875
+ "items": {
876
+ "type": "string"
877
+ },
878
+ "description": "The ids of the nodes the finding is about."
879
+ },
880
+ "plugin": {
881
+ "type": "string",
882
+ "description": "For a plugin's finding: the kind file that returned it, as in kinds."
883
+ },
884
+ "refs": {
885
+ "type": "array",
886
+ "items": {
887
+ "type": "string"
888
+ },
889
+ "description": "For a plugin's finding: the refs as the plugin gave them. Those that name a node in the graph are resolved to its id in concerns, after the commit the finding was returned for."
890
+ }
891
+ }
892
+ },
893
+ "edge": {
894
+ "description": "constrains: decision to region, file or contract. pins: decision to artifact. touched-by: region to commit. produced-by: commit to unit. serves: unit to contract. supersedes: the newer decision to the one it replaces. cites-evidence: unit, contract or decision to evidence. links: consumer member to producer member. within: commit to a decision whose path window it falls in.",
895
+ "oneOf": [
896
+ {
897
+ "$ref": "#/$defs/constrainsEdge"
898
+ },
899
+ {
900
+ "$ref": "#/$defs/pinsEdge"
901
+ },
902
+ {
903
+ "$ref": "#/$defs/touchedEdge"
904
+ },
905
+ {
906
+ "$ref": "#/$defs/withinEdge"
907
+ },
908
+ {
909
+ "$ref": "#/$defs/plainEdge"
910
+ }
911
+ ]
912
+ },
913
+ "reason": {
914
+ "type": "object",
915
+ "required": [
916
+ "code",
917
+ "message"
918
+ ],
919
+ "properties": {
920
+ "code": {
921
+ "enum": [
922
+ "intent-history-shallow",
923
+ "intent-plugin-failed"
924
+ ]
925
+ },
926
+ "message": {
927
+ "type": "string"
928
+ }
929
+ }
930
+ },
931
+ "failure": {
932
+ "description": "The declaration, a record kind or the region could not be read, and nothing was walked. Exit code 1.",
933
+ "type": "object",
934
+ "required": [
935
+ "$schema",
936
+ "contract",
937
+ "chant",
938
+ "error"
939
+ ],
940
+ "properties": {
941
+ "$schema": {
942
+ "const": "https://intentius.io/chant/schemas/workspace/intent/v1/intent.schema.json"
943
+ },
944
+ "contract": {
945
+ "const": 1
946
+ },
947
+ "chant": {
948
+ "type": "string"
949
+ },
950
+ "error": {
951
+ "type": "object",
952
+ "required": [
953
+ "code",
954
+ "message"
955
+ ],
956
+ "properties": {
957
+ "code": {
958
+ "enum": [
959
+ "declaration-missing",
960
+ "declaration-ambiguous",
961
+ "declaration-unparseable",
962
+ "declaration-invalid",
963
+ "placement-invalid",
964
+ "reader-too-old",
965
+ "root-chant-required",
966
+ "not-a-git-repository",
967
+ "revision-unknown",
968
+ "kind-unreadable",
969
+ "kind-invalid",
970
+ "schema-unreadable",
971
+ "schema-id-mismatch",
972
+ "schema-invalid",
973
+ "location-missing",
974
+ "intent-region-invalid"
975
+ ]
976
+ },
977
+ "message": {
978
+ "type": "string"
979
+ }
980
+ }
981
+ },
982
+ "nodes": false
983
+ }
984
+ },
985
+ "constrainsEdge": {
986
+ "type": "object",
987
+ "required": [
988
+ "kind",
989
+ "from",
990
+ "to",
991
+ "granularity",
992
+ "entry"
993
+ ],
994
+ "properties": {
995
+ "from": {
996
+ "type": "string"
997
+ },
998
+ "to": {
999
+ "type": "string"
1000
+ },
1001
+ "kind": {
1002
+ "const": "constrains"
1003
+ },
1004
+ "granularity": {
1005
+ "enum": [
1006
+ "path",
1007
+ "member",
1008
+ "contract",
1009
+ "issue"
1010
+ ]
1011
+ },
1012
+ "entry": {
1013
+ "type": "string",
1014
+ "description": "The constrains entry as written."
1015
+ }
1016
+ }
1017
+ },
1018
+ "pinsEdge": {
1019
+ "type": "object",
1020
+ "required": [
1021
+ "kind",
1022
+ "from",
1023
+ "to",
1024
+ "pinnedSha256",
1025
+ "pinState"
1026
+ ],
1027
+ "properties": {
1028
+ "from": {
1029
+ "type": "string"
1030
+ },
1031
+ "to": {
1032
+ "type": "string"
1033
+ },
1034
+ "kind": {
1035
+ "const": "pins"
1036
+ },
1037
+ "pinnedSha256": {
1038
+ "type": [
1039
+ "string",
1040
+ "null"
1041
+ ],
1042
+ "pattern": "^[0-9a-f]{64}$"
1043
+ },
1044
+ "pinState": {
1045
+ "enum": [
1046
+ "pinned",
1047
+ "drifted",
1048
+ "missing",
1049
+ "stale",
1050
+ "unpinned"
1051
+ ]
1052
+ }
1053
+ }
1054
+ },
1055
+ "touchedEdge": {
1056
+ "type": "object",
1057
+ "required": [
1058
+ "kind",
1059
+ "from",
1060
+ "to",
1061
+ "lines"
1062
+ ],
1063
+ "properties": {
1064
+ "from": {
1065
+ "type": "string"
1066
+ },
1067
+ "to": {
1068
+ "type": "string"
1069
+ },
1070
+ "kind": {
1071
+ "const": "touched-by"
1072
+ },
1073
+ "lines": {
1074
+ "oneOf": [
1075
+ {
1076
+ "type": "null"
1077
+ },
1078
+ {
1079
+ "type": "array",
1080
+ "items": {
1081
+ "$ref": "#/$defs/lineRange"
1082
+ }
1083
+ }
1084
+ ]
1085
+ }
1086
+ }
1087
+ },
1088
+ "plainEdge": {
1089
+ "type": "object",
1090
+ "required": [
1091
+ "kind",
1092
+ "from",
1093
+ "to"
1094
+ ],
1095
+ "properties": {
1096
+ "from": {
1097
+ "type": "string"
1098
+ },
1099
+ "to": {
1100
+ "type": "string"
1101
+ },
1102
+ "kind": {
1103
+ "enum": [
1104
+ "produced-by",
1105
+ "serves",
1106
+ "supersedes",
1107
+ "cites-evidence",
1108
+ "links"
1109
+ ]
1110
+ }
1111
+ }
1112
+ },
1113
+ "withinEdge": {
1114
+ "description": "A commit made inside a decision's window, from the commit that added the decision's record until the one that added its successor (#2656). state is decided when the decision's own unit made the commit, and decided-by-window otherwise.",
1115
+ "type": "object",
1116
+ "required": [
1117
+ "kind",
1118
+ "from",
1119
+ "to",
1120
+ "state"
1121
+ ],
1122
+ "properties": {
1123
+ "from": {
1124
+ "type": "string"
1125
+ },
1126
+ "to": {
1127
+ "type": "string"
1128
+ },
1129
+ "kind": {
1130
+ "const": "within"
1131
+ },
1132
+ "state": {
1133
+ "enum": [
1134
+ "decided",
1135
+ "decided-by-window"
1136
+ ]
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+ }