@rcrsr/rill 0.15.0 → 0.17.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 (316) hide show
  1. package/README.md +37 -21
  2. package/dist/ast-nodes.d.ts +2 -13
  3. package/dist/ast-nodes.js +0 -1
  4. package/dist/ast-unions.d.ts +0 -1
  5. package/dist/ast-unions.js +0 -1
  6. package/dist/constants.d.ts +0 -1
  7. package/dist/constants.js +0 -1
  8. package/dist/error-classes.d.ts +0 -1
  9. package/dist/error-classes.js +0 -1
  10. package/dist/error-formatter.d.ts +0 -1
  11. package/dist/error-formatter.js +0 -1
  12. package/dist/error-registry.d.ts +0 -1
  13. package/dist/error-registry.js +32 -1
  14. package/dist/ext/crypto/index.d.ts +3 -4
  15. package/dist/ext/crypto/index.js +66 -64
  16. package/dist/ext/exec/index.d.ts +3 -4
  17. package/dist/ext/exec/index.js +17 -12
  18. package/dist/ext/exec/runner.d.ts +0 -1
  19. package/dist/ext/exec/runner.js +0 -1
  20. package/dist/ext/fetch/index.d.ts +3 -4
  21. package/dist/ext/fetch/index.js +23 -49
  22. package/dist/ext/fetch/request.d.ts +0 -1
  23. package/dist/ext/fetch/request.js +0 -1
  24. package/dist/ext/fs/index.d.ts +3 -4
  25. package/dist/ext/fs/index.js +268 -266
  26. package/dist/ext/fs/sandbox.d.ts +0 -1
  27. package/dist/ext/fs/sandbox.js +0 -1
  28. package/dist/ext/kv/index.d.ts +3 -4
  29. package/dist/ext/kv/index.js +216 -215
  30. package/dist/ext/kv/store.d.ts +0 -1
  31. package/dist/ext/kv/store.js +2 -2
  32. package/dist/ext-parse-bridge.d.ts +10 -0
  33. package/dist/ext-parse-bridge.js +10 -0
  34. package/dist/generated/introspection-data.d.ts +1 -2
  35. package/dist/generated/introspection-data.js +385 -297
  36. package/dist/generated/version-data.d.ts +1 -2
  37. package/dist/generated/version-data.js +2 -3
  38. package/dist/highlight-map.d.ts +0 -1
  39. package/dist/highlight-map.js +0 -1
  40. package/dist/index.d.ts +15 -5
  41. package/dist/index.js +14 -6
  42. package/dist/lexer/errors.d.ts +0 -1
  43. package/dist/lexer/errors.js +0 -1
  44. package/dist/lexer/helpers.d.ts +0 -1
  45. package/dist/lexer/helpers.js +0 -1
  46. package/dist/lexer/index.d.ts +0 -1
  47. package/dist/lexer/index.js +0 -1
  48. package/dist/lexer/operators.d.ts +0 -1
  49. package/dist/lexer/operators.js +0 -1
  50. package/dist/lexer/readers.d.ts +0 -1
  51. package/dist/lexer/readers.js +0 -1
  52. package/dist/lexer/state.d.ts +0 -1
  53. package/dist/lexer/state.js +0 -1
  54. package/dist/lexer/tokenizer.d.ts +0 -1
  55. package/dist/lexer/tokenizer.js +0 -1
  56. package/dist/parser/helpers.d.ts +0 -1
  57. package/dist/parser/helpers.js +0 -1
  58. package/dist/parser/index.d.ts +0 -1
  59. package/dist/parser/index.js +0 -1
  60. package/dist/parser/parser-collect.d.ts +0 -1
  61. package/dist/parser/parser-collect.js +0 -1
  62. package/dist/parser/parser-control.d.ts +0 -1
  63. package/dist/parser/parser-control.js +0 -1
  64. package/dist/parser/parser-expr.d.ts +0 -1
  65. package/dist/parser/parser-expr.js +0 -1
  66. package/dist/parser/parser-extract.d.ts +0 -1
  67. package/dist/parser/parser-extract.js +0 -1
  68. package/dist/parser/parser-functions.d.ts +0 -1
  69. package/dist/parser/parser-functions.js +0 -1
  70. package/dist/parser/parser-literals.d.ts +0 -1
  71. package/dist/parser/parser-literals.js +4 -2
  72. package/dist/parser/parser-script.d.ts +0 -1
  73. package/dist/parser/parser-script.js +0 -1
  74. package/dist/parser/parser-shape.d.ts +2 -3
  75. package/dist/parser/parser-shape.js +8 -52
  76. package/dist/parser/parser-types.d.ts +28 -2
  77. package/dist/parser/parser-types.js +76 -13
  78. package/dist/parser/parser-use.d.ts +0 -1
  79. package/dist/parser/parser-use.js +7 -2
  80. package/dist/parser/parser-variables.d.ts +0 -1
  81. package/dist/parser/parser-variables.js +0 -1
  82. package/dist/parser/parser.d.ts +0 -1
  83. package/dist/parser/parser.js +0 -1
  84. package/dist/parser/state.d.ts +0 -1
  85. package/dist/parser/state.js +0 -1
  86. package/dist/runtime/core/callable.d.ts +59 -20
  87. package/dist/runtime/core/callable.js +188 -39
  88. package/dist/runtime/core/context.d.ts +0 -12
  89. package/dist/runtime/core/context.js +77 -77
  90. package/dist/runtime/core/equals.d.ts +0 -1
  91. package/dist/runtime/core/equals.js +35 -3
  92. package/dist/runtime/core/eval/base.d.ts +0 -1
  93. package/dist/runtime/core/eval/base.js +0 -1
  94. package/dist/runtime/core/eval/evaluator.d.ts +0 -1
  95. package/dist/runtime/core/eval/evaluator.js +0 -1
  96. package/dist/runtime/core/eval/index.d.ts +2 -3
  97. package/dist/runtime/core/eval/index.js +11 -1
  98. package/dist/runtime/core/eval/mixins/annotations.d.ts +0 -1
  99. package/dist/runtime/core/eval/mixins/annotations.js +0 -1
  100. package/dist/runtime/core/eval/mixins/closures.d.ts +0 -1
  101. package/dist/runtime/core/eval/mixins/closures.js +92 -70
  102. package/dist/runtime/core/eval/mixins/collections.d.ts +0 -1
  103. package/dist/runtime/core/eval/mixins/collections.js +9 -4
  104. package/dist/runtime/core/eval/mixins/control-flow.d.ts +0 -1
  105. package/dist/runtime/core/eval/mixins/control-flow.js +0 -1
  106. package/dist/runtime/core/eval/mixins/conversion.d.ts +0 -1
  107. package/dist/runtime/core/eval/mixins/conversion.js +196 -188
  108. package/dist/runtime/core/eval/mixins/core.d.ts +0 -1
  109. package/dist/runtime/core/eval/mixins/core.js +2 -3
  110. package/dist/runtime/core/eval/mixins/expressions.d.ts +0 -1
  111. package/dist/runtime/core/eval/mixins/expressions.js +35 -28
  112. package/dist/runtime/core/eval/mixins/extraction.d.ts +0 -1
  113. package/dist/runtime/core/eval/mixins/extraction.js +8 -9
  114. package/dist/runtime/core/eval/mixins/list-dispatch.d.ts +0 -1
  115. package/dist/runtime/core/eval/mixins/list-dispatch.js +0 -1
  116. package/dist/runtime/core/eval/mixins/literals.d.ts +0 -1
  117. package/dist/runtime/core/eval/mixins/literals.js +6 -10
  118. package/dist/runtime/core/eval/mixins/types.d.ts +2 -1
  119. package/dist/runtime/core/eval/mixins/types.js +231 -261
  120. package/dist/runtime/core/eval/mixins/use.d.ts +0 -1
  121. package/dist/runtime/core/eval/mixins/use.js +0 -1
  122. package/dist/runtime/core/eval/mixins/variables.d.ts +0 -1
  123. package/dist/runtime/core/eval/mixins/variables.js +16 -15
  124. package/dist/runtime/core/eval/types.d.ts +0 -1
  125. package/dist/runtime/core/eval/types.js +0 -1
  126. package/dist/runtime/core/execute.d.ts +0 -1
  127. package/dist/runtime/core/execute.js +0 -1
  128. package/dist/runtime/core/field-descriptor.d.ts +4 -5
  129. package/dist/runtime/core/field-descriptor.js +2 -2
  130. package/dist/runtime/core/introspection.d.ts +0 -1
  131. package/dist/runtime/core/introspection.js +6 -7
  132. package/dist/runtime/core/markers.d.ts +12 -0
  133. package/dist/runtime/core/markers.js +7 -0
  134. package/dist/runtime/core/resolvers.d.ts +0 -1
  135. package/dist/runtime/core/resolvers.js +0 -1
  136. package/dist/runtime/core/signals.d.ts +0 -1
  137. package/dist/runtime/core/signals.js +0 -1
  138. package/dist/runtime/core/type-registrations.d.ts +136 -0
  139. package/dist/runtime/core/type-registrations.js +749 -0
  140. package/dist/runtime/core/type-structures.d.ts +128 -0
  141. package/dist/runtime/core/type-structures.js +12 -0
  142. package/dist/runtime/core/types.d.ts +15 -4
  143. package/dist/runtime/core/types.js +0 -1
  144. package/dist/runtime/core/values.d.ts +88 -146
  145. package/dist/runtime/core/values.js +466 -470
  146. package/dist/runtime/ext/builtins.d.ts +0 -1
  147. package/dist/runtime/ext/builtins.js +125 -80
  148. package/dist/runtime/ext/extensions.d.ts +30 -125
  149. package/dist/runtime/ext/extensions.js +0 -94
  150. package/dist/runtime/ext/test-context.d.ts +28 -0
  151. package/dist/runtime/ext/test-context.js +154 -0
  152. package/dist/runtime/index.d.ts +22 -9
  153. package/dist/runtime/index.js +18 -5
  154. package/dist/signature-parser.d.ts +2 -3
  155. package/dist/signature-parser.js +19 -17
  156. package/dist/source-location.d.ts +0 -1
  157. package/dist/source-location.js +0 -1
  158. package/dist/token-types.d.ts +0 -1
  159. package/dist/token-types.js +0 -1
  160. package/dist/types.d.ts +0 -1
  161. package/dist/types.js +0 -1
  162. package/dist/value-types.d.ts +15 -12
  163. package/dist/value-types.js +0 -1
  164. package/package.json +2 -1
  165. package/dist/ast-nodes.d.ts.map +0 -1
  166. package/dist/ast-nodes.js.map +0 -1
  167. package/dist/ast-unions.d.ts.map +0 -1
  168. package/dist/ast-unions.js.map +0 -1
  169. package/dist/constants.d.ts.map +0 -1
  170. package/dist/constants.js.map +0 -1
  171. package/dist/error-classes.d.ts.map +0 -1
  172. package/dist/error-classes.js.map +0 -1
  173. package/dist/error-formatter.d.ts.map +0 -1
  174. package/dist/error-formatter.js.map +0 -1
  175. package/dist/error-registry.d.ts.map +0 -1
  176. package/dist/error-registry.js.map +0 -1
  177. package/dist/ext/crypto/index.d.ts.map +0 -1
  178. package/dist/ext/crypto/index.js.map +0 -1
  179. package/dist/ext/exec/index.d.ts.map +0 -1
  180. package/dist/ext/exec/index.js.map +0 -1
  181. package/dist/ext/exec/runner.d.ts.map +0 -1
  182. package/dist/ext/exec/runner.js.map +0 -1
  183. package/dist/ext/fetch/index.d.ts.map +0 -1
  184. package/dist/ext/fetch/index.js.map +0 -1
  185. package/dist/ext/fetch/request.d.ts.map +0 -1
  186. package/dist/ext/fetch/request.js.map +0 -1
  187. package/dist/ext/fs/index.d.ts.map +0 -1
  188. package/dist/ext/fs/index.js.map +0 -1
  189. package/dist/ext/fs/sandbox.d.ts.map +0 -1
  190. package/dist/ext/fs/sandbox.js.map +0 -1
  191. package/dist/ext/kv/index.d.ts.map +0 -1
  192. package/dist/ext/kv/index.js.map +0 -1
  193. package/dist/ext/kv/store.d.ts.map +0 -1
  194. package/dist/ext/kv/store.js.map +0 -1
  195. package/dist/generated/introspection-data.d.ts.map +0 -1
  196. package/dist/generated/introspection-data.js.map +0 -1
  197. package/dist/generated/version-data.d.ts.map +0 -1
  198. package/dist/generated/version-data.js.map +0 -1
  199. package/dist/highlight-map.d.ts.map +0 -1
  200. package/dist/highlight-map.js.map +0 -1
  201. package/dist/index.d.ts.map +0 -1
  202. package/dist/index.js.map +0 -1
  203. package/dist/lexer/errors.d.ts.map +0 -1
  204. package/dist/lexer/errors.js.map +0 -1
  205. package/dist/lexer/helpers.d.ts.map +0 -1
  206. package/dist/lexer/helpers.js.map +0 -1
  207. package/dist/lexer/index.d.ts.map +0 -1
  208. package/dist/lexer/index.js.map +0 -1
  209. package/dist/lexer/operators.d.ts.map +0 -1
  210. package/dist/lexer/operators.js.map +0 -1
  211. package/dist/lexer/readers.d.ts.map +0 -1
  212. package/dist/lexer/readers.js.map +0 -1
  213. package/dist/lexer/state.d.ts.map +0 -1
  214. package/dist/lexer/state.js.map +0 -1
  215. package/dist/lexer/tokenizer.d.ts.map +0 -1
  216. package/dist/lexer/tokenizer.js.map +0 -1
  217. package/dist/parser/helpers.d.ts.map +0 -1
  218. package/dist/parser/helpers.js.map +0 -1
  219. package/dist/parser/index.d.ts.map +0 -1
  220. package/dist/parser/index.js.map +0 -1
  221. package/dist/parser/parser-collect.d.ts.map +0 -1
  222. package/dist/parser/parser-collect.js.map +0 -1
  223. package/dist/parser/parser-control.d.ts.map +0 -1
  224. package/dist/parser/parser-control.js.map +0 -1
  225. package/dist/parser/parser-expr.d.ts.map +0 -1
  226. package/dist/parser/parser-expr.js.map +0 -1
  227. package/dist/parser/parser-extract.d.ts.map +0 -1
  228. package/dist/parser/parser-extract.js.map +0 -1
  229. package/dist/parser/parser-functions.d.ts.map +0 -1
  230. package/dist/parser/parser-functions.js.map +0 -1
  231. package/dist/parser/parser-literals.d.ts.map +0 -1
  232. package/dist/parser/parser-literals.js.map +0 -1
  233. package/dist/parser/parser-script.d.ts.map +0 -1
  234. package/dist/parser/parser-script.js.map +0 -1
  235. package/dist/parser/parser-shape.d.ts.map +0 -1
  236. package/dist/parser/parser-shape.js.map +0 -1
  237. package/dist/parser/parser-types.d.ts.map +0 -1
  238. package/dist/parser/parser-types.js.map +0 -1
  239. package/dist/parser/parser-use.d.ts.map +0 -1
  240. package/dist/parser/parser-use.js.map +0 -1
  241. package/dist/parser/parser-variables.d.ts.map +0 -1
  242. package/dist/parser/parser-variables.js.map +0 -1
  243. package/dist/parser/parser.d.ts.map +0 -1
  244. package/dist/parser/parser.js.map +0 -1
  245. package/dist/parser/state.d.ts.map +0 -1
  246. package/dist/parser/state.js.map +0 -1
  247. package/dist/runtime/core/callable.d.ts.map +0 -1
  248. package/dist/runtime/core/callable.js.map +0 -1
  249. package/dist/runtime/core/context.d.ts.map +0 -1
  250. package/dist/runtime/core/context.js.map +0 -1
  251. package/dist/runtime/core/equals.d.ts.map +0 -1
  252. package/dist/runtime/core/equals.js.map +0 -1
  253. package/dist/runtime/core/eval/base.d.ts.map +0 -1
  254. package/dist/runtime/core/eval/base.js.map +0 -1
  255. package/dist/runtime/core/eval/evaluator.d.ts.map +0 -1
  256. package/dist/runtime/core/eval/evaluator.js.map +0 -1
  257. package/dist/runtime/core/eval/index.d.ts.map +0 -1
  258. package/dist/runtime/core/eval/index.js.map +0 -1
  259. package/dist/runtime/core/eval/mixins/annotations.d.ts.map +0 -1
  260. package/dist/runtime/core/eval/mixins/annotations.js.map +0 -1
  261. package/dist/runtime/core/eval/mixins/closures.d.ts.map +0 -1
  262. package/dist/runtime/core/eval/mixins/closures.js.map +0 -1
  263. package/dist/runtime/core/eval/mixins/collections.d.ts.map +0 -1
  264. package/dist/runtime/core/eval/mixins/collections.js.map +0 -1
  265. package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +0 -1
  266. package/dist/runtime/core/eval/mixins/control-flow.js.map +0 -1
  267. package/dist/runtime/core/eval/mixins/conversion.d.ts.map +0 -1
  268. package/dist/runtime/core/eval/mixins/conversion.js.map +0 -1
  269. package/dist/runtime/core/eval/mixins/core.d.ts.map +0 -1
  270. package/dist/runtime/core/eval/mixins/core.js.map +0 -1
  271. package/dist/runtime/core/eval/mixins/expressions.d.ts.map +0 -1
  272. package/dist/runtime/core/eval/mixins/expressions.js.map +0 -1
  273. package/dist/runtime/core/eval/mixins/extraction.d.ts.map +0 -1
  274. package/dist/runtime/core/eval/mixins/extraction.js.map +0 -1
  275. package/dist/runtime/core/eval/mixins/list-dispatch.d.ts.map +0 -1
  276. package/dist/runtime/core/eval/mixins/list-dispatch.js.map +0 -1
  277. package/dist/runtime/core/eval/mixins/literals.d.ts.map +0 -1
  278. package/dist/runtime/core/eval/mixins/literals.js.map +0 -1
  279. package/dist/runtime/core/eval/mixins/types.d.ts.map +0 -1
  280. package/dist/runtime/core/eval/mixins/types.js.map +0 -1
  281. package/dist/runtime/core/eval/mixins/use.d.ts.map +0 -1
  282. package/dist/runtime/core/eval/mixins/use.js.map +0 -1
  283. package/dist/runtime/core/eval/mixins/variables.d.ts.map +0 -1
  284. package/dist/runtime/core/eval/mixins/variables.js.map +0 -1
  285. package/dist/runtime/core/eval/types.d.ts.map +0 -1
  286. package/dist/runtime/core/eval/types.js.map +0 -1
  287. package/dist/runtime/core/execute.d.ts.map +0 -1
  288. package/dist/runtime/core/execute.js.map +0 -1
  289. package/dist/runtime/core/field-descriptor.d.ts.map +0 -1
  290. package/dist/runtime/core/field-descriptor.js.map +0 -1
  291. package/dist/runtime/core/introspection.d.ts.map +0 -1
  292. package/dist/runtime/core/introspection.js.map +0 -1
  293. package/dist/runtime/core/resolvers.d.ts.map +0 -1
  294. package/dist/runtime/core/resolvers.js.map +0 -1
  295. package/dist/runtime/core/signals.d.ts.map +0 -1
  296. package/dist/runtime/core/signals.js.map +0 -1
  297. package/dist/runtime/core/types.d.ts.map +0 -1
  298. package/dist/runtime/core/types.js.map +0 -1
  299. package/dist/runtime/core/values.d.ts.map +0 -1
  300. package/dist/runtime/core/values.js.map +0 -1
  301. package/dist/runtime/ext/builtins.d.ts.map +0 -1
  302. package/dist/runtime/ext/builtins.js.map +0 -1
  303. package/dist/runtime/ext/extensions.d.ts.map +0 -1
  304. package/dist/runtime/ext/extensions.js.map +0 -1
  305. package/dist/runtime/index.d.ts.map +0 -1
  306. package/dist/runtime/index.js.map +0 -1
  307. package/dist/signature-parser.d.ts.map +0 -1
  308. package/dist/signature-parser.js.map +0 -1
  309. package/dist/source-location.d.ts.map +0 -1
  310. package/dist/source-location.js.map +0 -1
  311. package/dist/token-types.d.ts.map +0 -1
  312. package/dist/token-types.js.map +0 -1
  313. package/dist/types.d.ts.map +0 -1
  314. package/dist/types.js.map +0 -1
  315. package/dist/value-types.d.ts.map +0 -1
  316. package/dist/value-types.js.map +0 -1
@@ -5,7 +5,8 @@
5
5
  * Public API for host applications.
6
6
  */
7
7
  import { RuntimeError } from '../../types.js';
8
- import { BUILTIN_FUNCTIONS, BUILTIN_METHODS } from '../ext/builtins.js';
8
+ import { BUILTIN_FUNCTIONS } from '../ext/builtins.js';
9
+ import { BUILT_IN_TYPES } from './type-registrations.js';
9
10
  import { bindDictCallables } from './types.js';
10
11
  import { inferType } from './values.js';
11
12
  import { callable, validateDefaultValueType, } from './callable.js';
@@ -14,72 +15,26 @@ import { callable, validateDefaultValueType, } from './callable.js';
14
15
  // chain: pipe form sends 1 arg when signature declares 2 (pipeValue is the first).
15
16
  const UNTYPED_BUILTINS = new Set(['log', 'chain']);
16
17
  // Built-in methods that do their own internal arg validation with specific error
17
- // messages expected by protected language tests. Generic validateCallableArgs
18
+ // messages expected by protected language tests. Generic marshalArgs
18
19
  // must not fire before the method body's own check.
19
20
  export const UNVALIDATED_METHOD_PARAMS = new Set(['has', 'has_any', 'has_all']);
20
- // Built-in methods that perform their own receiver type checking with specific
21
- // error messages. Generic RILL-R003 must not fire before the method body runs.
22
- // Mirrors the old flat-structure convention of receiverTypes: [].
23
- export const UNVALIDATED_METHOD_RECEIVERS = new Set([
24
- 'head',
25
- 'tail',
26
- 'first',
27
- 'at',
28
- 'eq',
29
- 'ne',
30
- 'keys',
31
- 'values',
32
- 'entries',
33
- 'has',
34
- 'has_any',
35
- 'has_all',
36
- 'dimensions',
37
- 'model',
38
- 'similarity',
39
- 'dot',
40
- 'distance',
41
- 'norm',
42
- 'normalize',
43
- ]);
44
21
  /**
45
- * Build a ReadonlyMap of frozen ApplicationCallable dicts from an array of
46
- * [typeName, methods] pairs. Accepts pairs (not a plain object) so the same
47
- * typeName can appear more than once duplicate method names across entries
48
- * for the same type trigger an Error (EC-6).
49
- *
50
- * Re-exported from the public barrel index for host integration use.
22
+ * Derive the set of method names that handle their own receiver type checking.
23
+ * Collects names from methods where skipReceiverValidation is true.
24
+ * Methods without the flag default to standard RILL-R003 receiver validation.
51
25
  */
52
- export function buildTypeMethodDicts(pairs) {
53
- const registry = new Map();
54
- const result = new Map();
55
- for (const [typeName, methods] of pairs) {
56
- const seen = registry.get(typeName) ?? new Set();
57
- registry.set(typeName, seen);
58
- const existing = result.get(typeName) ?? {};
59
- const dict = { ...existing };
60
- for (const [name, fn] of Object.entries(methods)) {
61
- if (seen.has(name)) {
62
- throw new Error(`Duplicate method '${name}' on type '${typeName}'`);
26
+ function deriveUnvalidatedMethodReceivers(registrations) {
27
+ const bypass = new Set();
28
+ for (const reg of registrations) {
29
+ for (const [name, method] of Object.entries(reg.methods)) {
30
+ if (method.skipReceiverValidation) {
31
+ bypass.add(name);
63
32
  }
64
- seen.add(name);
65
- const appCallable = {
66
- __type: 'callable',
67
- kind: 'application',
68
- params: fn.params,
69
- returnType: fn.returnType,
70
- annotations: fn.annotations ?? {},
71
- isProperty: false,
72
- fn: fn.fn,
73
- };
74
- dict[name] = appCallable;
75
33
  }
76
- result.set(typeName, Object.freeze(dict));
77
34
  }
78
- return result;
35
+ return Object.freeze(bypass);
79
36
  }
80
37
  const BUILTIN_FN_CACHE = new Map();
81
- const BUILTIN_METHOD_PARAMS_CACHE = new Map();
82
- const BUILTIN_METHOD_RECEIVER_TYPES_CACHE = new Map();
83
38
  function initBuiltinCaches() {
84
39
  for (const [name, entry] of Object.entries(BUILTIN_FUNCTIONS)) {
85
40
  if (UNTYPED_BUILTINS.has(name)) {
@@ -94,21 +49,6 @@ function initBuiltinCaches() {
94
49
  };
95
50
  BUILTIN_FN_CACHE.set(name, { appCallable: typedCallable });
96
51
  }
97
- for (const [typeName, methods] of Object.entries(BUILTIN_METHODS)) {
98
- for (const [name, impl] of Object.entries(methods)) {
99
- // Accumulate receiver types across all type groups for this method name.
100
- // Skip methods that perform their own receiver type checking.
101
- if (!UNVALIDATED_METHOD_RECEIVERS.has(name)) {
102
- const existing = BUILTIN_METHOD_RECEIVER_TYPES_CACHE.get(name);
103
- BUILTIN_METHOD_RECEIVER_TYPES_CACHE.set(name, existing !== undefined ? [...existing, typeName] : [typeName]);
104
- }
105
- if (!UNVALIDATED_METHOD_PARAMS.has(name)) {
106
- if (impl.params.length > 0) {
107
- BUILTIN_METHOD_PARAMS_CACHE.set(name, impl.params);
108
- }
109
- }
110
- }
111
- }
112
52
  }
113
53
  // Initialise once at module load.
114
54
  initBuiltinCaches();
@@ -194,15 +134,74 @@ export function createRuntimeContext(options = {}) {
194
134
  const resolverConfigs = new Map(options.configurations?.resolvers
195
135
  ? Object.entries(options.configurations.resolvers)
196
136
  : []);
197
- // Build typeMethodDicts fresh per context so duplicate detection (EC-6)
198
- // uses isolated state and does not leak across context instances.
199
- const typeMethodDicts = buildTypeMethodDicts(Object.entries(BUILTIN_METHODS));
137
+ // EC-1: Validate no duplicate type names in registrations.
138
+ const seenTypeNames = new Set();
139
+ for (const reg of BUILT_IN_TYPES) {
140
+ if (seenTypeNames.has(reg.name)) {
141
+ throw new Error(`Duplicate type registration '${reg.name}'`);
142
+ }
143
+ seenTypeNames.add(reg.name);
144
+ }
145
+ // EC-2: Validate every registration has protocol.format.
146
+ for (const reg of BUILT_IN_TYPES) {
147
+ if (!reg.protocol.format) {
148
+ throw new Error(`Type '${reg.name}' missing required format protocol`);
149
+ }
150
+ }
151
+ // Derive typeNames from registrations (replaces VALID_TYPE_NAMES in context).
152
+ const typeNames = Object.freeze(BUILT_IN_TYPES.map((r) => r.name));
153
+ // Derive leafTypes from registrations where isLeaf === true, plus 'any'
154
+ // which has no registration but rejects type arguments (AC-4).
155
+ const leafTypes = Object.freeze(new Set([
156
+ ...BUILT_IN_TYPES.filter((r) => r.isLeaf).map((r) => r.name),
157
+ 'any',
158
+ ]));
159
+ // Derive method dicts from registration.methods (absorbs buildTypeMethodDicts
160
+ // logic). Validates EC-6: duplicate method on same type.
161
+ const methodRegistry = new Map();
162
+ const typeMethodDicts = new Map();
163
+ for (const reg of BUILT_IN_TYPES) {
164
+ const methods = reg.methods;
165
+ if (!methods || Object.keys(methods).length === 0)
166
+ continue;
167
+ const seen = methodRegistry.get(reg.name) ?? new Set();
168
+ methodRegistry.set(reg.name, seen);
169
+ const existing = typeMethodDicts.get(reg.name) ?? {};
170
+ const dict = { ...existing };
171
+ for (const [name, fn] of Object.entries(methods)) {
172
+ if (seen.has(name)) {
173
+ throw new Error(`Duplicate method '${name}' on type '${reg.name}'`);
174
+ }
175
+ seen.add(name);
176
+ const appCallable = {
177
+ __type: 'callable',
178
+ kind: 'application',
179
+ params: fn.params,
180
+ returnType: fn.returnType,
181
+ annotations: fn.annotations ?? {},
182
+ isProperty: false,
183
+ fn: fn.fn,
184
+ };
185
+ dict[name] = appCallable;
186
+ }
187
+ typeMethodDicts.set(reg.name, Object.freeze(dict));
188
+ }
189
+ // Derive bypass set from registrations: method names that handle their own
190
+ // receiver type checking. Generic RILL-R003 must not fire before the method body.
191
+ const unvalidatedMethodReceivers = deriveUnvalidatedMethodReceivers(BUILT_IN_TYPES);
192
+ // BC-5: Freeze all derived collections after creation.
193
+ Object.freeze(typeNames);
194
+ Object.freeze(typeMethodDicts);
195
+ // Suppress unused-variable warning for typeNames (consumed in later phases).
196
+ void typeNames;
200
197
  return {
201
198
  parent: undefined,
202
199
  variables,
203
200
  variableTypes,
204
201
  functions,
205
202
  typeMethodDicts,
203
+ leafTypes,
204
+ unvalidatedMethodReceivers,
206
205
  callbacks: { ...defaultCallbacks, ...options.callbacks },
207
206
  observability: options.observability ?? {},
208
207
  pipeValue: null,
@@ -232,6 +231,8 @@ export function createChildContext(parent, overrides) {
232
231
  variableTypes: new Map(),
233
232
  functions: parent.functions,
234
233
  typeMethodDicts: parent.typeMethodDicts,
234
+ leafTypes: parent.leafTypes,
235
+ unvalidatedMethodReceivers: parent.unvalidatedMethodReceivers,
235
236
  callbacks: parent.callbacks,
236
237
  observability: parent.observability,
237
238
  pipeValue: parent.pipeValue,
@@ -319,4 +320,3 @@ export function popCallFrame(ctx) {
319
320
  ctx.callStack.pop();
320
321
  }
321
322
  }
322
- //# sourceMappingURL=context.js.map
@@ -6,4 +6,3 @@
6
6
  */
7
7
  import type { ASTNode } from '../../types.js';
8
8
  export declare function astEquals(a: ASTNode, b: ASTNode): boolean;
9
- //# sourceMappingURL=equals.d.ts.map
@@ -544,7 +544,7 @@ function typeRefStaticEquals(a, b) {
544
544
  return typeRefArgListEquals(a.args, b.args);
545
545
  }
546
546
  /**
547
- * Compare two optional TypeRefArg arrays for structural equality.
547
+ * Compare two optional FieldArg arrays for structural equality.
548
548
  */
549
549
  function typeRefArgListEquals(a, b) {
550
550
  const aArgs = a ?? [];
@@ -556,7 +556,9 @@ function typeRefArgListEquals(a, b) {
556
556
  const bArg = bArgs[i];
557
557
  if (aArg.name !== bArg.name)
558
558
  return false;
559
- if (!typeRefEquals(aArg.ref, bArg.ref))
559
+ if (!typeRefEquals(aArg.value, bArg.value))
560
+ return false;
561
+ if (!literalNodeEquals(aArg.defaultValue, bArg.defaultValue))
560
562
  return false;
561
563
  }
562
564
  return true;
@@ -578,4 +580,34 @@ function typeRefEquals(a, b) {
578
580
  }
579
581
  return false;
580
582
  }
581
- //# sourceMappingURL=equals.js.map
583
+ /**
584
+ * Compare two optional LiteralNode values for structural equality.
585
+ * Both-undefined returns true. One-undefined returns false.
586
+ * Complex nodes (ListLiteral, Dict, Closure) return false defensively.
587
+ */
588
+ function literalNodeEquals(a, b) {
589
+ if (a === undefined && b === undefined)
590
+ return true;
591
+ if (a === undefined || b === undefined)
592
+ return false;
593
+ if (a.type !== b.type)
594
+ return false;
595
+ switch (a.type) {
596
+ case 'NumberLiteral':
597
+ return a.value === b.value;
598
+ case 'BoolLiteral':
599
+ return a.value === b.value;
600
+ case 'StringLiteral': {
601
+ const bStr = b;
602
+ if (a.parts.length !== 1 || bStr.parts.length !== 1)
603
+ return false;
604
+ return a.parts[0] === bStr.parts[0];
605
+ }
606
+ case 'ListLiteral':
607
+ case 'Dict':
608
+ case 'Closure':
609
+ return false;
610
+ default:
611
+ return false;
612
+ }
613
+ }
@@ -62,4 +62,3 @@ export declare class EvaluatorBase {
62
62
  */
63
63
  protected accessDictField(value: RillValue, field: string, location?: SourceLocation, allowMissing?: boolean): Promise<RillValue>;
64
64
  }
65
- //# sourceMappingURL=base.d.ts.map
@@ -112,4 +112,3 @@ export class EvaluatorBase {
112
112
  return dictValue;
113
113
  }
114
114
  }
115
- //# sourceMappingURL=base.js.map
@@ -122,4 +122,3 @@ export type Evaluator = InstanceType<typeof Evaluator>;
122
122
  * @internal
123
123
  */
124
124
  export declare function getEvaluator(ctx: RuntimeContext): InstanceType<typeof Evaluator>;
125
- //# sourceMappingURL=evaluator.d.ts.map
@@ -151,4 +151,3 @@ export function getEvaluator(ctx) {
151
151
  }
152
152
  return evaluator;
153
153
  }
154
- //# sourceMappingURL=evaluator.js.map
@@ -9,7 +9,7 @@
9
9
  import type { AnnotatedStatementNode, ASTNode, CaptureNode, ExpressionNode, RillTypeName, SourceLocation, StatementNode } from '../../../types.js';
10
10
  import type { RillCallable } from '../callable.js';
11
11
  import type { RuntimeContext } from '../types.js';
12
- import type { RillValue, RillType } from '../values.js';
12
+ import type { RillValue, TypeStructure } from '../values.js';
13
13
  /**
14
14
  * Capture information returned by handleCapture.
15
15
  */
@@ -39,7 +39,7 @@ export declare function handleCapture(capture: CaptureNode | null, value: RillVa
39
39
  * Assert that a value is of the expected type.
40
40
  * Returns the value unchanged if assertion passes, throws on mismatch.
41
41
  */
42
- export declare function assertType(value: RillValue, expected: RillTypeName | RillType, location?: SourceLocation): RillValue;
42
+ export declare function assertType(value: RillValue, expected: RillTypeName | TypeStructure, location?: SourceLocation): RillValue;
43
43
  /**
44
44
  * Evaluate an expression and return its value.
45
45
  * Main entry point for expression evaluation.
@@ -69,4 +69,3 @@ export declare function getAnnotation(ctx: RuntimeContext, key: string): RillVal
69
69
  * @param location - Optional call site location for error reporting
70
70
  */
71
71
  export declare function invokeCallable(callable: RillCallable, args: RillValue[], ctx: RuntimeContext, location?: SourceLocation): Promise<RillValue>;
72
- //# sourceMappingURL=index.d.ts.map
@@ -70,6 +70,17 @@ export function assertType(value, expected, location) {
70
70
  resolverConfigs: new Map(),
71
71
  resolvingSchemes: new Set(),
72
72
  typeMethodDicts: new Map(),
73
+ leafTypes: new Set([
74
+ 'string',
75
+ 'number',
76
+ 'bool',
77
+ 'vector',
78
+ 'type',
79
+ 'any',
80
+ 'closure',
81
+ 'field_descriptor',
82
+ ]),
83
+ unvalidatedMethodReceivers: new Set(),
73
84
  };
74
85
  const evaluator = getEvaluator(minimalContext);
75
86
  return evaluator.assertType(value, expected, location);
@@ -117,4 +128,3 @@ export async function invokeCallable(callable, args, ctx, location) {
117
128
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
129
  return evaluator.invokeCallable(callable, args, location);
119
130
  }
120
- //# sourceMappingURL=index.js.map
@@ -16,4 +16,3 @@
16
16
  * @internal
17
17
  */
18
18
  export declare const AnnotationsMixin: any;
19
- //# sourceMappingURL=annotations.d.ts.map
@@ -149,4 +149,3 @@ function createAnnotationsMixin(Base) {
149
149
  // TypeScript can't generate declarations for functions returning classes with protected members
150
150
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
151
151
  export const AnnotationsMixin = createAnnotationsMixin;
152
- //# sourceMappingURL=annotations.js.map
@@ -42,4 +42,3 @@
42
42
  * @internal
43
43
  */
44
44
  export declare const ClosuresMixin: any;
45
- //# sourceMappingURL=closures.d.ts.map
@@ -42,9 +42,9 @@
42
42
  * @internal
43
43
  */
44
44
  import { RillError, RuntimeError } from '../../../../types.js';
45
- import { isCallable, isScriptCallable, isApplicationCallable, isDict, validateCallableArgs, paramsToStructuralType, } from '../../callable.js';
46
- import { getVariable, pushCallFrame, popCallFrame, UNVALIDATED_METHOD_PARAMS, UNVALIDATED_METHOD_RECEIVERS, } from '../../context.js';
47
- import { inferType, isTypeValue, isTuple, isOrdered, createOrdered, inferStructuralType, structuralTypeMatches, formatStructuralType, anyTypeValue, } from '../../values.js';
45
+ import { isCallable, isScriptCallable, isApplicationCallable, isDict, marshalArgs, } from '../../callable.js';
46
+ import { getVariable, pushCallFrame, popCallFrame, UNVALIDATED_METHOD_PARAMS, } from '../../context.js';
47
+ import { inferType, isTypeValue, isTuple, isOrdered, paramToFieldDef, inferStructure, structureMatches, formatStructure, anyTypeValue, structureToTypeValue, } from '../../values.js';
48
48
  /**
49
49
  * ClosuresMixin implementation.
50
50
  *
@@ -153,14 +153,22 @@ function createClosuresMixin(Base) {
153
153
  async invokeFnCallable(callable, args, callLocation, functionName = 'callable') {
154
154
  // Apply boundDict BEFORE validation (property-style callables need dict as first arg)
155
155
  const effectiveArgs = callable.boundDict && args.length === 0 ? [callable.boundDict] : args;
156
- // Validate arguments for typed ApplicationCallable (task 1.5)
156
+ // Marshal arguments for typed ApplicationCallable (IC-1).
157
157
  // Skip when params is undefined (untyped callable() factory).
158
- // Explicitly registered zero-param callables have params: [] and still validate.
158
+ // Untyped callables still receive RillValue[] cast as Record to preserve
159
+ // existing runtime behavior without changing the fn contract.
160
+ let fnArgs;
159
161
  if (isApplicationCallable(callable) && callable.params !== undefined) {
160
- validateCallableArgs(effectiveArgs, callable.params, functionName, callLocation);
162
+ fnArgs = marshalArgs(effectiveArgs, callable.params, {
163
+ functionName,
164
+ location: callLocation,
165
+ });
166
+ }
167
+ else {
168
+ fnArgs = effectiveArgs;
161
169
  }
162
170
  try {
163
- const result = callable.fn(effectiveArgs, this.ctx, callLocation);
171
+ const result = callable.fn(fnArgs, this.ctx, callLocation);
164
172
  return result instanceof Promise ? await result : result;
165
173
  }
166
174
  catch (error) {
@@ -207,8 +215,8 @@ function createClosuresMixin(Base) {
207
215
  validateParamType(param, value, callLocation) {
208
216
  if (param.type === undefined)
209
217
  return;
210
- if (!structuralTypeMatches(value, param.type)) {
211
- const expectedType = formatStructuralType(param.type);
218
+ if (!structureMatches(value, param.type)) {
219
+ const expectedType = formatStructure(param.type);
212
220
  const actualType = inferType(value);
213
221
  throw new RuntimeError('RILL-R001', `Parameter type mismatch: ${param.name} expects ${expectedType}, got ${actualType}`, callLocation, { paramName: param.name, expectedType, actualType });
214
222
  }
@@ -219,28 +227,20 @@ function createClosuresMixin(Base) {
219
227
  */
220
228
  async invokeScriptCallable(callable, args, callLocation) {
221
229
  const callableCtx = this.createCallableContext(callable);
222
- // Validate excess arguments (EC-8)
223
- if (args.length > callable.params.length) {
224
- throw new RuntimeError('RILL-R001', `Function expects ${callable.params.length} arguments, got ${args.length}`, callLocation);
230
+ // Marshal positional args to named record (IC-1).
231
+ // Script callables always have params defined.
232
+ const record = marshalArgs(args, callable.params, {
233
+ functionName: '<anonymous>',
234
+ location: callLocation,
235
+ });
236
+ // Bind each named value into the callable context.
237
+ for (const [name, value] of Object.entries(record)) {
238
+ callableCtx.variables.set(name, value);
225
239
  }
226
- for (let i = 0; i < callable.params.length; i++) {
227
- const param = callable.params[i];
228
- let value;
229
- if (i < args.length) {
230
- value = args[i];
231
- }
232
- else if (param.defaultValue !== undefined) {
233
- value = param.defaultValue;
234
- }
235
- else {
236
- throw new RuntimeError('RILL-R001', `Missing argument for parameter '${param.name}' at position ${i}`, callLocation, { paramName: param.name, position: i });
237
- }
238
- this.validateParamType(param, value, callLocation);
239
- callableCtx.variables.set(param.name, value);
240
- // Block-closures have param named '$': sync with pipeValue for bare $ references
241
- if (param.name === '$') {
242
- callableCtx.pipeValue = value;
243
- }
240
+ // IR-4: Block closure pipe sync first param named '$' means block closure.
241
+ // Sync pipeValue so bare '$' references resolve correctly inside the body.
242
+ if (callable.params[0]?.name === '$') {
243
+ callableCtx.pipeValue = record['$'];
244
244
  }
245
245
  // EC-1: Reject empty block bodies before execution (AC-17)
246
246
  if (callable.body.type === 'Block' &&
@@ -541,13 +541,13 @@ function createClosuresMixin(Base) {
541
541
  throw new RuntimeError('RILL-R003', `Method .${node.name} not available on callable (invoke with -> $() first)`, this.getNodeLocation(node), { methodName: node.name, receiverType: 'callable' });
542
542
  }
543
543
  // IR-3: .name on type values returns the typeName string (method path)
544
- // IR-4: .signature on type values returns formatStructuralType(structure)
544
+ // IR-4: .signature on type values returns formatStructure(structure)
545
545
  if (isTypeValue(receiver)) {
546
546
  if (node.name === 'name') {
547
547
  return receiver.typeName;
548
548
  }
549
549
  if (node.name === 'signature') {
550
- return formatStructuralType(receiver.structure);
550
+ return formatStructure(receiver.structure);
551
551
  }
552
552
  }
553
553
  const args = await this.evaluateArgs(node.args);
@@ -557,23 +557,39 @@ function createClosuresMixin(Base) {
557
557
  const typeDict = this.ctx.typeMethodDicts.get(typeName);
558
558
  const typeMethod = typeDict?.[node.name];
559
559
  if (typeMethod !== undefined && isApplicationCallable(typeMethod)) {
560
- // AC-24 (EC-7): validate method args via typeMethod.params when set.
561
- // Methods in UNVALIDATED_METHOD_PARAMS handle their own arg validation
562
- // with specific error messages; skip generic validation for them.
563
- if (!UNVALIDATED_METHOD_PARAMS.has(node.name) &&
564
- typeMethod.params !== undefined &&
565
- typeMethod.params.length > 0) {
566
- validateCallableArgs(args, typeMethod.params, node.name, this.getNodeLocation(node));
567
- }
568
- // buildMethodEntry wraps fn(args) where args[0] = receiver and args[1..] = method args
569
- // Invoke fn directly to preserve the receiver-as-first-arg contract without
570
- // triggering invokeCallable's arity validation (params counts method args only)
560
+ // IC-1: marshalArgs handles type method dispatch.
561
+ // effectiveArgs prepends receiver as first element; after task 2.3 typeMethod.params
562
+ // will include the receiver param so the counts align.
563
+ // UNVALIDATED_METHOD_PARAMS methods handle their own validation internally;
564
+ // skip marshalArgs for them and pass the positional array via cast.
565
+ const callLocation = this.getNodeLocation(node);
566
+ const effectiveArgs = [receiver, ...args];
567
+ let methodArgs;
568
+ if (typeMethod.params === undefined) {
569
+ // Untyped method: pass positional array via cast.
570
+ methodArgs = effectiveArgs;
571
+ }
572
+ else if (UNVALIDATED_METHOD_PARAMS.has(node.name)) {
573
+ // UNVALIDATED_METHOD_PARAMS: method handles its own arity and type
574
+ // validation with custom error messages. Pass the actual user args
575
+ // via __positionalArgs so buildMethodEntry reconstructs positionalArgs
576
+ // with the correct length, letting method body arity checks fire.
577
+ methodArgs = {
578
+ receiver,
579
+ __positionalArgs: args,
580
+ };
581
+ }
582
+ else {
583
+ methodArgs = marshalArgs(effectiveArgs, typeMethod.params, {
584
+ functionName: node.name,
585
+ location: callLocation,
586
+ });
587
+ }
571
588
  try {
572
- const result = typeMethod.fn([receiver, ...args], this.ctx, this.getNodeLocation(node));
589
+ const result = typeMethod.fn(methodArgs, this.ctx, callLocation);
573
590
  return result instanceof Promise ? await result : result;
574
591
  }
575
592
  catch (error) {
576
- const callLocation = this.getNodeLocation(node);
577
593
  if (error instanceof RuntimeError &&
578
594
  !error.location &&
579
595
  callLocation) {
@@ -601,10 +617,10 @@ function createClosuresMixin(Base) {
601
617
  throw new RuntimeError('RILL-R009', `Property '${node.name}' not found on type value (available: name, signature)`, this.getNodeLocation(node), { property: node.name, type: 'type value' });
602
618
  }
603
619
  // RILL-R003: method exists on other types but not this receiver's type.
604
- // Methods in UNVALIDATED_METHOD_RECEIVERS handle their own receiver validation
620
+ // Methods in unvalidatedMethodReceivers handle their own receiver validation
605
621
  // with specific error messages; skip generic RILL-R003 for them and let the
606
622
  // method body run its own check (they exist in at least one type dict).
607
- if (!UNVALIDATED_METHOD_RECEIVERS.has(node.name)) {
623
+ if (!this.ctx.unvalidatedMethodReceivers.has(node.name)) {
608
624
  const supportedTypes = [];
609
625
  for (const [dictType, dict] of this.ctx.typeMethodDicts) {
610
626
  if (dict[node.name] !== undefined) {
@@ -616,14 +632,25 @@ function createClosuresMixin(Base) {
616
632
  }
617
633
  }
618
634
  else {
619
- // UNVALIDATED_METHOD_RECEIVERS: dispatch to the method in ANY type dict so the
635
+ // unvalidatedMethodReceivers: dispatch to the method in ANY type dict so the
620
636
  // method body can run its own custom receiver validation and error message.
621
637
  for (const [, dict] of this.ctx.typeMethodDicts) {
622
638
  const fallbackMethod = dict[node.name];
623
639
  if (fallbackMethod !== undefined &&
624
640
  isApplicationCallable(fallbackMethod)) {
625
641
  try {
626
- const result = fallbackMethod.fn([receiver, ...args], this.ctx, this.getNodeLocation(node));
642
+ // Unvalidated methods handle their own receiver validation.
643
+ // Build named record with receiver so buildMethodEntry extracts it correctly;
644
+ // the method body performs its own receiver type check with a custom error.
645
+ const fbMethodArgs = { receiver };
646
+ if (fallbackMethod.params) {
647
+ for (let i = 1; i < fallbackMethod.params.length; i++) {
648
+ const p = fallbackMethod.params[i];
649
+ if (p)
650
+ fbMethodArgs[p.name] = args[i - 1] ?? null;
651
+ }
652
+ }
653
+ const result = fallbackMethod.fn(fbMethodArgs, this.ctx, this.getNodeLocation(node));
627
654
  return result instanceof Promise ? await result : result;
628
655
  }
629
656
  catch (error) {
@@ -679,7 +706,7 @@ function createClosuresMixin(Base) {
679
706
  const typeValue = Object.freeze({
680
707
  __rill_type: true,
681
708
  typeName: inferType(value),
682
- structure: inferStructuralType(value),
709
+ structure: inferStructure(value),
683
710
  });
684
711
  return typeValue;
685
712
  }
@@ -695,16 +722,16 @@ function createClosuresMixin(Base) {
695
722
  if (key === 'description') {
696
723
  return value.annotations['description'] ?? {};
697
724
  }
698
- // IR-3: ^input computes from callable.params via paramsToStructuralType() for all kinds
699
- // Params are converted from internal tuples to RillOrdered so the
700
- // value survives rill's homogeneous-list constraint.
725
+ // IR-3: ^input computes from callable.params for all kinds.
726
+ // Each param's RillType is converted to a RillTypeValue so it is recognized
727
+ // as a type token (not a plain dict) in rill's type system.
701
728
  if (key === 'input') {
702
729
  // Untyped host callables have params set to undefined at runtime (see callable() factory)
703
730
  if (value.params === undefined) {
704
- return createOrdered([]);
731
+ return structureToTypeValue({ kind: 'ordered', fields: [] });
705
732
  }
706
- const shape = paramsToStructuralType(value.params);
707
- return createOrdered(shape.params);
733
+ const fields = value.params.map((param) => paramToFieldDef(param.name, param.type ?? { kind: 'any' }, param.defaultValue));
734
+ return structureToTypeValue({ kind: 'ordered', fields });
708
735
  }
709
736
  // IR-3: ^output reads callable.returnType directly for all kinds
710
737
  if (key === 'output') {
@@ -723,7 +750,14 @@ function createClosuresMixin(Base) {
723
750
  *
724
751
  * Evaluates positional args LTR, evaluates the spread expression, dispatches
725
752
  * by value type (Tuple, Ordered, or Dict), validates bindings, and returns
726
- * a Map of param name → value.
753
+ * a BoundArgs map of param name → value.
754
+ *
755
+ * Output is compatible with marshalArgs stages 2-3 (IR-1):
756
+ * - All params present in returned map (defaults applied, missing required throws)
757
+ * - Stage 1 (excess args) is NOT checked here; bindArgsToParams validates arity
758
+ * differently per spread source type (tuple length, dict key match, etc.)
759
+ * - Phase 2 callers convert BoundArgs.params to positional RillValue[] then
760
+ * feed into marshalArgs stages 2-3 for type-checking
727
761
  *
728
762
  * EC-3: bare ... with null pipe value → RuntimeError
729
763
  * EC-4: spread value is not tuple/dict/ordered → RuntimeError
@@ -835,17 +869,6 @@ function createClosuresMixin(Base) {
835
869
  finally {
836
870
  this.ctx.pipeValue = savedPipeValue;
837
871
  }
838
- // EC-8: check for missing required parameters
839
- for (const param of params) {
840
- if (!bound.has(param.name)) {
841
- if (param.defaultValue !== null && param.defaultValue !== undefined) {
842
- bound.set(param.name, param.defaultValue);
843
- }
844
- else {
845
- throw new RuntimeError('RILL-R001', `Missing required parameter '${param.name}'`, callLocation);
846
- }
847
- }
848
- }
849
872
  return { params: bound };
850
873
  }
851
874
  /**
@@ -871,7 +894,7 @@ function createClosuresMixin(Base) {
871
894
  const paramEntry = {};
872
895
  // Add type field if param has type annotation
873
896
  if (param.type !== undefined) {
874
- paramEntry['type'] = formatStructuralType(param.type);
897
+ paramEntry['type'] = formatStructure(param.type);
875
898
  }
876
899
  // Add __annotations field if param has parameter-level annotations
877
900
  if (Object.keys(param.annotations).length > 0) {
@@ -887,4 +910,3 @@ function createClosuresMixin(Base) {
887
910
  // TypeScript can't generate declarations for functions returning classes with protected members
888
911
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
889
912
  export const ClosuresMixin = createClosuresMixin;
890
- //# sourceMappingURL=closures.js.map
@@ -21,4 +21,3 @@
21
21
  * @internal
22
22
  */
23
23
  export declare const CollectionsMixin: any;
24
- //# sourceMappingURL=collections.d.ts.map