aontu 0.52.1 → 0.54.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 (310) hide show
  1. package/README.md +88 -0
  2. package/bin/aontu-mcp.js +4 -0
  3. package/dist/agentsmd.d.ts +16 -0
  4. package/dist/agentsmd.js +107 -0
  5. package/dist/agentsmd.js.map +1 -0
  6. package/dist/aontu.d.ts +15 -3
  7. package/dist/aontu.js +126 -5
  8. package/dist/aontu.js.map +1 -1
  9. package/dist/cli.d.ts +45 -1
  10. package/dist/cli.js +2845 -69
  11. package/dist/cli.js.map +1 -1
  12. package/dist/ctx.d.ts +18 -0
  13. package/dist/ctx.js +44 -0
  14. package/dist/ctx.js.map +1 -1
  15. package/dist/diff.d.ts +22 -0
  16. package/dist/diff.js +141 -0
  17. package/dist/diff.js.map +1 -0
  18. package/dist/err.d.ts +3 -1
  19. package/dist/err.js +45 -8
  20. package/dist/err.js.map +1 -1
  21. package/dist/graph.d.ts +13 -0
  22. package/dist/graph.js +110 -0
  23. package/dist/graph.js.map +1 -0
  24. package/dist/hcanon.d.ts +3 -0
  25. package/dist/hcanon.js +145 -0
  26. package/dist/hcanon.js.map +1 -0
  27. package/dist/hints.js +235 -8
  28. package/dist/hints.js.map +1 -1
  29. package/dist/jsonschema.d.ts +20 -0
  30. package/dist/jsonschema.js +425 -0
  31. package/dist/jsonschema.js.map +1 -0
  32. package/dist/lang.js +955 -110
  33. package/dist/lang.js.map +1 -1
  34. package/dist/lsp.d.ts +9 -2
  35. package/dist/lsp.js +343 -48
  36. package/dist/lsp.js.map +1 -1
  37. package/dist/mcp-server.d.ts +20 -0
  38. package/dist/mcp-server.js +147 -0
  39. package/dist/mcp-server.js.map +1 -0
  40. package/dist/mcp.d.ts +42 -0
  41. package/dist/mcp.js +941 -0
  42. package/dist/mcp.js.map +1 -0
  43. package/dist/mod-tool.d.ts +58 -0
  44. package/dist/mod-tool.js +532 -0
  45. package/dist/mod-tool.js.map +1 -0
  46. package/dist/mod.d.ts +35 -0
  47. package/dist/mod.js +345 -0
  48. package/dist/mod.js.map +1 -0
  49. package/dist/patch.d.ts +49 -0
  50. package/dist/patch.js +506 -0
  51. package/dist/patch.js.map +1 -0
  52. package/dist/provenance.d.ts +41 -0
  53. package/dist/provenance.js +336 -0
  54. package/dist/provenance.js.map +1 -0
  55. package/dist/query.d.ts +27 -0
  56. package/dist/query.js +294 -0
  57. package/dist/query.js.map +1 -0
  58. package/dist/reach.d.ts +15 -0
  59. package/dist/reach.js +168 -0
  60. package/dist/reach.js.map +1 -0
  61. package/dist/relation.d.ts +23 -0
  62. package/dist/relation.js +230 -0
  63. package/dist/relation.js.map +1 -0
  64. package/dist/report-sarif.d.ts +14 -0
  65. package/dist/report-sarif.js +102 -0
  66. package/dist/report-sarif.js.map +1 -0
  67. package/dist/sig.d.ts +25 -0
  68. package/dist/sig.js +277 -0
  69. package/dist/sig.js.map +1 -0
  70. package/dist/sigdecl.d.ts +2 -0
  71. package/dist/sigdecl.js +11 -0
  72. package/dist/sigdecl.js.map +1 -0
  73. package/dist/siggate.d.ts +4 -0
  74. package/dist/siggate.js +90 -0
  75. package/dist/siggate.js.map +1 -0
  76. package/dist/site.d.ts +4 -0
  77. package/dist/site.js +31 -0
  78. package/dist/site.js.map +1 -1
  79. package/dist/std.d.ts +1 -0
  80. package/dist/std.js +129 -0
  81. package/dist/std.js.map +1 -0
  82. package/dist/subsume.d.ts +39 -0
  83. package/dist/subsume.js +573 -0
  84. package/dist/subsume.js.map +1 -0
  85. package/dist/trim.d.ts +19 -0
  86. package/dist/trim.js +155 -0
  87. package/dist/trim.js.map +1 -0
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/dist/type.d.ts +17 -1
  90. package/dist/type.js.map +1 -1
  91. package/dist/unify.d.ts +2 -1
  92. package/dist/unify.js +234 -38
  93. package/dist/unify.js.map +1 -1
  94. package/dist/utility.d.ts +8 -1
  95. package/dist/utility.js +68 -1
  96. package/dist/utility.js.map +1 -1
  97. package/dist/val/AggFuncVal.d.ts +44 -0
  98. package/dist/val/AggFuncVal.js +364 -0
  99. package/dist/val/AggFuncVal.js.map +1 -0
  100. package/dist/val/ArithFuncVal.d.ts +31 -0
  101. package/dist/val/ArithFuncVal.js +62 -0
  102. package/dist/val/ArithFuncVal.js.map +1 -0
  103. package/dist/val/BagVal.d.ts +7 -0
  104. package/dist/val/BagVal.js +150 -11
  105. package/dist/val/BagVal.js.map +1 -1
  106. package/dist/val/CloseFuncVal.js +9 -1
  107. package/dist/val/CloseFuncVal.js.map +1 -1
  108. package/dist/val/ConjunctVal.d.ts +1 -1
  109. package/dist/val/ConjunctVal.js +19 -0
  110. package/dist/val/ConjunctVal.js.map +1 -1
  111. package/dist/val/ConstraintVal.d.ts +7 -1
  112. package/dist/val/ConstraintVal.js +523 -45
  113. package/dist/val/ConstraintVal.js.map +1 -1
  114. package/dist/val/ContainerKindVal.d.ts +35 -0
  115. package/dist/val/ContainerKindVal.js +99 -0
  116. package/dist/val/ContainerKindVal.js.map +1 -0
  117. package/dist/val/CopyFuncVal.d.ts +1 -2
  118. package/dist/val/CopyFuncVal.js.map +1 -1
  119. package/dist/val/Decimal.d.ts +1 -0
  120. package/dist/val/Decimal.js +13 -0
  121. package/dist/val/Decimal.js.map +1 -1
  122. package/dist/val/DeprecateFuncVal.d.ts +11 -0
  123. package/dist/val/DeprecateFuncVal.js +47 -0
  124. package/dist/val/DeprecateFuncVal.js.map +1 -0
  125. package/dist/val/DisjunctVal.d.ts +1 -2
  126. package/dist/val/DisjunctVal.js +269 -53
  127. package/dist/val/DisjunctVal.js.map +1 -1
  128. package/dist/val/EachFuncVal.d.ts +15 -0
  129. package/dist/val/EachFuncVal.js +75 -0
  130. package/dist/val/EachFuncVal.js.map +1 -0
  131. package/dist/val/ExpectVal.js +62 -4
  132. package/dist/val/ExpectVal.js.map +1 -1
  133. package/dist/val/FeatureVal.js +1 -1
  134. package/dist/val/FeatureVal.js.map +1 -1
  135. package/dist/val/FilterFuncVal.d.ts +15 -0
  136. package/dist/val/FilterFuncVal.js +91 -0
  137. package/dist/val/FilterFuncVal.js.map +1 -0
  138. package/dist/val/FuncBaseVal.d.ts +7 -1
  139. package/dist/val/FuncBaseVal.js +183 -2
  140. package/dist/val/FuncBaseVal.js.map +1 -1
  141. package/dist/val/GraphAtomVal.d.ts +39 -0
  142. package/dist/val/GraphAtomVal.js +184 -0
  143. package/dist/val/GraphAtomVal.js.map +1 -0
  144. package/dist/val/HideFuncVal.js.map +1 -1
  145. package/dist/val/JunctionVal.js +24 -1
  146. package/dist/val/JunctionVal.js.map +1 -1
  147. package/dist/val/KeyFuncVal.d.ts +1 -1
  148. package/dist/val/KeyFuncVal.js +38 -30
  149. package/dist/val/KeyFuncVal.js.map +1 -1
  150. package/dist/val/ListVal.js +94 -14
  151. package/dist/val/ListVal.js.map +1 -1
  152. package/dist/val/LowerFuncVal.js.map +1 -1
  153. package/dist/val/MapVal.d.ts +1 -0
  154. package/dist/val/MapVal.js +146 -14
  155. package/dist/val/MapVal.js.map +1 -1
  156. package/dist/val/MatchFuncVal.d.ts +15 -0
  157. package/dist/val/MatchFuncVal.js +107 -0
  158. package/dist/val/MatchFuncVal.js.map +1 -0
  159. package/dist/val/MoveFuncVal.js.map +1 -1
  160. package/dist/val/NilVal.js +24 -0
  161. package/dist/val/NilVal.js.map +1 -1
  162. package/dist/val/OpBaseVal.d.ts +1 -1
  163. package/dist/val/OpBaseVal.js +19 -1
  164. package/dist/val/OpBaseVal.js.map +1 -1
  165. package/dist/val/OpenFuncVal.js +4 -1
  166. package/dist/val/OpenFuncVal.js.map +1 -1
  167. package/dist/val/PackFuncVal.d.ts +15 -0
  168. package/dist/val/PackFuncVal.js +108 -0
  169. package/dist/val/PackFuncVal.js.map +1 -0
  170. package/dist/val/PathFuncVal.d.ts +2 -2
  171. package/dist/val/PathFuncVal.js +75 -16
  172. package/dist/val/PathFuncVal.js.map +1 -1
  173. package/dist/val/PathVal.d.ts +25 -0
  174. package/dist/val/PathVal.js +150 -0
  175. package/dist/val/PathVal.js.map +1 -0
  176. package/dist/val/PlaceVal.d.ts +13 -0
  177. package/dist/val/PlaceVal.js +131 -0
  178. package/dist/val/PlaceVal.js.map +1 -0
  179. package/dist/val/PlusOpVal.d.ts +2 -1
  180. package/dist/val/PlusOpVal.js +61 -37
  181. package/dist/val/PlusOpVal.js.map +1 -1
  182. package/dist/val/PrefFuncVal.js.map +1 -1
  183. package/dist/val/PrefVal.d.ts +4 -2
  184. package/dist/val/PrefVal.js +223 -41
  185. package/dist/val/PrefVal.js.map +1 -1
  186. package/dist/val/RecurseVal.d.ts +19 -0
  187. package/dist/val/RecurseVal.js +217 -0
  188. package/dist/val/RecurseVal.js.map +1 -0
  189. package/dist/val/RefVal.d.ts +3 -2
  190. package/dist/val/RefVal.js +181 -66
  191. package/dist/val/RefVal.js.map +1 -1
  192. package/dist/val/ReferFuncVal.d.ts +59 -0
  193. package/dist/val/ReferFuncVal.js +604 -0
  194. package/dist/val/ReferFuncVal.js.map +1 -0
  195. package/dist/val/ScalarKindVal.d.ts +4 -3
  196. package/dist/val/ScalarKindVal.js +12 -12
  197. package/dist/val/ScalarKindVal.js.map +1 -1
  198. package/dist/val/SuperFuncVal.d.ts +4 -2
  199. package/dist/val/SuperFuncVal.js +118 -14
  200. package/dist/val/SuperFuncVal.js.map +1 -1
  201. package/dist/val/TopVal.d.ts +1 -1
  202. package/dist/val/TopVal.js.map +1 -1
  203. package/dist/val/TypeFuncVal.js.map +1 -1
  204. package/dist/val/UpperFuncVal.js.map +1 -1
  205. package/dist/val/Val.d.ts +7 -1
  206. package/dist/val/Val.js +170 -2
  207. package/dist/val/Val.js.map +1 -1
  208. package/dist/val/VarVal.js.map +1 -1
  209. package/dist/val/arith.d.ts +6 -0
  210. package/dist/val/arith.js +173 -0
  211. package/dist/val/arith.js.map +1 -0
  212. package/dist/vet.d.ts +45 -0
  213. package/dist/vet.js +802 -0
  214. package/dist/vet.js.map +1 -0
  215. package/dist/view.d.ts +85 -0
  216. package/dist/view.js +1948 -0
  217. package/dist/view.js.map +1 -0
  218. package/dist/walk.d.ts +2 -0
  219. package/dist/walk.js +91 -0
  220. package/dist/walk.js.map +1 -0
  221. package/grammar/aontu.gbnf +138 -0
  222. package/grammar/aontu.lark +118 -0
  223. package/grammar/aontu.tmLanguage.json +184 -0
  224. package/package.json +30 -8
  225. package/skill/SKILL.md +37 -0
  226. package/skill/error-codes.md +62 -0
  227. package/skill/examples.md +99 -0
  228. package/skill/grammar-card.md +56 -0
  229. package/src/agentsmd.ts +135 -0
  230. package/src/aontu.ts +166 -5
  231. package/src/cli.ts +3324 -72
  232. package/src/ctx.ts +93 -1
  233. package/src/diff.ts +198 -0
  234. package/src/err.ts +50 -8
  235. package/src/graph.ts +185 -0
  236. package/src/hcanon.ts +167 -0
  237. package/src/hints.ts +291 -8
  238. package/src/jsonschema.ts +552 -0
  239. package/src/lang.ts +1049 -110
  240. package/src/lsp.ts +351 -49
  241. package/src/mcp-server.ts +187 -0
  242. package/src/mcp.ts +1130 -0
  243. package/src/mod-tool.ts +718 -0
  244. package/src/mod.ts +453 -0
  245. package/src/patch.ts +628 -0
  246. package/src/provenance.ts +437 -0
  247. package/src/query.ts +381 -0
  248. package/src/reach.ts +213 -0
  249. package/src/relation.ts +298 -0
  250. package/src/report-sarif.ts +137 -0
  251. package/src/sig.ts +345 -0
  252. package/src/sigdecl.ts +11 -0
  253. package/src/siggate.ts +144 -0
  254. package/src/site.ts +36 -1
  255. package/src/std.ts +131 -0
  256. package/src/subsume.ts +739 -0
  257. package/src/trim.ts +195 -0
  258. package/src/tsconfig.json +10 -4
  259. package/src/type.ts +51 -2
  260. package/src/unify.ts +253 -38
  261. package/src/utility.ts +79 -1
  262. package/src/val/AggFuncVal.ts +546 -0
  263. package/src/val/ArithFuncVal.ts +108 -0
  264. package/src/val/BagVal.ts +158 -12
  265. package/src/val/CloseFuncVal.ts +9 -1
  266. package/src/val/ConjunctVal.ts +20 -0
  267. package/src/val/ConstraintVal.ts +576 -48
  268. package/src/val/ContainerKindVal.ts +158 -0
  269. package/src/val/CopyFuncVal.ts +0 -1
  270. package/src/val/Decimal.ts +15 -0
  271. package/src/val/DeprecateFuncVal.ts +84 -0
  272. package/src/val/DisjunctVal.ts +282 -59
  273. package/src/val/EachFuncVal.ts +133 -0
  274. package/src/val/ExpectVal.ts +65 -8
  275. package/src/val/FeatureVal.ts +1 -1
  276. package/src/val/FilterFuncVal.ts +154 -0
  277. package/src/val/FuncBaseVal.ts +206 -2
  278. package/src/val/GraphAtomVal.ts +264 -0
  279. package/src/val/HideFuncVal.ts +0 -2
  280. package/src/val/JunctionVal.ts +24 -1
  281. package/src/val/KeyFuncVal.ts +39 -35
  282. package/src/val/ListVal.ts +101 -15
  283. package/src/val/LowerFuncVal.ts +0 -1
  284. package/src/val/MapVal.ts +153 -14
  285. package/src/val/MatchFuncVal.ts +176 -0
  286. package/src/val/MoveFuncVal.ts +0 -2
  287. package/src/val/NilVal.ts +25 -0
  288. package/src/val/OpBaseVal.ts +20 -1
  289. package/src/val/OpenFuncVal.ts +4 -2
  290. package/src/val/PackFuncVal.ts +175 -0
  291. package/src/val/PathFuncVal.ts +107 -20
  292. package/src/val/PathVal.ts +221 -0
  293. package/src/val/PlaceVal.ts +193 -0
  294. package/src/val/PlusOpVal.ts +67 -39
  295. package/src/val/PrefFuncVal.ts +0 -1
  296. package/src/val/PrefVal.ts +251 -60
  297. package/src/val/RecurseVal.ts +285 -0
  298. package/src/val/RefVal.ts +183 -78
  299. package/src/val/ReferFuncVal.ts +732 -0
  300. package/src/val/ScalarKindVal.ts +12 -13
  301. package/src/val/SuperFuncVal.ts +137 -13
  302. package/src/val/TopVal.ts +1 -2
  303. package/src/val/TypeFuncVal.ts +0 -2
  304. package/src/val/UpperFuncVal.ts +0 -1
  305. package/src/val/Val.ts +216 -4
  306. package/src/val/VarVal.ts +0 -1
  307. package/src/val/arith.ts +319 -0
  308. package/src/vet.ts +1025 -0
  309. package/src/view.ts +2563 -0
  310. package/src/walk.ts +99 -0
@@ -11,21 +11,52 @@ import {
11
11
 
12
12
  import { AontuContext } from '../ctx'
13
13
  import { unite } from '../unify'
14
- import { AontuError } from '../err'
14
+ import { AontuError, makeNilErr } from '../err'
15
15
 
16
16
  import {
17
17
  explainOpen,
18
18
  ec,
19
- explainClose,
19
+ explainClose
20
20
  } from '../utility'
21
21
 
22
22
 
23
23
  import { top } from './top'
24
24
 
25
25
  import { FeatureVal } from './FeatureVal'
26
- import { ScalarKindVal, kindFamily } from './ScalarKindVal'
26
+ import { trialUnify } from './FuncBaseVal'
27
+ import { superOf } from './SuperFuncVal'
28
+
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
+ function prefInnerPeg(v: Val): Val {
36
+ let out: any = v
37
+ while (true === out?.isPref) {
38
+ out = out.peg
39
+ }
40
+ return out
41
+ }
27
42
 
28
43
 
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.
29
60
  class PrefVal extends FeatureVal {
30
61
  isPref = true
31
62
  isGenable = true
@@ -37,22 +68,40 @@ class PrefVal extends FeatureVal {
37
68
  // Both are assigned by resuper(), called from the constructor.
38
69
  superpeg!: Val
39
70
 
40
- // The gate an overriding peer must pass. A preference is a DEFAULT, so
41
- // a concrete peer replaces it -- but only within the preferred value's
42
- // FAMILY: `*lower(1.1) & a` is a conflict, not an override.
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.
43
81
  //
44
- // Family and not leaf, because the number tower made `integer` and
45
- // `float` disjoint siblings under `number`. Gating on the leaf would
46
- // turn `*lower(2.2) & 3` (a float default overridden by an integer)
47
- // into an error, which is a tightening no document asked for; gating
48
- // on the family keeps it working and makes the mirror case
49
- // (`*2 & 3.0`, an error before the tower) work too. For every
50
- // non-numeric value the family root IS the leaf, so this is the
51
- // preferred value's type as before.
52
- familypeg!: Val
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.
53
93
 
54
94
  rank: number = 0
55
95
 
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
+ narrowed?: Val
104
+
56
105
  constructor(
57
106
  spec: ValSpec,
58
107
  ctx?: AontuContext
@@ -66,45 +115,66 @@ class PrefVal extends FeatureVal {
66
115
  this.rank = 1 + spec.peg.rank
67
116
  }
68
117
 
69
- this.resuper()
118
+ this.resuper(ctx)
70
119
  // console.log('PVC', this.peg.canon, this.superpeg.canon)
71
120
  }
72
121
 
73
122
 
74
123
  // Recompute the type yardstick and the override gate from the current
75
124
  // peg. Called again whenever the peg resolves (e.g. a ref).
76
- private resuper() {
77
- const peg: any = this.peg
78
-
79
- // A preference whose peg is ITSELF a kind (`*integer`) constrains
80
- // nothing: there is no type-of-a-type in this lattice, so any peer
81
- // wins. (Pinned by test/spec/var.tsv:var-pref-kind-narrow. Before
82
- // the tower this fell out of a ScalarKindVal's superior being top;
83
- // now that a leaf kind lifts to `number`, it has to be said.)
84
- if (true === peg.isScalarKind) {
85
- this.superpeg = top()
86
- this.familypeg = this.superpeg
87
- return
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
+ 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
+ let peg: any = this.peg
150
+ while (true === peg?.isPref) {
151
+ peg = peg.peg
88
152
  }
89
153
 
90
- const sup: any = peg.superior()
91
- this.superpeg = sup
92
-
93
- // No optional chain: superior() is contractually non-null (every
94
- // Val returns one, a NilVal returning itself), so guarding against
95
- // nullish here would claim a possibility the type does not have.
96
- if (true === sup.isScalarKind) {
97
- const family = kindFamily(sup.peg)
98
- // The gate stands in for the preferred value in any conflict it
99
- // reports, so it must carry the same site and path as the type it
100
- // widens -- otherwise NilVal.make picks a different primary and
101
- // the error moves to the wrong path.
102
- this.familypeg = family === sup.peg ?
103
- sup : sup.place(new ScalarKindVal({ peg: family, path: sup.path }))
104
- }
105
- else {
106
- this.familypeg = sup
154
+ const base = superOf(ctx as AontuContext, peg)
155
+
156
+ // A gate that a meet has already narrowed stays narrowed: the
157
+ // override space only ever shrinks.
158
+ this.superpeg = null == this.narrowed ? base
159
+ : unite(ctx as AontuContext, base, this.narrowed,
160
+ 'pref-narrow/' + this.id)
161
+ }
162
+
163
+
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
+ private restand(met: Val, ctx: AontuContext): Val {
173
+ let out: Val = met
174
+ for (let rI = 0; rI <= this.rank; rI++) {
175
+ out = new PrefVal({ peg: out }, ctx)
107
176
  }
177
+ return this.place(out)
108
178
  }
109
179
 
110
180
 
@@ -122,9 +192,27 @@ class PrefVal extends FeatureVal {
122
192
  this.peg, top(), 'pref/resolve')
123
193
  // console.log('PREF-RESOLVED', this.peg.canon, '->', resolved)
124
194
  this.peg = resolved
125
- this.resuper()
195
+ this.resuper(ctx)
126
196
  }
127
197
 
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
+
128
216
  if (peer instanceof PrefVal) {
129
217
  why += 'pref-'
130
218
  if (this.id === peer.id) {
@@ -152,9 +240,20 @@ class PrefVal extends FeatureVal {
152
240
  // peer.peg.id, peer.peg, peer.peg.done,
153
241
  // )
154
242
 
155
- let peg = unite(te ? ctx.clone({ explain: ec(te, 'PREF-PEER') }) : ctx,
156
- this.peg, peer.peg, 'pref-peer/' + this.id)
157
- out = new PrefVal({ peg }, ctx)
243
+ const peg = trialUnify(ctx, prefInnerPeg(this).clone(ctx),
244
+ prefInnerPeg(peer))
245
+
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
+ out = undefined === peg
255
+ ? makeNilErr(ctx, 'pref_rank_clash', this, peer, 'unify')
256
+ : this.restand(peg, ctx)
158
257
  // console.log('PREF-RANK-SAME-OUT', peg, peg.done, out, out.done)
159
258
  why += 'rank-same'
160
259
  }
@@ -162,17 +261,84 @@ class PrefVal extends FeatureVal {
162
261
  else if (!peer.isTop) {
163
262
  why += 'super-'
164
263
 
165
- out = unite(te ? ctx.clone({ explain: ec(te, 'SUPER') }) : ctx,
166
- this.familypeg, peer, 'pref-super/' + this.id)
167
-
168
- // The peer added nothing beyond a type the preferred value already
169
- // satisfies (`*1 & integer`, `*1 & number`), so the preference
170
- // stands. Anything else is a concrete override and wins.
171
- if (out.same(this.superpeg) || out.same(this.familypeg)) {
172
- out = this.peg
173
- why += 'same'
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
+ const met = trialUnify(ctx, prefInnerPeg(this).clone(ctx), peer)
292
+
293
+ 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
+ const gate = unite(te ? ctx.clone({ explain: ec(te, 'GATE') }) : ctx,
307
+ this.superpeg.clone(ctx), peer, 'pref-gate/' + this.id)
308
+
309
+ // Unchanged on both counts is the SAME preference, returned as
310
+ // itself: minting a new one every pass would keep the fixpoint
311
+ // moving for ever.
312
+ if (met.same(prefInnerPeg(this)) && gate.same(this.superpeg)) {
313
+ out = this
314
+ }
315
+ else {
316
+ const stood = this.restand(met, ctx) as PrefVal
317
+ stood.narrowed = gate
318
+ stood.superpeg = gate
319
+ out = stood
320
+ }
321
+
322
+ why += 'stands'
323
+ explainClose(te, out)
324
+ out.dc = DONE
325
+ return out
174
326
  }
175
327
 
328
+ // The override arm is trialled too: its failure is not the
329
+ // answer, it is half of the reason the answer is `empty`, and a
330
+ // recorded `no_scalar_unify` would be the code the reader sees
331
+ // however the refusal is relabelled afterwards.
332
+ const over = trialUnify(ctx, this.superpeg.clone(ctx), peer)
333
+
334
+ out = undefined !== over ? over
335
+ // A peer that arrived already failed keeps its own refusal:
336
+ // that is its failure, not the default's.
337
+ : peer.isNil ? peer
338
+ : makeNilErr(ctx, 'empty', this, peer, 'unify')
339
+
340
+
341
+
176
342
  // }
177
343
  }
178
344
  else {
@@ -205,7 +371,31 @@ class PrefVal extends FeatureVal {
205
371
 
206
372
  clone(ctx: AontuContext, spec?: ValSpec): Val {
207
373
  let out = (super.clone(ctx, spec) as PrefVal)
208
- // out.pref = this.pref.clone(null, ctx)
374
+
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
+ if (null != this.narrowed) {
382
+ out.narrowed = this.narrowed
383
+ out.superpeg = this.superpeg
384
+ }
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
+ if (true === spec?.dup && true === (this.peg as any)?.isVal) {
397
+ out.peg = this.peg.clone(ctx, { dup: true })
398
+ }
209
399
  return out
210
400
  }
211
401
 
@@ -227,9 +417,10 @@ class PrefVal extends FeatureVal {
227
417
 
228
418
  return val.gen(ctx)
229
419
  }
230
- } /* node:coverage ignore next 6 */
420
+ } /* node:coverage ignore next 7 */
231
421
 
232
422
 
233
423
  export {
234
424
  PrefVal,
425
+ prefInnerPeg,
235
426
  }