aontu 0.62.0 → 0.64.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 (373) hide show
  1. package/README.md +7 -7
  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 +3 -3
  8. package/dist/aontu.js +4 -84
  9. package/dist/aontu.js.map +1 -1
  10. package/dist/aontumodel.d.ts +4 -0
  11. package/dist/aontumodel.js +27 -0
  12. package/dist/aontumodel.js.map +1 -0
  13. package/dist/casing.d.ts +5 -0
  14. package/dist/casing.js +90 -0
  15. package/dist/casing.js.map +1 -0
  16. package/dist/cli.d.ts +2 -2
  17. package/dist/cli.js +228 -935
  18. package/dist/cli.js.map +1 -1
  19. package/dist/ctx.js +0 -48
  20. package/dist/ctx.js.map +1 -1
  21. package/dist/diff.js +0 -32
  22. package/dist/diff.js.map +1 -1
  23. package/dist/err.js +0 -40
  24. package/dist/err.js.map +1 -1
  25. package/dist/escape.js +0 -45
  26. package/dist/escape.js.map +1 -1
  27. package/dist/exactjson.d.ts +0 -35
  28. package/dist/exactjson.js +0 -131
  29. package/dist/exactjson.js.map +1 -1
  30. package/dist/format.js +13 -203
  31. package/dist/format.js.map +1 -1
  32. package/dist/grammar.d.ts +9 -0
  33. package/dist/grammar.js +54 -0
  34. package/dist/grammar.js.map +1 -0
  35. package/dist/graph.js +0 -26
  36. package/dist/graph.js.map +1 -1
  37. package/dist/hcanon.js +0 -82
  38. package/dist/hcanon.js.map +1 -1
  39. package/dist/helpdoc.js +2 -2
  40. package/dist/helpdoc.js.map +1 -1
  41. package/dist/hints.d.ts +0 -6
  42. package/dist/hints.js +57 -55
  43. package/dist/hints.js.map +1 -1
  44. package/dist/jsonschema.js +0 -114
  45. package/dist/jsonschema.js.map +1 -1
  46. package/dist/keyorder.d.ts +0 -7
  47. package/dist/keyorder.js +0 -41
  48. package/dist/keyorder.js.map +1 -1
  49. package/dist/lang.js +17 -915
  50. package/dist/lang.js.map +1 -1
  51. package/dist/lsp-server.js +0 -16
  52. package/dist/lsp-server.js.map +1 -1
  53. package/dist/lsp.d.ts +1 -1
  54. package/dist/lsp.js +12 -159
  55. package/dist/lsp.js.map +1 -1
  56. package/dist/mcp-server.js +0 -26
  57. package/dist/mcp-server.js.map +1 -1
  58. package/dist/mcp.js +0 -149
  59. package/dist/mcp.js.map +1 -1
  60. package/dist/mod-tool.js +16 -131
  61. package/dist/mod-tool.js.map +1 -1
  62. package/dist/mod.js +0 -162
  63. package/dist/mod.js.map +1 -1
  64. package/dist/patch.js +0 -217
  65. package/dist/patch.js.map +1 -1
  66. package/dist/profile.d.ts +9 -0
  67. package/dist/profile.js +28 -0
  68. package/dist/profile.js.map +1 -0
  69. package/dist/provenance.js +0 -140
  70. package/dist/provenance.js.map +1 -1
  71. package/dist/query.js +0 -75
  72. package/dist/query.js.map +1 -1
  73. package/dist/reach.js +0 -43
  74. package/dist/reach.js.map +1 -1
  75. package/dist/relation.js +0 -61
  76. package/dist/relation.js.map +1 -1
  77. package/dist/report-sarif.d.ts +0 -11
  78. package/dist/report-sarif.js +0 -28
  79. package/dist/report-sarif.js.map +1 -1
  80. package/dist/sig.js +0 -35
  81. package/dist/sig.js.map +1 -1
  82. package/dist/sigdecl.js +1 -1
  83. package/dist/sigdecl.js.map +1 -1
  84. package/dist/siggate.js +0 -4
  85. package/dist/siggate.js.map +1 -1
  86. package/dist/site.js +3 -29
  87. package/dist/site.js.map +1 -1
  88. package/dist/subsume.d.ts +0 -10
  89. package/dist/subsume.js +0 -137
  90. package/dist/subsume.js.map +1 -1
  91. package/dist/template.d.ts +2 -1
  92. package/dist/template.js +58 -138
  93. package/dist/template.js.map +1 -1
  94. package/dist/trace.d.ts +21 -0
  95. package/dist/trace.js +107 -0
  96. package/dist/trace.js.map +1 -0
  97. package/dist/trim.js +0 -41
  98. package/dist/trim.js.map +1 -1
  99. package/dist/tsconfig.tsbuildinfo +1 -1
  100. package/dist/type.js.map +1 -1
  101. package/dist/unify.js +13 -248
  102. package/dist/unify.js.map +1 -1
  103. package/dist/utility.js +0 -22
  104. package/dist/utility.js.map +1 -1
  105. package/dist/val/AbnfFuncVal.d.ts +18 -0
  106. package/dist/val/AbnfFuncVal.js +132 -0
  107. package/dist/val/AbnfFuncVal.js.map +1 -0
  108. package/dist/val/AbsentVal.d.ts +11 -0
  109. package/dist/val/AbsentVal.js +30 -0
  110. package/dist/val/AbsentVal.js.map +1 -0
  111. package/dist/val/AggFuncVal.d.ts +10 -1
  112. package/dist/val/AggFuncVal.js +104 -116
  113. package/dist/val/AggFuncVal.js.map +1 -1
  114. package/dist/val/ArithFuncVal.js +0 -12
  115. package/dist/val/ArithFuncVal.js.map +1 -1
  116. package/dist/val/BagVal.js +1 -78
  117. package/dist/val/BagVal.js.map +1 -1
  118. package/dist/val/BigDecimalVal.js +0 -16
  119. package/dist/val/BigDecimalVal.js.map +1 -1
  120. package/dist/val/BigIntegerVal.js +0 -16
  121. package/dist/val/BigIntegerVal.js.map +1 -1
  122. package/dist/val/CloseFuncVal.js +0 -9
  123. package/dist/val/CloseFuncVal.js.map +1 -1
  124. package/dist/val/CmpFuncVal.d.ts +2 -0
  125. package/dist/val/CmpFuncVal.js +49 -72
  126. package/dist/val/CmpFuncVal.js.map +1 -1
  127. package/dist/val/ConjunctVal.js +0 -29
  128. package/dist/val/ConjunctVal.js.map +1 -1
  129. package/dist/val/ConstraintVal.js +0 -500
  130. package/dist/val/ConstraintVal.js.map +1 -1
  131. package/dist/val/ContainerKindVal.js +0 -2
  132. package/dist/val/ContainerKindVal.js.map +1 -1
  133. package/dist/val/CopyFuncVal.js +0 -3
  134. package/dist/val/CopyFuncVal.js.map +1 -1
  135. package/dist/val/Decimal.js +0 -179
  136. package/dist/val/Decimal.js.map +1 -1
  137. package/dist/val/DeprecateFuncVal.js.map +1 -1
  138. package/dist/val/DisjunctVal.js +0 -152
  139. package/dist/val/DisjunctVal.js.map +1 -1
  140. package/dist/val/EachFuncVal.js +0 -3
  141. package/dist/val/EachFuncVal.js.map +1 -1
  142. package/dist/val/EmitFuncVal.d.ts +1 -1
  143. package/dist/val/EmitFuncVal.js +6 -119
  144. package/dist/val/EmitFuncVal.js.map +1 -1
  145. package/dist/val/ExpectVal.js +0 -62
  146. package/dist/val/ExpectVal.js.map +1 -1
  147. package/dist/val/FilterFuncVal.js +0 -25
  148. package/dist/val/FilterFuncVal.js.map +1 -1
  149. package/dist/val/FuncBaseVal.d.ts +1 -0
  150. package/dist/val/FuncBaseVal.js +7 -127
  151. package/dist/val/FuncBaseVal.js.map +1 -1
  152. package/dist/val/GraphAtomVal.js +0 -15
  153. package/dist/val/GraphAtomVal.js.map +1 -1
  154. package/dist/val/HideFuncVal.js +0 -13
  155. package/dist/val/HideFuncVal.js.map +1 -1
  156. package/dist/val/IntegerVal.js +0 -61
  157. package/dist/val/IntegerVal.js.map +1 -1
  158. package/dist/val/JunctionVal.js +0 -20
  159. package/dist/val/JunctionVal.js.map +1 -1
  160. package/dist/val/KeyFuncVal.js +0 -46
  161. package/dist/val/KeyFuncVal.js.map +1 -1
  162. package/dist/val/ListVal.js +0 -57
  163. package/dist/val/ListVal.js.map +1 -1
  164. package/dist/val/LowerFuncVal.js +0 -11
  165. package/dist/val/LowerFuncVal.js.map +1 -1
  166. package/dist/val/MapVal.js +0 -151
  167. package/dist/val/MapVal.js.map +1 -1
  168. package/dist/val/MatchFuncVal.js +0 -27
  169. package/dist/val/MatchFuncVal.js.map +1 -1
  170. package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
  171. package/dist/val/MaybeFuncVal.js +50 -0
  172. package/dist/val/MaybeFuncVal.js.map +1 -0
  173. package/dist/val/MoveFuncVal.js +0 -18
  174. package/dist/val/MoveFuncVal.js.map +1 -1
  175. package/dist/val/NilVal.js +0 -60
  176. package/dist/val/NilVal.js.map +1 -1
  177. package/dist/val/NomFuncVal.js +18 -54
  178. package/dist/val/NomFuncVal.js.map +1 -1
  179. package/dist/val/NumberVal.js +0 -15
  180. package/dist/val/NumberVal.js.map +1 -1
  181. package/dist/val/OpBaseVal.d.ts +1 -0
  182. package/dist/val/OpBaseVal.js +3 -15
  183. package/dist/val/OpBaseVal.js.map +1 -1
  184. package/dist/val/PackFuncVal.js +0 -34
  185. package/dist/val/PackFuncVal.js.map +1 -1
  186. package/dist/val/PathFuncVal.js +0 -6
  187. package/dist/val/PathFuncVal.js.map +1 -1
  188. package/dist/val/PathVal.js +0 -41
  189. package/dist/val/PathVal.js.map +1 -1
  190. package/dist/val/PlaceVal.js +0 -25
  191. package/dist/val/PlaceVal.js.map +1 -1
  192. package/dist/val/PlusOpVal.d.ts +1 -7
  193. package/dist/val/PlusOpVal.js +13 -74
  194. package/dist/val/PlusOpVal.js.map +1 -1
  195. package/dist/val/PrefFuncVal.js +0 -1
  196. package/dist/val/PrefFuncVal.js.map +1 -1
  197. package/dist/val/PrefVal.js +0 -167
  198. package/dist/val/PrefVal.js.map +1 -1
  199. package/dist/val/RecurseVal.js +0 -55
  200. package/dist/val/RecurseVal.js.map +1 -1
  201. package/dist/val/RefVal.js +0 -282
  202. package/dist/val/RefVal.js.map +1 -1
  203. package/dist/val/ReferFuncVal.js +3 -232
  204. package/dist/val/ReferFuncVal.js.map +1 -1
  205. package/dist/val/ScalarKindVal.js +0 -49
  206. package/dist/val/ScalarKindVal.js.map +1 -1
  207. package/dist/val/ScalarVal.js +0 -11
  208. package/dist/val/ScalarVal.js.map +1 -1
  209. package/dist/val/StrFuncVal.js +0 -18
  210. package/dist/val/StrFuncVal.js.map +1 -1
  211. package/dist/val/SuperFuncVal.js +0 -32
  212. package/dist/val/SuperFuncVal.js.map +1 -1
  213. package/dist/val/TopVal.js +0 -1
  214. package/dist/val/TopVal.js.map +1 -1
  215. package/dist/val/TranslateFuncVal.js +1 -3
  216. package/dist/val/TranslateFuncVal.js.map +1 -1
  217. package/dist/val/UpperFuncVal.js +0 -11
  218. package/dist/val/UpperFuncVal.js.map +1 -1
  219. package/dist/val/Val.d.ts +1 -0
  220. package/dist/val/Val.js +2 -133
  221. package/dist/val/Val.js.map +1 -1
  222. package/dist/val/VarVal.js +0 -12
  223. package/dist/val/VarVal.js.map +1 -1
  224. package/dist/val/arith.js +0 -37
  225. package/dist/val/arith.js.map +1 -1
  226. package/dist/val/caserange.js +0 -61
  227. package/dist/val/caserange.js.map +1 -1
  228. package/dist/val/members.js +0 -6
  229. package/dist/val/members.js.map +1 -1
  230. package/dist/val/numcmp.js +0 -11
  231. package/dist/val/numcmp.js.map +1 -1
  232. package/dist/val/numkind.js +0 -145
  233. package/dist/val/numkind.js.map +1 -1
  234. package/dist/val/valutil.js +0 -16
  235. package/dist/val/valutil.js.map +1 -1
  236. package/dist/vet.js +0 -461
  237. package/dist/vet.js.map +1 -1
  238. package/dist/view.js +0 -414
  239. package/dist/view.js.map +1 -1
  240. package/dist/walk.js +0 -41
  241. package/dist/walk.js.map +1 -1
  242. package/grammar/aontu.abnf +8 -6
  243. package/grammar/aontu.gbnf +4 -4
  244. package/grammar/aontu.lark +4 -4
  245. package/grammar/aontu.tmLanguage.json +1 -1
  246. package/package.json +4 -2
  247. package/skill/tasks.md +9 -7
  248. package/src/agentsmd.ts +0 -35
  249. package/src/alias.ts +0 -39
  250. package/src/allow.ts +1 -96
  251. package/src/aontu.ts +4 -116
  252. package/src/aontumodel.ts +26 -0
  253. package/src/casing.ts +95 -0
  254. package/src/cli.ts +258 -1024
  255. package/src/ctx.ts +0 -103
  256. package/src/diff.ts +0 -40
  257. package/src/err.ts +0 -40
  258. package/src/escape.ts +0 -46
  259. package/src/exactjson.ts +0 -131
  260. package/src/format.ts +14 -257
  261. package/src/grammar.ts +72 -0
  262. package/src/graph.ts +0 -61
  263. package/src/hcanon.ts +0 -82
  264. package/src/helpdoc.ts +2 -2
  265. package/src/hints.ts +69 -57
  266. package/src/jsonschema.ts +0 -123
  267. package/src/keyorder.ts +0 -42
  268. package/src/lang.ts +19 -931
  269. package/src/lsp-server.ts +0 -16
  270. package/src/lsp.ts +12 -180
  271. package/src/mcp-server.ts +0 -31
  272. package/src/mcp.ts +0 -169
  273. package/src/mod-tool.ts +18 -159
  274. package/src/mod.ts +0 -178
  275. package/src/patch.ts +0 -232
  276. package/src/profile.ts +42 -0
  277. package/src/provenance.ts +0 -183
  278. package/src/query.ts +0 -84
  279. package/src/reach.ts +0 -53
  280. package/src/relation.ts +0 -84
  281. package/src/report-sarif.ts +0 -48
  282. package/src/sig.ts +0 -35
  283. package/src/sigdecl.ts +1 -1
  284. package/src/siggate.ts +0 -30
  285. package/src/site.ts +3 -29
  286. package/src/subsume.ts +1 -161
  287. package/src/template.ts +69 -140
  288. package/src/trace.ts +157 -0
  289. package/src/trim.ts +0 -53
  290. package/src/type.ts +2 -45
  291. package/src/unify.ts +14 -257
  292. package/src/utility.ts +0 -31
  293. package/src/val/AbnfFuncVal.ts +181 -0
  294. package/src/val/AbsentVal.ts +54 -0
  295. package/src/val/AggFuncVal.ts +152 -188
  296. package/src/val/ArithFuncVal.ts +0 -20
  297. package/src/val/BagVal.ts +1 -78
  298. package/src/val/BigDecimalVal.ts +0 -16
  299. package/src/val/BigIntegerVal.ts +0 -16
  300. package/src/val/CloseFuncVal.ts +0 -9
  301. package/src/val/CmpFuncVal.ts +68 -184
  302. package/src/val/ConjunctVal.ts +0 -33
  303. package/src/val/ConstraintVal.ts +2 -537
  304. package/src/val/ContainerKindVal.ts +0 -18
  305. package/src/val/CopyFuncVal.ts +0 -5
  306. package/src/val/Decimal.ts +1 -185
  307. package/src/val/DeprecateFuncVal.ts +0 -10
  308. package/src/val/DisjunctVal.ts +0 -157
  309. package/src/val/EachFuncVal.ts +0 -40
  310. package/src/val/EmitFuncVal.ts +8 -208
  311. package/src/val/ExpectVal.ts +0 -62
  312. package/src/val/FilterFuncVal.ts +0 -55
  313. package/src/val/FuncBaseVal.ts +9 -130
  314. package/src/val/GraphAtomVal.ts +0 -42
  315. package/src/val/HideFuncVal.ts +0 -15
  316. package/src/val/IntegerVal.ts +0 -61
  317. package/src/val/JunctionVal.ts +0 -20
  318. package/src/val/KeyFuncVal.ts +0 -48
  319. package/src/val/ListVal.ts +0 -59
  320. package/src/val/LowerFuncVal.ts +0 -12
  321. package/src/val/MapVal.ts +0 -151
  322. package/src/val/MatchFuncVal.ts +0 -59
  323. package/src/val/MaybeFuncVal.ts +86 -0
  324. package/src/val/MoveFuncVal.ts +0 -20
  325. package/src/val/NilVal.ts +0 -60
  326. package/src/val/NomFuncVal.ts +10 -99
  327. package/src/val/NumberVal.ts +0 -16
  328. package/src/val/OpBaseVal.ts +4 -17
  329. package/src/val/PackFuncVal.ts +0 -63
  330. package/src/val/PathFuncVal.ts +0 -32
  331. package/src/val/PathVal.ts +0 -66
  332. package/src/val/PlaceVal.ts +0 -45
  333. package/src/val/PlusOpVal.ts +18 -75
  334. package/src/val/PrefFuncVal.ts +0 -1
  335. package/src/val/PrefVal.ts +0 -179
  336. package/src/val/RecurseVal.ts +0 -81
  337. package/src/val/RefVal.ts +1 -285
  338. package/src/val/ReferFuncVal.ts +4 -255
  339. package/src/val/ScalarKindVal.ts +0 -50
  340. package/src/val/ScalarVal.ts +0 -12
  341. package/src/val/StrFuncVal.ts +0 -44
  342. package/src/val/SuperFuncVal.ts +0 -42
  343. package/src/val/TopVal.ts +0 -1
  344. package/src/val/TranslateFuncVal.ts +1 -51
  345. package/src/val/UpperFuncVal.ts +0 -12
  346. package/src/val/Val.ts +3 -192
  347. package/src/val/VarVal.ts +0 -15
  348. package/src/val/arith.ts +0 -92
  349. package/src/val/caserange.ts +0 -62
  350. package/src/val/members.ts +0 -23
  351. package/src/val/numcmp.ts +1 -27
  352. package/src/val/numkind.ts +0 -149
  353. package/src/val/valutil.ts +0 -16
  354. package/src/vet.ts +1 -582
  355. package/src/view.ts +0 -507
  356. package/src/walk.ts +0 -41
  357. package/dist/lower.d.ts +0 -23
  358. package/dist/lower.js +0 -578
  359. package/dist/lower.js.map +0 -1
  360. package/dist/render.d.ts +0 -53
  361. package/dist/render.js +0 -547
  362. package/dist/render.js.map +0 -1
  363. package/dist/std.d.ts +0 -3
  364. package/dist/std.js +0 -672
  365. package/dist/std.js.map +0 -1
  366. package/dist/val/FormFuncVal.js +0 -55
  367. package/dist/val/FormFuncVal.js.map +0 -1
  368. package/dist/val/NamerFuncVal.d.ts +0 -12
  369. package/dist/val/NamerFuncVal.js +0 -176
  370. package/dist/val/NamerFuncVal.js.map +0 -1
  371. package/src/lower.ts +0 -636
  372. package/src/render.ts +0 -732
  373. package/src/std.ts +0 -683
@@ -1,24 +1,5 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
- // CHECKED, TYPED, LINK-SHAPED REFERENCES (G4 phase 2,
4
- // docs/capability-review/g4-identity-relations.md): `refer(t)` is a
5
- // constraint on a string-valued field. The string must be an ENTITY
6
- // ADDRESS, the addressed node must exist in the evaluation, and — when
7
- // `t` is given — `t` is unified INTO the target. The field's own value
8
- // stays the address string: a LINK, not an embedding.
9
- //
10
- // This is the piece a plain reference cannot be. `$.a.b` resolves by
11
- // CLONING its target into place, so `dependsOn: [$.services.auth]`
12
- // generates a full copy of the auth node where the author meant a
13
- // name. `refer` leaves the name and checks it.
14
- //
15
- // Constraint FLOW rather than a check: `refer(t)` does not merely test
16
- // the target against `t`, it unifies `t` into it. Referring to
17
- // something as a Service MAKES it one, and if it cannot be, the
18
- // conflict is an ordinary located error. Check-only semantics would be
19
- // non-monotone — true, then false as the target grows — and the
20
- // lattice guarantee is that more information never falsifies what has
21
- // been observed.
22
3
 
23
4
  import type {
24
5
  Val,
@@ -49,16 +30,9 @@ import { top } from './top'
49
30
  import { propagateMarks, walk } from '../utility'
50
31
 
51
32
 
52
- // A RELATION PREDICATE is still a declared D-1 name
53
- // (docs/design/RELATIONS.0.md §3.2). Entity names are gone with
54
- // ADR-014; predicate names are not -- a relation is a vocabulary term,
55
- // not an address.
56
33
  const PREDICATE_NAME = /^[_a-zA-Z][-_a-zA-Z0-9]*$/
57
34
 
58
35
 
59
- // The tree path an address resolves to from `at` -- the position of
60
- // the link itself -- or undefined when a relative address climbs off
61
- // the top of the tree.
62
36
  export function addressPath(
63
37
  addr: Address, at: (string | number)[]
64
38
  ): string[] | undefined {
@@ -75,10 +49,6 @@ export function addressPath(
75
49
  }
76
50
 
77
51
 
78
- // The node a tree path names, with the parent and key that hold it so
79
- // a type flow can be written back. Pending is not failure: the target
80
- // may be introduced by a later conjunct, include or spread, so `refer`
81
- // residuates exactly as a forward reference does.
82
52
  export function findAt(
83
53
  root: Val | undefined, path: string[]
84
54
  ): { parent?: any, key?: string, val: Val } | undefined {
@@ -104,10 +74,6 @@ export function findAt(
104
74
  }
105
75
 
106
76
 
107
- // concreteFlow is `t` as it enters the target: a copy with the
108
- // type/hide marks cleared at every depth. The clone matters as much as
109
- // the clearing — `t` is shared by every position that refers to the
110
- // same thing, and clearing in place would unmark the schema itself.
111
77
  function concreteFlow(ctx: AontuContext, t: Val): Val {
112
78
  let marked = false
113
79
  walk(t, (_key: string | number | undefined, v: Val) => {
@@ -130,20 +96,9 @@ function concreteFlow(ctx: AontuContext, t: Val): Val {
130
96
  }
131
97
 
132
98
 
133
- // ReferVal is what `refer(t)` RESOLVES to: the residual constraint,
134
- // carrying the type to flow and — once it has met a string — the
135
- // address to flow it into. A separate value from the function for the
136
- // reason every residual is: the function is written once and the
137
- // constraint is met many times, and only the constraint has state
138
- // worth carrying.
139
99
  class ReferVal extends FeatureVal {
140
100
  isRefer = true
141
101
  isGenable = true
142
- // AFTER the plain values (base 99999), BEFORE the sizing atoms
143
- // (LATE_CJO): sibling path values fold together first under the
144
- // prefix rule, and the residual then meets ONE merged address --
145
- // without this, `refer() & path($.a) & path($.a.b)` settled on the
146
- // first path and the second met the finished link too late.
147
102
  cjo = 120000
148
103
 
149
104
  // The type to flow into the target; TOP when `refer()` was written
@@ -156,10 +111,6 @@ class ReferVal extends FeatureVal {
156
111
  // Constraints met while the address was still pending — a kind, a
157
112
  // regex, a preference. They meet the LINK once there is one.
158
113
  held?: Val
159
- // The PREDICATE the produced link belongs to, when this residual was
160
- // minted by `rel()` on a field: the field's key, stamped onto the
161
- // link so the graph reports the edge under a DECLARED relation
162
- // rather than inferring one from the path (RELATIONS.0.md §3.2).
163
114
  relkey?: string
164
115
  // The codes this residual refuses with: refer() keeps its own,
165
116
  // rel()-minted residuals carry rel_address/rel_unresolved.
@@ -175,16 +126,6 @@ class ReferVal extends FeatureVal {
175
126
  this.dc = 0
176
127
  }
177
128
 
178
- // The residual's own state — the type to flow, the address it has
179
- // met, the constraints it holds — TRAVELS with the clone. A spread
180
- // template holds the FUNCTION, so a template never needs this; a
181
- // REFERENCE to a value that already contains a resolved link does
182
- // (`z: {u: refer() & "$.a"}` then `s: $.z`). Without it the
183
- // clone came back as a bare `refer()` — the address silently
184
- // dropped, and the copied link resolving to nothing.
185
- //
186
- // No path-dependence hook, though: a residual is minted at its
187
- // destination, so `key()` inside a template resolves there already.
188
129
  clone(ctx: AontuContext, spec?: ValSpec): Val {
189
130
  const out: any = super.clone(ctx, spec)
190
131
  out.tval = this.tval
@@ -221,20 +162,11 @@ class ReferVal extends FeatureVal {
221
162
  return peer
222
163
  }
223
164
 
224
- // A PATH VALUE is the ADDRESS, when there is not one yet. Only a
225
- // path value can be one (PATHS.0.md, amended): a bare string is
226
- // never a path -- `path("...")` is the one string conversion, and
227
- // it happens at the call, not here. The peg is pre-validated by
228
- // the capture, so no parse can fail.
229
165
  if (undefined === this.addr && true === p.isPath) {
230
166
  const addr = parseAddress(p.peg) as Address
231
167
  return this.with(ctx, { addr, addrsrc: p.peg }, peer)
232
168
  }
233
169
 
234
- // A SECOND path peer refines the address by the prefix rule: the
235
- // longer of the two when one opens the other, exactly as two path
236
- // values meet on their own. Two incomparable addresses are the
237
- // same conflict two unequal scalars are.
238
170
  if (undefined !== this.addr && true === p.isPath) {
239
171
  const merged = prefixMeet(this.addrsrc as string, p.peg)
240
172
  if (undefined === merged) {
@@ -244,24 +176,15 @@ class ReferVal extends FeatureVal {
244
176
  { addr: parseAddress(merged) as Address, addrsrc: merged }, peer)
245
177
  }
246
178
 
247
- // A value that can never BE a path cannot be the address, and no
248
- // later pass can repair it — so this arm refuses rather than
249
- // defers. A bare STRING is in it now (PATHS.0.md, amended):
250
- // `path("...")` is the one conversion, at the call. A KIND or a
251
- // constraint is not in it: `string`, `re("^svc_")` and the like
252
- // are perfectly good constraints on an address, and are held
253
- // below until there is one to apply them to.
254
179
  if ((true === p.isScalar && true !== p.isPath)
255
180
  || true === p.isMap || true === p.isList) {
256
181
  return makeNilErr(ctx, this.addrcode, this, peer, 'refer')
257
182
  }
258
183
 
259
- // HELD: everything else waits for the address. Carried on the
260
- // residual rather than parked in a conjunct, because a conjunct
261
- // rebuilt every pass grows a level every pass; the held constraint
262
- // meets the link the moment the address resolves, so
263
- // `refer() & re("a") & re("b") & path($.z)` still applies both and
264
- // `refer() & string & path($.z)` still passes.
184
+ if (true === p.isFunc) {
185
+ return peer.unify(this, ctx)
186
+ }
187
+
265
188
  return this.with(ctx, {
266
189
  held: null == this.held ? peer : unite(ctx, this.held, peer, 'refer-held'),
267
190
  }, this)
@@ -290,24 +213,6 @@ class ReferVal extends FeatureVal {
290
213
  // resolved string should take.
291
214
  settle(ctx: AontuContext, site: Val): Val {
292
215
  if (undefined === this.addr) {
293
- // DONE while unmet, as `string` and `min(1)` are, and as RelVal
294
- // has been since it was written (see its constructor). An
295
- // ADDRESS-LESS refer has nothing to check yet and nothing to
296
- // refuse: it is its own settled residual, and the meet
297
- // re-activates it the moment a value arrives, because map
298
- // merges build the conjunct regardless.
299
- //
300
- // NOT-DONE here used to be justified as keeping the pass loop
301
- // offering the refer a chance -- but that is the job of the
302
- // OTHER pending branch below, where an address exists and its
303
- // target has not appeared. This branch has no address to
304
- // resolve, so staying not-done bought nothing and cost the
305
- // schema idiom: a `type()` body holding a link never settled,
306
- // so its mark never transferred, so generation could not skip
307
- // the marked subtree and raised `mapval_no_gen` naming the
308
- // definition. `type({p: integer})`, `type({p: path()})` and
309
- // `type({p: min(1)})` all settled; only a link did not
310
- // (aontu-lang/aontu#172, G4 phase 4's recorded cost).
311
216
  this.dc = DONE
312
217
  return this
313
218
  }
@@ -321,13 +226,6 @@ class ReferVal extends FeatureVal {
321
226
  }
322
227
  const found = findAt(ctx?.root, target)
323
228
  if (undefined === found) {
324
- // PENDING, not failed — until the last pass. The target may be
325
- // introduced by a later conjunct, include or spread, so `refer`
326
- // residuates as a forward reference does; but within ONE
327
- // evaluation the document-set is fixed, so existence IS
328
- // decidable, and the final pass is where it is decided. A
329
- // pending refer keeps the tree not-done, so the pass loop always
330
- // reaches that pass when there is one to decide.
331
229
  if (ctx.cc + 1 >= ctx.budget.passes) {
332
230
  return makeNilErr(ctx, this.unresolvedcode, this, undefined, 'refer',
333
231
  { addr: this.addrsrc as string })
@@ -336,58 +234,13 @@ class ReferVal extends FeatureVal {
336
234
  return this
337
235
  }
338
236
 
339
- // THE FLOW. `t` is unified into the target and written back at the
340
- // target's own position — one position, because the tree is the
341
- // namespace and a path names exactly one node.
342
- //
343
- // RE-ENTRANT ONLY ONCE PER TARGET (use-cases/BUGS.md §19). Uniting
344
- // the target drives the target's OWN subtree, and if the target
345
- // links back — `a` typed-refers `b`, `b` typed-refers `a`, the
346
- // shape every inverse pair has — that drives this target again,
347
- // and the two flow into each other until the depth budget or the
348
- // host stack ends it. `unify_cycle` on a model whose meet plainly
349
- // converges: `{k:1}` meeting `{k:1}` is a fixpoint, and the
350
- // evaluator never got far enough to notice.
351
- //
352
- // The guard is the set of paths a flow is currently inside, on the
353
- // context. A flow that would re-enter one has its MEET skipped:
354
- // the outer flow it is nested in is already uniting that node, and
355
- // re-entering is what runs the host stack out.
356
- //
357
- // ITS RECORD IS STILL WRITTEN. The skip used to take the record
358
- // with it, on the reasoning that "the same information arrives by
359
- // the same channel one frame up" -- true of the outer flow's TYPE,
360
- // and false of a nested flow carrying a DIFFERENT one. The outer
361
- // flow delivers only its own type, the residual is consumed into a
362
- // settled link in the same breath, and nothing re-offers it: the
363
- // nested type was lost for good, and which of two flows was the
364
- // nested one depended on which link the evaluator happened to
365
- // reach first. A layering rule declared on one field and reached
366
- // through another module's mirror therefore held in one
367
- // declaration order and not in the other (BUGS.md 69).
368
- //
369
- // Recording it DEFERS the meet to `applyFlows`, which runs at the
370
- // top of the tree with no flow in flight and so cannot re-enter
371
- // anything -- the channel this record already exists to be.
372
237
  const guard = target.join('.')
373
238
  // Seeded on the unify root (ts/src/unify.ts): a `??=` here would
374
239
  // make a fresh set on whichever descended context asked first.
375
240
  const flowing: Set<string> = (ctx as any)._referflow ?? new Set<string>()
376
241
  if (!this.tval.isTop) {
377
- // The flowed type is CONCRETE at the target: a schema flowing
378
- // into a value must not make the value a schema. Same reasoning
379
- // as a reference's clone clearing marks — `refer($.std.Service)`
380
- // says the target IS a Service, not that it is the definition
381
- // of one — and without it the target silently stopped
382
- // generating.
383
242
  const flow = concreteFlow(ctx, this.tval)
384
243
 
385
- // THE RECORD, keyed by the target's path, replayed onto every
386
- // later pass by applyFlows in ts/src/unify.ts. A pass rebuilds
387
- // subtrees, so the write below does not survive one when the
388
- // link sits inside its own target or two nodes link at each
389
- // other; the record is what makes the flow reach the result
390
- // rather than the tree it was computed from.
391
244
  const flows: Map<string, Val> = (ctx as any).referflows ??
392
245
  new Map<string, Val>()
393
246
  const key = target.join('\x00')
@@ -402,18 +255,6 @@ class ReferVal extends FeatureVal {
402
255
  if (true === (merged as any).isNil) {
403
256
  return merged
404
257
  }
405
- // The write into THIS pass's view, so the rest of the pass
406
- // sees it. findAt refuses the empty path, so a resolved
407
- // target always has a parent holding it.
408
- //
409
- // NOT FROM INSIDE A TRIAL. A disjunction member is a
410
- // HYPOTHESIS, and writing its flow into the live tree
411
- // asserts the member's type on another node before the
412
- // member is known to survive. The `unite` above still runs:
413
- // its nil is how a member legitimately fails. Only the
414
- // COMMIT waits, and the surviving member's flow reaches the
415
- // tree on the next pass, from the record DisjunctVal stages
416
- // and merges for survivors alone.
417
258
  if (true !== (ctx as any)._trialMode) {
418
259
  found.parent.peg[found.key as string] = merged
419
260
  }
@@ -424,24 +265,8 @@ class ReferVal extends FeatureVal {
424
265
  }
425
266
  }
426
267
 
427
- // The value IS the address, as a PATH VALUE (ADR-016): a link,
428
- // not an embedding -- and re-stating or refining the address
429
- // still meets it, which a string link could not do under the
430
- // strict rules.
431
268
  const out: any = new PathVal({ peg: this.addrsrc as string }, ctx)
432
269
  out.dc = DONE
433
- // STAMPED as a link (G4 phase 3): the value is the address string,
434
- // so without this nothing downstream could tell a checked link from
435
- // a literal that happens to look like one. The edge set is exactly
436
- // the set of these stamps. A rel()-minted link also carries its
437
- // PREDICATE (the rel field's key), so the graph reports a declared
438
- // relation rather than inferring one from the path.
439
- //
440
- // The stamp is the RESOLVED path, not the written one: a relative
441
- // address means a different node from each position it is written
442
- // at, and an edge set whose far ends were spellings rather than
443
- // nodes could not be traversed. The VALUE stays what the author
444
- // wrote --- the link is what it says, the edge is where it goes.
445
270
  out.link = '$.' + target.join('.')
446
271
  if (undefined !== this.relkey) {
447
272
  out.relkey = this.relkey
@@ -456,23 +281,12 @@ class ReferVal extends FeatureVal {
456
281
  const t = this.tval.isTop ? '' : this.tval.canon
457
282
  const call = 'refer(' + t + ')' +
458
283
  (null == this.held ? '' : '&' + this.held.canon)
459
- // The address renders as the path call: a bare string address no
460
- // longer reparses (PATHS.0.md, amended), and canon must.
461
284
  return undefined === this.addrsrc
462
285
  ? call : call + '&path(' + this.addrsrc + ')'
463
286
  }
464
287
  }
465
288
 
466
289
 
467
- // RelVal is what `rel(t?)` RESOLVES to (RELATIONS.0.md §3.2): the
468
- // relation constraint, sited on the FIELD the way the sizing atoms sit
469
- // on containers. Its value may be one address, a LIST of addresses, or
470
- // a MAP whose string leaves are addresses -- the container shapes are
471
- // rewritten leaf by leaf through the refer machinery, so pending
472
- // resolution, type flow and link stamping are the one battle-tested
473
- // path, and the data side stays plain strings. The PREDICATE of every
474
- // edge produced is the key the rel() sits on -- declared once, in the
475
- // schema, never inferred from the path.
476
290
  class RelVal extends FeatureVal {
477
291
  isRel = true
478
292
  isGenable = true
@@ -489,15 +303,6 @@ class RelVal extends FeatureVal {
489
303
  super(spec, ctx)
490
304
  this.tval = (spec as any).tval ?? top()
491
305
  this.held = (spec as any).held
492
- // DONE while unmet, deliberately: a type() body holding a rel()
493
- // must SETTLE, or the schema idiom (`dependsOn?: rel($.T)` inside
494
- // a vocabulary) leaves the type unresolved and every reference to
495
- // it deferring forever. This was the property refer() lacked --
496
- // G4 phase 4 recorded the cost -- until 2026-09-07, when an
497
- // address-less refer was given it too (#172); the two now settle
498
- // by the same rule, which is what the shared reasoning below is. An unmet rel is its own settled residual,
499
- // like `min(1)`; the meet re-activates it whenever a value
500
- // arrives, because map merges build the conjunct regardless.
501
306
  this.dc = DONE
502
307
  }
503
308
 
@@ -508,32 +313,12 @@ class RelVal extends FeatureVal {
508
313
  return out
509
314
  }
510
315
 
511
- // The predicate: the last segment of the field path the constraint
512
- // is being APPLIED at -- when that segment is a D-1 NAME. A relation
513
- // predicate is a declared name (RELATIONS.0.md §3.2), so a list
514
- // index or a key outside the name grammar produces unlabelled
515
- // links, and the graph falls back to its old inference. The D-1
516
- // test is also what keeps the two ports' edges identical: a list
517
- // index is a number here and a string in Go.
518
- //
519
- // THE PATH COMES FROM THE CONTEXT, not from `this.path`. The val's
520
- // own path records where this constraint was CLONED FROM, and the
521
- // two part company the moment a second document merges into an
522
- // entity: the field's constraint is then driven at the ENTITY, and
523
- // `this.path` names the entity while the context names the field.
524
- // The predicate became the entity's own key, every link under it
525
- // minted an edge starting one level too high, and `inverse(n)`
526
- // reported a mirror that was written as missing.
527
316
  fieldkey(ctx: AontuContext): string | undefined {
528
317
  const path: any[] = (ctx as any).path
529
318
  const seg = path[path.length - 1]
530
319
  return 'string' === typeof seg && PREDICATE_NAME.test(seg) ? seg : undefined
531
320
  }
532
321
 
533
- // One leaf's residual: the refer machinery carrying rel's codes,
534
- // predicate and type. The predicate is passed IN, because the field
535
- // it names is decided where the rewrite starts and must not be
536
- // re-read on the way down (see `rewriteUnder`).
537
322
  leafRefer(ctx: AontuContext, relkey: string | undefined): ReferVal {
538
323
  const rv = new ReferVal({ tval: this.tval } as any, ctx)
539
324
  rv.addrcode = 'rel_address'
@@ -544,20 +329,10 @@ class RelVal extends FeatureVal {
544
329
  return rv
545
330
  }
546
331
 
547
- // The container, every string leaf wrapped as a link. Nested
548
- // containers descend; a leaf already STAMPED as a link is left
549
- // alone, which is what makes a second application (a template
550
- // re-applied, a later pass) a no-op.
551
332
  rewrite(ctx: AontuContext, container: any): Val {
552
333
  return this.rewriteUnder(ctx, container, this.fieldkey(ctx))
553
334
  }
554
335
 
555
- // The rewrite proper, carrying the predicate decided at the field.
556
- // It is decided ONCE, at the top: a map-valued relation
557
- // (`dependsOn: {primary: [...]}`) descends through the inner label
558
- // and must still report `dependsOn`, which is the whole reason a
559
- // link carries a declared predicate rather than letting the graph
560
- // infer one from its position.
561
336
  rewriteUnder(
562
337
  ctx: AontuContext, container: any, relkey: string | undefined
563
338
  ): Val {
@@ -581,10 +356,6 @@ class RelVal extends FeatureVal {
581
356
  else if (undefined === child.link) {
582
357
  let leaf = unite(ctx.descend('' + k), this.leafRefer(ctx, relkey),
583
358
  child, 'rel-leaf')
584
- // The held constraints apply PER LEAF: a re() on the relation
585
- // constrains every address, never the container that holds
586
- // them (found by the service catalog, whose re("^svc_") met
587
- // the whole list and refused it).
588
359
  if (null != this.held) {
589
360
  leaf = unite(ctx.descend('' + k), leaf, this.held, 'rel-held')
590
361
  }
@@ -592,26 +363,9 @@ class RelVal extends FeatureVal {
592
363
  pending = pending || true !== leaf.done
593
364
  }
594
365
  }
595
- // The rewrite holds its PENDING leaves open (an address whose
596
- // entity a later statement declares), so the pass loop keeps
597
- // driving the container until every link settles. A rewrite that
598
- // minted NOTHING pending -- every leaf already linked or settled
599
- // in place -- keeps the clone's doneness: re-applying a template
600
- // over a settled value must converge in the same pass, or the
601
- // enclosing bags reopen forever (the service catalog, where the
602
- // entity merge drops the spread stamp each pass).
603
366
  if (pending) {
604
367
  out.dc = 0
605
368
  }
606
- // Elements that arrive AFTER this rewrite -- another statement of
607
- // the list, a patch position of the entity -- must convert too, so
608
- // the rewrite installs its own leaf constraint as the container's
609
- // ELEMENT SPREAD, exactly the machinery the old per-element
610
- // `[&: refer()]` idiom used. Only on a FLAT address container (a
611
- // labelled map's sub-containers get their own spread from the
612
- // recursion above; a leaf template meeting a map child would
613
- // refuse it), and only where no spread already stands: a schema's
614
- // own template is not this rewrite's to clobber.
615
369
  if (!nested && null == (out as any).spread.cj) {
616
370
  let tmpl: Val = this.leafRefer(ctx, relkey)
617
371
  if (null != this.held) {
@@ -638,11 +392,6 @@ class RelVal extends FeatureVal {
638
392
  return out
639
393
  }
640
394
 
641
- // No null/top/nil arms: unite's dispatch ladder absorbs those
642
- // peers before any Val's own unify is consulted (a null or top
643
- // peer returns this side; a nil peer returns the nil), and unite
644
- // is the only entrance -- the container hand-offs pass the
645
- // container itself.
646
395
 
647
396
  // ONE ADDRESS: the scalar-valued field, refer's own shape. A path
648
397
  // value only -- a bare string is never an address (PATHS.0.md,
@@ -20,33 +20,9 @@ import {
20
20
 
21
21
  import { makeNilErr, AontuError } from '../err'
22
22
 
23
- // import { BaseVal } from './BaseVal'
24
23
  import { FeatureVal } from './FeatureVal'
25
24
 
26
25
 
27
- // Kind markers.
28
- //
29
- // A ScalarKindVal's canon is its marker's constructor name, lowercased,
30
- // so these class names are load-bearing language surface: `Integer` is
31
- // the keyword `integer`, `Float` is the keyword `float`.
32
- //
33
- // The numeric part of the lattice is a pure supertype over disjoint
34
- // leaves:
35
- //
36
- // number (the global Number constructor)
37
- // |- integer Integer int64-window exact
38
- // |- float Float IEEE-754 binary64
39
- // |- biginteger BigInteger exact, opt-in via 0d
40
- // |- bigdecimal BigDecimal exact, opt-in via 0d
41
- //
42
- // The global `Number` constructor is the marker for the SUPERTYPE only:
43
- // no concrete ScalarVal ever carries it. A binary64 value is FLOAT kind
44
- // (NumberVal is the binary64 leaf; the class name is historical).
45
- //
46
- // A ScalarKindVal for `number` matches a concrete value of any numeric
47
- // leaf, and meeting it with a leaf yields that leaf. Two distinct leaves
48
- // are disjoint sets with no common lower bound, so they do not unify.
49
-
50
26
  // A ScalarKind for the int64-window exact integers.
51
27
  class Integer { }
52
28
 
@@ -57,28 +33,14 @@ class Float { }
57
33
  // literal with no fraction and no exponent.
58
34
  class BigInteger { }
59
35
 
60
- // A ScalarKind for the exact base-10 decimals, reached only by a `0d`
61
- // literal carrying a `.` or an exponent.
62
36
  class BigDecimal { }
63
37
 
64
38
  // A ScalarKind for null.
65
39
  class Null { }
66
40
 
67
- // A ScalarKind for tree addresses (docs/design/PATHS.0.md): the value
68
- // a `path(p)` call captures. Sits UNDER string -- an address is a
69
- // string with more structure, so string-kinded schemas over address
70
- // fields keep admitting -- while staying a distinct leaf, so a plain
71
- // string literal and a path value refuse each other exactly as the
72
- // number tower's leaves do. Reached only by the `path()` builtin, as
73
- // the exact numeric leaves are reached only by `0d`.
74
41
  class Path { }
75
42
 
76
43
 
77
- // The immediate lattice parent of each kind marker. A marker absent from
78
- // this table sits directly under top (string, boolean, null -- and
79
- // `number` itself, which is the root of the numeric family).
80
- //
81
- // Adding a leaf is one row.
82
44
  const KIND_PARENT = new Map<any, any>([
83
45
  [Integer, Number],
84
46
  [Float, Number],
@@ -121,7 +83,6 @@ type ScalarConstructor =
121
83
  (typeof Integer.constructor)
122
84
 
123
85
 
124
- // class ScalarKindVal extends BaseVal {
125
86
  class ScalarKindVal extends FeatureVal {
126
87
  isScalarKind = true
127
88
 
@@ -156,9 +117,6 @@ class ScalarKindVal extends FeatureVal {
156
117
  else if (peerIsScalarVal) {
157
118
  let peerKind = (peer as any).kind
158
119
 
159
- // A kind admits a concrete value of that kind, or of any kind
160
- // below it: `float & 1.5` is 1.5, and `number & 1` is 1 because
161
- // integer sits under number.
162
120
  if (kindSubsumes(this.peg, peerKind)) {
163
121
  out = peer
164
122
  }
@@ -167,9 +125,6 @@ class ScalarKindVal extends FeatureVal {
167
125
  }
168
126
  }
169
127
  else if (peerIsScalarKind) {
170
- // The meet of two kinds is the narrower one when they are
171
- // comparable. Distinct leaves (float & integer) are disjoint sets
172
- // of values, so they have no common lower bound and fail.
173
128
  if (this.peg === peer.peg) {
174
129
  out = this
175
130
  }
@@ -189,7 +144,6 @@ class ScalarKindVal extends FeatureVal {
189
144
 
190
145
  ctx.explain && explainClose(te, out)
191
146
 
192
- // console.log('SCALARKINDVAL', this.canon.peer.canon, '->', out.canon)
193
147
  return out
194
148
  }
195
149
 
@@ -200,10 +154,6 @@ class ScalarKindVal extends FeatureVal {
200
154
  }
201
155
 
202
156
 
203
- // The super() ladder: a leaf kind lifts to its parent kind
204
- // (super(integer) -> number, super(float) -> number), and a kind with
205
- // no parent lifts to top (super(number) -> top). A concrete value
206
- // lifts to its own leaf via ScalarVal.superior.
207
157
  superior(): Val {
208
158
  const parent = kindParent(this.peg)
209
159
  return null == parent ?
@@ -23,7 +23,6 @@ import { Val } from './Val'
23
23
  import { ScalarKindVal } from './ScalarKindVal'
24
24
 
25
25
 
26
-
27
26
  class ScalarVal extends Val {
28
27
  kind: any
29
28
 
@@ -71,7 +70,6 @@ class ScalarVal extends Val {
71
70
  ((peer as any).kind === this.kind ? 'value' : 'kind'), this, peer)
72
71
  }
73
72
 
74
- // console.log('SCALAR', this.canon, peer.canon, '->', out.canon)
75
73
 
76
74
  explainClose(te, out)
77
75
 
@@ -87,22 +85,12 @@ class ScalarVal extends Val {
87
85
 
88
86
 
89
87
  same(peer: any): boolean {
90
- // Two concrete scalars are the same only when KIND and value both
91
- // match. Comparing peg alone is a leftover from before integer and
92
- // number were distinct kinds; without the kind test `1|1.0` would
93
- // collapse to a single alternative and `(1|1.0) & 1.0` could pick
94
- // the integer.
95
88
  return peer?.isScalar ?
96
89
  (peer.kind === this.kind && this.samePeg(peer.peg)) :
97
90
  super.same(peer)
98
91
  }
99
92
 
100
93
 
101
- // Value comparison for this leaf's peg (D2: identity is kind AND
102
- // value, NEVER the identity of the object holding the value). `===` is
103
- // right for every peg that is a primitive -- including a bigint, where
104
- // two separately built copies of the same number compare equal -- and
105
- // wrong for a peg that is an object, so BigDecimalVal overrides it.
106
94
  samePeg(peg: any): boolean {
107
95
  return peg === this.peg
108
96
  }
@@ -1,31 +1,5 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
- // THE STRING BUILTINS the rule layer needs (G9 phase 6,
4
- // docs/design/TEMPLATE.0.md D4 and D5).
5
- //
6
- // esc(s, variant?) make `s` safe inside a literal
7
- // usc(s, variant?) read it back out
8
- // rep(s, pattern, sub) replace every match
9
- // split(s, sep) a list of fields
10
- //
11
- // All four are ORDINARY string builtins beside `upper` and `lower`:
12
- // they return values, compose with `+`, and know nothing about
13
- // generation, which is why they can land before the renderer does.
14
- // They are not staged -- a scalar argument that is `done` is done.
15
- //
16
- // WHY `rep` AND `split` CARRY THEIR OWN MATCHING LOOPS. The host
17
- // engines disagree about every part of this. `String.replace` reads
18
- // `$1x` as group 1 then `x` while Go's Expand reads the name `1x`;
19
- // `String.split` INSERTS a pattern's capture groups into the result
20
- // and Go's Split does not; and the two disagree about empty matches at
21
- // the ends. So the loops below are written once, in the semantics Go's
22
- // regexp package defines, and go/strfunc.go is their twin -- the same
23
- // discipline ADR-003 applies to the pattern language itself.
24
- //
25
- // THE PATTERN IS THE PORTABLE SUBSET `re()` TAKES, normalised before
26
- // either engine compiles it. One regexp language in the document, not
27
- // two -- and the subset's linear-time guarantee matters more here than
28
- // in a constraint, because a generator runs this over model data.
29
3
 
30
4
  import type {
31
5
  Val,
@@ -63,11 +37,6 @@ function variantOf(v: Val | undefined): string | undefined {
63
37
  }
64
38
 
65
39
 
66
- // The number of CAPTURING groups in a normalised pattern. Counted by
67
- // scanning rather than by asking either host, because the count decides
68
- // whether a substitution is refused and the two ports must refuse the
69
- // same ones. The subset admits no named groups, so a capturing group is
70
- // exactly `(` that is not `(?`.
71
40
  function reGroupCount(norm: string): number {
72
41
  let count = 0
73
42
  let inClass = false
@@ -85,8 +54,6 @@ function reGroupCount(norm: string): number {
85
54
  }
86
55
 
87
56
 
88
- // One code point at `at`, as a count of UTF-16 units: the "advance by
89
- // one rune" Go's matching loop performs after an empty match.
90
57
  function stepAt(src: string, at: number): number {
91
58
  const c = src.codePointAt(at)
92
59
  return undefined === c ? 1 : (0xFFFF < c ? 2 : 1)
@@ -131,12 +98,6 @@ function allMatches(src: string, re: RegExp): RegExpExecArray[] {
131
98
  }
132
99
 
133
100
 
134
- // A substitution template expanded against one match. `$1`..`$9` are
135
- // the numbered groups, `$&` the whole match and `$$` a literal `$`;
136
- // anything else after a `$` names nothing, and naming nothing is a
137
- // REFUSAL rather than a silent literal. A group the pattern does not
138
- // have is the same refusal -- a generator that expands it to the empty
139
- // string writes a file with a hole in it and says nothing.
140
101
  function expandSub(sub: string, m: RegExpExecArray, groups: number)
141
102
  : string | undefined {
142
103
  let out = ''
@@ -176,8 +137,6 @@ function splitRe(src: string, re: RegExp): string[] {
176
137
  }
177
138
 
178
139
 
179
- // An EMPTY separator yields the CODE POINTS, not the UTF-16 units a
180
- // host split would give: `split("é", "")` is one field in both ports.
181
140
  function splitLiteral(src: string, sep: string): string[] {
182
141
  if ('' === sep) { return [...src] }
183
142
  return src.split(sep)
@@ -190,9 +149,6 @@ function compileRe(src: string): RegExp | string {
190
149
  const [norm, why] = normaliseRe(src)
191
150
  if ('' !== why) { return 'rep_pattern' }
192
151
  try {
193
- // The `u` flag is REQUIRED for parity, exactly as it is for `re()`:
194
- // without it JavaScript counts UTF-16 units where Go counts code
195
- // points.
196
152
  return new RegExp(norm, 'gu')
197
153
  }
198
154
  catch (e: any) {