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
@@ -64,6 +64,15 @@ class BigDecimal { }
64
64
  // A ScalarKind for null.
65
65
  class Null { }
66
66
 
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
+ class Path { }
75
+
67
76
 
68
77
  // The immediate lattice parent of each kind marker. A marker absent from
69
78
  // this table sits directly under top (string, boolean, null -- and
@@ -75,6 +84,7 @@ const KIND_PARENT = new Map<any, any>([
75
84
  [Float, Number],
76
85
  [BigInteger, Number],
77
86
  [BigDecimal, Number],
87
+ [Path, String],
78
88
  ])
79
89
 
80
90
 
@@ -85,18 +95,6 @@ function kindParent(kind: any): any {
85
95
  }
86
96
 
87
97
 
88
- // The root of a kind marker's family: the highest ancestor below top.
89
- // Every numeric leaf answers `number`; a kind with no parent is its own
90
- // family root (string, boolean, null).
91
- function kindFamily(kind: any): any {
92
- let root = kind
93
- for (let k = KIND_PARENT.get(kind); null != k; k = KIND_PARENT.get(k)) {
94
- root = k
95
- }
96
- return root
97
- }
98
-
99
-
100
98
  // True when `sub` is `sup`, or sits anywhere below it. The numeric
101
99
  // lattice is two deep today; walking the chain keeps this correct if it
102
100
  // ever deepens.
@@ -119,6 +117,7 @@ type ScalarConstructor =
119
117
  (typeof BigInteger) |
120
118
  (typeof BigDecimal) |
121
119
  (typeof Null) |
120
+ (typeof Path) |
122
121
  (typeof Integer.constructor)
123
122
 
124
123
 
@@ -228,9 +227,9 @@ export {
228
227
  Float,
229
228
  Integer,
230
229
  Null,
230
+ Path,
231
231
  ScalarConstructor,
232
232
  ScalarKindVal,
233
- kindFamily,
234
233
  kindParent,
235
234
  kindSubsumes,
236
235
  }
@@ -1,6 +1,16 @@
1
1
  /* Copyright (c) 2021-2025 Richard Rodger, MIT License */
2
2
 
3
3
 
4
+ // THE IMMEDIATE PARENT TYPE (docs/design/SUPER.0.md): super(x) answers
5
+ // the type one step above its argument, structurally. The lattice
6
+ // primitive Val.superior() stays what it always was -- the preference
7
+ // override gate and query's kind lift -- and answers here only for the
8
+ // forms it already served (scalars, kinds, top). Everything structural
9
+ // is this file's walk: maps and lists lift child by child, preferences
10
+ // unwrap, disjunctions distribute, constraints answer the kind they
11
+ // constrain, and a recursion residual stays a symbolic call -- the
12
+ // finite spelling of a lift that is itself recursive.
13
+
4
14
  import type {
5
15
  Val,
6
16
  ValSpec,
@@ -12,6 +22,11 @@ import {
12
22
 
13
23
 
14
24
  import { FuncBaseVal } from './FuncBaseVal'
25
+ import { MapVal } from './MapVal'
26
+ import { ListVal } from './ListVal'
27
+ import { DisjunctVal } from './DisjunctVal'
28
+ import { ScalarKindVal } from './ScalarKindVal'
29
+ import { top } from './top'
15
30
 
16
31
 
17
32
  class SuperFuncVal extends FuncBaseVal {
@@ -34,26 +49,135 @@ class SuperFuncVal extends FuncBaseVal {
34
49
  }
35
50
 
36
51
 
37
- resolve(_ctx: AontuContext, args: Val[]) {
38
- // super(x) is the lattice-superior of its ARGUMENT, not of the
39
- // super() call itself: super(1) -> integer, super(1.5) -> number,
40
- // super(a) -> string, super(true) -> boolean. Returning the
41
- // function's own superior (top) is what made super() inert.
42
- const arg: any = args?.[0]
43
- if (arg?.isVal) {
44
- const sup = arg.superior()
45
- // Where the argument has no meaningful superior (superior()
46
- // defaults to top), fall back to the previous behaviour.
47
- if (null != sup && true !== sup.isTop) {
48
- return this.place(sup)
52
+ // A DIRECT residual rides the residuate path rather than resolving:
53
+ // the pending call IS the answer (SUPER.0.md, the phase boundary),
54
+ // printing as written and refusing at generation exactly as an
55
+ // unexpanded recursion does. Residuals met DURING descent are minted
56
+ // as pending child calls by superOf below; only the top-level
57
+ // argument needs the defer, or resolve would re-mint the same call
58
+ // inside one pass forever.
59
+ deferResolve(_ctx: AontuContext, args?: Val[]): boolean {
60
+ return true === (args?.[0] as any)?.isRecurse
61
+ }
62
+
63
+
64
+ resolve(ctx: AontuContext, args: Val[]) {
65
+ // One argument, always a Val: funcArity pins super at [1,1]
66
+ // before any resolve, and the parser builds arguments as Vals --
67
+ // a guarded fallback here is dead code under ADR-002.
68
+ return this.place(superOf(ctx, args[0]))
69
+ }
70
+
71
+ }
72
+
73
+
74
+ // superOf answers the immediate parent type of a RESOLVED value (the
75
+ // caller drives arguments before resolve fires, so pending forms --
76
+ // held conjuncts, unresolved references, holes -- never arrive).
77
+ function superOf(ctx: AontuContext, v: any): Val {
78
+ // The residual's lift is itself recursive, so the finite answer is
79
+ // the symbolic call (SUPER.0.md): a fresh pending super() holding a
80
+ // clone of the residual, standing wherever the residual stood --
81
+ // the `next?` slot of a lifted recursive body prints
82
+ // `super($.Node)` and drops under an optional key at generation.
83
+ if (true === v.isRecurse) {
84
+ const call = new SuperFuncVal({ peg: [v.clone(ctx)] }, ctx)
85
+ return v.place(call)
86
+ }
87
+
88
+ // Maps and lists lift child by child. Shape is carried, not lifted:
89
+ // key optionality and closedness describe the container, and the
90
+ // spread template lifts so the result admits at the lifted level
91
+ // for future keys exactly as the original admitted at its own.
92
+ // A fresh bag (ADR-005 instantiation): type/hide marks are not
93
+ // copied -- the lift of a hidden definition is output.
94
+ if (true === v.isMap) {
95
+ const peg: Record<string, Val> = {}
96
+ for (const k of Object.keys(v.peg)) {
97
+ peg[k] = superOf(ctx, v.peg[k])
98
+ }
99
+ const out: any = new MapVal({ peg }, ctx)
100
+ out.optionalKeys = [...v.optionalKeys]
101
+ out.closed = v.closed
102
+ if (null != v.spread?.cj) {
103
+ out.spread.cj = superOf(ctx, v.spread.cj)
104
+ }
105
+ return v.place(out)
106
+ }
107
+
108
+ if (true === v.isList) {
109
+ const peg: Val[] = v.peg.map((e: Val) => superOf(ctx, e))
110
+ const out: any = new ListVal({ peg }, ctx)
111
+ out.closed = v.closed
112
+ if (null != v.spread?.cj) {
113
+ out.spread.cj = superOf(ctx, v.spread.cj)
114
+ }
115
+ return v.place(out)
116
+ }
117
+
118
+ // The parent TYPE of a soft value is the parent of the value --
119
+ // softness does not survive typing. Deliberately NOT superpeg,
120
+ // whose top-for-a-kind answer is override-gate semantics.
121
+ if (true === v.isPref) {
122
+ return superOf(ctx, v.peg)
123
+ }
124
+
125
+ // A choice lifts arm by arm: super(1|2) is integer, super(1|"a") is
126
+ // integer|string. An arm whose lift is top absorbs the whole answer
127
+ // -- a disjunct carrying top says nothing -- and duplicate lifts
128
+ // collapse so the common case answers as the one kind it is.
129
+ if (true === v.isDisjunct) {
130
+ const arms: Val[] = []
131
+ const seen: Record<string, boolean> = {}
132
+ for (const a of v.peg) {
133
+ const lift = superOf(ctx, a)
134
+ if (true === (lift as any).isTop) {
135
+ return v.place(top())
136
+ }
137
+ if (true !== seen[lift.canon]) {
138
+ seen[lift.canon] = true
139
+ arms.push(lift)
49
140
  }
50
141
  }
51
- return this.place(this.superior())
142
+ if (1 === arms.length) {
143
+ return v.place(arms[0])
144
+ }
145
+ return v.place(new DisjunctVal({ peg: arms }, ctx))
52
146
  }
53
147
 
148
+ // A constraint's parent is the kind it constrains: the absorbed
149
+ // leaf kind when it has one (integer & min(3) -> integer), else the
150
+ // domain its atoms compare in (min(3) -> number, min("a") ->
151
+ // string). length() constrains strings, lists and maps alike, so
152
+ // with neither it falls through to top.
153
+ if (true === v.isConstraint) {
154
+ if (null != v.kind) {
155
+ return v.place(new ScalarKindVal({ peg: v.kind }))
156
+ }
157
+ if ('number' === v.domain) {
158
+ return v.place(new ScalarKindVal({ peg: Number }))
159
+ }
160
+ if ('string' === v.domain) {
161
+ return v.place(new ScalarKindVal({ peg: String }))
162
+ }
163
+ return v.place(top())
164
+ }
165
+
166
+ // The lattice primitive answers for the forms it always served:
167
+ // a concrete scalar lifts to its leaf kind, a kind to its parent,
168
+ // top to itself, and a NIL to itself -- which is how a failed
169
+ // argument stays the failure: `super(1 & 2)` reports the conflict
170
+ // rather than typing it. Where it has no meaningful answer (superior()
171
+ // defaults to top for features), top is the honest remainder.
172
+ const sup = v.superior()
173
+ if (null != sup && true !== (sup as any).isTop) {
174
+ return sup
175
+ }
176
+ return v.place(top())
54
177
  } /* node:coverage ignore next 6 */
55
178
 
56
179
 
57
180
  export {
58
181
  SuperFuncVal,
182
+ superOf,
59
183
  }
package/src/val/TopVal.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  /* Copyright (c) 2021-2025 Richard Rodger, MIT License */
2
2
 
3
- import { inspect } from 'node:util'
4
3
 
5
4
  import type {
6
5
  ValSpec,
@@ -53,7 +52,7 @@ class TopVal extends Val {
53
52
  return this
54
53
  }
55
54
 
56
- clone(_ctx: AontuContext, _spec?: ValSpec) {
55
+ clone(_ctx: AontuContext, _spec?: ValSpec): Val {
57
56
  return this
58
57
  }
59
58
 
@@ -14,8 +14,6 @@ import { makeNilErr } from '../err'
14
14
 
15
15
  import {
16
16
  walk,
17
- explainOpen,
18
- explainClose,
19
17
  } from '../utility'
20
18
 
21
19
 
@@ -13,7 +13,6 @@ import {
13
13
  import { makeNilErr } from '../err'
14
14
 
15
15
 
16
- import { NilVal } from '../val/NilVal'
17
16
  import { ScalarKindVal } from '../val/ScalarKindVal'
18
17
  import { makeScalarLike } from '../val/valutil'
19
18
  import { Decimal } from '../val/Decimal'
package/src/val/Val.ts CHANGED
@@ -8,6 +8,8 @@ import {
8
8
  Site
9
9
  } from '../site'
10
10
 
11
+ import { INNER_OF, WRITTEN } from '../provenance'
12
+
11
13
 
12
14
  type ValMark = {
13
15
  type: boolean,
@@ -22,6 +24,21 @@ type ValSpec = {
22
24
  mark?: Partial<ValMark>,
23
25
  kind?: any,
24
26
 
27
+ // THE PER-DESTINATION INSTANTIATION FLAG (ADR-005). A generator's
28
+ // template is cloned once per destination, and every clone must be
29
+ // a full instance: nothing path-dependent may be shared between two
30
+ // destinations, or the first destination's resolution answers for
31
+ // them all. The default clone shares inner structure deliberately
32
+ // (`peg: this.peg` below — the move()/copy() ghost rows in
33
+ // test/spec/func.tsv pin that sharing), so instantiation asks for
34
+ // depth explicitly: `dup: true` makes FuncBaseVal, PrefVal and
35
+ // OpBaseVal clone their inner Vals too, and the bag/junction clones
36
+ // carry the flag down. Set by pack/each template instantiation,
37
+ // filter condition testing, and spread application (MapVal/
38
+ // ListVal.spreadClone) — never by the residuation or ref-resolution
39
+ // clones, whose sharing is pinned behaviour.
40
+ dup?: boolean,
41
+
25
42
 
26
43
  row?: number,
27
44
  col?: number,
@@ -134,6 +151,28 @@ abstract class Val {
134
151
  hide: false,
135
152
  }
136
153
 
154
+ // The deprecation record (G3 phase 4, `deprecate(x, m)`): boolean
155
+ // marks cannot hold a message, a replacement path and a version, so
156
+ // the Val carries one optional record. Keys are the three the
157
+ // builtin defines (msg, use, since), all optional, values strings;
158
+ // `use` is a path spelled as a STRING — a live reference would
159
+ // resolve and unify, which is not wanted. Propagated through meets
160
+ // by propagateMarks and carried by clone, exactly as the boolean
161
+ // marks are.
162
+ deprecation?: Record<string, string>
163
+
164
+ // The LINK (G4 phase 2/3): the tree address a `refer` resolved to,
165
+ // stamped on the string it answers. The string IS the value — a
166
+ // link, not an embedding — so nothing downstream could otherwise
167
+ // tell a checked link from a literal that happens to look like one,
168
+ // and the edge set (ts/src/graph.ts) is exactly the set of these.
169
+ link?: string
170
+
171
+ // The GRAPH of an evaluated document (G4 phase 3): the edge set,
172
+ // stamped on the result by Aontu.unify the way the include manifest
173
+ // is. Absent on every Val that is not a unify result.
174
+ graph?: any
175
+
137
176
  // Actual native value.
138
177
  peg: any = undefined
139
178
 
@@ -225,11 +264,85 @@ abstract class Val {
225
264
  out.site.row = spec?.row ?? this.site.row
226
265
  out.site.col = spec?.col ?? this.site.col
227
266
  out.site.url = spec?.url ?? this.site.url
267
+ // THE SPAN TRAVELS WITH THE POSITION. Copying row and col but not
268
+ // the extent would leave a site that names a place and denies it has
269
+ // any width — internally inconsistent, and it made the two ports
270
+ // disagree on every derived value (the shared subsume rows caught
271
+ // it). Safe because the span is VERIFIABLE: a consumer reads the
272
+ // document at (row, col, len) and refuses when it does not match
273
+ // `src`, so a span that has stopped describing its value is
274
+ // detectable rather than believed. See ts/src/site.ts.
275
+ //
276
+ // Read from `this.site`, never from the spec: ValSpec.src is a
277
+ // DIFFERENT field — ScalarVal's literal spelling, kept so `$.a.0x0`
278
+ // addresses the key `0x0` — and reading it here would put a path
279
+ // segment where a source span belongs.
280
+ //
281
+ // UNCONDITIONAL, as the Go twin is (clonePath, go/clone.go). A
282
+ // guard dropping the span when the spec relocates the value was
283
+ // written first and the coverage gate refused it as dead: nothing
284
+ // clones to a new row or column. Should a relocating caller ever
285
+ // appear it must drop both fields — an extent belongs to a place,
286
+ // and the text at a new one is not this value's to claim.
287
+ out.site.len = this.site.len
288
+ out.site.src = this.site.src
228
289
 
229
290
  out.mark = Object.assign({}, this.mark, fullspec.mark ?? {})
230
291
  out.mark.type = this.mark.type && (fullspec.mark?.type ?? true)
231
292
  out.mark.hide = this.mark.hide && (fullspec.mark?.hide ?? true)
232
293
 
294
+ // The LINK rider travels with the clone: the address a resolved
295
+ // link POINTS AT is part of what the value is, and a copy of a
296
+ // link is still a link.
297
+ if (null != this.link) {
298
+ out.link = this.link
299
+ }
300
+ if (null != this.deprecation) {
301
+ out.deprecation = this.deprecation
302
+ }
303
+
304
+ // THE APPLY-ONCE MARK TRAVELS WITH THE CLONE. `_spr` records which
305
+ // spread template has already been merged into this value, and the
306
+ // bag loops read it to keep a template from being applied twice
307
+ // (MapVal.unify, ListVal.unify). A clone that dropped it looked
308
+ // un-spread, so a REFERENCE resolving to a templated bag had the
309
+ // template applied a second time -- over the value the first
310
+ // application had already produced. With `n: key()` that meant
311
+ // meeting the answered `"x"` as though it were a map and asking
312
+ // `key()` again, which answered `"n"`: `$.a.b.f.x.n.n`, "n"
313
+ // against "x" (use-cases/BUGS.md §50). The Go port carries it and
314
+ // answered correctly; this is the canonical side catching up.
315
+ if (null != (this as any)._spr) {
316
+ ; (out as any)._spr = (this as any)._spr
317
+ }
318
+ if (null != (this as any)._sid) {
319
+ ; (out as any)._sid = (this as any)._sid
320
+ }
321
+
322
+ // PROVENANCE TRAVELS WITH THE CLONE, exactly as the site does, and
323
+ // for the same reason: a clone of a value the author wrote IS that
324
+ // written value somewhere else, and it carries the author's site,
325
+ // so it can be pointed at. Without this a default reaching a
326
+ // `pack()`-generated child, or a shape carried by a `$ref`, was
327
+ // invisible to `why` -- which answered "nothing met at this path"
328
+ // over a value it had just printed (the review's finding E). See
329
+ // WRITTEN in ts/src/provenance.ts; the mark is only ever set by an
330
+ // instrumented run, so this is one undefined read otherwise.
331
+ if (true === (this as any)[WRITTEN]) {
332
+ (out as any)[WRITTEN] = true
333
+ }
334
+ // AND SO DOES BEING PART OF SOMETHING. A clone of a disjunction's
335
+ // member is still that member of that written disjunction, and the
336
+ // whole statement is what the author needs shown -- otherwise a
337
+ // default reaching a generated child reports `*"info"` and
338
+ // `string` as two contributions at two columns, where the author
339
+ // wrote `*info | string` once. A number, deliberately: a Val
340
+ // holding another Val as an own property is a cycle through the
341
+ // tree. See INNER_OF in ts/src/provenance.ts.
342
+ if (null != (this as any)[INNER_OF]) {
343
+ (out as any)[INNER_OF] = (this as any)[INNER_OF]
344
+ }
345
+
233
346
  return out
234
347
  }
235
348
 
@@ -237,8 +350,17 @@ abstract class Val {
237
350
  // Shallow clone for spread constraints: creates a new Val with the
238
351
  // correct path context but shares non-path-dependent children.
239
352
  // Override in MapVal/ListVal to avoid deep-cloning simple children.
353
+ //
354
+ // A FULL INSTANCE (`dup`, ADR-005): a spread constraint is applied
355
+ // once per destination child, and each application must own its
356
+ // path-dependent innards — a bare clone shared a call's arguments
357
+ // and a preference's inner value across destinations, so a spread
358
+ // like `&: {k: key(0)} & $.schema.C` resolved its one shared key()
359
+ // at the first child it met (use-cases/BUGS.md §12's id_name form).
240
360
  spreadClone(ctx: AontuContext): Val {
241
- return this.clone(ctx)
361
+ const out = this.clone(ctx, { dup: true })
362
+ repathInstance(out, out.path)
363
+ return out
242
364
  }
243
365
 
244
366
 
@@ -278,10 +400,26 @@ abstract class Val {
278
400
  }
279
401
 
280
402
 
403
+ // PUT A MINTED VALUE WHERE THIS ONE STANDS: the site travels, and so
404
+ // does provenance, because the two answer one question. A narrowed
405
+ // disjunction, a lifted kind, a resolved reference -- each is a
406
+ // value the engine built from a value the author wrote, standing
407
+ // where that one stood. Carrying the site and withholding the mark
408
+ // would let `why` print a value, know the line it came from, and
409
+ // still answer "nothing met at this path" (the review's finding E).
410
+ // See WRITTEN and INNER_OF in ts/src/provenance.ts.
281
411
  place(v: Val) {
282
412
  v.site.row = this.site.row
283
413
  v.site.col = this.site.col
284
414
  v.site.url = this.site.url
415
+ v.site.len = this.site.len
416
+ v.site.src = this.site.src
417
+ if (true === (this as any)[WRITTEN]) {
418
+ (v as any)[WRITTEN] = true
419
+ }
420
+ if (null != (this as any)[INNER_OF]) {
421
+ (v as any)[INNER_OF] = (this as any)[INNER_OF]
422
+ }
285
423
  return v
286
424
  }
287
425
 
@@ -431,6 +569,64 @@ Object.assign(Val.prototype, {
431
569
  })
432
570
 
433
571
 
572
+ // THE INSTANCE PATH NORMALISATION (ADR-005), the TS mirror of the Go
573
+ // port's setPaths (go/clone.go): assign every value in a freshly
574
+ // instantiated template the path the PARSER would have given it at the
575
+ // instance's destination. A deep instance clone (`dup`) copies values
576
+ // whose stored parse paths are argument-shaped — a func argument has
577
+ // no key of its own, a spread template lives under a '&' segment — and
578
+ // Val.clone's ctx-cut cannot rebase those: it derives the child path
579
+ // from the driving ctx alone and drops the segments in between, which
580
+ // is how a nested list spread inside a close()d template lost its
581
+ // parent key and every finding under it named the wrong path (the
582
+ // 06-k8s use case's env findings). One canonical walk instead:
583
+ // bag children descend by key (numeric for a list element, as the
584
+ // parser records them), a spread constraint sits under '&' with its
585
+ // content at the bag's own path, and junction members, operator
586
+ // operands, function arguments and a preference's value all sit AT
587
+ // their holder's path — exactly the parse-time shape.
588
+ function repathInstance(v: any, path: string[]): void {
589
+ if (true !== v?.isVal) {
590
+ return
591
+ }
592
+ v.path = path
593
+
594
+ const peg = v.peg
595
+
596
+ if (true === v.isBag) {
597
+ const spread = v.spread?.cj
598
+ if (null != spread && true === spread.isVal) {
599
+ // The spread's CONTENT is pathed at the bag (its fields land on
600
+ // the bag's children); only its ROOT carries the '&' segment —
601
+ // the same two steps as the Go twin's setPaths.
602
+ repathInstance(spread, path)
603
+ spread.path = [...path, '&']
604
+ }
605
+ if (true === v.isList) {
606
+ for (let i = 0; i < peg.length; i++) {
607
+ // Numeric, as the parser records list positions: a numeric
608
+ // segment is what tells key() an element is not a keyed
609
+ // position (KeyFuncVal.resolve, `positioned`).
610
+ repathInstance(peg[i], [...path, i as unknown as string])
611
+ }
612
+ }
613
+ else {
614
+ for (const k of Object.keys(peg)) {
615
+ repathInstance(peg[k], [...path, k])
616
+ }
617
+ }
618
+ }
619
+ else if (Array.isArray(peg)) {
620
+ for (const t of peg) {
621
+ repathInstance(t, path)
622
+ }
623
+ }
624
+ else if (true === peg?.isVal) {
625
+ repathInstance(peg, path)
626
+ }
627
+ }
628
+
629
+
434
630
  function inspectpeg(peg: any, d: number) {
435
631
  const indent = ' '.repeat(d)
436
632
  return pretty(Array.isArray(peg) ?
@@ -454,14 +650,27 @@ function pretty(s: string) {
454
650
  }
455
651
 
456
652
 
653
+ // THE STABLE IDENTITY OF A SPREAD TEMPLATE, across clones. Every Val
654
+ // takes a fresh `id` when it is constructed, so the bag loops'
655
+ // apply-once mark -- which records WHICH template has already been
656
+ // merged into a value -- could never match after a clone: a reference
657
+ // resolving to a templated bag clones the bag AND its template, and the
658
+ // fresh template's id matched nothing, so the template was applied a
659
+ // second time over the value the first application had produced
660
+ // (use-cases/BUGS.md §50). The first call fixes the identity to the
661
+ // original's own id; Val.clone carries `_sid`, so every clone of that
662
+ // template answers with it.
663
+ function spreadId(cj: any): number {
664
+ return cj._sid ?? (cj._sid = cj.id)
665
+ }
666
+
457
667
  function empty(o: any) {
458
668
  return (
459
669
  (Array.isArray(o) && 0 === o.length)
460
670
  || (null != o && 'object' === typeof o && 0 === Object.keys(o).length)
461
671
  || false
462
672
  )
463
- } /* node:coverage ignore next 16 */
464
-
673
+ } /* node:coverage ignore next 17 */
465
674
 
466
675
 
467
676
  export type {
@@ -469,10 +678,13 @@ export type {
469
678
  ValSpec,
470
679
  }
471
680
 
681
+
472
682
  export {
683
+ spreadId,
473
684
  Val,
474
685
  DONE,
475
686
  SPREAD,
476
687
  EMPTY_ERR,
477
- empty
688
+ empty,
689
+ repathInstance,
478
690
  }
package/src/val/VarVal.ts CHANGED
@@ -24,7 +24,6 @@ import {
24
24
 
25
25
 
26
26
  import { StringVal } from './StringVal'
27
- import { NilVal } from './NilVal'
28
27
  import { FeatureVal } from './FeatureVal'
29
28
  import { NullVal } from './NullVal'
30
29
  import { BooleanVal } from './BooleanVal'