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
package/src/val/BagVal.ts CHANGED
@@ -30,6 +30,17 @@ abstract class BagVal extends FeatureVal {
30
30
  closed: boolean = false
31
31
  optionalKeys: string[] = []
32
32
 
33
+ // ALIAS DECLARATIONS, by key. `%uint8: …` binds a name for this file
34
+ // and is not a field of the document: it does not generate and does
35
+ // not appear in canon, so a document using aliases and its expanded
36
+ // twin are the SAME document and hash identically
37
+ // (docs/design/ALIASES.0.md §4).
38
+ //
39
+ // Keyed on the map rather than marked on the value, because a
40
+ // reference copies the value it resolves to -- a mark riding the
41
+ // value would erase the referring field along with the declaration.
42
+ aliasKeys: string[] = []
43
+
33
44
  spread = {
34
45
  cj: (undefined as Val | undefined),
35
46
  }
@@ -49,20 +60,101 @@ abstract class BagVal extends FeatureVal {
49
60
 
50
61
 
51
62
  handleExpectedVal(key: string, val: Val, parent: Val, ctx: AontuContext): Val {
52
- if (val.isGenable) {
63
+ // A MARKED value is carried, never expected (ADR-005 era, BUGS.md
64
+ // §12's include form): a type()/hide()-marked child legitimately
65
+ // participates in unification without ever generating — that is
66
+ // the marks contract — so wrapping one as an expectation turned a
67
+ // schema field arriving through an include's map meet into a
68
+ // bogus `mapval_spread_required` naming a spread that exists in
69
+ // neither file. The bag's gen already skips marked children.
70
+ //
71
+ // An OPERATOR is carried too (BUGS.md §36): an expression is a
72
+ // computation that resolves by itself once its operands do — the
73
+ // bag's own-key loop drives it every pass — so `m:{y:.x+1}`
74
+ // arriving as a peer key must keep computing exactly as it does
75
+ // written inline. Wrapping it froze the op (an expectation only
76
+ // advances when a peer arrives) and the residue then reported the
77
+ // phantom `mapval_spread_required` naming a spread that exists
78
+ // nowhere. An op that truly never resolves is honest *_no_gen
79
+ // residue naming the expression itself.
80
+ if (val.isGenable || val.isOp || val.mark.type || val.mark.hide) {
53
81
  return val
54
82
  }
55
- const expectVal = new ExpectVal({ peg: val }, ctx)
83
+ // An expectation baked into a combined spread template (the
84
+ // 'map-self' meet of two unequal templates) is re-wrapped FRESH, so
85
+ // key/parent name THIS bag and the template's own node is never
86
+ // stored at a destination.
87
+ const expectVal = new ExpectVal({ peg: val.isExpect ? val.peg : val }, ctx)
56
88
  expectVal.key = key
57
89
  expectVal.parent = parent
58
90
  return expectVal
59
91
  }
60
92
 
61
93
 
94
+ // TWO BAGS ARE THE SAME VALUE WHEN THEY HAVE THE SAME SHAPE. Val.same
95
+ // falls back to object IDENTITY, which no two separately built maps
96
+ // share -- so `x:*{a:1}|{a:number}` met by `x:{a:2}` left
97
+ // `{"a":2}|{"a":2}`, a disjunction of one value spelled twice, past
98
+ // the DisjunctVal dedup. Generation's old member FOLD hid that
99
+ // (folding a value with itself is that value); ADR-007 does not, and
100
+ // a disjunction whose alternatives are all the SAME value is
101
+ // resolved, not ambiguous. Canon prints the collapse too, which is
102
+ // the more honest text.
103
+ //
104
+ // Structural, and deliberately strict: container kind, closedness,
105
+ // the marks, the optional keys and the key set must all agree before
106
+ // the children are compared pairwise. Recursion terminates because a
107
+ // reference is not a bag -- RefVal keeps the identity comparison.
108
+ same(peer: any): boolean {
109
+ if (this === peer) {
110
+ return true
111
+ }
112
+ if (null == peer || true !== peer.isBag) {
113
+ return false
114
+ }
115
+ if (this.isMap !== peer.isMap ||
116
+ this.closed !== peer.closed ||
117
+ this.mark.type !== peer.mark.type ||
118
+ this.mark.hide !== peer.mark.hide) {
119
+ return false
120
+ }
121
+ // The SPREAD is part of the shape (BUGS.md §52 regime 4): `[]`
122
+ // and `[&: T]` share an empty key set, and calling them the same
123
+ // value collapsed the disjunction to its first arm before any
124
+ // data could pick -- the vacuous-schema hole. Two spreads are the
125
+ // same when their canons are.
126
+ const scj: any = (this as any).spread?.cj
127
+ const pcj: any = peer.spread?.cj
128
+ if ((null == scj) !== (null == pcj) ||
129
+ (null != scj && null != pcj && scj.canon !== pcj.canon)) {
130
+ return false
131
+ }
132
+
133
+ const keys = Object.keys(this.peg)
134
+ if (keys.length !== Object.keys(peer.peg).length) {
135
+ return false
136
+ }
137
+ if (this.optionalKeys.length !== peer.optionalKeys.length ||
138
+ this.optionalKeys.some((k) => !peer.optionalKeys.includes(k))) {
139
+ return false
140
+ }
141
+
142
+ for (const k of keys) {
143
+ const mine: any = (this.peg as any)[k]
144
+ const theirs: any = (peer.peg as any)[k]
145
+ if (null == mine || null == theirs || !mine.same(theirs)) {
146
+ return false
147
+ }
148
+ }
149
+
150
+ return true
151
+ }
152
+
153
+
62
154
  gen(ctx: AontuContext) {
63
155
  let out: any = this.isMap ? {} : []
64
156
 
65
- if (this.mark.type || this.mark.hide) {
157
+ if ((this.mark.type || this.mark.hide) && true !== ctx?.probe) {
66
158
  return undefined
67
159
  }
68
160
 
@@ -83,7 +175,15 @@ abstract class BagVal extends FeatureVal {
83
175
  const p = item[0]
84
176
  const child = item[1]
85
177
 
86
- if (child.mark.type || child.mark.hide) {
178
+ if ((child.mark.type || child.mark.hide) && true !== ctx?.probe) {
179
+ continue
180
+ }
181
+
182
+ // An alias declaration contributes no field, and unlike a marked
183
+ // one it is skipped even under `probe`: the probe descends
184
+ // through output marks to check what a `--at` anchor really
185
+ // holds, and an alias is not part of the document at all.
186
+ if (this.aliasKeys.includes('' + p)) {
87
187
  continue
88
188
  }
89
189
 
@@ -114,14 +214,15 @@ abstract class BagVal extends FeatureVal {
114
214
  put(cval)
115
215
  }
116
216
 
117
- else if (child.isScalar
118
- || child.isMap
119
- || child.isList
120
- || child.isPref
121
- || child.isRef
122
- || child.isDisjunct
123
- || child.isNil
124
- ) {
217
+ // A CONJUNCT IS GENERABLE WHEN IT IS A SETTLED SIZING RESIDUE
218
+ // (the review's finding C, use-cases/BUGS.md §16). `length` and
219
+ // `unique` over a container keep the readings more members could
220
+ // still change, so `a: length(3) a:[1,2,3]` is a conjunct of the
221
+ // atom and the list right up to generation -- which is where the
222
+ // atom decides, in ConjunctVal.gen. Any OTHER conjunct is
223
+ // unresolved and falls through to the residue error below,
224
+ // exactly as before.
225
+ else if (bagGenable(child)) {
125
226
  // An optional child is generated in an isolated collect context so an
126
227
  // unresolved inner value (a bare type that survived unification, e.g.
127
228
  // an absent optional sub-map's `field: string`) is dropped rather than
@@ -184,3 +285,48 @@ abstract class BagVal extends FeatureVal {
184
285
  export {
185
286
  BagVal,
186
287
  }
288
+
289
+
290
+ // A conjunct of exactly one sizing constraint and one container: the
291
+ // shape ConstraintVal.admitContainer leaves when its reading is still
292
+ // provisional, and the one ConjunctVal.gen knows how to finish. Kept
293
+ // here rather than as a flag on the conjunct because it is a question
294
+ // about the TERMS, and they can change until the meet converges.
295
+ export function sizingResidue(v: any): { con: any, bag: any } | undefined {
296
+ if (true !== v?.isConjunct || 2 !== v.peg?.length) {
297
+ return undefined
298
+ }
299
+ const [a, b]: any[] = v.peg
300
+ const con = true === a?.isConstraint ? a :
301
+ true === b?.isConstraint ? b : undefined
302
+ const bag = true === a?.isConstraint ? b : a
303
+ return undefined !== con && (true === bag?.isMap || true === bag?.isList) ?
304
+ { con, bag } : undefined
305
+ }
306
+
307
+ // bagGenable is the bag's generability whitelist. A graph atom
308
+ // (RELATIONS P2) is exactly as generable as the value it carries: the
309
+ // atom is transparent at generation, so wrapping a field's value in
310
+ // acyclic() must not change whether the bag accepts it -- an unmet
311
+ // rel() refuses required generation with or without the atom, and a
312
+ // BARE atom generates nothing and is dropped, exactly as an unmet
313
+ // rel() under an optional key is.
314
+ export function bagGenable(child: any): boolean {
315
+ if (true === child.isGraphAtom) {
316
+ return undefined === child.held || bagGenable(child.held)
317
+ }
318
+ // The recursive residual carries its own generation refusal
319
+ // (recursion_unexpanded), which names the schema and the site --
320
+ // the bag's generic residue error would bury both.
321
+ if (true === child.isRecurse) {
322
+ return true
323
+ }
324
+ return true === child.isScalar
325
+ || true === child.isMap
326
+ || true === child.isList
327
+ || true === child.isPref
328
+ || true === child.isRef
329
+ || true === child.isDisjunct
330
+ || true === child.isNil
331
+ || undefined !== sizingResidue(child)
332
+ }
@@ -39,13 +39,21 @@ class CloseFuncVal extends FuncBaseVal {
39
39
 
40
40
 
41
41
  resolve(ctx: AontuContext, args: Val[]) {
42
- const argval: any = args[0]
42
+ let argval: any = args[0]
43
43
 
44
44
  if (null == argval) {
45
45
  return makeNilErr(ctx, 'no_first_arg', this, undefined, 'close')
46
46
  }
47
47
 
48
48
  if (argval.isMap || argval.isList) {
49
+ // The in-place write is safe BECAUSE of the per-destination
50
+ // instantiation rule (ADR-005): everywhere a close() call is
51
+ // multiplied — a pack/each template, a spread constraint — the
52
+ // clone now owns its argument (`dup`), so `closed` lands on that
53
+ // instance alone. Cloning the bag here instead was tried and
54
+ // rejected: the re-path it implies corrupts the source
55
+ // attribution of children inside nested spread templates (the
56
+ // 06-k8s use case's env findings named the wrong path).
49
57
  (argval as BagVal).closed = true
50
58
  // console.log('CLOSED', argval.canon)
51
59
  }
@@ -22,6 +22,7 @@ import {
22
22
 
23
23
 
24
24
  import { JunctionVal } from './JunctionVal'
25
+ import { sizingResidue } from './BagVal'
25
26
 
26
27
  import {
27
28
  explainOpen,
@@ -215,6 +216,25 @@ class ConjunctVal extends JunctionVal {
215
216
 
216
217
 
217
218
  gen(ctx?: AontuContext) {
219
+ // A RESIDUATED SIZING ATOM DECIDES HERE (the review's finding C,
220
+ // use-cases/BUGS.md §16). `length`/`unique` over a container keep
221
+ // the readings that MORE MEMBERS COULD STILL CHANGE -- an upper
222
+ // bound satisfied, a lower bound violated, distinctness so far --
223
+ // rather than deciding against whatever the container held when it
224
+ // first settled (ConstraintVal.admitContainer). Generation is where
225
+ // no more members can arrive, so it is where the provisional
226
+ // reading becomes the verdict: the container generates if the atom
227
+ // is satisfied, and the atom's OWN refusal is raised if it is not.
228
+ //
229
+ // Without this the conjunct would report `conjunct` for a document
230
+ // whose only fault is a length -- the constraint's message is the
231
+ // one the author needs.
232
+ const residue = sizingResidue(this)
233
+ if (undefined !== residue) {
234
+ const settled: any = residue.con.settleContainer(residue.bag, ctx)
235
+ return true === settled?.isNil ? undefined : settled.gen(ctx)
236
+ }
237
+
218
238
  // Unresolved conjunct cannot be generated, so always an error.
219
239
  let nil = makeNilErr(
220
240
  ctx,