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
@@ -1,28 +1,5 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
- // FIRST-CLASS PATHS (docs/design/PATHS.0.md). A PathVal is the value
4
- // `path(p)` captures: a tree address as DATA -- the spelling, never
5
- // the resolution. It is a scalar whose peg is the address string in
6
- // exactly the grammar `refer` reads (`$.a.b` from the root, `.b` from
7
- // the sibling scope, one more leading dot per parent step), which is
8
- // what lets a captured path meet the checking machinery unchanged.
9
- //
10
- // Meets are SYNTACTIC, by the PREFIX rule (amended, ADR-016): two
11
- // path values meet when one spells a prefix of the other -- same
12
- // anchor, the shorter's segments opening the longer's -- and the
13
- // result is the LONGER: a path can always be told more precisely.
14
- // Incomparable spellings refuse as any two unequal scalars do.
15
- // Resolving during a meet would make the meet depend on the value's
16
- // position, which is the property the staging machinery exists to
17
- // quarantine -- resolution stays the business of `refer`, `rel` and
18
- // the graph.
19
- //
20
- // The kind sits UNDER string (ScalarKindVal.KIND_PARENT), so `string`
21
- // admits a path value and the string constraints keep working; a
22
- // plain string LITERAL and a path value refuse each other, exactly as
23
- // the number tower's leaves do. A bare string is NEVER a path
24
- // (ADR-016): `path("...")` -- the call's own string argument -- is
25
- // the one conversion the language has.
26
3
 
27
4
  import type {
28
5
  Val,
@@ -41,10 +18,6 @@ import { ScalarVal } from './ScalarVal'
41
18
  import { ScalarKindVal, Path } from './ScalarKindVal'
42
19
 
43
20
 
44
-
45
- // A segment of a tree path: a map key or a list index. The same
46
- // grammar the rest of the engine spells keys with, and a leading digit
47
- // is legitimate because a list index is one.
48
21
  const ADDR_SEGMENT = /^[A-Za-z0-9_-]+$/
49
22
 
50
23
  export type Address = {
@@ -58,12 +31,6 @@ export type Address = {
58
31
  }
59
32
 
60
33
 
61
- // The address a string spells, or undefined when it does not spell
62
- // one. An address is a TREE PATH, in exactly the two spellings a
63
- // reference uses: `$.services.auth` from the root, `.auth` from the
64
- // link's own sibling scope. The tree is the only namespace -- which is
65
- // what makes a model instantiable more than once, each instance
66
- // resolving its relative links inside itself (ADR-014).
67
34
  export function parseAddress(s: string): Address | undefined {
68
35
  if ('$' === s) {
69
36
  // The whole document is not a relation's target: an address must
@@ -104,29 +71,11 @@ export function parseAddress(s: string): Address | undefined {
104
71
  }
105
72
 
106
73
 
107
- // The spelling string TEXT converts by, inside a `path(...)` call:
108
- // text that carries no anchor is RELATIVE (`"a.b"` is the address
109
- // `.a.b`), matching the raw form (`path(a.b)` captures `.a.b`). Only
110
- // the anchor is supplied -- the result still has to parse, so
111
- // malformed text (`""`, `"a..b"`, a bad `$` spelling) refuses as
112
- // before. The prefix is not applied to text that claims an anchor:
113
- // `"$x"` is a broken absolute address, not a relative one.
114
74
  export function textAddress(s: string): string {
115
75
  return ('$' === s[0] || '.' === s[0]) ? s : '.' + s
116
76
  }
117
77
 
118
78
 
119
- // The LONGER of two addresses when one spells a prefix of the other
120
- // (docs/design/PATHS.0.md, amended): same anchor -- absolute or the
121
- // same number of parent steps -- and the shorter's segments open the
122
- // longer's. The meet of two path values, and of a refer's address
123
- // with a later path peer: a path can always be told more precisely,
124
- // and the more precise spelling is the result. Undefined when the two
125
- // are not comparable, which refuses as any two unequal scalars do.
126
- // Both arguments must already be valid addresses: every caller hands
127
- // over a PathVal peg or a refer addrsrc, and both are validated at
128
- // capture or conversion -- the same trust `unify`'s own address arm
129
- // extends (`parseAddress(p.peg) as Address`).
130
79
  export function prefixMeet(a: string, b: string): string | undefined {
131
80
  const pa = parseAddress(a) as Address
132
81
  const pb = parseAddress(b) as Address
@@ -144,7 +93,6 @@ export function prefixMeet(a: string, b: string): string | undefined {
144
93
  }
145
94
 
146
95
 
147
-
148
96
  class PathVal extends ScalarVal {
149
97
  isPath = true
150
98
 
@@ -155,11 +103,6 @@ class PathVal extends ScalarVal {
155
103
  super({ peg: spec.peg, kind: Path }, ctx)
156
104
  }
157
105
 
158
- // Two path values meet by the PREFIX rule (ADR-016): the longer
159
- // when one opens the other, refusal otherwise. Exactly equal pegs
160
- // are absorbed by unite's fast path before this runs, so the arm
161
- // sees the unequal pairs; the winner carries both sides' marks, as
162
- // the equal-scalar arm has always ratcheted them.
163
106
  unify(peer: Val, ctx: AontuContext): Val {
164
107
  const p: any = peer
165
108
  if (true === p.isPath) {
@@ -182,10 +125,6 @@ class PathVal extends ScalarVal {
182
125
  return 'path(' + this.peg + ')'
183
126
  }
184
127
 
185
- // The super() ladder lifts a path value to its own kind, and the
186
- // kind must render as `path()` -- the bare word `path` is an
187
- // ordinary string. ScalarVal.superior would mint the plain
188
- // ScalarKindVal, whose canon is the bare word.
189
128
  superior() {
190
129
  return this.place(new PathKindVal({}))
191
130
  }
@@ -193,11 +132,6 @@ class PathVal extends ScalarVal {
193
132
  } /* node:coverage ignore next 4 */
194
133
 
195
134
 
196
- // The path KIND, `path()`: admits every path value and defaults to
197
- // nothing, as `string` does. It does NOT promote (ADR-016): a bare
198
- // string meeting the kind refuses through the generic kind ladder,
199
- // exactly as `integer & "x"` does -- `path("...")` is the one string
200
- // conversion, and it happens at the call.
201
135
  class PathKindVal extends ScalarKindVal {
202
136
  isPathKind = true
203
137
 
@@ -1,25 +1,5 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
- // THE PLACEHOLDER `_` (G8 phase 3,
4
- // docs/capability-review/g8-generation.md): a HOLE in a call, filled
5
- // by whatever the call is unified with.
6
- //
7
- // x: {&: {m: _ + 2}} x: a: m: 1 -> a: m: 3
8
- // greeting: upper(_) & hello -> "HELLO"
9
- //
10
- // WHY A HOLE AND NOT A FUNCTION PARAMETER. Aontu has no user-defined
11
- // functions and will not get them (G8's Boundary): a function value
12
- // crossing into the data plane is the step that makes a configuration
13
- // language a programming language. A hole is not a parameter -- it
14
- // cannot be named, passed, or partially applied. It says only "the
15
- // value that arrives here", which is what a template needs to compute
16
- // from the value it lands on.
17
- //
18
- // ALONE, `_` IS TOP WITH A MARK: it admits everything and is filled by
19
- // its peer, exactly as TOP is dropped by one. What makes it different
20
- // is that a CALL can see it, and a call that holds one waits for a
21
- // peer to fill it instead of resolving around it. Unfilled at
22
- // generation it is an error, as TOP is -- a hole is not a value.
23
3
 
24
4
  import type {
25
5
  Val,
@@ -72,17 +52,6 @@ class PlaceVal extends ValBase {
72
52
  }
73
53
 
74
54
 
75
- // A HOLE BELONGS TO ITS NEAREST ENCLOSING GENERATOR. A `_` inside a
76
- // generator's template (pack/each, arg 1), condition (filter, arg 1)
77
- // or rule table (emit, arg 1) is that generator's to bind — "_ is the
78
- // source child" — so neither the hole test nor the fill walk may cross
79
- // into those arguments from outside. Before this boundary, `close(pack(d, _ & t))` reported a
80
- // hole to the OUTER call, so an ordinary overlay statement was
81
- // absorbed into the template instead of merging with the generated
82
- // child (use-cases/BUGS.md §10), and an outer pack's fill pass
83
- // captured a NESTED pack's hole lexically, binding it to the outer
84
- // source (§34). The data argument (arg 0) is not a binding position,
85
- // so it stays visible: a hole there is an outer hole as before.
86
55
  function boundArgStart(v: any): number {
87
56
  return true === v.isPackFunc || true === v.isEachFunc ||
88
57
  true === v.isFilterFunc || true === v.isEmitFunc ||
@@ -90,10 +59,6 @@ function boundArgStart(v: any): number {
90
59
  }
91
60
 
92
61
 
93
- // Does this value CONTAIN a hole? Asked of a call before it resolves:
94
- // a call holding one must wait for a peer to fill it. Holes inside a
95
- // generator's own binding arguments are NOT this value's holes — see
96
- // boundArgStart above.
97
62
  function hasPlace(v: Val): boolean {
98
63
  if (true === (v as any).isPlace) {
99
64
  return true
@@ -125,18 +90,8 @@ function hasPlace(v: Val): boolean {
125
90
  }
126
91
 
127
92
 
128
- // The same tree with every hole filled by `fill`. Answers the value
129
- // UNCHANGED when it holds no hole, so a caller can test identity to
130
- // know whether anything was filled -- and so a tree with no hole is
131
- // never needlessly cloned. A nested generator's binding arguments are
132
- // left untouched (boundArgStart): those holes are the inner
133
- // generator's to fill with its OWN source children when it fires.
134
93
  function fillPlace(v: Val, fill: Val, ctx: AontuContext): Val {
135
94
  if (true === (v as any).isPlace) {
136
- // A FILL IS A POSITION. The hole knows where it sits in the
137
- // instance; the datum arriving in it does not, and inserted as it
138
- // stands it keeps the paths it had at its SOURCE, so every finding
139
- // under it names a path that does not exist.
140
95
  return fill.clone(ctx, { path: [...(v as any).path] })
141
96
  }
142
97
 
@@ -18,6 +18,7 @@ import { IntegerVal } from '../val/IntegerVal'
18
18
  import { NumberVal } from '../val/NumberVal'
19
19
  import { StringVal } from '../val/StringVal'
20
20
  import { BooleanVal } from '../val/BooleanVal'
21
+ import { ListVal } from '../val/ListVal'
21
22
  import { BigIntegerVal } from '../val/BigIntegerVal'
22
23
  import { BigDecimalVal } from '../val/BigDecimalVal'
23
24
  import { Decimal, decimalOverBudget } from '../val/Decimal'
@@ -33,20 +34,6 @@ type OpKind =
33
34
  'string' | 'boolean' | 'integer' | 'float' | 'biginteger' | 'bigdecimal'
34
35
 
35
36
 
36
- // D6 -- THE EXACT LADDER: integer < biginteger < bigdecimal. A mixed
37
- // operation between exact leaves promotes to the WIDEST operand and is
38
- // computed exactly, so `1 + 0d2` is a biginteger and `1 + 0d0.5` a
39
- // bigdecimal.
40
- //
41
- // `float` is deliberately absent: it is OFF the ladder, keeping only its
42
- // classic contagion against `integer`. Its absence from this table is
43
- // what makes the float-with-big pairs fall through to the hard error
44
- // below rather than promoting.
45
- //
46
- // Results NEVER demote: `0d5 + -0d2` stays a biginteger even though 3
47
- // would fit an int64. Demotion would make the result kind depend on the
48
- // values rather than on the operand kinds, and a document could then
49
- // change leaf under a value edit.
50
37
  const EXACT_RANK: Record<string, number> = {
51
38
  integer: 1,
52
39
  biginteger: 2,
@@ -59,13 +46,6 @@ function isBig(k: OpKind): boolean {
59
46
  }
60
47
 
61
48
 
62
- // Only concrete scalar operands are valid: anything else (kinds, maps,
63
- // lists, null, top, funcs) must not coerce — the JS `+` would leak
64
- // internals like "[object Object]" into output. A non-scalar operand
65
- // leaves the op unresolved, which generate() reports.
66
- //
67
- // A pref operand contributes its preferred value (`pref(1)+2`), and
68
- // therefore that value's kind too.
69
49
  function operand(v: any) {
70
50
  while (v?.isPref) {
71
51
  v = v.peg
@@ -99,14 +79,6 @@ function opkind(v: any): OpKind | undefined {
99
79
  }
100
80
 
101
81
 
102
- // THE TEXT `+` WOULD MAKE OF THIS OPERAND, or undefined if `+` would not
103
- // take it at all.
104
- //
105
- // `join` folds with `+` seeded with `""`, so every member goes through
106
- // concatenation's string branch — and this is the function that branch
107
- // calls. Exported so that the fold and the operator cannot drift into
108
- // two answers to "how does a number become text": there is one
109
- // rendering, `digits` below, and both reach it here.
110
82
  function plusText(v: Val): string | undefined {
111
83
  const o: any = operand(v)
112
84
  const k = opkind(o)
@@ -134,9 +106,25 @@ class PlusOpVal extends OpBaseVal {
134
106
  }
135
107
 
136
108
 
137
- operate(ctx: AontuContext, args: Val[]) {
109
+ operate(ctx: AontuContext, args: Val[]): Val | undefined {
138
110
  const av: any = operand(args[0])
139
111
  const bv: any = operand(args[1])
112
+
113
+ // ABSENCE PROPAGATES (ADR-034).
114
+ if (true === av?.isAbsent) {
115
+ return av
116
+ }
117
+ if (true === bv?.isAbsent) {
118
+ return bv
119
+ }
120
+
121
+ // Lists concatenate (ADR-037).
122
+ if (true === av?.isList && true === bv?.isList) {
123
+ const peg: Val[] = [...av.peg, ...bv.peg].map(
124
+ (v: Val, i: number) => v.clone(ctx.descend(String(i))))
125
+ return new ListVal({ peg }, ctx)
126
+ }
127
+
140
128
  const ak = opkind(av)
141
129
  const bk = opkind(bv)
142
130
 
@@ -148,12 +136,6 @@ class PlusOpVal extends OpBaseVal {
148
136
  return new BooleanVal({ peg: av.peg || bv.peg })
149
137
  }
150
138
 
151
- // STRING CONCATENATION RENDERS DIGITS, NOT KIND DECORATION. The `0d`
152
- // marker is canon's way of naming the leaf and never belongs in a
153
- // string, exactly as R4's `.0` float suffix does not ("q" + 0d0.1 is
154
- // "q0.1", and "q" + 1.0 is "q1"). Decimal.toString() is that
155
- // marker-free rendering, which is why canon() wraps it rather than
156
- // the other way round.
157
139
  if ('string' === ak || 'string' === bk) {
158
140
  return new StringVal({ peg: digits(av, ak) + digits(bv, bk) })
159
141
  }
@@ -163,25 +145,11 @@ class PlusOpVal extends OpBaseVal {
163
145
  return undefined
164
146
  }
165
147
 
166
- // FLOAT IS OFF THE EXACT LADDER, and mixing it with either big leaf
167
- // is a hard error in BOTH operand orders: a big type never silently
168
- // becomes a binary float. Promotion the other way is no better —
169
- // binary64 cannot hold every exact value, so either direction throws
170
- // away exactness the document explicitly asked for by writing `0d`.
171
- // The error names both leaves in operand order.
172
148
  if (('float' === ak && isBig(bk)) || (isBig(ak) && 'float' === bk)) {
173
149
  return makeNilErr(ctx, 'exact_float_mix', this, undefined, 'add',
174
150
  { left: ak, right: bk })
175
151
  }
176
152
 
177
- // Float with float or integer: unchanged R5 contagion, binary64
178
- // addition, float result (`1 + 2.0` is `3.0`) -- but a sum that
179
- // leaves binary64's finite range is NOT a value. Aontu is a JSON
180
- // superset and there is no notation for an infinity, so one here
181
- // used to escape as `[aontu/internal]` in TypeScript and as Go's
182
- // raw `json: unsupported value: +Inf` with no code at all
183
- // (use-cases/BUGS.md 39). The same check governs the arithmetic
184
- // family (float_overflow, ts/src/val/arith.ts).
185
153
  if ('float' === ak || 'float' === bk) {
186
154
  const sum = av.peg + bv.peg
187
155
  return Number.isFinite(sum) ?
@@ -211,13 +179,6 @@ class PlusOpVal extends OpBaseVal {
211
179
  return new BigIntegerVal({ peg: sum })
212
180
  }
213
181
 
214
- // INTEGER + INTEGER IS COMPUTED EXACTLY, then offered to the integer
215
- // leaf under the same storage contract R1 applies to a literal.
216
- // Adding through float64 (as this did) silently rounded sums of
217
- // exact operands — 4503599627370496 + 4503599627370497 came back as
218
- // …992 — which is precisely the corruption the tower refuses. The
219
- // sum that will not fit is an error pointing at `0d`, not a rounded
220
- // answer.
221
182
  return isIntegerStorable(sum) ?
222
183
  new IntegerVal({ peg: Number(sum) }) :
223
184
  makeNilErr(ctx, 'inexact_integer_sum', this, undefined, 'add',
@@ -232,19 +193,6 @@ class PlusOpVal extends OpBaseVal {
232
193
  }
233
194
 
234
195
 
235
- // The digits of an operand for string concatenation: no `0d` marker, no
236
- // R4 `.0` suffix — the plain rendering of the number, in every leaf.
237
- //
238
- // INTEGER KIND GOES THROUGH integerDigits. This was the THIRD site to
239
- // render an integer-kind peg with JavaScript's shortest round-tripping
240
- // form, so `"" + 1152921504606846976` produced "1152921504606847000" — a
241
- // different integer — where Go produced the exact digits. See #21 and
242
- // integerDigits, which exists so the set of such sites is greppable.
243
- //
244
- // The other leaves are already exact or already correct: a bigint
245
- // stringifies to its exact digits, a Decimal renders its own, and a FLOAT
246
- // must keep String() because its shortest form is the right answer and is
247
- // what Go prints too (`"a" + 1.0` is "a1").
248
196
  function digits(v: any, k: OpKind): string {
249
197
  return 'bigdecimal' === k ? v.peg.toString() :
250
198
  'integer' === k ? integerDigits(v.peg) :
@@ -252,16 +200,11 @@ function digits(v: any, k: OpKind): string {
252
200
  }
253
201
 
254
202
 
255
- // An exact-ladder operand as an exact integer. Only reached for the two
256
- // integral leaves; an `integer` peg is integral by construction, so
257
- // BigInt() is exact.
258
203
  function integer(v: any, k: OpKind): bigint {
259
204
  return 'biginteger' === k ? v.peg : BigInt(v.peg)
260
205
  }
261
206
 
262
207
 
263
- // An exact-ladder operand as a Decimal, for the promotion to bigdecimal.
264
- // Scale 0 normalises to the one decimal place the leaf keeps.
265
208
  function decimal(v: any, k: OpKind): Decimal {
266
209
  return 'bigdecimal' === k ? v.peg : new Decimal(integer(v, k), 0)
267
210
  } /* node:coverage ignore next 6 */
@@ -49,7 +49,6 @@ class PrefFuncVal extends FuncBaseVal {
49
49
  // Wrap every child val in a PrefVal
50
50
  out = walk(out, (_key: string | number | undefined, val: Val) => {
51
51
  let oval = val
52
- // console.log('PREFVAL', _key, oval.canon, oval.constructor.name)
53
52
  if (
54
53
  val.isScalar
55
54
  || val.isPref
@@ -27,11 +27,6 @@ import { trialUnify } from './FuncBaseVal'
27
27
  import { superOf } from './SuperFuncVal'
28
28
 
29
29
 
30
- // The innermost preferred value under every pref layer: the value a
31
- // preference of ANY rank ultimately defends, and the one generation
32
- // emits for it. Shared by the disjunct admission gate (DisjunctVal),
33
- // the defaulted-scrutinee rule (MatchFuncVal) and the effective-default
34
- // walk (subsume.ts) so "the default's value" cannot mean three things.
35
30
  function prefInnerPeg(v: Val): Val {
36
31
  let out: any = v
37
32
  while (true === out?.isPref) {
@@ -41,65 +36,16 @@ function prefInnerPeg(v: Val): Val {
41
36
  }
42
37
 
43
38
 
44
- // A CONTAINER DEFAULT IS LEAFWISE (ADR-011 R3,
45
- // docs/design/DEFAULTS.0.md): `*{p:1}` MEANS `{p: *1}` and `*[1]`
46
- // means `[*1]`, so there is no such thing as a preference whose
47
- // preferred value is a bag. Shape is not a value and takes no star --
48
- // key optionality, closedness and a `&:` spread template ride through
49
- // untouched; only the values a reader could override are defaulted.
50
- //
51
- // This is the rule `pref()` already had (its resolve walked and
52
- // wrapped every scalar child) and the star prefix did not, so the two
53
- // spellings of one operator disagreed: `pref({p:1}) & {q:2}` kept the
54
- // `p` default and `*{p:1} & {q:2}` dropped it. Both spellings and the
55
- // resolve-time case (`*$.shape`) come through here now, so they
56
- // cannot drift apart again. Wrapping the non-bag arm rather than
57
- // walking for scalars also closes the other half of that gap:
58
- // `pref(integer)` and `pref(min(3))` used to answer the bare value,
59
- // losing the preference outright.
60
39
  class PrefVal extends FeatureVal {
61
40
  isPref = true
62
41
  isGenable = true
63
42
  cjo = 30000
64
43
 
65
- // The preferred value's own type: the yardstick for "did the peer say
66
- // anything I did not already say?". A peer that resolves to this (or
67
- // to the family gate below) leaves the preference standing.
68
- // Both are assigned by resuper(), called from the constructor.
69
44
  superpeg!: Val
70
45
 
71
- // THE GATE AN OVERRIDING PEER MUST PASS IS `superpeg` ITSELF — the
72
- // preferred value's own KIND, not its family.
73
- //
74
- // A preference is a DEFAULT, so a concrete peer replaces it, but only
75
- // where the peer is the same kind of thing: `*lower(1.1) & a` is a
76
- // conflict, not an override. The number tower made `integer` and
77
- // `float` disjoint siblings under `number`, and this gate used to
78
- // widen to that family — so `*2.2 & 3` worked, and so did
79
- // `*8080 & 3.5`. Those are ONE rule in two directions; no kind-based
80
- // gate can keep the first and refuse the second.
81
- //
82
- // Refusing both is the choice, because the second is the documented
83
- // default idiom: `port: *8080 | integer` accepted 3.5 in both ports,
84
- // silently widening every key written that way from integer to
85
- // number — the finding §6 of the 2026-08-21 status report calls the
86
- // most consequential, precisely because docs/skill/examples.md
87
- // teaches the idiom to agents.
88
- //
89
- // What the tightening costs is named rather than hidden: mixing the
90
- // numeric leaves around a preference is now an error instead of a
91
- // silent widening. `*1.5 & integer` used to answer `integer` and
92
- // DISCARD a default that could never apply; it now says so.
93
46
 
94
47
  rank: number = 0
95
48
 
96
- // THE OVERRIDE SPACE, NARROWED (ADR-011 R1). The second arm of the
97
- // distribution -- `super(x) & every peer met so far` -- kept here as
98
- // well as in `superpeg`, because resuper() recomputes the gate from
99
- // the peg whenever the peg resolves and would otherwise widen it
100
- // back to `super(x)`: a rank>=2 default, whose peg is itself a
101
- // preference and so is re-driven, lost its narrowing that way and
102
- // let a pinned `***false & false` be overridden by `true`.
103
49
  narrowed?: Val
104
50
 
105
51
  constructor(
@@ -107,45 +53,17 @@ class PrefVal extends FeatureVal {
107
53
  ctx?: AontuContext
108
54
  ) {
109
55
  super(spec, ctx)
110
- // this.pref = spec.pref || spec.peg
111
56
 
112
- // this.superpeg = makeSuper(spec.peg)
113
57
 
114
58
  if (spec.peg instanceof PrefVal) {
115
59
  this.rank = 1 + spec.peg.rank
116
60
  }
117
61
 
118
62
  this.resuper(ctx)
119
- // console.log('PVC', this.peg.canon, this.superpeg.canon)
120
63
  }
121
64
 
122
65
 
123
- // Recompute the type yardstick and the override gate from the current
124
- // peg. Called again whenever the peg resolves (e.g. a ref).
125
- //
126
- // THE GATE IS super() (ADR-011 R4, docs/design/DEFAULTS.0.md). `*x`
127
- // is sugar for `*x | super(x)`, so the type an overriding peer must
128
- // pass is the one the long form spells out loud -- one function, not
129
- // a second implementation that agrees with it on the common case.
130
- // Two special cases retired with the switch: a KIND peg gated
131
- // nothing (`*integer` was overridden by `"s"`) and a CONSTRAINT peg
132
- // had no gate at all, both written when a kind's superior was top.
133
- // `super(integer)` is `number`, so `7` still wins and `"s"` refuses.
134
66
  private resuper(ctx?: AontuContext) {
135
- // THE RANK-UNIFORM MEET (ADR-004). The yardstick is the INNERMOST
136
- // preferred value's kind, whatever the preference's rank: `**1.5`
137
- // defends `float` exactly as `*1.5` does. The old rule read the
138
- // immediate peg, and a rank>=2 peg is itself a PrefVal whose
139
- // superior is top -- so ANY conjunct overrode a ranked default
140
- // (`**1.5 & float` dropped the default and died as mapval_no_gen;
141
- // `**2|integer` met by a bare `integer` lost the default the
142
- // spelling exists to carry -- use-cases/BUGS.md §3), while the
143
- // rank-1 spelling of the same document kept it. One rule, every
144
- // rank. Pinned by test/spec/pref.tsv (pref-rank2-* rows, and the
145
- // flipped pref-nested-concrete-wins).
146
- // THE RANK-UNIFORM MEET (ADR-004) is unchanged: the yardstick is
147
- // the INNERMOST preferred value, whatever the rank, so `**1.5`
148
- // defends `float` exactly as `*1.5` does.
149
67
  let peg: any = this.peg
150
68
  while (true === peg?.isPref) {
151
69
  peg = peg.peg
@@ -161,14 +79,6 @@ class PrefVal extends FeatureVal {
161
79
  }
162
80
 
163
81
 
164
- // The default, standing but NARROWED: `*integer & 7` is `*7`, which
165
- // is what the long form answers (`(integer&7) | (number&7)` keeps
166
- // the star on the arm that survived). The rank rides across -- a
167
- // ladder rung that narrows is still that rung.
168
- // The rank is REBUILT as nesting rather than stamped: canon renders
169
- // one star per layer (`'*' + peg.canon`), so a rank set directly on
170
- // a single layer would print `*x` for a rank-2 default and the
171
- // document would no longer round-trip.
172
82
  private restand(met: Val, ctx: AontuContext): Val {
173
83
  let out: Val = met
174
84
  for (let rI = 0; rI <= this.rank; rI++) {
@@ -190,28 +100,10 @@ class PrefVal extends FeatureVal {
190
100
  if (!this.peg.done) {
191
101
  const resolved = unite(te ? ctx.clone({ explain: ec(te, 'RES') }) : ctx,
192
102
  this.peg, top(), 'pref/resolve')
193
- // console.log('PREF-RESOLVED', this.peg.canon, '->', resolved)
194
103
  this.peg = resolved
195
104
  this.resuper(ctx)
196
105
  }
197
106
 
198
- // A CONTAINER DEFAULT IS LEAFWISE IN EFFECT (ADR-011 R3), and it
199
- // gets there through the meet above rather than through a rewrite.
200
- // `*{p:1}` keeps its written shape -- canon prints `*{"p":1}` and
201
- // reparses to itself, which a rewrite to `{p:*1}` would break, and
202
- // an alternative still has a star for a disjunction to choose by.
203
- // What makes it leafwise is that the two arms decide:
204
- //
205
- // `& {q:2}` the preferred value ITSELF admits the peer (maps
206
- // merge), so the default stands as `*{p:1,q:2}` and
207
- // `p` survives -- it used to be REPLACED outright.
208
- // `& {p:2}` the preferred value refuses, so the gate answers:
209
- // `super({p:1})` is `{p:integer}`, which admits it.
210
- // `& "s"` both arms are empty, so the whole default is --
211
- // a string used to override a map default silently.
212
- //
213
- // Which is every rule R3 asks for, with no bag ever standing where
214
- // the author wrote a scalar and no canon that fails to round-trip.
215
107
 
216
108
  if (peer instanceof PrefVal) {
217
109
  why += 'pref-'
@@ -235,74 +127,22 @@ class PrefVal extends FeatureVal {
235
127
  why += 'rank-lose'
236
128
  }
237
129
  else {
238
- // console.log('PREF-PEER',
239
- // this.peg.id, this.peg, this.peg.done,
240
- // peer.peg.id, peer.peg, peer.peg.done,
241
- // )
242
130
 
243
131
  const peg = trialUnify(ctx, prefInnerPeg(this).clone(ctx),
244
132
  prefInnerPeg(peer))
245
133
 
246
- // TWO DEFAULTS OF EQUAL RANK THAT CANNOT AGREE (ADR-011 R2):
247
- // the refusal is about the DEFAULTS, not about the values they
248
- // happen to hold, and its hint names the fix -- rank one of
249
- // them. Compatible pegs still fold (`*1 & *integer` is `*1`),
250
- // and identical ones collapse, so only a real disagreement
251
- // reaches this arm. The three spellings of it -- `*1 & *7`,
252
- // `(*1|integer) & *7` and `*1|*7` -- used to answer a value
253
- // conflict, the newcomer, and the newcomer again.
254
134
  out = undefined === peg
255
135
  ? makeNilErr(ctx, 'pref_rank_clash', this, peer, 'unify')
256
136
  : this.restand(peg, ctx)
257
- // console.log('PREF-RANK-SAME-OUT', peg, peg.done, out, out.done)
258
137
  why += 'rank-same'
259
138
  }
260
139
  }
261
140
  else if (!peer.isTop) {
262
141
  why += 'super-'
263
142
 
264
- // THE MEET IS THE DESUGARING, DISTRIBUTED (ADR-011 R1,
265
- // docs/design/DEFAULTS.0.md). `*x` stands for `*x | super(x)`,
266
- // and a peer meets a disjunction arm by arm:
267
- //
268
- // (x & peer) | (super(x) & peer)
269
- //
270
- // THE FIRST ARM DECIDES. When the preferred value itself still
271
- // satisfies the peer the default STANDS -- `*1 & integer`,
272
- // `*8080 & min(1024)`, `**2 & neq(1)`: the peer narrowed the
273
- // type without ruling the default out, which is the whole point
274
- // of writing one. Only when that arm is empty does the second
275
- // answer, and that is the override. When BOTH are empty nothing
276
- // remains of the disjunction the star stands for -- `empty`,
277
- // the same refusal the written-out long form gives.
278
- //
279
- // The old rule asked instead whether the peer resolved to
280
- // exactly `super(x)`, so any narrowing at all counted as an
281
- // override: `*1 & integer` stood (the peer WAS the gate) but
282
- // `*8080 & min(1024)` silently dropped the default and answered
283
- // the bare constraint, and a rank ladder lost its weaker arm to
284
- // the same rule the moment anything narrowed it.
285
- //
286
- // Trialled against a CLONE, on the innermost value (the
287
- // rank-uniform meet): the preferred value must stay pristine for
288
- // the arm that stands, and a failed trial must not leave its
289
- // errors on the context -- the DisjunctVal admission gate's own
290
- // precedent, and its mechanism.
291
143
  const met = trialUnify(ctx, prefInnerPeg(this).clone(ctx), peer)
292
144
 
293
145
  if (undefined !== met) {
294
- // THE SECOND ARM IS CARRIED FORWARD, not discarded. It is the
295
- // override space -- everything the peer would still admit
296
- // INSTEAD of the default -- and meeting a peer narrows it just
297
- // as it narrows the default: two successive meets compose to
298
- // `(x & p1 & p2) | (super(x) & p1 & p2)`, which is the
299
- // distribution over both. Dropping it let a constraint that
300
- // arrived beside a default vanish: `r:*2` with `r:max(20)`
301
- // stood as a bare `*2`, and `r:40` then overrode it through a
302
- // gate that no longer remembered the bound.
303
- //
304
- // It cannot fail: the first arm succeeded, so `x & peer` has a
305
- // value, and that value satisfies `super(x)` and `peer` both.
306
146
  const gate = unite(te ? ctx.clone({ explain: ec(te, 'GATE') }) : ctx,
307
147
  this.superpeg.clone(ctx), peer, 'pref-gate/' + this.id)
308
148
 
@@ -338,7 +178,6 @@ class PrefVal extends FeatureVal {
338
178
  : makeNilErr(ctx, 'empty', this, peer, 'unify')
339
179
 
340
180
 
341
-
342
181
  // }
343
182
  }
344
183
  else {
@@ -349,7 +188,6 @@ class PrefVal extends FeatureVal {
349
188
  // superior-unify (mirrored by PrefVal.Unify in go/pref.go).
350
189
  out.dc = DONE
351
190
 
352
- // console.log('PREFVAL-OUT', why, this.canon, peer.canon, '->', out.canon, out.done)
353
191
 
354
192
  ctx.explain && explainClose(te, out)
355
193
 
@@ -372,27 +210,10 @@ class PrefVal extends FeatureVal {
372
210
  clone(ctx: AontuContext, spec?: ValSpec): Val {
373
211
  let out = (super.clone(ctx, spec) as PrefVal)
374
212
 
375
- // THE NARROWED OVERRIDE SPACE TRAVELS WITH THE COPY (ADR-011 R1).
376
- // A default a meet has pinned stays pinned through a reference:
377
- // without this, `T:{e:***false & false}` copied by `f:$.T` handed
378
- // back a default whose gate had widened again to `boolean`, and
379
- // `f:{e:true}` overrode a value the author had pinned. The Go
380
- // twin carries the same two fields explicitly (clone.go).
381
213
  if (null != this.narrowed) {
382
214
  out.narrowed = this.narrowed
383
215
  out.superpeg = this.superpeg
384
216
  }
385
- // THE PER-DESTINATION INSTANTIATION RULE (ADR-005). The default
386
- // clone shares the preferred value (`peg: this.peg` in Val.clone)
387
- // — a cloned pref spread template resolves its inner value at the
388
- // template's own location, pinned behaviour. But a template
389
- // INSTANCE must own it: with the peg shared, a rank-2 default
390
- // (`**key(1) | string`) in a pack template resolved its one
391
- // shared inner key() at the first destination and every child got
392
- // the first child's key (use-cases/BUGS.md §9 — rank 1 escaped
393
- // only because its unify builds a fresh PrefVal per meet). The
394
- // superpeg yardstick from the shared peg still holds: the clone's
395
- // innermost value is the same kind.
396
217
  if (true === spec?.dup && true === (this.peg as any)?.isVal) {
397
218
  out.peg = this.peg.clone(ctx, { dup: true })
398
219
  }