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
@@ -18,98 +18,16 @@ const err_1 = require("../err");
18
18
  const FeatureVal_1 = require("./FeatureVal");
19
19
  const ScalarKindVal_1 = require("./ScalarKindVal");
20
20
  const numcmp_1 = require("./numcmp");
21
- // THE PATTERN SUBSET, AND HOW IT IS ENFORCED (G1 phase 2; ADR-003).
22
- //
23
- // `re(p)` must mean the same thing in both engines and cost about the
24
- // same, and the two host engines guarantee neither: TypeScript compiles
25
- // with JavaScript's backtracking RegExp, Go with RE2 — a different
26
- // language in a different complexity class, over a different alphabet.
27
- //
28
- // The enforcement is NORMALISATION, not refusal (ADR-003). Every
29
- // construct whose expansion is engine-defined is rewritten here, by
30
- // this function, into an explicit form that cannot be read two ways;
31
- // only the rewritten pattern reaches a host engine. The alternative —
32
- // refusing everything that might differ — was tried first and leaked
33
- // three times, because its correctness depended on this comment knowing
34
- // every difference between two large engines.
35
- //
36
- // Aontu therefore DEFINES the abbreviations rather than inheriting
37
- // either host's. The definitions are deliberately the small ASCII ones,
38
- // because a config value containing U+00A0 is a mistake to catch, not a
39
- // space to accept silently:
40
- //
41
- // \d [0-9] \D [^0-9]
42
- // \w [0-9A-Za-z_] \W [^0-9A-Za-z_]
43
- // \s [ \t\n\r\f\v] \S [^ \t\n\r\f\v]
44
- // . [^\n]
45
- // \A ^ \z $
46
- //
47
- // Neither host agreed with all of these before rewriting: JavaScript's
48
- // \s also matches U+00A0 and other Unicode spaces, RE2's omits \v, and
49
- // the two `.` sets differ by \r and the Unicode line separators. After
50
- // rewriting, both engines see one explicit class and cannot disagree.
51
- //
52
- // What is still REFUSED, and why refusal is right for these:
53
- //
54
- // 1. Constructs one engine simply lacks — backreferences and
55
- // lookaround (not in RE2, and not expressible as regular
56
- // expressions at all), POSIX classes, `\p{...}`, `\x{...}`, `\u`.
57
- // There is nothing to normalise them TO.
58
- // 2. `(?` other than `(?:` — named groups are spelled differently
59
- // (`(?P<n>` in RE2, `(?<n>` in JavaScript) and inline flags change
60
- // the meaning of everything after them.
61
- // 3. A quantifier applied to a group containing a quantifier or an
62
- // alternation. This one is about TIME, not meaning: `(a+)+$`
63
- // against twenty-nine characters takes 45 SECONDS in JavaScript
64
- // and 0.065s under RE2, and a regex match is counted by no
65
- // evaluator budget, so an untrusted schema could otherwise stall
66
- // the TypeScript evaluator indefinitely (docs/trust.md clause 2).
67
- // Normalisation cannot fix a complexity difference; only owning the
68
- // matcher could, which ADR-003 records as the future option.
69
- //
70
- // The alphabet is fixed separately, by compiling with the `u` flag:
71
- // JavaScript otherwise matches UTF-16 code units where RE2 matches code
72
- // points, so `^.$` accepted U+1D11E in Go and refused it in TypeScript.
73
- //
74
- // This function is mirrored statement for statement in go/constraint.go,
75
- // and `test/spec/files/regex-corpus.txt` pins that the two produce
76
- // byte-identical output for every pattern in a generated corpus.
77
- // The largest repeat count Aontu's pattern language admits. RE2 caps a
78
- // repeat at 1000 and refuses to compile past it, where JavaScript's
79
- // backtracking engine accepts any count -- so `re("^a{1001}$")` was
80
- // VALID in TypeScript and an `error` verdict in Go, a cross-port
81
- // verdict flip on a schema an agent could be handed
82
- // (status-2026-08-21.md section 4). Under ADR-003 the host's own
83
- // compile failure must never be what a user sees, so the bound is
84
- // Aontu's: at most RE_REPEAT_MAX, refused identically in both ports
85
- // before either engine compiles. Nested products beyond the cap were
86
- // already refused, by the quantified-group rule below.
87
21
  const RE_REPEAT_MAX = 1000;
88
22
  // The normative expansions. These are Aontu's definitions, not either
89
23
  // host's; both hosts are rewritten to them.
90
24
  const RE_CLASS_DIGIT = '0-9';
91
25
  const RE_CLASS_WORD = '0-9A-Za-z_';
92
26
  const RE_CLASS_SPACE = ' \\t\\n\\r\\f\\v';
93
- // Metacharacters that may be escaped to mean themselves, in both
94
- // engines. `-` is handled separately: it is legal escaped only INSIDE a
95
- // character class, because RE2 accepts `a\-b` and JavaScript's unicode
96
- // mode makes it a syntax error.
97
27
  const RE_ESCAPE_PUNCT = '\\.+*?()[]{}|^$/';
98
28
  // Escapes passed through unchanged: the control characters, the ASCII
99
29
  // word boundary, and `\xHH`. Each was probed in both engines.
100
30
  const RE_ESCAPE_PASS = 'tnrfv';
101
- // A counted quantifier `{n}`, `{n,}` or `{n,m}` starting at `src[at]`.
102
- // Two rules, both about what the hosts do NOT share:
103
- //
104
- // - A bound above RE_REPEAT_MAX: RE2 refuses to compile it, JavaScript
105
- // accepts it.
106
- // - A brace that does not open a well-formed counted quantifier at
107
- // all (`x{y}`, `a{`, `{,5}`): JavaScript compiled with the `u` flag
108
- // makes it a SYNTAX ERROR, while RE2 reads it as a literal brace, so
109
- // `re("^x{y}$")` was `constraint_pattern` in TypeScript and a plain
110
- // unresolved value in Go -- the same class of verdict flip as the
111
- // repeat cap, found by sweeping around it. A literal brace is
112
- // written escaped (`a\\{1001\\}`), which both engines share.
113
31
  function repeatWhy(src, at) {
114
32
  const bad = (what) => [
115
33
  'a ' + what + ', which the two engines do not read the same way', -1
@@ -241,10 +159,6 @@ function normaliseEscape(n, src, i, inClass) {
241
159
  function normaliseRe(src) {
242
160
  let inClass = false;
243
161
  const out = [];
244
- // One frame per open group, recording whether it contains a quantifier
245
- // or an alternation. A group carrying either may not itself be
246
- // quantified; containment is transitive, so a frame hands its flags up
247
- // to its parent when it closes.
248
162
  const groups = [];
249
163
  const mark = (k) => {
250
164
  if (0 < groups.length) {
@@ -266,23 +180,12 @@ function normaliseRe(src) {
266
180
  return ['', why];
267
181
  }
268
182
  out.push(emit);
269
- // `\b` AND `\B` ARE ASSERTIONS TOO, and quantifying one is the
270
- // same disagreement `^{1}` is: JavaScript under `u` calls it a
271
- // syntax error, RE2 quantifies the assertion happily. The rule
272
- // said "`\b` and `\B` quantify identically in both and are left
273
- // alone" and that was measured wrong -- `re("\\b{1}x")` is
274
- // `constraint_pattern` in TypeScript and an accepted schema in
275
- // Go. Only OUTSIDE a class: inside one, `\b` is a backspace in
276
- // both engines and repeats like any other character.
277
183
  if (!inClass && ('b' === src[i + 1] || 'B' === src[i + 1])) {
278
184
  anchorPrev = true;
279
185
  }
280
186
  i += 1 + extra;
281
187
  continue;
282
188
  }
283
- // A POSIX class opener, anywhere: the form lives inside an ordinary
284
- // class (`[[:alpha:]]`), and refusing it everywhere is one rule
285
- // rather than two.
286
189
  if ('[' === c && ':' === src[i + 1]) {
287
190
  return ['', 'a POSIX class ([:...:]), which JavaScript does not have'];
288
191
  }
@@ -347,12 +250,6 @@ function normaliseRe(src) {
347
250
  continue;
348
251
  }
349
252
  if ('*' === c || '+' === c || '?' === c || '{' === c) {
350
- // Nothing to repeat. JavaScript under the `u` flag makes this a
351
- // SYNTAX ERROR, where RE2 quantifies the assertion happily and
352
- // matches, so `re("^{1}")` was `constraint_pattern` in
353
- // TypeScript and an accepted schema in Go. The four assertions
354
- // behave alike here -- `^`, `$`, `\b` and `\B` -- so the rule
355
- // names all four.
356
253
  if (afterAnchor) {
357
254
  return ['', 'a quantifier applied to `^`, `$`, `\\b` or ' +
358
255
  '`\\B`, which has nothing to repeat'];
@@ -368,10 +265,6 @@ function normaliseRe(src) {
368
265
  out.push(c);
369
266
  continue;
370
267
  }
371
- // A `}` that closes no counted quantifier: JavaScript under `u`
372
- // refuses it as a lone quantifier bracket, RE2 reads it as a
373
- // literal. Written escaped inside a class (`[}]`) it is a literal
374
- // in both, which is the spelling that survives.
375
268
  if ('}' === c) {
376
269
  if (i !== repeatEnd) {
377
270
  return ['', 'a `}` that closes no counted quantifier, which ' +
@@ -401,18 +294,9 @@ function numericLeaf(v) {
401
294
  function stringLeaf(v) {
402
295
  return true === v?.isScalar && 'string' === typeof v.peg && v.isString;
403
296
  }
404
- // The VALUE-admission widening of stringLeaf: a path value is a string
405
- // with more structure (path <: string, ADR-016), so the string-domain
406
- // constraints admit one -- `refer() & re("auth$")` must still check a
407
- // link whose value is now a path. The ARGUMENT sites keep the strict
408
- // test: a pattern, a bound or an exclusion is spelled with a plain
409
- // string, never a path.
410
297
  function stringishLeaf(v) {
411
298
  return stringLeaf(v) || (true === v?.isScalar && true === v.isPath);
412
299
  }
413
- // Scalar identity: leaf AND value, the lattice's own rule (1 and 1.0
414
- // are different scalars). Exact numeric comparison decides the value
415
- // half for numeric leaves.
416
300
  function sameScalar(a, b) {
417
301
  if (numericLeaf(a) && numericLeaf(b)) {
418
302
  return (0, numcmp_1.towerRank)(a) === (0, numcmp_1.towerRank)(b) && 0 === (0, numcmp_1.cmpNumeric)(a, b);
@@ -438,20 +322,6 @@ function leafMarker(v) {
438
322
  return v.isBigDecimal ? ScalarKindVal_1.BigDecimal : v.isBigInteger ? ScalarKindVal_1.BigInteger :
439
323
  v.isInteger ? ScalarKindVal_1.Integer : ScalarKindVal_1.Float;
440
324
  }
441
- // Conjunct sort order for an atom that must see the WHOLE value.
442
- // Every other value sorts below the container default (99999), so such
443
- // an atom is the LAST term to fold: `a:length(2) a:{x:1} a:{y:2}` must
444
- // count the MERGED map, and a constraint that folded at 50000 would
445
- // count `{x:1}` alone and refuse the layering that is the whole point
446
- // of the language.
447
- //
448
- // The order atoms keep the low slot: `min(2) & 1 & 2` may decide as
449
- // soon as it sees a scalar, because meeting more scalars can only
450
- // narrow. Meeting more containers GROWS the member set, which is why
451
- // the two orders differ.
452
- //
453
- // Three atoms are late: `length` and `unique` (they count members), and
454
- // `must` (an evaluate-only check against the finished value).
455
325
  const LATE_CJO = 150000;
456
326
  function lateAtom(atom) {
457
327
  return 'length' === atom || 'unique' === atom || 'must' === atom;
@@ -483,16 +353,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
483
353
  }
484
354
  else if (spec.atom) {
485
355
  const args = atomArgs(spec.atom, spec.peg ?? []);
486
- // An argument that is not yet concrete — a reference, an
487
- // arithmetic expression, a conjunct of atoms — makes the whole
488
- // atom PENDING rather than invalid (G1 phase 4). It is resolved
489
- // in unify, where there is a ctx to resolve through, and the
490
- // residual is built from the settled arguments. Only a settled
491
- // argument of the wrong shape is an `invalid-arg`.
492
- // The effectful-argument refusal happens HERE, on the written
493
- // form, and not in fromAtom: settling is what runs the effect, so
494
- // by the time fromAtom sees a settled `move($.b)` the move has
495
- // already happened and the argument is just its result.
496
356
  if ('must' === spec.atom && args.some((a) => holdsMove(a))) {
497
357
  this.invalid = 'invalid-arg';
498
358
  }
@@ -518,26 +378,10 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
518
378
  this.notdone();
519
379
  }
520
380
  }
521
- // Normalise one atom call into state. Every argument here is already
522
- // SETTLED — the constructor routes an unsettled one to `pending` —
523
- // so a shape this cannot use is a genuine `invalid-arg`, not a
524
- // not-yet.
525
381
  fromAtom(atom, args) {
526
- // Mark the residual invalid. It answers NOTHING: every caller
527
- // spells its exit `return bad(...)` and none reads a value, so a
528
- // return type would be a value nobody consumes -- and a routine
529
- // that answers on some paths and not others is the shape a reader
530
- // (and a static analyser) has to stop and check.
531
382
  const bad = (why) => {
532
383
  this.invalid = why;
533
384
  };
534
- // `unique()` is a property of the container -- not a comparison
535
- // against a value -- so with no argument it says the members are
536
- // pairwise DISTINCT. THE ONE ARGUMENT IS A PROJECTOR (the review's
537
- // finding I: "unique()-by-field is reserved but absent", and the
538
- // arity was reserved for exactly this): `unique(port)` says no two
539
- // members share a `port`, which is how "no two services share a
540
- // port" and "event ids are unique" are said.
541
385
  if ('unique' === atom) {
542
386
  if (0 === args.length) {
543
387
  this.uniq = true;
@@ -549,12 +393,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
549
393
  this.uniqBy = [args[0].peg];
550
394
  return;
551
395
  }
552
- // `must(c, msg)` is Band B: an evaluate-only check against the
553
- // finished value, carrying the author's own message. It is KEPT,
554
- // never simplified and never consulted for emptiness or
555
- // subsumption — Band B is opaque by construction, which is exactly
556
- // what makes it the honest channel for a rule the algebra cannot
557
- // reason about (docs/reference-language.md, "Band B: `must`").
558
396
  if ('must' === atom) {
559
397
  if (2 !== args.length) {
560
398
  return bad('arg');
@@ -562,11 +400,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
562
400
  if (!stringLeaf(args[1])) {
563
401
  return bad('invalid-arg');
564
402
  }
565
- // A check carrying a nil can never be satisfied, so it is refused
566
- // as an ARGUMENT rather than left to fail against every value with
567
- // the author's message attached -- which would blame the data for
568
- // a mistake in the check. `must([1-x],m)` is the reachable case: a
569
- // degenerate expression leaves a nil inside the written list.
570
403
  if (holdsNil(args[0])) {
571
404
  return bad('invalid-arg');
572
405
  }
@@ -604,8 +437,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
604
437
  return bad('invalid-arg');
605
438
  }
606
439
  const src = a.peg;
607
- // Normalise BEFORE compiling: the host engines only ever see a
608
- // pattern that cannot be read two ways (ADR-003).
609
440
  const [norm, why] = normaliseRe(src);
610
441
  if ('' !== why) {
611
442
  this.invalidWhy = why;
@@ -613,23 +444,9 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
613
444
  }
614
445
  let re;
615
446
  try {
616
- // The `u` flag is REQUIRED for parity, not an optimisation.
617
- // Without it JavaScript matches UTF-16 code units while RE2
618
- // matches code points, so `re("^.$")` accepted U+1D11E in Go
619
- // and refused it in TypeScript (and `^..$` did the reverse).
620
- // With it, `.` and every quantifier count code points in both.
621
- // It also makes JavaScript refuse the identity escapes this
622
- // scanner rejects by hand, which is defence in depth rather
623
- // than a substitute: RE2 accepts some of them, so the scanner
624
- // is what keeps the two ports agreeing.
625
447
  re = new RegExp(norm, 'u');
626
448
  }
627
449
  catch (e) {
628
- // The host engine refuses what the subset scanner passed — a
629
- // malformed quantifier, an unbalanced group. Same refusal under
630
- // the same code: the author gets one rule, not two. The message
631
- // is the host's, so it is NOT pinned by a shared row; the code
632
- // and the located frame are.
633
450
  this.invalidWhy = 'not a valid pattern';
634
451
  return bad('constraint_pattern');
635
452
  }
@@ -637,16 +454,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
637
454
  this.res = [{ v: a, src, norm, re }];
638
455
  return;
639
456
  }
640
- // `length` is the other non-ORDER atom: its argument constrains the
641
- // COUNT, not the value, so it is itself a residual over the integer
642
- // domain (docs/reference-language.md, "`length` semantics"). It is
643
- // resolved HERE, at construction, by walking the written argument
644
- // rather than by unifying it: the func-paren handler builds atoms
645
- // without an AontuContext, so there is nothing to fold a nested
646
- // conjunct through. Walking is enough because a length argument is by
647
- // definition a meet of concrete Band A atoms; anything else (a
648
- // reference, an expression) is refused rather than deferred, the
649
- // same discipline min/max apply to their own arguments.
650
457
  if ('length' === atom) {
651
458
  const arg = countArgState(a);
652
459
  if (null == arg) {
@@ -680,15 +487,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
680
487
  // Every branch of the ladder assigns, so no initialiser: a
681
488
  // residual is stable and the ladder is total.
682
489
  let out;
683
- // A rel residual or a graph atom HOLDS constraints for the value
684
- // they stand for (RELATIONS P1/P2): hand the drive over before
685
- // any settling, exactly as a container does, so `rel(t) & re(x)`
686
- // reads the same in either order. Reached through the INCLUDE
687
- // flow (a loaded schema's conjunct re-drives with the constraint
688
- // on the left) -- inline documents route rel/atom peers through
689
- // unite's b-drives first, which is why use-cases/12-relations
690
- // refused without this arm while every inline row stayed green;
691
- // pinned by constraint-hands-drive-to-rel-and-atom.
692
490
  if (true === peer?.isRel
693
491
  || true === peer?.isGraphAtom) {
694
492
  out = peer.unify(this, ctx);
@@ -719,31 +517,11 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
719
517
  }
720
518
  /* node:coverage ignore next 12 */
721
519
  else {
722
- // Every other shape: no order, no membership, nothing to count —
723
- // a conflict of the constraint family. The ladder above is total
724
- // in practice: every remaining Val kind either sorts BELOW a
725
- // constraint in a conjunct (conjunct, disjunct, pref, ref) and so
726
- // drives the meet from its own side, or resolves to a
727
- // scalar/container before a constraint sees it (func, op, var,
728
- // expect). The arm is kept because "in practice" depends on the
729
- // cjo table, and a future value class would land here rather than
730
- // falling out of unify with no result.
731
520
  out = this.fail(ctx, peer);
732
521
  }
733
522
  ctx.explain && (0, utility_1.explainClose)(te, out);
734
523
  return out;
735
524
  }
736
- // Resolve a pending atom's arguments and, once they have all settled,
737
- // become the residual they describe (G1 phase 4).
738
- //
739
- // This is the residuation discipline FuncBaseVal already follows for
740
- // its own operands: push each unsettled argument one step by unifying
741
- // it with `top`, and if any is still moving, mark not-done and defer
742
- // — either as this same pending atom (against a `top` peer) or
743
- // wrapped with the peer in a conjunct the next pass will re-enter.
744
- // Nothing is decided from a half-resolved argument, which is what
745
- // keeps `min($.lo)` from reporting a conflict against a bound that
746
- // has not arrived yet.
747
525
  settle(peer, ctx) {
748
526
  const TOP = (0, top_1.top)();
749
527
  const pend = this.pending;
@@ -752,9 +530,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
752
530
  for (const arg of pend.args) {
753
531
  let next = arg;
754
532
  if (true !== arg?.done) {
755
- // Charged to the depth budget: this recurses without going
756
- // through `unite`, so the counter would otherwise stay flat
757
- // while the stack grows (the rule FuncBaseVal follows).
758
533
  next = (0, unify_1.withDepth)(ctx, arg, TOP, () => arg.unify(TOP, ctx));
759
534
  }
760
535
  settled = settled && true === next?.done;
@@ -801,9 +576,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
801
576
  return this.fail(ctx, peer);
802
577
  }
803
578
  if (null != this.count) {
804
- // Only a string among the scalars has a length, and it is counted
805
- // in CODE POINTS -- not UTF-16 units (this host's native count)
806
- // and not bytes (Go's). Iterating a string yields code points.
807
579
  if (!stringishLeaf(peer)) {
808
580
  return this.fail(ctx, peer);
809
581
  }
@@ -820,30 +592,10 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
820
592
  }
821
593
  return peer;
822
594
  }
823
- // Band B, applied to a finished value. Each check is a plain
824
- // unification against a CLONE of the peer: `must` reports, it never
825
- // contributes: whatever the check would have added to the value is
826
- // discarded, and `peer` is returned untouched by the callers.
827
- //
828
- // The trial runs in an isolated collect context so a failing check
829
- // leaves nothing on the caller's error list — only the located nil
830
- // this returns, carrying the author's own message.
831
- // `final` is the generation-time reading (see settleContainer): a
832
- // must whose own check is a SIZING atom inherits that atom's
833
- // provisionality, because `must(length(2), …)` against a map that may
834
- // still gain members has not failed yet -- it has not been answered.
835
- // Without this the must would decide against whatever the container
836
- // held when it first settled, which is the very defect the sizing
837
- // atoms were fixed for (use-cases/BUGS.md §16, §17).
838
595
  checkMusts(peer, ctx, final) {
839
596
  for (const m of this.musts) {
840
597
  const trial = ctx.clone({ err: [], collect: true });
841
598
  let got = (0, unify_1.unite)(trial, m.v.clone(trial), peer.clone(trial), 'must');
842
- // A must whose check is a SIZING atom answers a residue rather
843
- // than a verdict, because the atom is waiting for members that
844
- // may still arrive. Before generation that residue IS the answer
845
- // -- the must has not failed, it has not been asked yet -- and at
846
- // generation it is settled, because nothing more can arrive.
847
599
  const residue = (0, BagVal_1.sizingResidue)(got);
848
600
  if (undefined !== residue) {
849
601
  if (true !== final) {
@@ -861,25 +613,9 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
861
613
  }
862
614
  return undefined;
863
615
  }
864
- // THE FINAL READING of a sizing atom over a container: the same
865
- // checks admitContainer makes, with the provisional ones taken as
866
- // decided. Called from ConjunctVal.gen, which is where no more
867
- // members can arrive. Returns the container (to generate) or the
868
- // constraint's own nil (to report).
869
616
  settleContainer(peer, ctx) {
870
617
  return this.admitContainer(peer, ctx, true);
871
618
  }
872
- // Membership for a container peer. Only the SIZING atoms have anything
873
- // to say about a map or a list; every other atom is scalar-domain and
874
- // refuses one.
875
- //
876
- // The members that count are the members that GENERATE
877
- // (docs/reference-language.md, "`length` semantics"), and rather than
878
- // mirror generation's filter — type/hide marks, optional keys that
879
- // drop, empty optional values — this asks generation itself, in an
880
- // isolated collect context so nothing leaks into the caller's errors.
881
- // A mirror would be a second copy of a filter that has already grown
882
- // subtle, free to drift from it; asking is correct by construction.
883
619
  admitContainer(peer, ctx, final) {
884
620
  // A scalar-domain residual has no reading over a container.
885
621
  if (null != this.domain) {
@@ -896,13 +632,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
896
632
  if (null != bad) {
897
633
  return bad;
898
634
  }
899
- // A MUST OVER A CONTAINER RESIDUATES with the atoms, for the same
900
- // reason (use-cases/BUGS.md §17): `must({t: max(60)}, …)` beside a
901
- // `{t: integer}` schema was answered against the schema layer
902
- // ALONE, and discharged before the data it was written to judge
903
- // ever arrived. It is decided at generation, where the value is
904
- // whole -- unless there is nothing else on the constraint AND the
905
- // reading is already final.
906
635
  if (!this.uniq && 0 === this.uniqBy.length && null == this.count) {
907
636
  if (true === final || 0 === this.musts.length) {
908
637
  return peer;
@@ -911,42 +640,11 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
911
640
  }
912
641
  const members = emittedMembers(peer, ctx);
913
642
  if (null == members) {
914
- // NOT COUNTABLE YET IS NOT A PASS. A container that cannot
915
- // generate cannot be counted, and a SCHEMA is exactly that: the
916
- // members of `{a: integer}` are types, so nothing is emitted and
917
- // nothing can be counted. Discharging the atom here was the §16
918
- // defect wearing its other face -- `length(min(2)) & {a: integer}`
919
- // dropped its bound while still alone, so the data half of a
920
- // `vet` meet was never measured at all and short data vetted
921
- // clean against a bound the evaluator enforces.
922
- //
923
- // At generation the reading IS final: a container that still
924
- // cannot generate has its own error, and that error is the one
925
- // worth reporting, so it passes through untouched.
926
643
  if (true === final) {
927
644
  return peer;
928
645
  }
929
646
  return this.hold(peer, ctx);
930
647
  }
931
- // MONOTONE READINGS ONLY (the review's finding C, use-cases/BUGS.md
932
- // §16). Members ACCUMULATE under unification -- a meet adds keys and
933
- // never removes them -- so a settled container is settled ON ITS
934
- // OWN and not against every value that may still contribute. The
935
- // schema half of a `vet` meet, a document that is about to receive
936
- // an `@` include, a bag a later `pack` will fill: each settles, and
937
- // an atom that decided there decided too early.
938
- //
939
- // So a verdict is taken only when MORE MEMBERS CANNOT CHANGE IT:
940
- // - an upper bound VIOLATED is permanent -> refuse now;
941
- // satisfied is provisional -> keep the atom, re-check later.
942
- // - a lower bound SATISFIED is permanent -> that part may go;
943
- // violated is provisional -> keep the atom (which is why
944
- // `length(min(1))` beside a template no longer kills the schema
945
- // it was written for).
946
- // - a DUPLICATE is permanent -> refuse now; distinctness is
947
- // provisional -> keep the atom.
948
- // Anything provisional residuates, exactly as an unsettled
949
- // container does above, and the two spellings then agree.
950
648
  const count = null == this.count ? undefined : this.count;
951
649
  const n = members.length;
952
650
  if (null != count) {
@@ -964,11 +662,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
964
662
  }
965
663
  }
966
664
  if (this.uniq) {
967
- // Members compare by CANONICAL FORM, which reduces to scalar
968
- // identity for scalars (so [1, 1.0] is distinct) and gives
969
- // structural equality for container members without a second
970
- // rule. A generated value could not express the first: `1` and
971
- // `1.0` generate the same JSON number.
972
665
  const seen = new Set();
973
666
  for (const m of members) {
974
667
  const key = m.canon;
@@ -978,10 +671,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
978
671
  seen.add(key);
979
672
  }
980
673
  }
981
- // ... and the same test per PROJECTED key. A member that has no such
982
- // key FAILS the constraint rather than being skipped: distinctness
983
- // it cannot be shown to have is distinctness it does not have, and
984
- // skipping would let one keyless record hide a duplicate.
985
674
  for (const field of this.uniqBy) {
986
675
  const seen = new Set();
987
676
  for (const m of members) {
@@ -1008,46 +697,14 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
1008
697
  if (spent) {
1009
698
  return peer;
1010
699
  }
1011
- // DONE, unlike the unsettled case above. The container HAS settled;
1012
- // the atom is kept only because a LATER value could still add
1013
- // members, and a residue that reported itself unresolved would
1014
- // leave every enclosing value unresolved with it -- a `type()`
1015
- // waiting on its argument for ever, and use case 09's whole
1016
- // registry with it.
1017
- // The ATOM is done too, not just the conjunct. An earlier pass may
1018
- // have set `dc = 0` on the unsettled branch above, and a conjunct
1019
- // recomputes its own doneness from its terms on every later meet --
1020
- // so a stale 0 here would drag the residue, and every value holding
1021
- // it, back to unresolved for ever.
1022
700
  return this.hold(peer, ctx);
1023
701
  }
1024
- // The atom kept on a value whose reading is still provisional.
1025
- // DONE, unlike the unsettled container above: the value HAS settled;
1026
- // the atom is kept only because a LATER value could still add
1027
- // members, and a residue that reported itself unresolved would leave
1028
- // every enclosing value unresolved with it -- a `type()` waiting on
1029
- // its argument for ever, and use case 09's whole registry with it.
1030
- // The ATOM is done too, not just the conjunct. An earlier pass may
1031
- // have set `dc = 0` on the unsettled branch, and a conjunct
1032
- // recomputes its own doneness from its terms on every later meet --
1033
- // so a stale 0 here would drag the residue, and every value holding
1034
- // it, back to unresolved for ever.
1035
702
  hold(peer, ctx) {
1036
703
  this.dc = type_1.DONE;
1037
704
  const held = new ConjunctVal_1.ConjunctVal({ peg: [this, peer] }, ctx);
1038
705
  held.dc = type_1.DONE;
1039
706
  return held;
1040
707
  }
1041
- // Meet with a kind: `number` (or `string` on the string domain) is
1042
- // already implied by an ORDER atom's argument; a numeric LEAF narrows
1043
- // the residual; anything else has an empty intersection with the
1044
- // constraint's domain.
1045
- //
1046
- // A sizing residual (`length`, `unique`) has no domain of its own -- a
1047
- // count says nothing about what is counted -- so a kind here SETS one
1048
- // rather than merely agreeing with it: `string & length(3)` is a
1049
- // three-character string, and `number & length(3)` is empty because a
1050
- // number has no length (stateEmpty decides that, not this).
1051
708
  meetKind(peer, ctx) {
1052
709
  const marker = peer.peg;
1053
710
  const merged = this.cloneState();
@@ -1101,14 +758,7 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
1101
758
  null == peer.count ? this.count : meetCount(this.count, peer.count);
1102
759
  // `unique()` is idempotent: two of them are one.
1103
760
  merged.uniq = this.uniq || peer.uniq;
1104
- // `unique(a) & unique(b)` is BOTH, not the later one: each names a
1105
- // key on which the members must differ, and dropping either would
1106
- // silently weaken the constraint. Sorted and deduplicated, so the
1107
- // meet is commutative and `unique(a) & unique(a)` is one atom.
1108
761
  merged.uniqBy = [...new Set([...this.uniqBy, ...peer.uniqBy])].sort();
1109
- // Band B checks accumulate in written order and are never merged,
1110
- // deduplicated or reordered: each carries its own author message,
1111
- // and two checks with the same shape may still say different things.
1112
762
  merged.musts = [...this.musts, ...peer.musts];
1113
763
  return this.finish(merged, ctx, peer);
1114
764
  }
@@ -1122,10 +772,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
1122
772
  out.site.row = this.site.row;
1123
773
  out.site.col = this.site.col;
1124
774
  out.site.url = this.site.url;
1125
- // Marks ratchet across a meet (the propagateMarks rule): a fresh
1126
- // residual must carry both operands' type/hide marks, or a
1127
- // `type(min(0)) & max(10)` merge would silently unmark the field
1128
- // (the Go fold re-ratchets from its terms; this is the TS twin).
1129
775
  (0, utility_1.propagateMarks)(this, out);
1130
776
  (0, utility_1.propagateMarks)(peer, out);
1131
777
  return out;
@@ -1189,9 +835,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
1189
835
  }
1190
836
  }
1191
837
  exports.ConstraintVal = ConstraintVal;
1192
- // The tighter of two like-direction bounds: the higher lower bound (or
1193
- // lower upper bound); on the same point the OPEN bound wins, and on a
1194
- // full tie the tower-lowest endpoint spelling survives.
1195
838
  function tighter(domain, a, b, lower) {
1196
839
  if (null == a)
1197
840
  return b;
@@ -1226,13 +869,6 @@ function dedupSorted(domain, neqs) {
1226
869
  }
1227
870
  return out;
1228
871
  }
1229
- // Is this value, or anything inside it, a nil? A written argument that
1230
- // holds one can never be satisfied, so the atom refuses it as an
1231
- // argument rather than reporting a mystery failure against every peer.
1232
- // Every caller passes a Val: `args[0]` comes from atomArgs, and the
1233
- // walk below descends only into container pegs, which hold Vals. The
1234
- // null/non-Val guard this function used to open with was therefore
1235
- // unreachable, and the coverage gate said so.
1236
872
  function holdsNil(v) {
1237
873
  if (true === v.isNil) {
1238
874
  return true;
@@ -1250,12 +886,6 @@ function holdsNil(v) {
1250
886
  }
1251
887
  return false;
1252
888
  }
1253
- // Whether a value, or anything inside it, is an effectful call — one
1254
- // whose evaluation changes a node OTHER than the one being computed.
1255
- // `move()` is the only builtin that does: it hides its resolution
1256
- // target in place. Band B refuses one as an argument, because settling
1257
- // it runs the effect against the live root before `must`'s trial clone
1258
- // is taken, and a check that mutates cannot be report-only.
1259
889
  function holdsMove(v) {
1260
890
  if (true === v.isFunc && 'move' === v.funcname?.()) {
1261
891
  return true;
@@ -1273,15 +903,6 @@ function holdsMove(v) {
1273
903
  }
1274
904
  return false;
1275
905
  }
1276
- // The written arguments of an atom, flattened.
1277
- //
1278
- // A multi-argument call arrives from the func-paren grammar as ONE
1279
- // entry holding the comma group, and `neq([3,1,2])` means the same as
1280
- // `neq(3,1,2)`. The group is always a ListVal by the time it reaches
1281
- // here -- the func-paren handler rawToVals every argument (issue #49) --
1282
- // so there is no raw-array case to unwrap. Flattening happens before
1283
- // the settled check, because an unsettled member hiding inside the
1284
- // group would otherwise make the atom look ready.
1285
906
  function atomArgs(atom, args) {
1286
907
  if (('neq' === atom || 'must' === atom) && 1 === args.length &&
1287
908
  true === args[0]?.isList) {
@@ -1289,19 +910,11 @@ function atomArgs(atom, args) {
1289
910
  }
1290
911
  return args;
1291
912
  }
1292
- // The canonical rendering of a residual, in the fixed atom order:
1293
- // kind, lower bound, upper bound, neq, re, length, unique. Taken over the
1294
- // STATE rather than the Val because `length`'s argument is a residual too,
1295
- // and renders by exactly the same rules.
1296
913
  function canonState(s) {
1297
914
  const parts = [];
1298
915
  if (null != s.kind) {
1299
916
  parts.push(s.kind.name.toLowerCase());
1300
917
  }
1301
- // An ORDER atom's argument implies the domain, so it is not spelled
1302
- // out. A SIZING residual carries no order, and there `string` is the
1303
- // only thing saying what is being sized -- drop it and the reparse
1304
- // would admit lists and maps too.
1305
918
  else if ('string' === s.domain &&
1306
919
  null == s.lo && null == s.hi && 0 === s.neqs.length && 0 === s.res.length) {
1307
920
  parts.push('string');
@@ -1319,19 +932,11 @@ function canonState(s) {
1319
932
  parts.push('re(' + r.v.canon + ')');
1320
933
  }
1321
934
  if (null != s.count) {
1322
- // Rendered UNABRIDGED, implied parts and all: `length(3)` canonicalises
1323
- // to `length(integer&min(3)&max(3))` because that IS the residual the
1324
- // count must satisfy, and canon is a normal form (G6 hashes it),
1325
- // not a pretty-printer. Abbreviating would mean a second set of
1326
- // rules for when the implied `integer & min(0)` may be dropped.
1327
935
  parts.push('length(' + canonState(s.count) + ')');
1328
936
  }
1329
937
  if (s.uniq) {
1330
938
  parts.push('unique()');
1331
939
  }
1332
- // After the bare atom, and sorted: canon is a normal form, so two
1333
- // documents writing the same keys in different orders must render
1334
- // the same string.
1335
940
  for (const key of s.uniqBy) {
1336
941
  parts.push('unique(' + JSON.stringify(key) + ')');
1337
942
  }
@@ -1344,15 +949,6 @@ function canonState(s) {
1344
949
  }
1345
950
  return parts.join('&');
1346
951
  }
1347
- // SUBSUMPTION over two residuals (G3, the query built on the table in
1348
- // docs/reference-language.md "Subsumption"): does every value `s`
1349
- // admits pass `g` too? Implemented here because the compare machinery
1350
- // (cmpVal, sameScalar, the recursive count state) is this module's.
1351
- //
1352
- // Three-valued: true / false / 'undecided'. `must` on the GENERAL side
1353
- // is undecided by construction (a Band B predicate is opaque — G3 maps
1354
- // the table's "never" to the query's honest sub_evaluate_only); every
1355
- // other approximation folds toward false, the safe direction.
1356
952
  function constraintStateSubsumes(g, s) {
1357
953
  // A Band B predicate on the general side makes its admitted set
1358
954
  // unknowable; an extra `must` on the SPECIFIC side only narrows it
@@ -1407,11 +1003,6 @@ function constraintStateSubsumes(g, s) {
1407
1003
  return false;
1408
1004
  }
1409
1005
  }
1410
- // `unique()` subsumes only itself on that axis: a general uniqueness
1411
- // demand admits no container the unconstrained specific also admits.
1412
- // ... and a general `unique(k)` needs the same key on the specific
1413
- // side: distinctness on `port` says nothing about distinctness on
1414
- // `name`.
1415
1006
  if (g.uniqBy.some((k) => !s.uniqBy.includes(k))) {
1416
1007
  return false;
1417
1008
  }
@@ -1440,18 +1031,11 @@ function constraintAdmitsScalar(g, scalar) {
1440
1031
  if (g.uniq || 0 < g.uniqBy.length) {
1441
1032
  return false;
1442
1033
  }
1443
- // A count residual admits by LENGTH, which is the meet's business;
1444
- // the query answers false (the safe direction) rather than
1445
- // reimplementing the sizing walk here.
1446
1034
  if (null != g.count) {
1447
1035
  return false;
1448
1036
  }
1449
1037
  return stateAdmits(g, scalar);
1450
1038
  }
1451
- // Does this residual's ORDER and MEMBERSHIP part admit the scalar? The
1452
- // sizing atoms are deliberately not consulted: `admit` applies them to
1453
- // the peer's length, and the count check applies this same function to
1454
- // the count.
1455
1039
  function stateAdmits(s, peer) {
1456
1040
  const domainOf = numericLeaf(peer) ? 'number' :
1457
1041
  stringishLeaf(peer) ? 'string' : undefined;
@@ -1488,10 +1072,6 @@ function stateAdmits(s, peer) {
1488
1072
  return false;
1489
1073
  }
1490
1074
  }
1491
- // Every accumulated pattern must match: the meet of two `re` atoms
1492
- // is conjunction, and matching is UNANCHORED in both engines
1493
- // (JS RegExp.test, Go regexp.MatchString), so `re("el")` admits
1494
- // "hello". Anchor with ^ and $ to mean the whole string.
1495
1075
  for (const r of s.res) {
1496
1076
  if (!r.re.test(peer.peg)) {
1497
1077
  return false;
@@ -1499,13 +1079,7 @@ function stateAdmits(s, peer) {
1499
1079
  }
1500
1080
  return true;
1501
1081
  }
1502
- // The eager emptiness rules. Each is EXACT -- it reports empty only
1503
- // where no value could satisfy the residual -- so the algebra stays
1504
- // sound; the incompleteness it accepts is documented in
1505
- // docs/reference-language.md, "Emptiness".
1506
1082
  function stateEmpty(s) {
1507
- // Two disagreeing kind narrowings inside a length argument, recorded by
1508
- // meetCount because that meet has no ctx to fail through.
1509
1083
  if (s.clash) {
1510
1084
  return true;
1511
1085
  }
@@ -1539,10 +1113,6 @@ function stateEmpty(s) {
1539
1113
  }
1540
1114
  }
1541
1115
  }
1542
- // Point deletion under a narrowed leaf: a closed point interval
1543
- // whose single value of the narrowed leaf is excluded is empty
1544
- // (integer & min(3) & max(3) & neq(3)). Without a narrowing the
1545
- // point survives in the other leaves.
1546
1116
  if (null != s.kind && null != s.lo && null != s.hi &&
1547
1117
  !s.lo.open && !s.hi.open &&
1548
1118
  0 === cmpVal(d, s.lo.v, s.hi.v)) {
@@ -1552,10 +1122,6 @@ function stateEmpty(s) {
1552
1122
  }
1553
1123
  }
1554
1124
  }
1555
- // Sizing over the number domain: a number has neither a length nor
1556
- // members, so `integer & length(3)` and `min(2) & unique()` admit
1557
- // nothing. Uniqueness over the string domain is empty for the same
1558
- // reason -- a string's members are not values the algebra compares.
1559
1125
  if ('number' === d && (null != s.count || s.uniq ||
1560
1126
  0 < s.uniqBy.length)) {
1561
1127
  return true;
@@ -1570,10 +1136,6 @@ function stateEmpty(s) {
1570
1136
  }
1571
1137
  return false;
1572
1138
  }
1573
- // The base every `length` argument meets: a count is a non-negative
1574
- // integer, whatever else the argument says (docs/reference-language.md,
1575
- // "`length` semantics" -- `length(c)` is empty iff `c & integer & min(0)`
1576
- // is).
1577
1139
  function countBase() {
1578
1140
  return {
1579
1141
  domain: 'number',
@@ -1592,12 +1154,6 @@ function countBase() {
1592
1154
  function countVal(n) {
1593
1155
  return new IntegerVal_1.IntegerVal({ peg: n });
1594
1156
  }
1595
- // The pure meet of two count residuals. Both are number-domain and
1596
- // carry no pattern or sizing atom of their own, so the merge is the
1597
- // interval/exclusion part alone. A kind disagreement becomes a `clash`
1598
- // rather than an error: this meet runs at construction, where there is
1599
- // no AontuContext to raise through, and an empty residual carries the
1600
- // same news to `unify`.
1601
1157
  function meetCount(a, b) {
1602
1158
  return {
1603
1159
  domain: 'number',
@@ -1615,18 +1171,6 @@ function meetCount(a, b) {
1615
1171
  (null != a.kind && null != b.kind && a.kind !== b.kind),
1616
1172
  };
1617
1173
  }
1618
- // Read a WRITTEN `length` argument as a count residual, or undefined when
1619
- // it is not one. Accepted: an integer literal (an exact count), a
1620
- // numeric kind, a Band A residual over the number domain, and any
1621
- // conjunct of those. A conjunct never reaches here any more: an
1622
- // unsettled argument is held as `pending` and folded before the count
1623
- // reads it (G1 phase 4), so `length(min(2)&max(5))` arrives as the
1624
- // single residual it folds to.
1625
- //
1626
- // Anything else is refused rather than deferred. A reference or an
1627
- // expression would have to residuate, and the sizing atoms do not
1628
- // residuate on their ARGUMENT -- only on the peer whose members are
1629
- // still settling.
1630
1174
  function countArgState(arg) {
1631
1175
  if (numericLeaf(arg)) {
1632
1176
  return {
@@ -1673,18 +1217,7 @@ function countArgState(arg) {
1673
1217
  }
1674
1218
  return undefined;
1675
1219
  }
1676
- // A container is SETTLED when it and every child have converged. Until
1677
- // then the member set can still change — an optional key whose value is
1678
- // a still-resolving reference may yet generate — so a sizing atom must
1679
- // defer rather than decide (docs/reference-language.md, "`length`
1680
- // semantics"). Note that an optional holding a settled-but-ungenerable
1681
- // value, `{x:1,y?:number}`, IS settled: the map converges on the first
1682
- // pass and `y` is simply never emitted.
1683
1220
  function containerSettled(bag) {
1684
- // The bag's OWN done-counter is enough: BagVal.unify sets it from the
1685
- // AND over its children, so an unsettled child already leaves the bag
1686
- // unsettled. Walking the children again would be a second, drifting
1687
- // copy of that rule.
1688
1221
  return true === bag.done;
1689
1222
  }
1690
1223
  // The child kinds `BagVal.gen` will attempt to generate. Anything else
@@ -1695,32 +1228,12 @@ function genable(child) {
1695
1228
  true === child.isList || true === child.isPref ||
1696
1229
  true === child.isRef || true === child.isDisjunct ||
1697
1230
  true === child.isNil ||
1698
- // A settled sizing residue generates through ConjunctVal.gen, so it
1699
- // is a member like any other -- and a `length` that did not count
1700
- // its sibling's `unique` would be the early-fold defect again, one
1701
- // level up.
1702
1231
  undefined !== (0, BagVal_1.sizingResidue)(child);
1703
1232
  }
1704
- // The children a bag would EMIT, mirroring the selection in
1705
- // `BagVal.gen` — type/hide marks skipped, non-generable residue and
1706
- // values that generate nothing dropped, optional keys dropped when
1707
- // they generate empty.
1708
- //
1709
- // It returns the member VALS rather than their generated values,
1710
- // because uniqueness compares canon and a generated value cannot
1711
- // express that distinction: `1` and `1.0` generate the same JSON number
1712
- // and canon differently. Counting uses the same list, so both sizing
1713
- // atoms see exactly one definition of "member".
1714
- //
1715
- // Returns undefined when a REQUIRED child is residue: the container's
1716
- // own `gen` raises there, and that error is the one worth reporting.
1717
1233
  function emittedMembers(bag, ctx) {
1718
1234
  const out = [];
1719
1235
  let entries = (0, utility_1.items)(bag.peg);
1720
1236
  if (bag.isMap) {
1721
- // Code-point order, because the two ports disagree on raw key order
1722
- // — JavaScript hoists integer-like keys, Go keeps insertion order —
1723
- // and a duplicate report must name the same pair in both.
1724
1237
  entries = entries
1725
1238
  .slice()
1726
1239
  .sort((a, b) => (0, keyorder_1.cmpCodePoint)(String(a[0]), String(b[0])));
@@ -1738,10 +1251,6 @@ function emittedMembers(bag, ctx) {
1738
1251
  }
1739
1252
  return undefined;
1740
1253
  }
1741
- // Generation decides in an isolated collect context, so an
1742
- // unresolved inner value neither raises here nor pollutes the
1743
- // caller's errors — the same isolation BagVal.gen uses for an
1744
- // optional child.
1745
1254
  const cval = child.gen(ctx.clone({ err: [], collect: true }));
1746
1255
  if (undefined === cval || (optional && (0, Val_1.empty)(cval))) {
1747
1256
  continue;
@@ -1750,12 +1259,6 @@ function emittedMembers(bag, ctx) {
1750
1259
  }
1751
1260
  return out;
1752
1261
  }
1753
- // Sort accumulated patterns by source in code-point order and drop
1754
- // exact duplicates. Patterns are NEVER simplified or compared for
1755
- // containment: deciding `re("a")` subsumes `re("a|b")` is regex
1756
- // containment, which the algebra deliberately does not do (emptiness
1757
- // stays approximate — sound, incomplete). Two spellings of one language
1758
- // therefore both survive, and both are tested.
1759
1262
  function dedupSortedRes(res) {
1760
1263
  const sorted = [...res].sort((a, b) => (0, numcmp_1.cmpCodePoints)(a.src, b.src));
1761
1264
  const out = [];
@@ -1766,9 +1269,6 @@ function dedupSortedRes(res) {
1766
1269
  }
1767
1270
  return out;
1768
1271
  }
1769
- // The atom classes registered in the parser's funcMap: each is a
1770
- // ConstraintVal that knows its atom name. Constructed by the
1771
- // func-paren handler as `new funcval({peg: args})`.
1772
1272
  class MinConstraintVal extends ConstraintVal {
1773
1273
  constructor(spec, ctx) {
1774
1274
  super({ ...spec, atom: 'min' }, ctx);