aontu 0.62.0 → 0.63.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 (356) hide show
  1. package/README.md +1 -1
  2. package/dist/agentsmd.js +0 -27
  3. package/dist/agentsmd.js.map +1 -1
  4. package/dist/alias.js.map +1 -1
  5. package/dist/allow.js +0 -92
  6. package/dist/allow.js.map +1 -1
  7. package/dist/aontu.d.ts +1 -1
  8. package/dist/aontu.js +1 -79
  9. package/dist/aontu.js.map +1 -1
  10. package/dist/aontumodel.d.ts +4 -0
  11. package/dist/aontumodel.js +33 -0
  12. package/dist/aontumodel.js.map +1 -0
  13. package/dist/cli.js +101 -620
  14. package/dist/cli.js.map +1 -1
  15. package/dist/ctx.js +0 -48
  16. package/dist/ctx.js.map +1 -1
  17. package/dist/diff.js +0 -32
  18. package/dist/diff.js.map +1 -1
  19. package/dist/err.js +0 -40
  20. package/dist/err.js.map +1 -1
  21. package/dist/escape.js +0 -45
  22. package/dist/escape.js.map +1 -1
  23. package/dist/exactjson.d.ts +0 -35
  24. package/dist/exactjson.js +0 -131
  25. package/dist/exactjson.js.map +1 -1
  26. package/dist/format.js +13 -203
  27. package/dist/format.js.map +1 -1
  28. package/dist/grammar.d.ts +9 -0
  29. package/dist/grammar.js +54 -0
  30. package/dist/grammar.js.map +1 -0
  31. package/dist/graph.js +0 -26
  32. package/dist/graph.js.map +1 -1
  33. package/dist/hcanon.js +0 -82
  34. package/dist/hcanon.js.map +1 -1
  35. package/dist/helpdoc.js +1 -1
  36. package/dist/helpdoc.js.map +1 -1
  37. package/dist/hints.d.ts +0 -6
  38. package/dist/hints.js +54 -55
  39. package/dist/hints.js.map +1 -1
  40. package/dist/jsonschema.js +0 -114
  41. package/dist/jsonschema.js.map +1 -1
  42. package/dist/keyorder.d.ts +0 -7
  43. package/dist/keyorder.js +0 -41
  44. package/dist/keyorder.js.map +1 -1
  45. package/dist/lang.js +17 -915
  46. package/dist/lang.js.map +1 -1
  47. package/dist/lower.js +11 -61
  48. package/dist/lower.js.map +1 -1
  49. package/dist/lsp-server.js +0 -16
  50. package/dist/lsp-server.js.map +1 -1
  51. package/dist/lsp.d.ts +1 -1
  52. package/dist/lsp.js +12 -159
  53. package/dist/lsp.js.map +1 -1
  54. package/dist/mcp-server.js +0 -26
  55. package/dist/mcp-server.js.map +1 -1
  56. package/dist/mcp.js +0 -113
  57. package/dist/mcp.js.map +1 -1
  58. package/dist/mod-tool.js +0 -130
  59. package/dist/mod-tool.js.map +1 -1
  60. package/dist/mod.js +0 -162
  61. package/dist/mod.js.map +1 -1
  62. package/dist/patch.js +0 -217
  63. package/dist/patch.js.map +1 -1
  64. package/dist/provenance.js +0 -140
  65. package/dist/provenance.js.map +1 -1
  66. package/dist/query.js +0 -75
  67. package/dist/query.js.map +1 -1
  68. package/dist/reach.js +0 -43
  69. package/dist/reach.js.map +1 -1
  70. package/dist/relation.js +0 -61
  71. package/dist/relation.js.map +1 -1
  72. package/dist/render.js +20 -135
  73. package/dist/render.js.map +1 -1
  74. package/dist/report-sarif.d.ts +0 -11
  75. package/dist/report-sarif.js +0 -28
  76. package/dist/report-sarif.js.map +1 -1
  77. package/dist/sig.js +0 -35
  78. package/dist/sig.js.map +1 -1
  79. package/dist/sigdecl.js +1 -1
  80. package/dist/sigdecl.js.map +1 -1
  81. package/dist/siggate.js +0 -4
  82. package/dist/siggate.js.map +1 -1
  83. package/dist/site.js +3 -29
  84. package/dist/site.js.map +1 -1
  85. package/dist/subsume.d.ts +0 -10
  86. package/dist/subsume.js +0 -137
  87. package/dist/subsume.js.map +1 -1
  88. package/dist/template.d.ts +2 -1
  89. package/dist/template.js +58 -138
  90. package/dist/template.js.map +1 -1
  91. package/dist/trim.js +0 -41
  92. package/dist/trim.js.map +1 -1
  93. package/dist/tsconfig.tsbuildinfo +1 -1
  94. package/dist/type.js.map +1 -1
  95. package/dist/unify.js +12 -242
  96. package/dist/unify.js.map +1 -1
  97. package/dist/utility.js +0 -22
  98. package/dist/utility.js.map +1 -1
  99. package/dist/val/AbnfFuncVal.d.ts +18 -0
  100. package/dist/val/AbnfFuncVal.js +132 -0
  101. package/dist/val/AbnfFuncVal.js.map +1 -0
  102. package/dist/val/AbsentVal.d.ts +11 -0
  103. package/dist/val/AbsentVal.js +30 -0
  104. package/dist/val/AbsentVal.js.map +1 -0
  105. package/dist/val/AggFuncVal.d.ts +10 -1
  106. package/dist/val/AggFuncVal.js +104 -116
  107. package/dist/val/AggFuncVal.js.map +1 -1
  108. package/dist/val/ArithFuncVal.js +0 -12
  109. package/dist/val/ArithFuncVal.js.map +1 -1
  110. package/dist/val/BagVal.js +1 -78
  111. package/dist/val/BagVal.js.map +1 -1
  112. package/dist/val/BigDecimalVal.js +0 -16
  113. package/dist/val/BigDecimalVal.js.map +1 -1
  114. package/dist/val/BigIntegerVal.js +0 -16
  115. package/dist/val/BigIntegerVal.js.map +1 -1
  116. package/dist/val/CloseFuncVal.js +0 -9
  117. package/dist/val/CloseFuncVal.js.map +1 -1
  118. package/dist/val/CmpFuncVal.js +2 -59
  119. package/dist/val/CmpFuncVal.js.map +1 -1
  120. package/dist/val/ConjunctVal.js +0 -29
  121. package/dist/val/ConjunctVal.js.map +1 -1
  122. package/dist/val/ConstraintVal.js +0 -500
  123. package/dist/val/ConstraintVal.js.map +1 -1
  124. package/dist/val/ContainerKindVal.js +0 -2
  125. package/dist/val/ContainerKindVal.js.map +1 -1
  126. package/dist/val/CopyFuncVal.js +0 -3
  127. package/dist/val/CopyFuncVal.js.map +1 -1
  128. package/dist/val/Decimal.js +0 -179
  129. package/dist/val/Decimal.js.map +1 -1
  130. package/dist/val/DeprecateFuncVal.js.map +1 -1
  131. package/dist/val/DisjunctVal.js +0 -152
  132. package/dist/val/DisjunctVal.js.map +1 -1
  133. package/dist/val/EachFuncVal.js +0 -3
  134. package/dist/val/EachFuncVal.js.map +1 -1
  135. package/dist/val/EmitFuncVal.d.ts +1 -1
  136. package/dist/val/EmitFuncVal.js +6 -119
  137. package/dist/val/EmitFuncVal.js.map +1 -1
  138. package/dist/val/ExpectVal.js +0 -62
  139. package/dist/val/ExpectVal.js.map +1 -1
  140. package/dist/val/FilterFuncVal.js +0 -25
  141. package/dist/val/FilterFuncVal.js.map +1 -1
  142. package/dist/val/FuncBaseVal.d.ts +1 -0
  143. package/dist/val/FuncBaseVal.js +7 -127
  144. package/dist/val/FuncBaseVal.js.map +1 -1
  145. package/dist/val/GraphAtomVal.js +0 -15
  146. package/dist/val/GraphAtomVal.js.map +1 -1
  147. package/dist/val/HideFuncVal.js +0 -13
  148. package/dist/val/HideFuncVal.js.map +1 -1
  149. package/dist/val/IntegerVal.js +0 -61
  150. package/dist/val/IntegerVal.js.map +1 -1
  151. package/dist/val/JunctionVal.js +0 -20
  152. package/dist/val/JunctionVal.js.map +1 -1
  153. package/dist/val/KeyFuncVal.js +0 -46
  154. package/dist/val/KeyFuncVal.js.map +1 -1
  155. package/dist/val/ListVal.js +0 -57
  156. package/dist/val/ListVal.js.map +1 -1
  157. package/dist/val/LowerFuncVal.js +0 -11
  158. package/dist/val/LowerFuncVal.js.map +1 -1
  159. package/dist/val/MapVal.js +0 -151
  160. package/dist/val/MapVal.js.map +1 -1
  161. package/dist/val/MatchFuncVal.js +0 -27
  162. package/dist/val/MatchFuncVal.js.map +1 -1
  163. package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
  164. package/dist/val/MaybeFuncVal.js +50 -0
  165. package/dist/val/MaybeFuncVal.js.map +1 -0
  166. package/dist/val/MoveFuncVal.js +0 -18
  167. package/dist/val/MoveFuncVal.js.map +1 -1
  168. package/dist/val/NilVal.js +0 -60
  169. package/dist/val/NilVal.js.map +1 -1
  170. package/dist/val/NomFuncVal.js +8 -42
  171. package/dist/val/NomFuncVal.js.map +1 -1
  172. package/dist/val/NumberVal.js +0 -15
  173. package/dist/val/NumberVal.js.map +1 -1
  174. package/dist/val/OpBaseVal.d.ts +1 -0
  175. package/dist/val/OpBaseVal.js +3 -15
  176. package/dist/val/OpBaseVal.js.map +1 -1
  177. package/dist/val/PackFuncVal.js +0 -34
  178. package/dist/val/PackFuncVal.js.map +1 -1
  179. package/dist/val/PathFuncVal.js +0 -6
  180. package/dist/val/PathFuncVal.js.map +1 -1
  181. package/dist/val/PathVal.js +0 -41
  182. package/dist/val/PathVal.js.map +1 -1
  183. package/dist/val/PlaceVal.js +0 -25
  184. package/dist/val/PlaceVal.js.map +1 -1
  185. package/dist/val/PlusOpVal.d.ts +1 -7
  186. package/dist/val/PlusOpVal.js +13 -74
  187. package/dist/val/PlusOpVal.js.map +1 -1
  188. package/dist/val/PrefFuncVal.js +0 -1
  189. package/dist/val/PrefFuncVal.js.map +1 -1
  190. package/dist/val/PrefVal.js +0 -167
  191. package/dist/val/PrefVal.js.map +1 -1
  192. package/dist/val/RecurseVal.js +0 -55
  193. package/dist/val/RecurseVal.js.map +1 -1
  194. package/dist/val/RefVal.js +0 -282
  195. package/dist/val/RefVal.js.map +1 -1
  196. package/dist/val/ReferFuncVal.js +0 -232
  197. package/dist/val/ReferFuncVal.js.map +1 -1
  198. package/dist/val/ScalarKindVal.js +0 -49
  199. package/dist/val/ScalarKindVal.js.map +1 -1
  200. package/dist/val/ScalarVal.js +0 -11
  201. package/dist/val/ScalarVal.js.map +1 -1
  202. package/dist/val/StrFuncVal.js +0 -18
  203. package/dist/val/StrFuncVal.js.map +1 -1
  204. package/dist/val/SuperFuncVal.js +0 -32
  205. package/dist/val/SuperFuncVal.js.map +1 -1
  206. package/dist/val/TopVal.js +0 -1
  207. package/dist/val/TopVal.js.map +1 -1
  208. package/dist/val/TranslateFuncVal.js +1 -3
  209. package/dist/val/TranslateFuncVal.js.map +1 -1
  210. package/dist/val/UpperFuncVal.js +0 -11
  211. package/dist/val/UpperFuncVal.js.map +1 -1
  212. package/dist/val/Val.d.ts +1 -0
  213. package/dist/val/Val.js +2 -133
  214. package/dist/val/Val.js.map +1 -1
  215. package/dist/val/VarVal.js +0 -12
  216. package/dist/val/VarVal.js.map +1 -1
  217. package/dist/val/arith.js +0 -37
  218. package/dist/val/arith.js.map +1 -1
  219. package/dist/val/caserange.js +0 -61
  220. package/dist/val/caserange.js.map +1 -1
  221. package/dist/val/members.js +0 -6
  222. package/dist/val/members.js.map +1 -1
  223. package/dist/val/numcmp.js +0 -11
  224. package/dist/val/numcmp.js.map +1 -1
  225. package/dist/val/numkind.js +0 -145
  226. package/dist/val/numkind.js.map +1 -1
  227. package/dist/val/valutil.js +0 -16
  228. package/dist/val/valutil.js.map +1 -1
  229. package/dist/vet.js +0 -461
  230. package/dist/vet.js.map +1 -1
  231. package/dist/view.js +0 -414
  232. package/dist/view.js.map +1 -1
  233. package/dist/walk.js +0 -41
  234. package/dist/walk.js.map +1 -1
  235. package/grammar/aontu.abnf +8 -6
  236. package/grammar/aontu.gbnf +4 -4
  237. package/grammar/aontu.lark +4 -4
  238. package/grammar/aontu.tmLanguage.json +1 -1
  239. package/package.json +4 -2
  240. package/src/agentsmd.ts +0 -35
  241. package/src/alias.ts +0 -39
  242. package/src/allow.ts +1 -96
  243. package/src/aontu.ts +3 -110
  244. package/src/aontumodel.ts +32 -0
  245. package/src/cli.ts +113 -682
  246. package/src/ctx.ts +0 -103
  247. package/src/diff.ts +0 -40
  248. package/src/err.ts +0 -40
  249. package/src/escape.ts +0 -46
  250. package/src/exactjson.ts +0 -131
  251. package/src/format.ts +14 -257
  252. package/src/grammar.ts +72 -0
  253. package/src/graph.ts +0 -61
  254. package/src/hcanon.ts +0 -82
  255. package/src/helpdoc.ts +1 -1
  256. package/src/hints.ts +66 -57
  257. package/src/jsonschema.ts +0 -123
  258. package/src/keyorder.ts +0 -42
  259. package/src/lang.ts +19 -931
  260. package/src/lower.ts +12 -62
  261. package/src/lsp-server.ts +0 -16
  262. package/src/lsp.ts +12 -180
  263. package/src/mcp-server.ts +0 -31
  264. package/src/mcp.ts +0 -130
  265. package/src/mod-tool.ts +0 -158
  266. package/src/mod.ts +0 -178
  267. package/src/patch.ts +0 -232
  268. package/src/provenance.ts +0 -183
  269. package/src/query.ts +0 -84
  270. package/src/reach.ts +0 -53
  271. package/src/relation.ts +0 -84
  272. package/src/render.ts +20 -172
  273. package/src/report-sarif.ts +0 -48
  274. package/src/sig.ts +0 -35
  275. package/src/sigdecl.ts +1 -1
  276. package/src/siggate.ts +0 -30
  277. package/src/site.ts +3 -29
  278. package/src/subsume.ts +1 -161
  279. package/src/template.ts +69 -140
  280. package/src/trim.ts +0 -53
  281. package/src/type.ts +2 -45
  282. package/src/unify.ts +13 -251
  283. package/src/utility.ts +0 -31
  284. package/src/val/AbnfFuncVal.ts +181 -0
  285. package/src/val/AbsentVal.ts +54 -0
  286. package/src/val/AggFuncVal.ts +152 -188
  287. package/src/val/ArithFuncVal.ts +0 -20
  288. package/src/val/BagVal.ts +1 -78
  289. package/src/val/BigDecimalVal.ts +0 -16
  290. package/src/val/BigIntegerVal.ts +0 -16
  291. package/src/val/CloseFuncVal.ts +0 -9
  292. package/src/val/CmpFuncVal.ts +4 -166
  293. package/src/val/ConjunctVal.ts +0 -33
  294. package/src/val/ConstraintVal.ts +2 -537
  295. package/src/val/ContainerKindVal.ts +0 -18
  296. package/src/val/CopyFuncVal.ts +0 -5
  297. package/src/val/Decimal.ts +1 -185
  298. package/src/val/DeprecateFuncVal.ts +0 -10
  299. package/src/val/DisjunctVal.ts +0 -157
  300. package/src/val/EachFuncVal.ts +0 -40
  301. package/src/val/EmitFuncVal.ts +8 -208
  302. package/src/val/ExpectVal.ts +0 -62
  303. package/src/val/FilterFuncVal.ts +0 -55
  304. package/src/val/FuncBaseVal.ts +9 -130
  305. package/src/val/GraphAtomVal.ts +0 -42
  306. package/src/val/HideFuncVal.ts +0 -15
  307. package/src/val/IntegerVal.ts +0 -61
  308. package/src/val/JunctionVal.ts +0 -20
  309. package/src/val/KeyFuncVal.ts +0 -48
  310. package/src/val/ListVal.ts +0 -59
  311. package/src/val/LowerFuncVal.ts +0 -12
  312. package/src/val/MapVal.ts +0 -151
  313. package/src/val/MatchFuncVal.ts +0 -59
  314. package/src/val/MaybeFuncVal.ts +86 -0
  315. package/src/val/MoveFuncVal.ts +0 -20
  316. package/src/val/NilVal.ts +0 -60
  317. package/src/val/NomFuncVal.ts +8 -95
  318. package/src/val/NumberVal.ts +0 -16
  319. package/src/val/OpBaseVal.ts +4 -17
  320. package/src/val/PackFuncVal.ts +0 -63
  321. package/src/val/PathFuncVal.ts +0 -32
  322. package/src/val/PathVal.ts +0 -66
  323. package/src/val/PlaceVal.ts +0 -45
  324. package/src/val/PlusOpVal.ts +18 -75
  325. package/src/val/PrefFuncVal.ts +0 -1
  326. package/src/val/PrefVal.ts +0 -179
  327. package/src/val/RecurseVal.ts +0 -81
  328. package/src/val/RefVal.ts +1 -285
  329. package/src/val/ReferFuncVal.ts +0 -255
  330. package/src/val/ScalarKindVal.ts +0 -50
  331. package/src/val/ScalarVal.ts +0 -12
  332. package/src/val/StrFuncVal.ts +0 -44
  333. package/src/val/SuperFuncVal.ts +0 -42
  334. package/src/val/TopVal.ts +0 -1
  335. package/src/val/TranslateFuncVal.ts +1 -51
  336. package/src/val/UpperFuncVal.ts +0 -12
  337. package/src/val/Val.ts +3 -192
  338. package/src/val/VarVal.ts +0 -15
  339. package/src/val/arith.ts +0 -92
  340. package/src/val/caserange.ts +0 -62
  341. package/src/val/members.ts +0 -23
  342. package/src/val/numcmp.ts +1 -27
  343. package/src/val/numkind.ts +0 -149
  344. package/src/val/valutil.ts +0 -16
  345. package/src/vet.ts +1 -582
  346. package/src/view.ts +0 -507
  347. package/src/walk.ts +0 -41
  348. package/dist/std.d.ts +0 -3
  349. package/dist/std.js +0 -672
  350. package/dist/std.js.map +0 -1
  351. package/dist/val/FormFuncVal.js +0 -55
  352. package/dist/val/FormFuncVal.js.map +0 -1
  353. package/dist/val/NamerFuncVal.d.ts +0 -12
  354. package/dist/val/NamerFuncVal.js +0 -176
  355. package/dist/val/NamerFuncVal.js.map +0 -1
  356. package/src/std.ts +0 -683
package/dist/vet.js CHANGED
@@ -16,11 +16,6 @@ const walk_1 = require("./walk");
16
16
  const BagVal_1 = require("./val/BagVal");
17
17
  const utility_1 = require("./utility");
18
18
  const subsume_1 = require("./subsume");
19
- // The `--at` refusal is the SAME refusal `get` and `why` give for a
20
- // path that names nothing, down to the "did you mean" -- so it is that
21
- // one, not a second spelling of it. A cycle in the module graph
22
- // (query imports anchorAt from here), and a benign one: both sides
23
- // use the other only from inside a function body, never at load time.
24
19
  const query_1 = require("./query");
25
20
  const keyorder_1 = require("./keyorder");
26
21
  // The default cap, exported because the CLI applies it to the WHOLE
@@ -29,37 +24,10 @@ const keyorder_1 = require("./keyorder");
29
24
  exports.VET_MAX_ERRORS = 20;
30
25
  const DEFAULT_SCHEMA_URL = 'schema';
31
26
  const DEFAULT_DATA_URL = 'data';
32
- // Every site in a freshly parsed tree carries the same url, and for a
33
- // bare parse that url is the empty string: `site.url` is only populated
34
- // by the multisource loader (ts/src/lang.ts). Vet takes two documents
35
- // from its CALLER, not from the filesystem, so it stamps provenance
36
- // itself — which is what lets the report assign site ROLES by
37
- // provenance rather than by NilVal's source-order heuristic, exactly as
38
- // the design requires.
39
- // EVERY SITE NAMES THE FILE WHOSE TEXT IT EXCERPTS (the review's
40
- // finding F, use-cases/BUGS.md §25). The parser already names the file
41
- // each value was read from -- a value loaded through `@"lib/types.aon"`
42
- // carries that path, with that file's row and column -- and this walk
43
- // used to OVERWRITE every url with the entry document's name. The
44
- // coordinates stayed the included file's, so a finding cited
45
- // `entry.aon:3:7` for text that lives three files away, at a line the
46
- // entry may not even have. A repair agent that follows the site edits
47
- // the wrong file.
48
- //
49
- // Only the values that carry no name of their own are stamped: those
50
- // are the ones the engine minted rather than read, and the entry is
51
- // the honest name for them. The urls actually seen are collected, so
52
- // the report can still tell WHICH DOCUMENT a site belongs to without
53
- // pretending they all came from one file -- see roleOf.
54
27
  function stampUrl(v, url, seen) {
55
28
  const urls = seen ?? new Set();
56
29
  urls.add(url);
57
30
  (0, walk_1.walkVals)(v, (n) => {
58
- // UNDEFINED counts as unstamped, not just empty: the parser leaves
59
- // the url undefined on one of its two paths (ts/src/lang.ts), and
60
- // treating that as a name would put `undefined` in the url set --
61
- // where the OTHER document's unstamped values would then match it,
62
- // and every site would read `data`.
63
31
  if (null == n.site.url || '' === n.site.url) {
64
32
  n.site.url = url;
65
33
  }
@@ -68,20 +36,6 @@ function stampUrl(v, url, seen) {
68
36
  }, new Set());
69
37
  return urls;
70
38
  }
71
- // A FILE THE READER CAN OPEN. The parser resolves an include to an
72
- // absolute path, which is the right identity (two files loading the
73
- // same library by different relative spellings must be one file) and
74
- // the wrong NAME: a report whose entry reads `contract.aon` and whose
75
- // included site reads `/home/someone/checkout/types.aon` is a report
76
- // that cannot be uploaded as SARIF, diffed between machines, or read
77
- // beside the command that produced it.
78
- //
79
- // So an included file is named as the ENTRY'S OWN NAME reaches it:
80
- // relative to the entry's directory, then re-anchored on however the
81
- // caller spelled the entry. `vet contract.aon` names `types.aon`;
82
- // `vet a/b/contract.aon` names `a/b/types.aon`; an absolute entry
83
- // keeps absolute includes. A caller who passed no path at all has no
84
- // base to relativise against and gets the url unchanged.
85
39
  function displayFile(url, label, path) {
86
40
  if (url === label || null == path || '' === url || !(0, node_path_1.isAbsolute)(url)) {
87
41
  return url;
@@ -90,57 +44,22 @@ function displayFile(url, label, path) {
90
44
  const dir = (0, node_path_1.dirname)(label);
91
45
  return '.' === dir ? rel : (0, node_path_1.join)(dir, rel);
92
46
  }
93
- // The name for one site, taken from the document the site BELONGS to
94
- // -- which is the role, already decided by url-set membership. Doing
95
- // it here rather than from a map built at stamping time is not a
96
- // shortcut: a nil's operands are off the tree by the time the report
97
- // is built, so a value first seen during the MEET (the commonest
98
- // schema site there is) would be missing from any such map.
99
47
  function displayOf(file, role, prov) {
100
48
  return 'data' === role
101
49
  ? displayFile(file, prov.dataUrl ?? file, prov.dataPath)
102
50
  : displayFile(file, prov.schemaUrl ?? file, prov.schemaPath);
103
51
  }
104
- // The ROLE of a site: which of the two documents it belongs to. Not a
105
- // name comparison -- a data document may itself include another file,
106
- // and that file's values are still data. Membership of the url set the
107
- // stamping walk collected is the question, and the answer is `schema`
108
- // for anything the data walk never reached (an engine-minted value
109
- // stamped with the schema entry, say).
110
52
  function roleOf(file, prov) {
111
53
  return prov.data.has(file) ? 'data' : 'schema';
112
54
  }
113
- // `$.a.b`, and `$` for the root. Deliberately NOT delimiter-escaped: a
114
- // map key may contain any character, including every separator a
115
- // compact summary might pick, so the path is carried as a JSON string
116
- // and never parsed back out of a larger token.
117
55
  function pathText(path) {
118
56
  return '$' + (null != path && 0 < path.length ? '.' + path.join('.') : '');
119
57
  }
120
- // `secondary` is the only operand that can be absent — a `closed` or an
121
- // incomplete finding has one side, a two-site conflict has both — so
122
- // this is the one nullable input, and every Val that does arrive
123
- // carries a site and a canon.
124
58
  function siteOf(v, prov) {
125
59
  if (null == v) {
126
60
  return undefined;
127
61
  }
128
- // The report's `file` is whatever the site carries, and by the time a
129
- // site reaches a report that is always a stamped name: vet walks both
130
- // documents before they meet, and the walk reaches the off-peg values
131
- // a finding can name (ts/src/walk.ts). A consumer therefore reads
132
- // `file` without a presence check, and the Go port -- whose field is
133
- // a plain string -- writes the same key.
134
- //
135
- // NOT coalesced. The parser leaves the url undefined on one of its
136
- // two paths (ts/src/lang.ts), and a `?? ''` here would be dead code
137
- // that hides it: if a value ever reaches a report unstamped, the two
138
- // ports should disagree loudly rather than quietly agree on an empty
139
- // name that neither of them meant.
140
62
  const file = v.site.url;
141
- // NAMED for the reader, ROLED by the raw url: the two questions are
142
- // different, and only the first is about how the file is spelled
143
- // (see displayFile).
144
63
  const role = roleOf(file, prov);
145
64
  return {
146
65
  file: displayOf(file, role, prov),
@@ -156,32 +75,16 @@ function siteOf(v, prov) {
156
75
  // The underlying NilVal fields are untouched: this is a report-layer
157
76
  // projection, so the existing error.tsv assertions do not move.
158
77
  function sitesOf(nil, prov) {
159
- // `?? nil`: a failure raised about a CONSTRUCT rather than about a
160
- // failed meet -- a lossy integer literal, say -- carries no operands
161
- // at all, and reporting it about ITSELF is what ctx.adderr already
162
- // does for the same reason. Without the fallback the report built a
163
- // site out of `undefined` and threw while partitioning it, which is
164
- // the one thing vet promises not to do: a bad value in the data is
165
- // DATA, and the caller gets a report.
166
78
  const sites = [siteOf(nil.primary ?? nil, prov)];
167
79
  const secondary = siteOf(nil.secondary, prov);
168
80
  if (null != secondary) {
169
81
  sites.push(secondary);
170
82
  }
171
- // Partitioned rather than sorted: which of the two NilVal operands is
172
- // `primary` follows source order within one document, which says
173
- // nothing useful when one side is a schema and the other is data.
174
83
  return [
175
84
  ...sites.filter((s) => 'data' === s.role),
176
85
  ...sites.filter((s) => 'schema' === s.role),
177
86
  ];
178
87
  }
179
- // The message text is MATERIALISED on demand, exactly as handleErrors
180
- // materialises one before a caller sees it: makeNilErr defers it
181
- // because most NilVals are transient and never rendered, and only the
182
- // throwing path asks for it. Without this a finding could carry an
183
- // empty `message` -- which is what the incomplete half of every report
184
- // did, and what any nil built during the PARSE of a document did.
185
88
  function materialise(nil, ctx) {
186
89
  if (null == nil.msg || '' === nil.msg) {
187
90
  (0, err_1.descErr)(nil, ctx);
@@ -201,30 +104,13 @@ function findingOf(nil, prov) {
201
104
  class: nil.class,
202
105
  severity: 'error',
203
106
  path: pathText(nil.path),
204
- // The HEADLINE only, WITHOUT ANSI: the frames below it are for a
205
- // human reading a terminal, and the first line is the part the two
206
- // ports hold to byte parity. Materialised before this runs, so it
207
- // is always there (see materialise above). The escapes matter for
208
- // one family only -- a parse failure's text comes from the parser,
209
- // which colours its marker -- and a machine-readable report is no
210
- // place for terminal control codes.
211
107
  message: stripAnsi(nil.msg.split('\n')[0]),
212
108
  sites: sitesOf(nil, prov),
213
109
  };
214
- // The hint, whole, with its detail placeholders filled in exactly as
215
- // the terminal frame fills them. Trailing whitespace is dropped
216
- // because it is spacing for the frame that used to follow it, not
217
- // part of the text; the deliberate blank lines INSIDE a hint are
218
- // `\n \n` and survive.
219
110
  const hint = (0, err_1.getHint)(nil.why, nil.details);
220
111
  if (null != hint && '' !== hint) {
221
112
  finding.hint = stripAnsi(hint).replace(/\s+$/, '');
222
113
  }
223
- // `expected`/`actual` are the admissible-alternatives contract, and
224
- // the constraint algebra already produces them: G1's atoms attach the
225
- // normalised residual and the offending value, and `must` attaches
226
- // the author's message. Read them where they are rather than
227
- // re-deriving them here.
228
114
  if ('string' === typeof details.expected) {
229
115
  finding.expected = details.expected;
230
116
  }
@@ -236,29 +122,10 @@ function findingOf(nil, prov) {
236
122
  }
237
123
  return finding;
238
124
  }
239
- // Findings are sorted BY VET, not by the walk. The underlying walk
240
- // iterates raw object keys and the two hosts disagree about their order
241
- // — `10:… 9:…` yields ["9","10"] in JavaScript, which hoists
242
- // integer-like keys, against Go's insertion order (ts/src/keyorder.ts
243
- // exists for exactly this) — so an unsorted report could never be in
244
- // cross-port parity.
245
- //
246
- // The order is by data site (file, row, column), then code, then path.
247
- // It is carried in ONE key string rather than a cascade of comparisons:
248
- // the row and column are zero-padded so lexicographic order is numeric
249
- // order, and NUL joins the fields because no field can contain one.
250
- // A cascade would need a test per tie-breaker to stay honest; a key
251
- // needs none, and cannot disagree with itself.
252
125
  const ORDER_PAD = 9;
253
126
  function pad(n) {
254
127
  return String(n).padStart(ORDER_PAD, '0');
255
128
  }
256
- // The walk index is the LAST field, which makes every key unique and
257
- // the sort below total: two findings can otherwise share everything the
258
- // key carries — same data site, same code, same path — and a comparator
259
- // that has to answer "equal" is one more thing to get right in two
260
- // languages. With the index appended, ties simply keep walk order, in
261
- // both ports, by construction rather than by the sort's promises.
262
129
  function orderKey(f, index) {
263
130
  const site = f.sites[0];
264
131
  return [
@@ -270,42 +137,9 @@ function orderKey(f, index) {
270
137
  pad(index),
271
138
  ].join('\u0000');
272
139
  }
273
- // A DOCUMENT THAT DOES NOT STAND UP, in the finding shape (the
274
- // review's finding F). `trim` and `relations` answered an unusable
275
- // document with `verdict: error` and an EMPTY list: the caller learned
276
- // that something was wrong and nothing about what, which is the one
277
- // thing a repair loop cannot work with. Both verbs take ONE document,
278
- // so there is no role to decide -- the document is the thing being
279
- // checked and the thing to edit, which is what `data` means here.
280
- //
281
- // The engine's own first error IS the finding: these verbs add nothing
282
- // to a diagnosis the evaluator already made, and the FIRST is enough
283
- // because everything after it is a consequence.
284
- //
285
- // The Go twin is failureFinding in go/vet.go.
286
140
  function failureFinding(ctx, url, failed) {
287
- // ctx.err IS SOMETIMES EMPTY, and the comment that used to stand here
288
- // said otherwise (use-cases/BUGS.md §43). `&: id(root)` fails with a
289
- // NIL ROOT and NO COLLECTED ERROR -- the id-spread refusal is the
290
- // root itself -- and every verb that reports "this document does not
291
- // stand up" then read `ctx.err[0]` as undefined and died: a TypeError
292
- // out of `relations`, `reaches` and `jsonschema` in TypeScript, a
293
- // panic in Go. The one shape where finding F's own invariant, that a
294
- // document which does not stand up SAYS SO in the finding shape, was
295
- // answered with a stack trace.
296
- //
297
- // `failed` is the caller's own root -- every caller has it, and its
298
- // condition is `0 < ctx.err.length || root.isNil`, so when the first
299
- // half is false the second holds and the root IS the reason.
300
141
  const nil = ctx.err[0] ?? failed;
301
142
  materialise(nil, ctx);
302
- // STAMPED, as vet stamps both documents before they meet: siteOf does
303
- // not coalesce a missing name (deliberately -- see there), so a site
304
- // that reached the report unstamped would carry `file: undefined`.
305
- // The three Vals a finding can name are the nil and its two operands,
306
- // and the url set collects whatever name each already had, so a value
307
- // read from an included file keeps that file's name and still counts
308
- // as part of the one document being checked.
309
143
  const at = url ?? '';
310
144
  const urls = new Set([at]);
311
145
  for (const v of [nil, nil.primary, nil.secondary]) {
@@ -327,27 +161,7 @@ function anchorAt(root, at) {
327
161
  const parts = trimmed.split('.').filter((p) => '' !== p);
328
162
  let node = root;
329
163
  for (const part of parts) {
330
- // A SIZING RESIDUE IS ITS CONTAINER, plus a note about what the
331
- // container must still satisfy (use-cases/BUGS.md §16). The path
332
- // steps through it: `$.a.ports.0.port` names the same node whether
333
- // or not `ports` still carries a `unique()`, and an anchor that
334
- // stopped here would report `no_path` for a key the document
335
- // plainly has.
336
164
  node = throughResidue(node);
337
- // TYPE-DIRECTED, not a property lookup on whatever `peg` happens to
338
- // be. An anchor is a STRUCTURAL path into the schema — the same
339
- // thing a reference means by `$.a.b` — so it walks map keys and
340
- // list indices, and stops at anything else.
341
- //
342
- // Indexing the peg generically walked much further than that: into
343
- // a junction's branches (`a:1|2` with `--at $.a.0` validated
344
- // against ONE branch), into a constraint's atom arguments (so
345
- // `min(2)` with `--at $.a.0` reported the bound's own argument as
346
- // the truth), into a pref's wrapped value through the literal key
347
- // `peg`, and into an array's `length` — that last one handing back
348
- // a JavaScript NUMBER as the anchor, after which every document
349
- // whatsoever came back valid. The Go port has always been
350
- // type-directed here; this is the canonical side moving to it.
351
165
  if (true === node?.isMap) {
352
166
  const peg = node.peg;
353
167
  if (null == peg || !Object.prototype.hasOwnProperty.call(peg, part)) {
@@ -371,47 +185,14 @@ function anchorAt(root, at) {
371
185
  return undefined;
372
186
  }
373
187
  }
374
- // THE ANCHOR KEEPS ITS ATOM. Stepping THROUGH a residue is right --
375
- // `$.x.a` names a key of the container whatever the container still
376
- // has to satisfy -- but ARRIVING at one and handing back the bare
377
- // container drops a constraint the author wrote, so `--at $.x` vetted
378
- // clean against a `length` the evaluator enforces. The residue is the
379
- // honest schema for the node: the meet drives it, and generation
380
- // settles it, exactly as it does without an anchor.
381
188
  return node;
382
189
  }
383
- // The container inside a settled sizing residue, or the value itself.
384
- // EXPORTED for the `doc` figure, which walks the same shape the anchor
385
- // does: a list still carrying a `unique()` is a list, and a drawing
386
- // that stopped at the residue would omit keys the document plainly
387
- // has.
388
190
  function throughResidue(v) {
389
191
  return (0, BagVal_1.sizingResidue)(v)?.bag ?? v;
390
192
  }
391
- // Validate `dataSrc` against `schemaSrc`.
392
- //
393
- // Never throws for findings: a contradiction in the data is DATA, and
394
- // the caller gets a report. It throws only when the caller's own inputs
395
- // are unusable — which is why an unusable schema is a verdict (`error`)
396
- // rather than an exception too: "the schema is broken" is a fact the
397
- // agent loop needs to branch on, not an exceptional condition.
398
- // THE COVERAGE ACCOUNTING (G11 phase 5). Structural, over the two
399
- // trees vet already holds, and deliberately NOT provenance-based: the
400
- // question is what the SCHEMA DECLARES about the data, which is a
401
- // property of the two documents rather than of the meet that ran. A
402
- // meet-based reading would also count a value the data supplied to
403
- // itself as "covered", which is the opposite of the thing being asked.
404
- //
405
- // A map's template lives on `spread.cj` rather than in `peg`, so a
406
- // declaration path spells it `&` -- the same character the language
407
- // spells it with, and one no map key can collide with, since a bare
408
- // `&` cannot be a key.
409
193
  const COVER_TEMPLATE = '&';
410
194
  // Is this value a bag with children to walk?
411
195
  function coverKids(v) {
412
- // NO KIND GUARD: the two tests below already reject anything that is
413
- // not a bag, exactly as the Go twin's type switch does, so a guard
414
- // above them is dead code (ADR-002).
415
196
  const out = [];
416
197
  if (true === v.isMap && null != v.peg) {
417
198
  for (const k of Object.keys(v.peg).sort(keyorder_1.cmpCodePoint)) {
@@ -423,28 +204,10 @@ function coverKids(v) {
423
204
  }
424
205
  return out;
425
206
  }
426
- // The template a bag applies to every child, when it has one. A spread
427
- // with no conjunct is not a declaration: `{"*":{...}}` carries the
428
- // empty spread every map carries, and reading that as a template is
429
- // precisely the confusion this phase exists to end.
430
207
  function coverTemplate(v) {
431
208
  const cj = v?.spread?.cj;
432
209
  return null != cj && true === cj.isVal && true !== cj.isTop ? cj : undefined;
433
210
  }
434
- // Every declaration the schema makes, as a path, with the node at it.
435
- // Named keys and templates alike, at every depth.
436
- //
437
- // NO IDENTITY GUARD, and that is a decision rather than an omission.
438
- // `walkVals` (ts/src/walk.ts) carries one because it walks values the
439
- // unification MINTED -- findings, conjunct operands, disjunct trials --
440
- // where a node really is reached twice. These two walks descend a
441
- // SETTLED bag through `peg` and `spread` alone, and such a tree is a
442
- // tree: a reference resolves by cloning its target, and an alias, a
443
- // repeated spread and a recursive residual were each probed and share
444
- // nothing. The property is already relied on repository-wide, because
445
- // `canon` walks the same edges with no guard and is computed on every
446
- // one of these values. A guard here would be a branch nothing can
447
- // take, which ADR-002 exists to keep out.
448
211
  function coverDeclare(v, path, out) {
449
212
  const tpl = coverTemplate(v);
450
213
  if (null != tpl) {
@@ -473,11 +236,6 @@ function coverDataPaths(v, path, out) {
473
236
  // constrains it -- the exact key where the schema has one, else the
474
237
  // covering template. Undefined when the schema declares nothing there.
475
238
  function coverMatch(anchor, segs) {
476
- // NO NIL GUARD ON `at`, and none on an empty `segs`: `at` starts as
477
- // the anchor and is only ever reassigned to a non-nil child or
478
- // template, and coverDataPaths never emits the root path, so a call
479
- // with no segments cannot happen. A guard that cannot fire is dead
480
- // code, and dead code is what ADR-002 exists to keep out.
481
239
  let at = anchor;
482
240
  let decl = '';
483
241
  for (const seg of segs) {
@@ -571,10 +329,6 @@ function vetCoverage(anchor, dataVal, coverageAt) {
571
329
  leaves,
572
330
  unchecked: coverShallowest(unchecked),
573
331
  unused: coverShallowest(unused),
574
- // VACUOUS IS ABOUT LEAVES, and a document with none cannot be
575
- // vacuously checked: `{}` against any schema examined nothing
576
- // because there was nothing to examine, which is not the failure
577
- // this reports.
578
332
  vacuous: 0 === checked && 0 < leaves,
579
333
  };
580
334
  }
@@ -583,9 +337,6 @@ function vet(schemaSrc, dataSrc, opts) {
583
337
  const schemaUrl = options.schemaUrl ?? DEFAULT_SCHEMA_URL;
584
338
  const dataUrl = options.dataUrl ?? DEFAULT_DATA_URL;
585
339
  const maxErrors = options.maxErrors ?? exports.VET_MAX_ERRORS;
586
- // ONE instance, two bases: the path rides on each CALL rather than on
587
- // the constructor, because the schema and the data may live in
588
- // different directories (Lang.parse takes `opts.path` per parse).
589
340
  const aontu = new aontu_1.Aontu((0, utility_1.includeOpts)(options));
590
341
  const schemaOpts = null == options.schemaPath ?
591
342
  undefined : { path: options.schemaPath };
@@ -596,33 +347,7 @@ function vet(schemaSrc, dataSrc, opts) {
596
347
  const schemaCtx = aontu.ctx({ collect: true });
597
348
  const schemaVal = aontu.unify(schemaSrc, schemaOpts, schemaCtx);
598
349
  if (0 < schemaCtx.err.length || true === schemaVal?.isNil) {
599
- // A broken schema REPORTS, exactly as broken data does. It used to
600
- // answer `findings: []` with exit 4 and nothing else, in both
601
- // ports: the engine had collected the fault and vet threw it away,
602
- // so an agent -- or a person -- was told the schema was broken and
603
- // not what or where. The verdict stays `error` (the fault is in
604
- // the truth, not in the data, and that distinction is the whole
605
- // point of the class), but the finding travels with it.
606
- //
607
- // The FIRST error only, and the data path's reasoning applies
608
- // unchanged: later errors in a document that does not stand up are
609
- // consequences of the first rather than separate things to fix.
610
- //
611
- // ONE OF THE TWO IS ALWAYS THERE, and both are nils: the branch
612
- // condition admits a collected error or a nil root, and every
613
- // value on `schemaCtx.err` is a NilVal. There is no third case, so
614
- // there is no guard here -- a guard that cannot fire is dead code,
615
- // and dead code is what ADR-002 exists to keep out. (One stood
616
- // here and the TypeScript line report called it covered; the Go
617
- // gate, which measures blocks, refused the twin.)
618
350
  const failure = 0 < schemaCtx.err.length ? schemaCtx.err[0] : schemaVal;
619
- // The normal path stamps both documents before they meet
620
- // (stampUrl(anchor...) below), and this early return never reaches
621
- // it, so it stamps what it is about to report: the unified root,
622
- // and the failure itself -- a COLLECTED error is minted during
623
- // unification and hangs off no tree, so nothing else would name
624
- // it. The walk reaches a failure's operands (ts/src/walk.ts),
625
- // which is what makes the sites say which file.
626
351
  stampUrl(schemaVal, schemaUrl);
627
352
  stampUrl(failure, schemaUrl);
628
353
  materialise(failure, schemaCtx);
@@ -639,11 +364,6 @@ function vet(schemaSrc, dataSrc, opts) {
639
364
  if (null != options.at) {
640
365
  anchor = anchorAt(schemaVal, options.at);
641
366
  if (null == anchor) {
642
- // AND IT SAYS WHICH SEGMENT. `--at` naming nothing is an error
643
- // verdict for the same reason a broken schema is -- the run
644
- // could not be set up from the truth's side -- and it reports
645
- // for the same reason too: a caller handed exit 4 and an empty
646
- // list has nothing to act on.
647
367
  return {
648
368
  verdict: 'error',
649
369
  truncated: false,
@@ -656,22 +376,6 @@ function vet(schemaSrc, dataSrc, opts) {
656
376
  const dataCtx = aontu.ctx({ collect: true });
657
377
  const dataVal = aontu.parse(dataSrc, dataOpts, dataCtx);
658
378
  if (0 < dataCtx.err.length || null == dataVal) {
659
- // A DATA DOCUMENT THAT WILL NOT PARSE IS THE DATA'S FAULT, and the
660
- // report says so: verdict `invalid`, with a finding carrying the
661
- // parser's own code and a site in the data. `error` is left to mean
662
- // what the exit table says it means -- the run could not be set up
663
- // from the SCHEMA side.
664
- //
665
- // The engine already answered it this way one character earlier: a
666
- // refused CONSTRUCT (`a: 9007199254740993`) reaches the tree as an
667
- // ordinary nil and is reported as an invalid data finding. A stray
668
- // `]` took the throwing path instead and came back as a broken
669
- // SCHEMA -- the same fault, classified two opposite ways by which
670
- // branch the parser happened to take.
671
- //
672
- // The FIRST error only: the parser stops at the first syntax error,
673
- // so a second entry would be a consequence of the first rather than
674
- // a separate thing to fix.
675
379
  const failure = dataCtx.err[0];
676
380
  if (null == failure) {
677
381
  return { verdict: 'error', truncated: false, findings: [] };
@@ -684,17 +388,6 @@ function vet(schemaSrc, dataSrc, opts) {
684
388
  findings: [findingOf(failure, { data: new Set([dataUrl]) })],
685
389
  };
686
390
  }
687
- // STAMP THE WHOLE SETTLED SCHEMA, not just the lifted anchor.
688
- // Without `--at` these are the same tree. With it, the anchor is a
689
- // subtree and the rest of the schema is still REACHABLE from inside
690
- // it -- a `%alias` declaration (`[&: %U]`, target `$.%U`) or a
691
- // recursive residual's `$.spec.Step`, both of which the meet
692
- // resolves through _fixroot (RefVal.find, RecurseVal.body). A node
693
- // reached that way but never stamped carries no url, so its site
694
- // named no file while excerpting the schema's text -- against the
695
- // invariant that every site names the file whose text it shows
696
- // (finding F, §25). stampUrl only fills a url that is EMPTY, so
697
- // stamping the superset never renames a value read from an include.
698
391
  stampUrl(schemaVal, schemaUrl);
699
392
  const dataUrls = stampUrl(dataVal, dataUrl);
700
393
  // The projection every site in this report goes through: roles by
@@ -704,15 +397,6 @@ function vet(schemaSrc, dataSrc, opts) {
704
397
  schemaUrl, schemaPath: options.schemaPath,
705
398
  dataUrl, dataPath: options.dataPath,
706
399
  };
707
- // COVERAGE IS MEASURED BEFORE THE MEET (G11 phase 5), because the
708
- // meet CONSUMES its operands: parsed trees are single-use, and under
709
- // `--at` the anchor itself is the left operand. Measuring after would
710
- // read a tree the fixpoint had already rewritten.
711
- //
712
- // The data side is its own evaluation rather than the parse above,
713
- // so a document that reaches its values through `@"..."` or a
714
- // reference is measured on the paths it actually has. It is one more
715
- // evaluation of one document, and it happens only when asked for.
716
400
  let coverage;
717
401
  if (true === options.coverage) {
718
402
  const coverCtx = aontu.ctx({ collect: true });
@@ -724,31 +408,6 @@ function vet(schemaSrc, dataSrc, opts) {
724
408
  ? settledData : dataVal;
725
409
  coverage = vetCoverage(anchor, measured, options.coverageAt);
726
410
  }
727
- // Default-validity lint (G3 phase 5, re-examined under ADR-004): for
728
- // every disjunction in the SCHEMA carrying a preference, warn when
729
- // the effective default is not an instance of any REMAINING
730
- // alternative (code `pref_not_instance`, class compat, severity
731
- // warning).
732
- //
733
- // What the finding MEANS changed with the admission gate (ADR-004).
734
- // Before the gate it flagged a soundness hole: the preference held
735
- // the disjunction open, so `a:*5|string` both generated a value the
736
- // alternatives refuse AND admitted any same-kind override. The gate
737
- // closed that hole — a preferred branch now contributes exactly its
738
- // own value to the admitted set, so a default can no longer be
739
- // "invalid against its own disjunct" and the enum-with-default idiom
740
- // (`*'auto'|'literal'|'data'`) is sound as written. The lint is KEPT,
741
- // as an advisory: a default admitted only because it is the default
742
- // is also the exact shape of a typo'd default
743
- // (`level:*wran|info|warn|debug` — the intended `*warn` would be
744
- // silent), and nothing at meet time can catch that. The
745
- // repeated-branch spelling (`*warn|warn|...`) states "the default is
746
- // a first-class member", silences the lint, and — unlike before the
747
- // gate — enforces exactly the same admitted set. The message names
748
- // the REMAINING alternatives because that is what was scanned: the
749
- // preferred branch itself always admits its own default, so the old
750
- // wording ("any alternative of *5|string") read as false on its face
751
- // (use-cases/BUGS.md §4).
752
411
  const lintFindings = [];
753
412
  (0, utility_1.walkBagVals)(anchor, (v, path) => {
754
413
  if (true === v.isDisjunct && Array.isArray(v.peg)) {
@@ -783,44 +442,9 @@ function vet(schemaSrc, dataSrc, opts) {
783
442
  }
784
443
  }
785
444
  });
786
- // `--closed` sets the flag `close()` itself sets, rather than wrapping
787
- // the anchor in a CloseFuncVal: the anchor is an already-evaluated
788
- // tree, and a func value would have to resolve again to have any
789
- // effect. A scalar anchor has no keys to close, so the flag is only
790
- // meaningful on a bag.
791
445
  if (true === options.closed && (true === anchor.isMap || true === anchor.isList)) {
792
446
  anchor.closed = true;
793
447
  }
794
- // THE MEET IS FROM A FRESH PARSE, NOT THE SETTLED SCHEMA (the
795
- // review's finding C, use-cases/BUGS.md §15).
796
- //
797
- // Step 1 evaluated the schema ALONE, to decide whether it stands up
798
- // before any data is blamed for it. That answer is a diagnosis, and
799
- // it was also being used as the left side of the meet -- so every
800
- // reference in the schema had already RESOLVED against the schema's
801
- // own values and been replaced by them. `a:integer b:$.a` settled to
802
- // `a:integer b:integer`, and data `{a:3,b:4}` then vetted VALID,
803
- // while the same four lines as one document refuse with
804
- // scalar_value. A reference is a statement about the FINAL model, and
805
- // vet is asking about a model the data is part of.
806
- //
807
- // Parsing again is what makes `vet(S,D)` and `eval(S ∪ D)` the same
808
- // question: the meet runs the fixpoint once, over both documents, so
809
- // references, spreads and generators all see the data. Parsed trees
810
- // are single-use, hence a second parse rather than a reuse of step
811
- // 1's. The lint above still reads the SETTLED tree, where
812
- // disjunctions are ranked and normalised.
813
- //
814
- // ONLY WHEN THERE IS NO `--at`. An anchor is a SUBTREE lifted out of
815
- // the schema, and an absolute reference inside it (`$.OrderPlaced`,
816
- // the discriminated-union idiom) names a sibling of the document
817
- // root -- which the lifted subtree no longer has. The settled tree is
818
- // where those references have already been resolved and substituted,
819
- // so an anchored run keeps meeting that, exactly as it always has.
820
- // Making the rule explicit rather than leaving it to whether
821
- // anchorAt happens to find the path in an unresolved tree: the two
822
- // ports answered that differently, which is an ADR-001 divergence
823
- // waiting to happen.
824
448
  const ctx = aontu.ctx({ collect: true });
825
449
  let meetAnchor = anchor;
826
450
  if (null == options.at) {
@@ -836,15 +460,6 @@ function vet(schemaSrc, dataSrc, opts) {
836
460
  }
837
461
  }
838
462
  else {
839
- // A RECURSIVE residual inside the lifted anchor still names its
840
- // definition by absolute path (`then?: $.spec.Step` -- the
841
- // fixpoint, RECURSION.0.md), and the meet's root is the anchored
842
- // subtree, which does not contain `$.spec`. Without a tree to
843
- // walk, the residual held its peer forever and everything under a
844
- // recursive field vetted VALID unchecked. The settled schema root
845
- // is kept on the meet context for exactly that walk
846
- // (AontuContext._fixroot; RecurseVal.body and RefVal.find fall
847
- // back to it).
848
463
  ;
849
464
  ctx._fixroot = schemaVal;
850
465
  ctx.path = options.at.replace(/^\$\.?/, '')
@@ -852,17 +467,6 @@ function vet(schemaSrc, dataSrc, opts) {
852
467
  }
853
468
  const pair = new ConjunctVal_1.ConjunctVal({ peg: [meetAnchor, dataVal] }, ctx);
854
469
  const unified = aontu.unify(pair, undefined, ctx);
855
- // 4. Contradictions: every NilVal standing in the result, PLUS the
856
- // ones that never made it into the tree.
857
- //
858
- // The second half is not belt-and-braces. When a parent collapses to
859
- // a nil the whole subtree goes with it, so `service: close({...})`
860
- // meeting a typo AND a kind conflict leaves ONE nil in the tree and
861
- // reports the other only on the context — the vet verb's own
862
- // motivating example, reporting half of what it found. The language
863
- // server already walks both for this reason; vet dedups by identity
864
- // the same way, and skips the transient disjunct-trial sentinel,
865
- // which is bookkeeping rather than a finding.
866
470
  const seen = new Set();
867
471
  const nils = (0, walk_1.collectNils)(unified, seen);
868
472
  for (const err of ctx.err) {
@@ -875,44 +479,16 @@ function vet(schemaSrc, dataSrc, opts) {
875
479
  materialise(n, ctx);
876
480
  return findingOf(n, prov);
877
481
  });
878
- // 5. Incompleteness: what is left standing that cannot generate. The
879
- // generate check runs in its own collect context so nothing it
880
- // raises reaches the caller's error list, and so a schema that is
881
- // merely unsatisfied does not look like one that is contradicted.
882
- // No try/catch: in collect mode `gen` records its reasons on the
883
- // context instead of throwing, which is the whole point of the mode.
884
482
  const genCtx = aontu.ctx({ collect: true });
885
483
  genCtx.root = unified;
886
- // Under `--at` the probe descends through the OUTPUT marks: the
887
- // caller named this node as the truth to validate against, so a
888
- // `type()` or `hide()` on it (or propagated into it) is not a reason
889
- // to check nothing. See AontuContext.probe.
890
484
  genCtx.probe = null != options.at;
891
485
  unified.gen(genCtx);
892
486
  for (const err of genCtx.err) {
893
- // A CONFLICT RAISED AT GENERATION COUNTS TOO (the review's finding
894
- // C, use-cases/BUGS.md §16). The filter used to keep the
895
- // `incomplete` class alone, on the reading that step 4 had already
896
- // found every contradiction -- true while every conflict was
897
- // decided during the meet, and untrue since a sizing atom or a
898
- // container `must` may hold a PROVISIONAL reading until generation,
899
- // which is where no more members can arrive. Dropping those left
900
- // `vet` answering `valid` for data the evaluator refuses, which is
901
- // the one disagreement the vet-equals-eval harness exists to catch
902
- // -- and did.
903
- //
904
- // Deduped against step 4 by the same cause key the loop below uses,
905
- // so a contradiction seen twice is still reported once.
906
487
  if ('incomplete' === err.class || 'conflict' === err.class) {
907
488
  materialise(err, genCtx);
908
489
  findings.push(findingOf(err, prov));
909
490
  }
910
491
  }
911
- // 5b. Deprecation warnings (G3 phase 4): a value that carries the
912
- // deprecate() record after the meet was USED — the data met a
913
- // deprecated schema value, or the schema's own default will
914
- // generate one. Severity `warning` (the slot G2 reserved for
915
- // exactly this mark), and warnings never touch the verdict below.
916
492
  findings.push(...lintFindings);
917
493
  for (const { val, path } of (0, utility_1.collectDeprecations)(unified)) {
918
494
  const v = val;
@@ -940,27 +516,6 @@ function vet(schemaSrc, dataSrc, opts) {
940
516
  const keyed = findings.map((f, i) => ({ key: orderKey(f, i), finding: f }));
941
517
  keyed.sort((a, b) => a.key < b.key ? -1 : 1);
942
518
  let ordered = keyed.map((k) => k.finding);
943
- // ONE CAUSE, ONE FINDING. A reference resolves by CLONING its target,
944
- // so a target that later fails can fail once per referrer — same
945
- // code, same two source sites, a different path each time. Multi-pass
946
- // collection (G2 phase 6) made this reachable: the pass loop now
947
- // continues past the erroring pass, so the clones' own folds run too.
948
- // The dedup key is the CODE plus the SITES (file, row, col, value,
949
- // role): two findings that name the same meet of the same two source
950
- // positions are one contradiction observed from two paths. The key is
951
- // NOT (code, path) — the design's sketch — because the paths are
952
- // exactly what differ. Sorted order makes the kept finding the first
953
- // by data site then path, deterministically in both ports.
954
- //
955
- // THE KEPT PATH IS THE DEEPEST one (use-cases/BUGS.md §41). A meet
956
- // that fails inside a REFERENCED map is recorded twice: once at the
957
- // key that actually conflicts, and once at the enclosing map, which
958
- // collapsed as a consequence and carries the child's two sites. Both
959
- // are the same cause; only the deeper one names the field an author
960
- // or an agent has to edit, and `$.q` for a conflict in `$.q.a` sent a
961
- // repair loop to rewrite the whole record -- twice over, identically,
962
- // when two of its fields conflicted. Depth first, then the sort order
963
- // above, so the choice stays deterministic in both ports.
964
519
  const causeKey = (f) => f.code + '\u0000' + f.sites.map((s) => [s.file, s.row, s.col, s.role, s.value].join('\u0000')).join('\u0000');
965
520
  const depth = (f) => f.path.split('.').length;
966
521
  const deepest = new Map();
@@ -982,22 +537,6 @@ function vet(schemaSrc, dataSrc, opts) {
982
537
  });
983
538
  const truncated = maxErrors < ordered.length;
984
539
  const kept = truncated ? ordered.slice(0, maxErrors) : ordered;
985
- // 6. The verdict derives from finding CLASSES, never from codes, so a
986
- // new code can never change exit behaviour.
987
- //
988
- // BY CLASS, NOT BY STAGE. The split used to be positional -- whatever
989
- // step 4 found counted as contradiction and whatever step 5 added
990
- // counted as incompleteness -- which stopped being true when a sizing
991
- // atom or a container `must` began holding a provisional reading
992
- // until generation (the review's finding C, use-cases/BUGS.md §16). A
993
- // CONTRADICTION found at generation is still a contradiction: reading
994
- // it as mere incompleteness answered `incomplete` where the evaluator
995
- // refuses, and `vet` and `eval` have to agree.
996
- //
997
- // So: an error-severity finding that is not INCOMPLETENESS makes the
998
- // document invalid, wherever it was found -- a contradiction, a parse
999
- // refusal, an unresolvable reference alike. Warnings (the `compat`
1000
- // class: lint and deprecation) never touch the verdict.
1001
540
  let verdict = 'valid';
1002
541
  const errors = ordered.filter((f) => 'error' === f.severity);
1003
542
  const unmet = errors.filter((f) => 'incomplete' === f.class).length;