aontu 0.61.0 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/README.md +4 -4
  2. package/dist/agentsmd.d.ts +1 -0
  3. package/dist/agentsmd.js +7 -28
  4. package/dist/agentsmd.js.map +1 -1
  5. package/dist/alias.js.map +1 -1
  6. package/dist/allow.d.ts +23 -0
  7. package/dist/allow.js +138 -0
  8. package/dist/allow.js.map +1 -0
  9. package/dist/aontu.d.ts +4 -2
  10. package/dist/aontu.js +4 -80
  11. package/dist/aontu.js.map +1 -1
  12. package/dist/aontumodel.d.ts +4 -0
  13. package/dist/aontumodel.js +33 -0
  14. package/dist/aontumodel.js.map +1 -0
  15. package/dist/cli.d.ts +10 -1
  16. package/dist/cli.js +877 -479
  17. package/dist/cli.js.map +1 -1
  18. package/dist/ctx.js +0 -48
  19. package/dist/ctx.js.map +1 -1
  20. package/dist/diff.js +0 -32
  21. package/dist/diff.js.map +1 -1
  22. package/dist/err.js +0 -40
  23. package/dist/err.js.map +1 -1
  24. package/dist/escape.js +0 -45
  25. package/dist/escape.js.map +1 -1
  26. package/dist/exactjson.d.ts +0 -35
  27. package/dist/exactjson.js +0 -131
  28. package/dist/exactjson.js.map +1 -1
  29. package/dist/format.js +55 -189
  30. package/dist/format.js.map +1 -1
  31. package/dist/grammar.d.ts +9 -0
  32. package/dist/grammar.js +54 -0
  33. package/dist/grammar.js.map +1 -0
  34. package/dist/graph.js +0 -26
  35. package/dist/graph.js.map +1 -1
  36. package/dist/hcanon.js +0 -82
  37. package/dist/hcanon.js.map +1 -1
  38. package/dist/helpdoc.d.ts +16 -0
  39. package/dist/helpdoc.js +59 -0
  40. package/dist/helpdoc.js.map +1 -0
  41. package/dist/hints.d.ts +0 -6
  42. package/dist/hints.js +59 -47
  43. package/dist/hints.js.map +1 -1
  44. package/dist/jsonschema.js +0 -114
  45. package/dist/jsonschema.js.map +1 -1
  46. package/dist/keyorder.d.ts +0 -7
  47. package/dist/keyorder.js +0 -41
  48. package/dist/keyorder.js.map +1 -1
  49. package/dist/lang.js +32 -877
  50. package/dist/lang.js.map +1 -1
  51. package/dist/lower.d.ts +3 -0
  52. package/dist/lower.js +14 -61
  53. package/dist/lower.js.map +1 -1
  54. package/dist/lsp-server.js +0 -16
  55. package/dist/lsp-server.js.map +1 -1
  56. package/dist/lsp.d.ts +1 -1
  57. package/dist/lsp.js +12 -159
  58. package/dist/lsp.js.map +1 -1
  59. package/dist/mcp-server.js +0 -26
  60. package/dist/mcp-server.js.map +1 -1
  61. package/dist/mcp.js +0 -113
  62. package/dist/mcp.js.map +1 -1
  63. package/dist/mod-tool.js +0 -130
  64. package/dist/mod-tool.js.map +1 -1
  65. package/dist/mod.js +0 -162
  66. package/dist/mod.js.map +1 -1
  67. package/dist/patch.js +0 -217
  68. package/dist/patch.js.map +1 -1
  69. package/dist/provenance.js +0 -140
  70. package/dist/provenance.js.map +1 -1
  71. package/dist/query.js +0 -75
  72. package/dist/query.js.map +1 -1
  73. package/dist/reach.js +0 -43
  74. package/dist/reach.js.map +1 -1
  75. package/dist/relation.d.ts +2 -0
  76. package/dist/relation.js +3 -58
  77. package/dist/relation.js.map +1 -1
  78. package/dist/render.js +33 -143
  79. package/dist/render.js.map +1 -1
  80. package/dist/report-sarif.d.ts +0 -11
  81. package/dist/report-sarif.js +0 -28
  82. package/dist/report-sarif.js.map +1 -1
  83. package/dist/sig.js +0 -35
  84. package/dist/sig.js.map +1 -1
  85. package/dist/sigdecl.js +1 -1
  86. package/dist/sigdecl.js.map +1 -1
  87. package/dist/siggate.js +0 -4
  88. package/dist/siggate.js.map +1 -1
  89. package/dist/site.js +3 -29
  90. package/dist/site.js.map +1 -1
  91. package/dist/subsume.d.ts +0 -10
  92. package/dist/subsume.js +0 -137
  93. package/dist/subsume.js.map +1 -1
  94. package/dist/template.d.ts +2 -1
  95. package/dist/template.js +58 -138
  96. package/dist/template.js.map +1 -1
  97. package/dist/trim.js +0 -41
  98. package/dist/trim.js.map +1 -1
  99. package/dist/tsconfig.tsbuildinfo +1 -1
  100. package/dist/type.js.map +1 -1
  101. package/dist/unify.js +12 -242
  102. package/dist/unify.js.map +1 -1
  103. package/dist/utility.js +0 -22
  104. package/dist/utility.js.map +1 -1
  105. package/dist/val/AbnfFuncVal.d.ts +18 -0
  106. package/dist/val/AbnfFuncVal.js +132 -0
  107. package/dist/val/AbnfFuncVal.js.map +1 -0
  108. package/dist/val/AbsentVal.d.ts +11 -0
  109. package/dist/val/AbsentVal.js +30 -0
  110. package/dist/val/AbsentVal.js.map +1 -0
  111. package/dist/val/AggFuncVal.d.ts +10 -1
  112. package/dist/val/AggFuncVal.js +104 -116
  113. package/dist/val/AggFuncVal.js.map +1 -1
  114. package/dist/val/ArithFuncVal.js +0 -12
  115. package/dist/val/ArithFuncVal.js.map +1 -1
  116. package/dist/val/BagVal.js +1 -78
  117. package/dist/val/BagVal.js.map +1 -1
  118. package/dist/val/BigDecimalVal.js +0 -16
  119. package/dist/val/BigDecimalVal.js.map +1 -1
  120. package/dist/val/BigIntegerVal.js +0 -16
  121. package/dist/val/BigIntegerVal.js.map +1 -1
  122. package/dist/val/CloseFuncVal.js +0 -9
  123. package/dist/val/CloseFuncVal.js.map +1 -1
  124. package/dist/val/CmpFuncVal.d.ts +20 -0
  125. package/dist/val/CmpFuncVal.js +188 -0
  126. package/dist/val/CmpFuncVal.js.map +1 -0
  127. package/dist/val/ConjunctVal.js +0 -29
  128. package/dist/val/ConjunctVal.js.map +1 -1
  129. package/dist/val/ConstraintVal.js +0 -500
  130. package/dist/val/ConstraintVal.js.map +1 -1
  131. package/dist/val/ContainerKindVal.js +0 -2
  132. package/dist/val/ContainerKindVal.js.map +1 -1
  133. package/dist/val/CopyFuncVal.js +0 -3
  134. package/dist/val/CopyFuncVal.js.map +1 -1
  135. package/dist/val/Decimal.js +0 -179
  136. package/dist/val/Decimal.js.map +1 -1
  137. package/dist/val/DeprecateFuncVal.js.map +1 -1
  138. package/dist/val/DisjunctVal.js +0 -152
  139. package/dist/val/DisjunctVal.js.map +1 -1
  140. package/dist/val/EachFuncVal.d.ts +1 -2
  141. package/dist/val/EachFuncVal.js +12 -29
  142. package/dist/val/EachFuncVal.js.map +1 -1
  143. package/dist/val/EmitFuncVal.d.ts +1 -1
  144. package/dist/val/EmitFuncVal.js +6 -119
  145. package/dist/val/EmitFuncVal.js.map +1 -1
  146. package/dist/val/ExpectVal.js +0 -62
  147. package/dist/val/ExpectVal.js.map +1 -1
  148. package/dist/val/FilterFuncVal.js +0 -25
  149. package/dist/val/FilterFuncVal.js.map +1 -1
  150. package/dist/val/FuncBaseVal.d.ts +1 -0
  151. package/dist/val/FuncBaseVal.js +7 -127
  152. package/dist/val/FuncBaseVal.js.map +1 -1
  153. package/dist/val/GraphAtomVal.js +0 -15
  154. package/dist/val/GraphAtomVal.js.map +1 -1
  155. package/dist/val/HideFuncVal.js +0 -13
  156. package/dist/val/HideFuncVal.js.map +1 -1
  157. package/dist/val/IntegerVal.js +0 -61
  158. package/dist/val/IntegerVal.js.map +1 -1
  159. package/dist/val/JunctionVal.js +0 -20
  160. package/dist/val/JunctionVal.js.map +1 -1
  161. package/dist/val/KeyFuncVal.js +0 -46
  162. package/dist/val/KeyFuncVal.js.map +1 -1
  163. package/dist/val/ListVal.js +0 -57
  164. package/dist/val/ListVal.js.map +1 -1
  165. package/dist/val/LowerFuncVal.js +11 -6
  166. package/dist/val/LowerFuncVal.js.map +1 -1
  167. package/dist/val/MapVal.js +0 -151
  168. package/dist/val/MapVal.js.map +1 -1
  169. package/dist/val/MatchFuncVal.js +0 -27
  170. package/dist/val/MatchFuncVal.js.map +1 -1
  171. package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
  172. package/dist/val/MaybeFuncVal.js +50 -0
  173. package/dist/val/MaybeFuncVal.js.map +1 -0
  174. package/dist/val/MoveFuncVal.js +0 -18
  175. package/dist/val/MoveFuncVal.js.map +1 -1
  176. package/dist/val/NilVal.js +2 -36
  177. package/dist/val/NilVal.js.map +1 -1
  178. package/dist/val/NomFuncVal.d.ts +12 -0
  179. package/dist/val/NomFuncVal.js +153 -0
  180. package/dist/val/NomFuncVal.js.map +1 -0
  181. package/dist/val/NumberVal.js +0 -15
  182. package/dist/val/NumberVal.js.map +1 -1
  183. package/dist/val/OpBaseVal.d.ts +1 -0
  184. package/dist/val/OpBaseVal.js +3 -15
  185. package/dist/val/OpBaseVal.js.map +1 -1
  186. package/dist/val/PackFuncVal.js +0 -34
  187. package/dist/val/PackFuncVal.js.map +1 -1
  188. package/dist/val/PathFuncVal.js +0 -6
  189. package/dist/val/PathFuncVal.js.map +1 -1
  190. package/dist/val/PathVal.js +0 -41
  191. package/dist/val/PathVal.js.map +1 -1
  192. package/dist/val/PlaceVal.js +0 -25
  193. package/dist/val/PlaceVal.js.map +1 -1
  194. package/dist/val/PlusOpVal.d.ts +1 -7
  195. package/dist/val/PlusOpVal.js +13 -74
  196. package/dist/val/PlusOpVal.js.map +1 -1
  197. package/dist/val/PrefFuncVal.js +0 -1
  198. package/dist/val/PrefFuncVal.js.map +1 -1
  199. package/dist/val/PrefVal.js +0 -167
  200. package/dist/val/PrefVal.js.map +1 -1
  201. package/dist/val/RecurseVal.js +0 -55
  202. package/dist/val/RecurseVal.js.map +1 -1
  203. package/dist/val/RefVal.js +0 -282
  204. package/dist/val/RefVal.js.map +1 -1
  205. package/dist/val/ReferFuncVal.js +0 -232
  206. package/dist/val/ReferFuncVal.js.map +1 -1
  207. package/dist/val/ScalarKindVal.js +0 -49
  208. package/dist/val/ScalarKindVal.js.map +1 -1
  209. package/dist/val/ScalarVal.js +0 -11
  210. package/dist/val/ScalarVal.js.map +1 -1
  211. package/dist/val/StrFuncVal.js +0 -18
  212. package/dist/val/StrFuncVal.js.map +1 -1
  213. package/dist/val/SuperFuncVal.js +0 -32
  214. package/dist/val/SuperFuncVal.js.map +1 -1
  215. package/dist/val/TopVal.js +0 -1
  216. package/dist/val/TopVal.js.map +1 -1
  217. package/dist/val/TranslateFuncVal.d.ts +12 -0
  218. package/dist/val/TranslateFuncVal.js +99 -0
  219. package/dist/val/TranslateFuncVal.js.map +1 -0
  220. package/dist/val/UpperFuncVal.js +11 -6
  221. package/dist/val/UpperFuncVal.js.map +1 -1
  222. package/dist/val/Val.d.ts +1 -0
  223. package/dist/val/Val.js +2 -133
  224. package/dist/val/Val.js.map +1 -1
  225. package/dist/val/VarVal.js +0 -12
  226. package/dist/val/VarVal.js.map +1 -1
  227. package/dist/val/arith.js +0 -37
  228. package/dist/val/arith.js.map +1 -1
  229. package/dist/val/caserange.d.ts +3 -0
  230. package/dist/val/caserange.js +49 -0
  231. package/dist/val/caserange.js.map +1 -0
  232. package/dist/val/members.js +0 -6
  233. package/dist/val/members.js.map +1 -1
  234. package/dist/val/numcmp.js +0 -11
  235. package/dist/val/numcmp.js.map +1 -1
  236. package/dist/val/numkind.js +0 -145
  237. package/dist/val/numkind.js.map +1 -1
  238. package/dist/val/valutil.js +0 -16
  239. package/dist/val/valutil.js.map +1 -1
  240. package/dist/vet.d.ts +12 -0
  241. package/dist/vet.js +159 -412
  242. package/dist/vet.js.map +1 -1
  243. package/dist/view.js +0 -414
  244. package/dist/view.js.map +1 -1
  245. package/dist/walk.js +0 -41
  246. package/dist/walk.js.map +1 -1
  247. package/grammar/aontu.abnf +9 -7
  248. package/grammar/aontu.gbnf +5 -5
  249. package/grammar/aontu.lark +5 -5
  250. package/grammar/aontu.tmLanguage.json +1 -1
  251. package/package.json +4 -2
  252. package/skill/SKILL.md +8 -0
  253. package/skill/init/check.sh +28 -0
  254. package/skill/init/data.aon +12 -0
  255. package/skill/init/model.aon +19 -0
  256. package/skill/tasks.md +151 -0
  257. package/src/agentsmd.ts +8 -32
  258. package/src/alias.ts +0 -39
  259. package/src/allow.ts +221 -0
  260. package/src/aontu.ts +10 -108
  261. package/src/aontumodel.ts +32 -0
  262. package/src/cli.ts +1009 -540
  263. package/src/ctx.ts +0 -103
  264. package/src/diff.ts +0 -40
  265. package/src/err.ts +0 -40
  266. package/src/escape.ts +0 -46
  267. package/src/exactjson.ts +0 -131
  268. package/src/format.ts +63 -234
  269. package/src/grammar.ts +72 -0
  270. package/src/graph.ts +0 -61
  271. package/src/hcanon.ts +0 -82
  272. package/src/helpdoc.ts +77 -0
  273. package/src/hints.ts +72 -49
  274. package/src/jsonschema.ts +0 -123
  275. package/src/keyorder.ts +0 -42
  276. package/src/lang.ts +39 -895
  277. package/src/lower.ts +15 -65
  278. package/src/lsp-server.ts +0 -16
  279. package/src/lsp.ts +12 -180
  280. package/src/mcp-server.ts +0 -31
  281. package/src/mcp.ts +0 -130
  282. package/src/mod-tool.ts +0 -158
  283. package/src/mod.ts +0 -178
  284. package/src/patch.ts +0 -232
  285. package/src/provenance.ts +0 -183
  286. package/src/query.ts +0 -84
  287. package/src/reach.ts +0 -53
  288. package/src/relation.ts +7 -71
  289. package/src/render.ts +33 -180
  290. package/src/report-sarif.ts +0 -48
  291. package/src/sig.ts +0 -35
  292. package/src/sigdecl.ts +1 -1
  293. package/src/siggate.ts +0 -30
  294. package/src/site.ts +3 -29
  295. package/src/subsume.ts +1 -161
  296. package/src/template.ts +69 -140
  297. package/src/trim.ts +0 -53
  298. package/src/type.ts +2 -45
  299. package/src/unify.ts +13 -251
  300. package/src/utility.ts +0 -31
  301. package/src/val/AbnfFuncVal.ts +181 -0
  302. package/src/val/AbsentVal.ts +54 -0
  303. package/src/val/AggFuncVal.ts +152 -188
  304. package/src/val/ArithFuncVal.ts +0 -20
  305. package/src/val/BagVal.ts +1 -78
  306. package/src/val/BigDecimalVal.ts +0 -16
  307. package/src/val/BigIntegerVal.ts +0 -16
  308. package/src/val/CloseFuncVal.ts +0 -9
  309. package/src/val/CmpFuncVal.ts +249 -0
  310. package/src/val/ConjunctVal.ts +0 -33
  311. package/src/val/ConstraintVal.ts +2 -537
  312. package/src/val/ContainerKindVal.ts +0 -18
  313. package/src/val/CopyFuncVal.ts +0 -5
  314. package/src/val/Decimal.ts +1 -185
  315. package/src/val/DeprecateFuncVal.ts +0 -10
  316. package/src/val/DisjunctVal.ts +0 -157
  317. package/src/val/EachFuncVal.ts +12 -53
  318. package/src/val/EmitFuncVal.ts +8 -208
  319. package/src/val/ExpectVal.ts +0 -62
  320. package/src/val/FilterFuncVal.ts +0 -55
  321. package/src/val/FuncBaseVal.ts +9 -130
  322. package/src/val/GraphAtomVal.ts +0 -42
  323. package/src/val/HideFuncVal.ts +0 -15
  324. package/src/val/IntegerVal.ts +0 -61
  325. package/src/val/JunctionVal.ts +0 -20
  326. package/src/val/KeyFuncVal.ts +0 -48
  327. package/src/val/ListVal.ts +0 -59
  328. package/src/val/LowerFuncVal.ts +12 -7
  329. package/src/val/MapVal.ts +0 -151
  330. package/src/val/MatchFuncVal.ts +0 -59
  331. package/src/val/MaybeFuncVal.ts +86 -0
  332. package/src/val/MoveFuncVal.ts +0 -20
  333. package/src/val/NilVal.ts +2 -36
  334. package/src/val/NomFuncVal.ts +200 -0
  335. package/src/val/NumberVal.ts +0 -16
  336. package/src/val/OpBaseVal.ts +4 -17
  337. package/src/val/PackFuncVal.ts +0 -63
  338. package/src/val/PathFuncVal.ts +0 -32
  339. package/src/val/PathVal.ts +0 -66
  340. package/src/val/PlaceVal.ts +0 -45
  341. package/src/val/PlusOpVal.ts +18 -75
  342. package/src/val/PrefFuncVal.ts +0 -1
  343. package/src/val/PrefVal.ts +0 -179
  344. package/src/val/RecurseVal.ts +0 -81
  345. package/src/val/RefVal.ts +1 -285
  346. package/src/val/ReferFuncVal.ts +0 -255
  347. package/src/val/ScalarKindVal.ts +0 -50
  348. package/src/val/ScalarVal.ts +0 -12
  349. package/src/val/StrFuncVal.ts +0 -44
  350. package/src/val/SuperFuncVal.ts +0 -42
  351. package/src/val/TopVal.ts +0 -1
  352. package/src/val/TranslateFuncVal.ts +132 -0
  353. package/src/val/UpperFuncVal.ts +12 -7
  354. package/src/val/Val.ts +3 -192
  355. package/src/val/VarVal.ts +0 -15
  356. package/src/val/arith.ts +0 -92
  357. package/src/val/caserange.ts +53 -0
  358. package/src/val/members.ts +0 -23
  359. package/src/val/numcmp.ts +1 -27
  360. package/src/val/numkind.ts +0 -149
  361. package/src/val/valutil.ts +0 -16
  362. package/src/vet.ts +209 -504
  363. package/src/view.ts +0 -507
  364. package/src/walk.ts +0 -41
  365. package/dist/std.d.ts +0 -3
  366. package/dist/std.js +0 -637
  367. package/dist/std.js.map +0 -1
  368. package/dist/val/FormFuncVal.js +0 -55
  369. package/dist/val/FormFuncVal.js.map +0 -1
  370. package/src/std.ts +0 -648
  371. package/src/val/FormFuncVal.ts +0 -119
package/src/render.ts CHANGED
@@ -1,25 +1,6 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
3
 
4
- // THE RENDERER (docs/design/RENDER.0.md; docs/capability-review/
5
- // g9-transformation.md §3). `render` evaluates a document, takes the
6
- // value at `--at` (the root by default), vets it against the bundled
7
- // `aontu:code` vocabulary, and folds `code.units` into bytes;
8
- // `renderValue` is the fold alone, over `generate()` output. The fold
9
- // is pure and total: it never touches the Val tree, never reads or
10
- // writes a file, never sorts and never iterates a map, and every piece
11
- // of a fragment carries its own depth (`at`), so the renderer owns
12
- // every prefix and no piece nests another (the second amendment's
13
- // fragment algebra, RENDER.0.md D2 and D6).
14
- //
15
- // WHAT THIS PHASE RENDERS (RENDER.0.md P3): fragments -- a line, a
16
- // blank run, a raw block, a bare string piece, a reference inline --
17
- // and the `text` escape, under a profile that knows its language. The
18
- // one bundled profile is `aontu:lang/text`, which every fragment-only
19
- // unit falls back to; a declaration (`record`, `enum`, ...) needs a
20
- // LOWERING, which P5 brings with the TypeScript and Go profiles, and
21
- // until then is `render_profile`.
22
-
23
4
  import { Aontu } from './aontu'
24
5
  import { vet, failureFinding, anchorAt } from './vet'
25
6
  import type { VetFinding } from './vet'
@@ -42,12 +23,6 @@ export type RenderUnit = {
42
23
  text: string
43
24
  }
44
25
 
45
- // THE THREE LOSS TIERS (RENDER.0.md D7). Tier 1 is a check the target's
46
- // type system cannot enforce (the declaration lowering's, P5); tier 2
47
- // a fragment -- structured, re-indentable, terminator-checked, saying
48
- // nothing about target syntax; tier 3 an opaque escape, a `text`
49
- // declaration or a `raw` piece. `strict` refuses tier 3 and only
50
- // tier 3.
51
26
  export type RenderLoss = {
52
27
  unit: string
53
28
  path: string
@@ -56,12 +31,6 @@ export type RenderLoss = {
56
31
  reason: string
57
32
  }
58
33
 
59
- // ONE PIECE'S PROVENANCE (RENDER.0.md D9, D11; P7). A dispatch stamps
60
- // every piece it emits with the node it matched and the rule it took,
61
- // and the fold reads the stamps back off the instance: `piece` is the
62
- // piece's own path there, `unit` the unit it landed in, `node` the
63
- // model address the rule matched, and `rule` the rule's address --
64
- // its table's, then `#`, then its index in that table.
65
34
  export type RenderTrace = {
66
35
  unit: string
67
36
  piece: string
@@ -69,8 +38,6 @@ export type RenderTrace = {
69
38
  rule: string
70
39
  }
71
40
 
72
- // THE COVERAGE REPORT (P7; G9 §6, "coverage cuts both ways"). Two
73
- // lists, and both are set computations over what the run recorded.
74
41
  export type RenderCoverage = {
75
42
  // Every model path a reference resolved to, in walk order: what the
76
43
  // render READ.
@@ -78,27 +45,15 @@ export type RenderCoverage = {
78
45
  // Dead model: the SHALLOWEST model paths no read reached. A path
79
46
  // whose subtree holds a read is not named; its unread children are.
80
47
  dead: string[]
81
- // A silent hole: a rendered declaration no rule produced. In a
82
- // document with no rule table that is every declaration, which is
83
- // the true statement about it -- the rule layer governs none of this
84
- // output.
85
48
  unruled: { unit: string, path: string }[]
86
49
  }
87
50
 
88
51
  export type RenderReport = {
89
52
  verdict: RenderVerdict
90
- // In `units[]` order. Empty on `error`.
91
53
  units: RenderUnit[]
92
54
  // Per unit and path. Empty on `error`.
93
55
  lossy: RenderLoss[]
94
- // On `error` only, in vet's finding shape: the document did not
95
- // stand up, the instance is not `aontu:code`, or a unit could not be
96
- // rendered (`render_*`).
97
56
  errors?: VetFinding[]
98
- // The dispatch trace, under `trace` or `coverage` (P7), in document
99
- // order. Absent when it is empty, on `error`, and from
100
- // `renderValue`, which folds an instance the recorder never watched
101
- // being built.
102
57
  trace?: RenderTrace[]
103
58
  // The coverage report, under `coverage` (P7).
104
59
  coverage?: RenderCoverage
@@ -111,31 +66,21 @@ export type RenderOptions = IncludeOptions & {
111
66
  // Where the document CAME FROM, so a relative `@"file"` load inside
112
67
  // it resolves from its own directory.
113
68
  path?: string
114
- // Profiles supplied by the caller, each an evaluated profile map
115
- // (`{lang, indent, ...}`), matched to a unit by `lang` before the
116
- // bundled set is asked (RENDER.0.md D5, step 1).
117
69
  profiles?: any[]
118
70
  // Render only the unit at this path.
119
71
  unit?: string
120
- // Refuse tier-3 loss: the opaque escapes.
121
72
  strict?: boolean
122
- // RECORD THE DISPATCH TRACE (P7). Off by default: an instrumented
123
- // run stamps every value a reference resolves and every piece a rule
124
- // emits, and an ordinary one pays one property load per meet.
125
73
  trace?: boolean
126
74
  // Compute the coverage report, which needs the trace and turns it on.
127
75
  coverage?: boolean
128
- // Measure coverage under this path only, instead of the document
129
- // root (RENDER.0.md X-3). The narrower measure a document with its
130
- // model under one key wants.
131
76
  coverageAt?: string
132
77
  }
133
78
 
134
79
 
135
80
  const VOCABULARY = '@"aontu:code"'
136
- // The bundled profiles, by lang: aontu:lang/<lang>.
137
- const BUNDLED_LANGS = ['go', 'text', 'typescript']
138
- const PROFILE_VOCABULARY = '@"aontu:profile"'
81
+ // The bundled profiles, by lang: aontu:render/lang/<lang>.
82
+ const BUNDLED_LANGS = ['go', 'markdown', 'text', 'typescript']
83
+ const PROFILE_VOCABULARY = '@"aontu:render"'
139
84
 
140
85
 
141
86
  function finding(
@@ -150,29 +95,10 @@ function errorReport(errors: VetFinding[]): RenderReport {
150
95
  }
151
96
 
152
97
 
153
- // The verb's evaluation, before the fold (RENDER.0.md D1): evaluate,
154
- // anchor, vet the anchored value against the vocabulary as `aontu vet`
155
- // would, and generate the MEET of the two -- so the vocabulary's
156
- // defaults (`at: 0`, `n: 1`, `reindent: true`) are in the instance the
157
- // fold reads, whether or not the document included the vocabulary
158
- // itself. THE VET AND THE MEET READ THE SETTLED VALUE, re-sourced
159
- // through its hash form (valid source that evaluates to the same
160
- // value), not the document's text: a fragment's lines are what a
161
- // transform COMPUTED -- an `emit`, a `join` -- and the vocabulary's
162
- // alternatives are tried against values, not against calls that are
163
- // still waiting to fire. A finding from that vet therefore addresses
164
- // the instance by path, which is the addressing every render finding
165
- // uses (G9 §3); a document that does not stand up at all is reported
166
- // with its own sites, before any of this.
167
98
  export function render(src: string, options?: RenderOptions): RenderReport {
168
99
  const opts = options ?? {}
169
100
  const aontu = new Aontu(includeOpts(opts))
170
101
 
171
- // THE RECORDER (P7), on for a run that was asked for a trace or a
172
- // coverage report and off for every other. Its presence is the one
173
- // switch: the read set fills as references resolve, and the two
174
- // riders that carry a read address and a dispatch stamp are written
175
- // only while it is there.
176
102
  const rec = true === opts.trace || true === opts.coverage
177
103
  const reads = rec ? new Set<string>() : undefined
178
104
 
@@ -198,39 +124,20 @@ export function render(src: string, options?: RenderOptions): RenderReport {
198
124
  node = found
199
125
  }
200
126
 
201
- // UNDER NO CALLER CAPABILITY, here and in the meet below: the
202
- // vocabulary is the engine's own and the instance is a canon, which
203
- // includes nothing, so the caller's include capability -- which
204
- // governs the DOCUMENT -- has nothing to govern here, and `none`
205
- // must not deny the renderer its own schema.
206
127
  const value = hcanon(node)
207
128
  const report = vet(VOCABULARY, value)
208
129
  if ('valid' !== report.verdict) {
209
130
  return errorReport(report.findings)
210
131
  }
211
132
 
212
- // The meet, keyed: the vocabulary's root holds `code`, and so does
213
- // the instance's (a value the vet admitted is a map), and a document
214
- // with no `code` at all is the vocabulary's own empty instance.
215
- const codeVal: any = node.peg.code
133
+ const codeVal: any = node.peg.aontu?.peg?.Code
216
134
  const instance = new Aontu().generate(
217
- VOCABULARY + (undefined === codeVal ? '' : '\ncode: ' + hcanon(codeVal)))
135
+ VOCABULARY + (undefined === codeVal ? '' : '\naontu: Code: ' + hcanon(codeVal)))
218
136
  const folded = renderValue(instance, opts)
219
137
 
220
- // THE TWO REPORTS ARE JOINED TO THE FOLD BY PATH (P7), which is what
221
- // lets the fold stay the pure total function D6 asks for: the
222
- // dispatch stamps ride the VALUE, the instance the fold reads is
223
- // that value re-sourced through its hash form, and a piece is at the
224
- // same path in both. Nothing to report on `error`: there are no
225
- // units to attribute pieces to.
226
138
  if (rec && 'error' !== folded.verdict) {
227
139
  const marks = emitted(node)
228
140
  const trace = traceOf(marks, instance, folded.units)
229
- // AN EMPTY TRACE IS NO TRACE, in both ports: Go omits an empty
230
- // slice, and a report shape that differed by port would be the one
231
- // thing the shared rows exist to refuse. A run that emitted no
232
- // piece has nothing to attribute, and the coverage report says so
233
- // in its own words.
234
141
  if (0 < trace.length) {
235
142
  folded.trace = trace
236
143
  }
@@ -267,10 +174,6 @@ function walkVals(root: any, fn: (v: any, path: string[]) => boolean): void {
267
174
  }
268
175
  else if (true === v.isMap && null != v.peg) {
269
176
  for (const k of Object.keys(v.peg).sort(cmpCodePoint)) {
270
- // AN ALIAS DECLARATION IS NOT A MEMBER, here for the reason
271
- // every fold has it (./val/members.ts): `%wire = …` holds a
272
- // value the document never generates, so it is neither a piece
273
- // to trace nor model that could be called dead.
274
177
  if (!v.aliasKeys.includes(k)) {
275
178
  walk(v.peg[k], [...path, k])
276
179
  }
@@ -302,19 +205,12 @@ function emitted(node: any): { path: string, mark: any }[] {
302
205
  }
303
206
 
304
207
 
305
- // The trace: one entry per stamped piece that a RENDERED unit holds. A
306
- // piece is IN the unit whose path prefixes its own, which is the whole
307
- // of the question -- no path is parsed, and a stamp that lies under no
308
- // unit at all (a rule set held under a key of its own, and referred to
309
- // from a unit) simply matches nothing. A unit the run did not render
310
- // (`--unit` names one) has no bytes for a piece of it to be in, so it
311
- // is not among the prefixes either.
312
208
  function traceOf(marks: { path: string, mark: any }[], instance: any,
313
209
  units: RenderUnit[]): RenderTrace[] {
314
210
  const pre: { at: string, path: string }[] = []
315
211
  unitList(instance).forEach((u: any, i: number) => {
316
212
  if (units.some((r) => r.path === u.path)) {
317
- pre.push({ at: '$.code.units.' + i, path: u.path })
213
+ pre.push({ at: '$.aontu.Code.units.' + i, path: u.path })
318
214
  }
319
215
  })
320
216
  const out: RenderTrace[] = []
@@ -340,10 +236,6 @@ function ancestors(a: string): string[] {
340
236
  }
341
237
 
342
238
 
343
- // Is the value at `a` covered by the set -- the address itself in it,
344
- // or an address above it? An address ABOVE it covers the whole subtree:
345
- // a reference that read `$.schema` read everything under it, and a rule
346
- // that emitted a unit emitted every declaration in it.
347
239
  function covered(set: Set<string>, a: string): boolean {
348
240
  if (set.has(a)) {
349
241
  return true
@@ -357,20 +249,13 @@ function covered(set: Set<string>, a: string): boolean {
357
249
  }
358
250
 
359
251
 
360
- // THE COVERAGE REPORT (P7). Dead model is measured over the DOCUMENT
361
- // ROOT, or under `coverageAt` when a document keeps its model under one
362
- // key (X-3, decided here): the read set is absolute, so a narrower
363
- // measure is a narrower walk, not a different origin. The render's own
364
- // output -- `code` under the anchor -- is not model and is never
365
- // walked into: nothing reads it, so every document would otherwise
366
- // report it dead.
367
252
  function coverOf(root: any, node: any, reads: Set<string>,
368
253
  opts: RenderOptions, marks: { path: string, mark: any }[], instance: any,
369
254
  units: RenderUnit[]): RenderCoverage | undefined {
370
- // THE ANCHOR IS THE ONE render() ALREADY FOUND, so `code` under it is
371
- // named without asking a second time: `--at` is resolved before the
372
- // vet, and an anchor that named nothing never reached here.
373
- const codeAddr = addr(node.path.concat('code'))
255
+ // THE ANCHOR IS THE ONE render() ALREADY FOUND, so the namespace
256
+ // under it is named without asking a second time: `--at` is resolved
257
+ // before the vet, and an anchor that named nothing never reached here.
258
+ const codeAddr = addr(node.path.concat('aontu'))
374
259
 
375
260
  let from: any = root
376
261
  let base: string[] = []
@@ -383,8 +268,6 @@ function coverOf(root: any, node: any, reads: Set<string>,
383
268
  base = found.path
384
269
  }
385
270
 
386
- // The two questions asked of the read set, as sets: is this address
387
- // read (or under one that is), and does a read lie BELOW it?
388
271
  const above = new Set<string>(reads)
389
272
  const below = new Set<string>()
390
273
  for (const r of reads) {
@@ -399,11 +282,6 @@ function coverOf(root: any, node: any, reads: Set<string>,
399
282
  if (a === codeAddr || covered(above, a)) {
400
283
  return false
401
284
  }
402
- // THE ROOT OF THE MEASURE IS NEVER ITSELF DEAD MODEL, and is
403
- // descended into whatever the read set holds. A document that is
404
- // only a transform reads nothing above its own model, and naming
405
- // the root there would report the whole document dead while its
406
- // one live subtree sat inside it.
407
285
  if (below.has(a) || 0 === path.length) {
408
286
  return true
409
287
  }
@@ -428,7 +306,7 @@ function coverOf(root: any, node: any, reads: Set<string>,
428
306
  }
429
307
  const decls: any[] = unit.decls
430
308
  decls.forEach((_d: any, j: number) => {
431
- const a = '$.code.units.' + i + '.decls.' + j
309
+ const a = '$.aontu.Code.units.' + i + '.decls.' + j
432
310
  if (!covered(stamped, a) && !inside.has(a)) {
433
311
  unruled.push({ unit: unit.path, path: a })
434
312
  }
@@ -443,25 +321,19 @@ function coverOf(root: any, node: any, reads: Set<string>,
443
321
  // whose declarations are fragments and text escapes only.
444
322
  const bundled: Record<string, any> = {}
445
323
 
446
- // A bundled profile, evaluated once: the meet of aontu:lang/<lang>
324
+ // A bundled profile, evaluated once: the meet of aontu:render/lang/<lang>
447
325
  // with the vocabulary, so its defaults are in it.
448
326
  function bundledProfile(lang: string): any {
449
327
  if (!BUNDLED_LANGS.includes(lang)) {
450
328
  return undefined
451
329
  }
452
330
  if (undefined === bundled[lang]) {
453
- bundled[lang] = new Aontu().generate('@"aontu:lang/' + lang + '"').profile
331
+ bundled[lang] = new Aontu().generate('@"aontu:render/lang/' + lang + '"').aontu.render.Lang
454
332
  }
455
333
  return bundled[lang]
456
334
  }
457
335
 
458
336
 
459
- // PROFILE SELECTION, per unit (RENDER.0.md D5): a caller-supplied
460
- // profile whose `lang` is the unit's; else the bundled profile of that
461
- // `lang`; else `aontu:lang/text`, if and only if every declaration in
462
- // the unit is a fragment or a text escape; else nothing, which the
463
- // caller reports as `render_profile`. The unit's inline `profile` is
464
- // merged over whichever base was found.
465
337
  function profileFor(lang: string, given: any[] | undefined, fragOnly: boolean): any {
466
338
  const supplied = (given ?? []).find((p: any) => p?.lang === lang)
467
339
  if (undefined !== supplied) {
@@ -493,16 +365,6 @@ function mergeProfile(base: any, over: any): any {
493
365
  }
494
366
 
495
367
 
496
- // THE FOLD (RENDER.0.md D6). `pad(at)` is `indent.unit` repeated
497
- // `indent.width × at` times; a line is `pad + text + LF`, and an empty
498
- // text emits no pad; a blank is its terminators alone; a raw block's
499
- // lines each get the pad unless `reindent: false`, which emits them
500
- // at column 0 verbatim -- and common leading indentation is never
501
- // stripped. A reference inline is its name, verbatim (a
502
- // declaration-capable profile puts it through its identifier rules,
503
- // P5). Nothing is trimmed (D3): the text is the transform's.
504
- // A profile with no indent -- a caller-supplied map the vocabulary
505
- // never filled -- takes the vocabulary's own default, two spaces.
506
368
  function pad(profile: any, at: number): string {
507
369
  const indent = profile.indent ?? { unit: ' ', width: 2 }
508
370
  return (indent.unit ?? ' ').repeat((indent.width ?? 2) * at)
@@ -529,7 +391,7 @@ function foldPiece(
529
391
  return line(profile, 0, piece)
530
392
  }
531
393
  if ('line' === piece.k) {
532
- return line(profile, piece.at ?? 0, piece.of.map((p: any) => inline(p, ctx)).join(''))
394
+ return line(profile, piece.at ?? 0, piece.n.map((p: any) => inline(p, ctx)).join(''))
533
395
  }
534
396
  if ('blank' === piece.k) {
535
397
  return '\n'.repeat(piece.n ?? 1)
@@ -548,13 +410,6 @@ function foldPiece(
548
410
  }
549
411
 
550
412
 
551
- // A PROFILE DOCUMENT (RENDER.0.md D5), evaluated the way `render`
552
- // evaluates its own: under the caller's include options, then vetted
553
- // against aontu:profile as a settled value and met with that vocabulary
554
- // so its defaults (`indent.width: 2`, ...) are in it. The answer is the
555
- // `profile` map the fold reads -- what `--profile <file>` hands to
556
- // RenderOptions.profiles -- or the findings that refused the document:
557
- // one that does not stand up, or one the vocabulary rejects.
558
413
  export function renderProfile(src: string, options?: RenderOptions):
559
414
  { profile?: any, errors?: VetFinding[] } {
560
415
  const opts = options ?? {}
@@ -571,8 +426,9 @@ export function renderProfile(src: string, options?: RenderOptions):
571
426
  // The meet, keyed as render's is: the vocabulary requires `profile`,
572
427
  // so a value the vet admitted has one.
573
428
  const instance = new Aontu().generate(
574
- PROFILE_VOCABULARY + '\nprofile: ' + hcanon(root.peg.profile))
575
- return { profile: instance.profile }
429
+ PROFILE_VOCABULARY + '\naontu: render: Lang: ' +
430
+ hcanon(root.peg.aontu.peg.render.peg.Lang))
431
+ return { profile: instance.aontu.render.Lang }
576
432
  }
577
433
 
578
434
 
@@ -580,14 +436,11 @@ export function renderProfile(src: string, options?: RenderOptions):
580
436
  // key and is always there, `units` is not. One reader, so the fold,
581
437
  // the trace and the coverage report all see the same list.
582
438
  function unitList(instance: any): any[] {
583
- return Array.isArray(instance?.code?.units) ? instance.code.units : []
439
+ return Array.isArray(instance?.aontu?.Code?.units) ?
440
+ instance.aontu.Code.units : []
584
441
  }
585
442
 
586
443
 
587
- // The fold alone, over `generate()` output: the instance is
588
- // `{code: {units: [...]}}` as the vocabulary shapes it, with its
589
- // defaults filled -- which is what `render` hands over, and what a
590
- // caller of this function is responsible for.
591
444
  export function renderValue(instance: any, options?: RenderOptions): RenderReport {
592
445
  const opts = options ?? {}
593
446
  const errors: VetFinding[] = []
@@ -598,7 +451,7 @@ export function renderValue(instance: any, options?: RenderOptions): RenderRepor
598
451
  const seen: string[] = []
599
452
  let selected = 0
600
453
  list.forEach((unit: any, i: number) => {
601
- const upath = '$.code.units.' + i
454
+ const upath = '$.aontu.Code.units.' + i
602
455
  const path: string = unit.path
603
456
  const lang: string = unit.lang
604
457
 
@@ -633,22 +486,18 @@ export function renderValue(instance: any, options?: RenderOptions): RenderRepor
633
486
  if (undefined === base) {
634
487
  errors.push(finding('render_profile', 'parse', upath + '.lang',
635
488
  'no profile renders ' + lang + ': a declaration needs a lowering, and ' +
636
- 'only fragments and text escapes render under aontu:lang/text.'))
489
+ 'only fragments and text escapes render under aontu:render/lang/text.'))
637
490
  return
638
491
  }
639
492
  const profile = null == unit.profile ? base : mergeProfile(base, unit.profile)
640
493
 
641
- // THE LOWERING (D5, P5), when the profile names one: the unit's
642
- // header -- banner, package clause, imports -- and each declaration
643
- // as pieces the fold takes, a blank line between two lowered
644
- // declarations. A fragment or a text escape owns its own blanks.
645
494
  const family: string | undefined = profile.lowering
646
495
  const ctx: LowerCtx | undefined = undefined === family ? undefined
647
496
  : { profile, family, unit: path, lossy }
648
497
 
649
498
  let text = ''
650
499
  if (undefined !== ctx) {
651
- const header = lowerHeader(unit, instance?.code?.source, ctx)
500
+ const header = lowerHeader(unit, instance?.aontu?.Code?.source, ctx)
652
501
  for (const piece of header) {
653
502
  text += foldPiece(piece, profile, path, upath, lossy, ctx)
654
503
  }
@@ -661,12 +510,16 @@ export function renderValue(instance: any, options?: RenderOptions): RenderRepor
661
510
  const dpath = upath + '.decls.' + j
662
511
  if ('frag' === decl.k) {
663
512
  lowered = false
664
- lossy.push({
665
- unit: path, path: dpath, tier: 2, construct: 'frag',
666
- reason: 'a fragment says nothing about ' + lang + ' syntax',
667
- })
668
- decl.of.forEach((piece: any, n: number) => {
669
- text += foldPiece(piece, profile, path, dpath + '.of.' + n, lossy, ctx)
513
+ // Lossy only against a language whose DECLARATIONS could have
514
+ // been lowered instead: a fragment is all the others have.
515
+ if (null != profile.lowering) {
516
+ lossy.push({
517
+ unit: path, path: dpath, tier: 2, construct: 'frag',
518
+ reason: 'a fragment says nothing about ' + lang + ' syntax',
519
+ })
520
+ }
521
+ decl.n.forEach((piece: any, n: number) => {
522
+ text += foldPiece(piece, profile, path, dpath + '.n.' + n, lossy, ctx)
670
523
  })
671
524
  }
672
525
  else if ('text' === decl.k) {
@@ -702,7 +555,7 @@ export function renderValue(instance: any, options?: RenderOptions): RenderRepor
702
555
  })
703
556
 
704
557
  if (undefined !== opts.unit && 0 === selected) {
705
- errors.push(finding('render_unit', 'reference', '$.code.units',
558
+ errors.push(finding('render_unit', 'reference', '$.aontu.Code.units',
706
559
  'no unit has the path ' + opts.unit + '.'))
707
560
  }
708
561
 
@@ -1,25 +1,5 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
- // SARIF rendering for a vet report (G2 phase 5,
4
- // docs/capability-review/g2-validation-verb.md).
5
- //
6
- // A MINIMAL SARIF 2.1.0 profile, and deliberately nothing more: one
7
- // run, one `result` per finding, the finding's first site as the
8
- // primary location, its remaining sites under `relatedLocations`, and
9
- // the whole finding object embedded in `properties` so a SARIF consumer
10
- // still holds the native contract. No fixes, no code flows, no
11
- // baselines — the JSON report is the native contract, SARIF is the
12
- // interchange skin CI systems already ingest (GitHub code scanning
13
- // uploads, PR annotation).
14
- //
15
- // This is library API, not CLI plumbing, for the same reason the vet
16
- // engine is: an embedder (and G7's MCP server later) must be able to
17
- // emit the interchange form without shelling out. The Go twin is
18
- // go/report_sarif.go, and the two are held to byte parity over the
19
- // shared fixture pair in test/spec/files/vet-sarif/ — with the message
20
- // text and producer version redacted, exactly as test/spec/vet.tsv
21
- // carves the message out of its goldens, because prose and the two
22
- // independent version series are deliberately not in cross-port parity.
23
3
 
24
4
  import type { VetReport, VetFinding, VetSite } from './vet'
25
5
 
@@ -37,13 +17,6 @@ const SARIF_LEVEL: Record<string, string> = {
37
17
  }
38
18
 
39
19
 
40
- // A site's file is a filesystem path, and a SARIF artifactLocation.uri
41
- // is a URI reference: `#`, `%`, spaces and every other URI-significant
42
- // character must be percent-encoded or a consumer parses the path as
43
- // something else (text after `#` becomes a fragment). Encoded BY BYTE
44
- // over UTF-8, with RFC 3986's unreserved and path characters kept
45
- // literal, so the Go twin produces identical bytes from an identical
46
- // loop (go/report_sarif.go sarifURI).
47
20
  function sarifUri(path: string): string {
48
21
  const bytes = Buffer.from(path, 'utf8')
49
22
  let out = ''
@@ -75,11 +48,6 @@ function sarifLocation(site: VetSite): any {
75
48
 
76
49
 
77
50
  function sarifResult(finding: VetFinding): any {
78
- // The engine orders sites data-first (the thing to fix), so the first
79
- // site is the primary location and the rest are related — which for a
80
- // two-site conflict puts the schema's declaration under
81
- // `relatedLocations`, exactly where a code-scanning UI shows "the
82
- // other side".
83
51
  const result: any = {
84
52
  level: SARIF_LEVEL[finding.severity],
85
53
  locations: [sarifLocation(finding.sites[0])],
@@ -95,26 +63,10 @@ function sarifResult(finding: VetFinding): any {
95
63
  }
96
64
 
97
65
 
98
- /**
99
- * Render a vet report as SARIF 2.1.0 text (a minimal profile: one run,
100
- * one result per finding, the finding embedded in `properties`).
101
- *
102
- * @param report A report from `vet()`.
103
- * @param version The producer version for `tool.driver.version` —
104
- * the CLI passes its package version; the two ports'
105
- * version series are independent by design.
106
- * @returns The SARIF JSON text, indented two spaces, keys in
107
- * the canonical emitter's sorted order.
108
- */
109
66
  function sarifReport(report: VetReport, version: string): string {
110
67
  return exactJSON({
111
68
  $schema: 'https://json.schemastore.org/sarif-2.1.0.json',
112
69
  runs: [{
113
- // An `error` verdict means the run could not be set up (an
114
- // unusable schema): zero findings from a FAILED run must not
115
- // read like zero findings from a clean one, so the failure is
116
- // carried in SARIF's own invocation metadata rather than by an
117
- // indistinguishable empty result list.
118
70
  invocations: [{
119
71
  executionSuccessful: 'error' !== report.verdict,
120
72
  }],
package/src/sig.ts CHANGED
@@ -1,29 +1,5 @@
1
1
  /* Copyright (c) 2021-2026 Richard Rodger, MIT License */
2
2
 
3
- // THE SIGNATURE REGISTRY (docs/design/SIGNATURES.0.md). The call
4
- // surface of the built-in functions is DECLARED, in the signature
5
- // syntax itself, in test/spec/signature.tsv; this module is the
6
- // TypeScript half of the pair that reads it. The declaration text is
7
- // inlined at build time (ts/src/sigdecl.ts, `make sig`) and parsed at
8
- // initialisation by the signature grammar -- a custom tabnas grammar,
9
- // the same engine the aontu grammar itself is built on -- into the
10
- // registry the runtime signature checker, the error-message builder,
11
- // the docs table and the LSP all consume. Neither port authors a
12
- // table: go/sig.go parses the same text with the same grammar, and
13
- // the shared suite round-trips every line (render(parse(line)) is the
14
- // line) so the two parsers cannot drift.
15
- //
16
- // line = name '(' [ arg {',' arg} ] ')' ':' type
17
- // arg = [mode] name ['?'] ':' type
18
- // | '...' name ':' ( type | '(' [mode] type {',' [mode] type} ')' )
19
- // type = word {'|' word}
20
- // mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'
21
- //
22
- // `value` mode is unmarked; the five marked modes are the vocabulary
23
- // plain pseudo-TypeScript cannot say (a captured spelling is not a
24
- // string value). The grammar is line-oriented: the loader strips
25
- // comment and blank lines and parses each declaration line alone, so
26
- // the grammar never sees line structure.
27
3
 
28
4
  import { Tabnas } from '@tabnas/parser'
29
5
 
@@ -59,11 +35,6 @@ const ARG_MODES: Record<string, boolean> = {
59
35
  }
60
36
 
61
37
 
62
- // The signature grammar, as a tabnas grammar plugin. Rules: sig (the
63
- // line) -> args -> arg -> argtype -> type | group -> gmember. Alts
64
- // match at most two tokens, the engine's shape; lists loop the
65
- // json-grammar way (the element rule replaces itself on ',' and
66
- // backtracks the closer for its parent to consume).
67
38
  function sigGrammar(tn: any) {
68
39
  tn.options({
69
40
  fixed: {
@@ -326,12 +297,6 @@ export type {
326
297
  FuncSig,
327
298
  }
328
299
 
329
- // The parsed registry, built once from the inlined declaration -- the
330
- // one source every consumer (the arity tables, the runtime gate, the
331
- // hints, the docs table, the LSP) reads. A parse failure here throws
332
- // at module load: the inlined text is repository content whose parse
333
- // the round-trip suite gates, so a failure is a build defect, not a
334
- // runtime condition. Twin: funcSig in go/sig.go.
335
300
  const funcSig: Record<string, FuncSig> =
336
301
  parseSigText(SIGDECL) /* node:coverage ignore next 9 */
337
302
 
package/src/sigdecl.ts CHANGED
@@ -6,6 +6,6 @@
6
6
  // this copy is identical with the shared file.
7
7
 
8
8
  const SIGDECL: string =
9
- "# The call surface: one declaration line per built-in function\n# (docs/design/SIGNATURES.0.md). THIS FILE IS THE SOURCE — both ports\n# carry a build-time-inlined copy (ts/src/sigdecl.ts, go/sigdecl.txt;\n# `make sig` regenerates both, and each port's suite asserts its copy\n# is byte-identical with this file) and parse it at initialisation\n# with the signature grammar, a tabnas grammar (ts/src/sig.ts,\n# go/sig.go). The suites also round-trip every line:\n# render(parse(line)) must be the line exactly, in both ports.\n#\n# The syntax (rendered TypeScript-ish, honest about argument MODES):\n# line = name '(' [ arg {',' arg} ] ')' ':' type\n# arg = [mode] name ['?'] ':' type\n# | '...' name ':' '(' [mode] type {',' [mode] type} ')'\n# type = word {'|' word}\n# mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'\n# `value` mode is unmarked. `constraint` is the result word for\n# residuals whose meet depends on the peer; `any` is the honest type\n# where a function is a wrapper.\nupper(s: string|number) : string\nlower(s: string|number) : string\ncopy(v: any) : any\npref(v: any) : any\nsuper(t: any) : any\ntype(t: any) : any\nhide(v: any) : any\nclose(m: any) : any\nopen(m: any) : any\nmove(v: any) : any\npath(capture p?: path) : path\nmap() : map\nlist() : list\nmin(n: number|string) : constraint\nmax(n: number|string) : constraint\nabove(n: number|string) : constraint\nbelow(n: number|string) : constraint\nre(text p: string) : constraint\nlength(n: number|constraint) : constraint\nkey(up?: integer|biginteger) : string\nunique(projector k?: string) : constraint\nneq(...vals: number|string) : constraint\nmust(trial c: any, text msg: string) : constraint\ndeprecate(v: any, r?: map) : any\nacyclic() : constraint\ninverse(projector k: string) : constraint\nrefer(template t?: any) : constraint\nrel(template t?: any) : constraint\npack(d: map|list, template t: any) : map\neach(d: map|list, template t?: any) : list\nform(d: map|list, template t: any) : list\nfilter(d: map|list, trial c: any) : map|list\nmatch(s: any, ...pr: (trial any, any), dflt?: any) : any\nadd(a: number, b: number) : number\nsub(a: number, b: number) : number\nmul(a: number, b: number) : number\ndiv(a: number, b: number) : number\nmod(a: number, b: number) : number\nrem(a: number, b: number) : number\nsum(d: map|list) : number\nleast(d: map|list) : number\ngreatest(d: map|list) : number\npick(d: map|list, projector k: string|integer) : any\njoin(d: map|list, sep?: string) : string\nesc(s: string, variant?: string) : string\nusc(s: string, variant?: string) : string\nrep(s: string, text p: string, text sub: string) : string\nsplit(s: string, sep: string|constraint) : list\nemit(s: map|list, template t: map|list) : list\n"
9
+ "# The call surface: one declaration line per built-in function\n# (docs/design/SIGNATURES.0.md). THIS FILE IS THE SOURCE — both ports\n# carry a build-time-inlined copy (ts/src/sigdecl.ts, go/sigdecl.txt;\n# `make sig` regenerates both, and each port's suite asserts its copy\n# is byte-identical with this file) and parse it at initialisation\n# with the signature grammar, a tabnas grammar (ts/src/sig.ts,\n# go/sig.go). The suites also round-trip every line:\n# render(parse(line)) must be the line exactly, in both ports.\n#\n# The syntax (rendered TypeScript-ish, honest about argument MODES):\n# line = name '(' [ arg {',' arg} ] ')' ':' type\n# arg = [mode] name ['?'] ':' type\n# | '...' name ':' '(' [mode] type {',' [mode] type} ')'\n# type = word {'|' word}\n# mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'\n# `value` mode is unmarked. `constraint` is the result word for\n# residuals whose meet depends on the peer; `any` is the honest type\n# where a function is a wrapper.\nupper(s: string|number, start?: integer|biginteger, len?: integer|biginteger) : string\nlower(s: string|number, start?: integer|biginteger, len?: integer|biginteger) : string\ncopy(v: any) : any\npref(v: any) : any\nsuper(t: any) : any\ntype(t: any) : any\nhide(v: any) : any\nmaybe(v: any) : any\nclose(m: any) : any\nopen(m: any) : any\nmove(v: any) : any\npath(capture p?: path) : path\nmap() : map\nlist() : list\nmin(n: number|string) : constraint\nmax(n: number|string) : constraint\nabove(n: number|string) : constraint\nbelow(n: number|string) : constraint\nre(text p: string) : constraint\nlength(n: number|constraint) : constraint\nkey(up?: integer|biginteger) : string\nunique(projector k?: string) : constraint\nneq(...vals: number|string) : constraint\nmust(trial c: any, text msg: string) : constraint\ndeprecate(v: any, r?: map) : any\nacyclic() : constraint\ninverse(projector k: string) : constraint\nrefer(template t?: any) : constraint\nrel(template t?: any) : constraint\npack(d: map|list, template t: any) : map\neach(d: map|list, template t: any) : list\nfilter(d: map|list, trial c: any) : map|list\nmatch(s: any, ...pr: (trial any, any), dflt?: any) : any\nadd(a: number, b: number) : number\nsub(a: number, b: number) : number\nmul(a: number, b: number) : number\ndiv(a: number, b: number) : number\nmod(a: number, b: number) : number\nrem(a: number, b: number) : number\nsum(d: map|list) : number\nleast(d: map|list) : number\ngreatest(d: map|list) : number\npick(d: map|list, projector k: string|integer) : any\nsort(d: map|list, projector k?: string|integer, dir?: string) : list\njoin(d: map|list, sep?: string) : string\nesc(s: string, variant?: string) : string\nusc(s: string, variant?: string) : string\nrep(s: string, text p: string, text sub: string) : string\nsplit(s: string, sep: string|constraint) : list\nemit(s: map|list, template t: map|list) : list\nabnf(g: string) : string\nparse(g: string, v?: string) : map|list|constraint\nnom(name: string, style?: string|list, acronyms?: list) : string|map\ntranslate(s: string, from: string, to?: string) : string\nproject(spec?: string|map, children?: list) : map\nfolder(spec: string|map, children?: list) : map\nfile(spec: string|map, children?: list) : map\ncontent(spec: string|map) : map\nline(spec: string|map) : map\nfragment(spec: string|map, children?: list) : map\nslot(spec: string|map, children?: list) : map\ninject(spec: string|map, children?: list) : map\ncopyfiles(spec: string|map) : map\nlistitems(spec: map, children?: list) : map\n"
10
10
 
11
11
  export { SIGDECL }
package/src/siggate.ts CHANGED
@@ -1,31 +1,5 @@
1
1
  /* Copyright (c) 2021-2026 Richard Rodger, MIT License */
2
2
 
3
- // THE RUNTIME SIGNATURE CHECKER (docs/design/SIGNATURES.0.md). One
4
- // argument gate, run by the shared function machinery
5
- // (FuncBaseVal.unify) just before a call resolves, when its arguments
6
- // are driven: for each VALUE-mode argument whose declared type is
7
- // scalar-kind words, the driven Val must be a concrete scalar of an
8
- // admitted kind. A failure refuses as `func_arg`, whose hint renders
9
- // the signature line and names the offending argument -- the
10
- // error-message builder the registry exists for.
11
- //
12
- // The gate owns exactly the argument-shape refusals that were bare
13
- // `invalid-arg` at the call: the case family's operand, the
14
- // arithmetic operands, join's separator, pick's key. Everything with
15
- // more meaning than a shape mismatch keeps its own code: the bag
16
- // arguments (`pack_data`, `each_data`, `filter_data`,
17
- // `aggregate_data` -- container words are not gate words), the
18
- // constraint atoms (not on this path at all -- their refusals ride
19
- // the residual), `key()` (whose level meaning `key_level` names, and
20
- // which is skipped here for that reason), and the capture, template,
21
- // trial, projector and text modes, none of which are read as values.
22
- //
23
- // What the gate refuses it must POSITIVELY identify: a concrete
24
- // scalar of a wrong kind, a map, a list, or a scalar KIND marker
25
- // where a value belongs. Anything else -- a preference, a residual, a
26
- // disjunct -- passes through to the builtin's own logic, which is
27
- // what keeps arith's unpref reading and join's deferral working.
28
- // Twin: sigRefuse in go/siggate.go.
29
3
 
30
4
  import type { Val } from './type'
31
5
  import { AontuContext } from './ctx'
@@ -44,10 +18,6 @@ import {
44
18
  } from './val/ScalarKindVal'
45
19
 
46
20
 
47
- // The scalar-kind words the gate enforces, each to its lattice
48
- // marker. A declared type is gate-checkable only when EVERY union
49
- // word is here: `any`, `constraint`, and the container words leave
50
- // the argument to the builtin.
51
21
  const SIG_KIND = new Map<string, any>([
52
22
  ['string', String],
53
23
  ['number', Number],