semantifold 0.3.0 → 0.5.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 (303) hide show
  1. package/README.md +61 -15
  2. package/build/index.d.ts +52 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +60 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/android.d.ts +49 -0
  11. package/build/src/backends/android.d.ts.map +1 -0
  12. package/build/src/backends/android.js +1274 -0
  13. package/build/src/backends/c-validation.d.ts.map +1 -1
  14. package/build/src/backends/c-validation.js +7 -3
  15. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  16. package/build/src/backends/cpp-validation.js +7 -3
  17. package/build/src/backends/csharp.js +7 -1
  18. package/build/src/backends/dart-runtime.d.ts +2 -0
  19. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  20. package/build/src/backends/dart-runtime.js +41 -0
  21. package/build/src/backends/dart.d.ts +20 -0
  22. package/build/src/backends/dart.d.ts.map +1 -0
  23. package/build/src/backends/dart.js +321 -0
  24. package/build/src/backends/effects.d.ts +60 -0
  25. package/build/src/backends/effects.d.ts.map +1 -0
  26. package/build/src/backends/effects.js +746 -0
  27. package/build/src/backends/go.js +18 -4
  28. package/build/src/backends/identifiers.d.ts +36 -4
  29. package/build/src/backends/identifiers.d.ts.map +1 -1
  30. package/build/src/backends/identifiers.js +160 -10
  31. package/build/src/backends/index.d.ts.map +1 -1
  32. package/build/src/backends/index.js +27 -4
  33. package/build/src/backends/ios.d.ts +68 -0
  34. package/build/src/backends/ios.d.ts.map +1 -0
  35. package/build/src/backends/ios.js +1503 -0
  36. package/build/src/backends/java.d.ts.map +1 -1
  37. package/build/src/backends/java.js +429 -36
  38. package/build/src/backends/javascript.d.ts +6 -0
  39. package/build/src/backends/javascript.d.ts.map +1 -1
  40. package/build/src/backends/javascript.js +380 -24
  41. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  42. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  43. package/build/src/backends/kotlin-runtime.js +29 -0
  44. package/build/src/backends/kotlin.d.ts +33 -0
  45. package/build/src/backends/kotlin.d.ts.map +1 -0
  46. package/build/src/backends/kotlin.js +138 -0
  47. package/build/src/backends/native-validation.d.ts +2 -2
  48. package/build/src/backends/native-validation.d.ts.map +1 -1
  49. package/build/src/backends/native-validation.js +2 -2
  50. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  51. package/build/src/backends/ordered-expressions.js +39 -7
  52. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  53. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  54. package/build/src/backends/php-stdlib-support.js +227 -0
  55. package/build/src/backends/php.d.ts.map +1 -1
  56. package/build/src/backends/php.js +448 -33
  57. package/build/src/backends/program.d.ts +83 -0
  58. package/build/src/backends/program.d.ts.map +1 -0
  59. package/build/src/backends/program.js +1309 -0
  60. package/build/src/backends/python.js +7 -1
  61. package/build/src/backends/ruby.d.ts.map +1 -1
  62. package/build/src/backends/ruby.js +310 -24
  63. package/build/src/backends/rust-runtime.d.ts +7 -0
  64. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  65. package/build/src/backends/rust-runtime.js +32 -0
  66. package/build/src/backends/rust-validation.d.ts +9 -0
  67. package/build/src/backends/rust-validation.d.ts.map +1 -0
  68. package/build/src/backends/rust-validation.js +78 -0
  69. package/build/src/backends/rust.d.ts +24 -0
  70. package/build/src/backends/rust.d.ts.map +1 -0
  71. package/build/src/backends/rust.js +344 -0
  72. package/build/src/backends/scalars.d.ts +14 -6
  73. package/build/src/backends/scalars.d.ts.map +1 -1
  74. package/build/src/backends/scalars.js +167 -17
  75. package/build/src/backends/shared.d.ts +23 -4
  76. package/build/src/backends/shared.d.ts.map +1 -1
  77. package/build/src/backends/shared.js +2174 -62
  78. package/build/src/backends/stdlib-support.d.ts +14 -0
  79. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  80. package/build/src/backends/stdlib-support.js +237 -0
  81. package/build/src/backends/swift-runtime.d.ts +3 -0
  82. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  83. package/build/src/backends/swift-runtime.js +14 -0
  84. package/build/src/backends/swift.d.ts +8 -0
  85. package/build/src/backends/swift.d.ts.map +1 -0
  86. package/build/src/backends/swift.js +127 -0
  87. package/build/src/backends/typescript.d.ts.map +1 -1
  88. package/build/src/backends/typescript.js +344 -24
  89. package/build/src/backends/wasm.d.ts +43 -0
  90. package/build/src/backends/wasm.d.ts.map +1 -0
  91. package/build/src/backends/wasm.js +2164 -0
  92. package/build/src/backends/writer.d.ts +255 -4
  93. package/build/src/backends/writer.d.ts.map +1 -1
  94. package/build/src/backends/writer.js +491 -3
  95. package/build/src/diagnostic.d.ts +4 -3
  96. package/build/src/diagnostic.d.ts.map +1 -1
  97. package/build/src/diagnostic.js +5 -3
  98. package/build/src/frontends/c.d.ts.map +1 -1
  99. package/build/src/frontends/c.js +5 -3
  100. package/build/src/frontends/cpp.d.ts.map +1 -1
  101. package/build/src/frontends/cpp.js +5 -3
  102. package/build/src/frontends/csharp.d.ts.map +1 -1
  103. package/build/src/frontends/csharp.js +7 -3
  104. package/build/src/frontends/dart.d.ts +10 -0
  105. package/build/src/frontends/dart.d.ts.map +1 -0
  106. package/build/src/frontends/dart.js +913 -0
  107. package/build/src/frontends/index.d.ts +3 -1
  108. package/build/src/frontends/index.d.ts.map +1 -1
  109. package/build/src/frontends/index.js +15 -5
  110. package/build/src/frontends/java.d.ts +110 -1
  111. package/build/src/frontends/java.d.ts.map +1 -1
  112. package/build/src/frontends/java.js +1725 -70
  113. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  114. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  115. package/build/src/frontends/javascript-typescript.js +1825 -93
  116. package/build/src/frontends/kotlin.d.ts +10 -0
  117. package/build/src/frontends/kotlin.d.ts.map +1 -0
  118. package/build/src/frontends/kotlin.js +685 -0
  119. package/build/src/frontends/php.d.ts +118 -1
  120. package/build/src/frontends/php.d.ts.map +1 -1
  121. package/build/src/frontends/php.js +1583 -76
  122. package/build/src/frontends/program.d.ts +74 -0
  123. package/build/src/frontends/program.d.ts.map +1 -0
  124. package/build/src/frontends/program.js +989 -0
  125. package/build/src/frontends/ruby.d.ts +68 -1
  126. package/build/src/frontends/ruby.d.ts.map +1 -1
  127. package/build/src/frontends/ruby.js +1446 -101
  128. package/build/src/frontends/rust-parser.d.ts +11 -0
  129. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  130. package/build/src/frontends/rust-parser.js +15 -0
  131. package/build/src/frontends/rust.d.ts +14 -0
  132. package/build/src/frontends/rust.d.ts.map +1 -0
  133. package/build/src/frontends/rust.js +715 -0
  134. package/build/src/frontends/scalars.d.ts +10 -0
  135. package/build/src/frontends/scalars.d.ts.map +1 -1
  136. package/build/src/frontends/scalars.js +28 -2
  137. package/build/src/frontends/swift.d.ts +10 -0
  138. package/build/src/frontends/swift.d.ts.map +1 -0
  139. package/build/src/frontends/swift.js +860 -0
  140. package/build/src/frontends/types.d.ts +186 -0
  141. package/build/src/frontends/types.d.ts.map +1 -0
  142. package/build/src/frontends/types.js +634 -0
  143. package/build/src/language-registry.d.ts +46 -4
  144. package/build/src/language-registry.d.ts.map +1 -1
  145. package/build/src/language-registry.js +177 -13
  146. package/build/src/mapping.d.ts +2 -2
  147. package/build/src/mapping.d.ts.map +1 -1
  148. package/build/src/mapping.js +31 -10
  149. package/build/src/semantic/capabilities.d.ts +66 -0
  150. package/build/src/semantic/capabilities.d.ts.map +1 -0
  151. package/build/src/semantic/capabilities.js +649 -0
  152. package/build/src/semantic/effects.d.ts +26 -0
  153. package/build/src/semantic/effects.d.ts.map +1 -0
  154. package/build/src/semantic/effects.js +764 -0
  155. package/build/src/semantic/generics.d.ts +23 -0
  156. package/build/src/semantic/generics.d.ts.map +1 -0
  157. package/build/src/semantic/generics.js +61 -0
  158. package/build/src/semantic/lifetime.d.ts +37 -0
  159. package/build/src/semantic/lifetime.d.ts.map +1 -0
  160. package/build/src/semantic/lifetime.js +527 -0
  161. package/build/src/semantic/provenance.d.ts +9 -2
  162. package/build/src/semantic/provenance.d.ts.map +1 -1
  163. package/build/src/semantic/provenance.js +462 -20
  164. package/build/src/semantic/scalars.d.ts +11 -0
  165. package/build/src/semantic/scalars.d.ts.map +1 -1
  166. package/build/src/semantic/scalars.js +16 -1
  167. package/build/src/semantic/stdlib.d.ts +254 -0
  168. package/build/src/semantic/stdlib.d.ts.map +1 -0
  169. package/build/src/semantic/stdlib.js +880 -0
  170. package/build/src/semantic/types.d.ts +3108 -178
  171. package/build/src/semantic/types.d.ts.map +1 -1
  172. package/build/src/semantic/types.js +730 -15
  173. package/build/src/semantic/validate.d.ts +85 -5
  174. package/build/src/semantic/validate.d.ts.map +1 -1
  175. package/build/src/semantic/validate.js +2576 -98
  176. package/build/src/stdlib-facades.d.ts +304 -0
  177. package/build/src/stdlib-facades.d.ts.map +1 -0
  178. package/build/src/stdlib-facades.js +1167 -0
  179. package/build/src/stdlib-negotiation.d.ts +69 -0
  180. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  181. package/build/src/stdlib-negotiation.js +403 -0
  182. package/build/src/stdlib-providers.d.ts +72 -0
  183. package/build/src/stdlib-providers.d.ts.map +1 -0
  184. package/build/src/stdlib-providers.js +339 -0
  185. package/build/src/toolchains.d.ts +55 -1
  186. package/build/src/toolchains.d.ts.map +1 -1
  187. package/build/src/toolchains.js +15 -4
  188. package/docs/android.md +79 -0
  189. package/docs/architecture.md +47 -13
  190. package/docs/dart.md +60 -0
  191. package/docs/goals.md +3 -3
  192. package/docs/ios.md +121 -0
  193. package/docs/kotlin.md +42 -0
  194. package/docs/language-support.md +238 -26
  195. package/docs/multi-file-modules.md +52 -0
  196. package/docs/parser-qualification.md +121 -8
  197. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  198. package/docs/rust.md +88 -0
  199. package/docs/source-maps.md +17 -7
  200. package/docs/specification.md +5 -0
  201. package/docs/standard-library-portability.md +39 -8
  202. package/docs/swift.md +44 -0
  203. package/docs/testing.md +381 -4
  204. package/docs/webassembly.md +52 -0
  205. package/index.js +66 -8
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  231. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  232. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  233. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  234. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  235. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  236. package/package.json +5 -2
  237. package/src/artifact-path.js +47 -2
  238. package/src/artifacts.js +67 -0
  239. package/src/backends/android.js +1370 -0
  240. package/src/backends/c-validation.js +6 -1
  241. package/src/backends/cpp-validation.js +6 -1
  242. package/src/backends/csharp.js +3 -0
  243. package/src/backends/dart-runtime.js +41 -0
  244. package/src/backends/dart.js +326 -0
  245. package/src/backends/effects.js +705 -0
  246. package/src/backends/go.js +14 -2
  247. package/src/backends/identifiers.js +166 -9
  248. package/src/backends/index.js +27 -2
  249. package/src/backends/ios.js +1612 -0
  250. package/src/backends/java.js +454 -36
  251. package/src/backends/javascript.js +389 -23
  252. package/src/backends/kotlin-runtime.js +29 -0
  253. package/src/backends/kotlin.js +144 -0
  254. package/src/backends/native-validation.js +1 -1
  255. package/src/backends/ordered-expressions.js +40 -6
  256. package/src/backends/php-stdlib-support.js +239 -0
  257. package/src/backends/php.js +469 -32
  258. package/src/backends/program.js +1408 -0
  259. package/src/backends/python.js +3 -0
  260. package/src/backends/ruby.js +326 -23
  261. package/src/backends/rust-runtime.js +34 -0
  262. package/src/backends/rust-validation.js +75 -0
  263. package/src/backends/rust.js +335 -0
  264. package/src/backends/scalars.js +141 -16
  265. package/src/backends/shared.js +2314 -115
  266. package/src/backends/stdlib-support.js +234 -0
  267. package/src/backends/swift-runtime.js +14 -0
  268. package/src/backends/swift.js +132 -0
  269. package/src/backends/typescript.js +349 -23
  270. package/src/backends/wasm.js +2208 -0
  271. package/src/backends/writer.js +545 -2
  272. package/src/diagnostic.js +4 -2
  273. package/src/frontends/c.js +4 -2
  274. package/src/frontends/cpp.js +4 -2
  275. package/src/frontends/csharp.js +4 -2
  276. package/src/frontends/dart.js +963 -0
  277. package/src/frontends/index.js +14 -4
  278. package/src/frontends/java.js +1977 -69
  279. package/src/frontends/javascript-typescript.js +2046 -102
  280. package/src/frontends/kotlin.js +713 -0
  281. package/src/frontends/php.js +1725 -79
  282. package/src/frontends/program.js +1062 -0
  283. package/src/frontends/ruby.js +1624 -98
  284. package/src/frontends/rust-parser.js +18 -0
  285. package/src/frontends/rust.js +714 -0
  286. package/src/frontends/scalars.js +31 -1
  287. package/src/frontends/swift.js +893 -0
  288. package/src/frontends/types.js +750 -0
  289. package/src/language-registry.js +182 -12
  290. package/src/mapping.js +33 -9
  291. package/src/semantic/capabilities.js +671 -0
  292. package/src/semantic/effects.js +737 -0
  293. package/src/semantic/generics.js +58 -0
  294. package/src/semantic/lifetime.js +517 -0
  295. package/src/semantic/provenance.js +412 -19
  296. package/src/semantic/scalars.js +17 -0
  297. package/src/semantic/stdlib.js +921 -0
  298. package/src/semantic/types.js +810 -14
  299. package/src/semantic/validate.js +2934 -209
  300. package/src/stdlib-facades.js +1211 -0
  301. package/src/stdlib-negotiation.js +446 -0
  302. package/src/stdlib-providers.js +377 -0
  303. package/src/toolchains.js +16 -3
@@ -0,0 +1,1211 @@
1
+ // @ts-check
2
+
3
+ import {isDenseArray} from "./array.js"
4
+ import {isSafeArtifactPath} from "./artifact-path.js"
5
+ import {SemantifoldDiagnostic} from "./diagnostic.js"
6
+ import {
7
+ compareStdlibVersions, parseStdlibVersion, parseStdlibVersionRange, resolveStdlibModule, stdlibVersionSatisfies
8
+ } from "./semantic/stdlib.js"
9
+
10
+ const facadeIdentityPattern = /^[a-z][a-z0-9.-]*$/u
11
+ const moduleIdPattern = /^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u
12
+ const declarationNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/u
13
+ const supportedLanguages = new Set(["php", "ruby", "javascript", "typescript", "java"])
14
+ const canonicalTypes = new Set(["boolean", "integer", "string", "void"])
15
+
16
+ /**
17
+ * @typedef StdlibFacadeFunctionDeclaration
18
+ * @property {"function"} kind - Closed public declaration kind.
19
+ * @property {string} name - Exact source-visible symbol.
20
+ * @property {{name: string, type: string}[]} parameters - Ordered source signature.
21
+ * @property {string} returnType - Canonical result type.
22
+ * @property {string[]} effects - Closed public effects.
23
+ * @property {string[]} failures - Escaping canonical failure names.
24
+ * @property {("direct-call" | "unqualified-call" | "receiver-call")[]} forms - Accepted source call forms.
25
+ * @property {"not-applicable"} ownership - Initial scalar qualification ownership.
26
+ */
27
+ /**
28
+ * @typedef StdlibFacadeClassDeclaration
29
+ * @property {"class"} kind - Closed public declaration kind.
30
+ * @property {string} name - Exact source-visible class symbol.
31
+ * @property {["constructor-call"]} forms - Accepted construction form.
32
+ * @property {"owned-reference"} ownership - Class instance ownership.
33
+ * @property {{effects: string[], failures: string[], ownership: "acquired", parameters: {name: string, type: string}[]}} constructor - Constructor contract.
34
+ * @property {{effects: string[], failures: string[], forms: ["receiver-call"], name: string, ownership: "borrowed" | "consumed", parameters: {name: string, type: string}[], returnType: string}[]} methods - Public instance methods.
35
+ */
36
+ /** @typedef {StdlibFacadeFunctionDeclaration | StdlibFacadeClassDeclaration} StdlibFacadePublicDeclaration */
37
+ /**
38
+ * @typedef StdlibFacadeRecord
39
+ * @property {{identity: string, range: string}[]} dependencies - Facade-module dependencies.
40
+ * @property {string} identity - Versioned facade identity.
41
+ * @property {import("./semantic/types.js").SemanticLanguage} language - Source language.
42
+ * @property {({identity: string, kind: "module", symbols: string[]} | {forms: ("unqualified-call" | "receiver-call")[], identity: string, kind: "builtin", symbols: string[]})[]} nativeModules - Exact source native identities.
43
+ * @property {StdlibFacadePublicDeclaration[]} publicDeclarations - Public source surface.
44
+ * @property {{module: string, operations: string[], range: string}[]} requirements - Canonical-only requirements.
45
+ * @property {string} runtimeProfile - Exact compatible source/runtime profile.
46
+ * @property {{content: string, filename: string, id: string}} source - Executable compiler-owned source module.
47
+ * @property {string} version - Exact facade version.
48
+ * @property {"internal" | "public"} visibility - Native-selectable visibility.
49
+ */
50
+ /**
51
+ * @typedef FacadeSourceNames
52
+ * @property {string} extension - Source filename extension.
53
+ * @property {string} nativeModule - Public native stdlib module identity.
54
+ * @property {string} publicName - Public native symbol.
55
+ * @property {string} unusedName - Unused-elimination fixture symbol.
56
+ * @property {string} unusedNativeModule - Unused-elimination fixture module.
57
+ * @property {string} probeSource - Public executable facade source.
58
+ * @property {string} runnerSource - Internal canonical runner source.
59
+ * @property {string} unusedSource - Unused executable facade source.
60
+ */
61
+ /**
62
+ * @typedef StdlibFacadeRegistry
63
+ * @property {readonly StdlibFacadeRecord[]} facades - Stable immutable facade records.
64
+ * @property {(language: string, nativeModule: string, symbol: string, range?: string) => StdlibFacadeRecord} resolveFacade - Exact native identity resolver.
65
+ * @property {(identity: string, language: string, range?: string) => StdlibFacadeRecord} resolveIdentity - Facade dependency resolver.
66
+ * @property {(language: string, nativeModule: string, range?: string) => StdlibFacadeRecord} resolveModule - Exact native module resolver.
67
+ */
68
+
69
+ /**
70
+ * Creates a detached immutable source-language facade registry.
71
+ * @param {unknown} records - Optional facade definitions; built-in qualification definitions by default.
72
+ * @returns {Readonly<StdlibFacadeRegistry>} Validated facade registry.
73
+ */
74
+ export function createStdlibFacadeRegistry(records = builtinFacadeRecords()) {
75
+ if (!isDenseArray(records)) invalidFacade("Facade records must be an ordered dense array.")
76
+ /** @type {StdlibFacadeRecord[]} */
77
+ const facades = []
78
+ /** @type {Map<string, Map<string, StdlibFacadeRecord>>} */
79
+ const byIdentity = new Map()
80
+ /** @type {Map<string, StdlibFacadeRecord[]>} */
81
+ const byNativeModule = new Map()
82
+ const sourceIds = new Map()
83
+ const sourceFilenames = new Map()
84
+
85
+ for (let index = 0; index < records.length; index += 1) {
86
+ const record = validateFacadeRecord(records[index])
87
+ const identityKey = `${record.language}\0${record.identity}`
88
+ const versions = byIdentity.get(identityKey) ?? new Map()
89
+
90
+ if (versions.has(record.version)) invalidFacade(`Duplicate facade '${record.identity}' version '${record.version}' for '${record.language}'.`)
91
+ if (sourceIds.has(record.source.id) && sourceIds.get(record.source.id) != identityKey) {
92
+ invalidFacade(`Duplicate facade source module identity '${record.source.id}'.`)
93
+ }
94
+ if (sourceFilenames.has(record.source.filename) && sourceFilenames.get(record.source.filename) != identityKey) {
95
+ invalidFacade(`Duplicate facade source filename '${record.source.filename}'.`)
96
+ }
97
+ versions.set(record.version, record)
98
+ byIdentity.set(identityKey, versions)
99
+ sourceIds.set(record.source.id, identityKey)
100
+ sourceFilenames.set(record.source.filename, identityKey)
101
+ facades.push(record)
102
+
103
+ for (const nativeModule of record.nativeModules) {
104
+ const nativeKey = `${record.language}\0${nativeModule.identity}`
105
+ const nativeRecords = byNativeModule.get(nativeKey) ?? []
106
+
107
+ nativeRecords.push(record)
108
+ byNativeModule.set(nativeKey, nativeRecords)
109
+ }
110
+ }
111
+
112
+ for (const record of facades) {
113
+ for (const dependency of record.dependencies) {
114
+ resolveIdentityFromStore(byIdentity, dependency.identity, record.language, dependency.range, record.identity)
115
+ }
116
+ }
117
+ validateFacadeDependencyCycles(facades, byIdentity)
118
+
119
+ return Object.freeze(/** @type {StdlibFacadeRegistry} */ ({
120
+ facades: Object.freeze(facades),
121
+ resolveFacade(language, nativeModule, symbol, range) {
122
+ return resolveNativeFacadeFromStore(byNativeModule, language, nativeModule, symbol, range)
123
+ },
124
+ resolveIdentity(identity, language, range) {
125
+ return resolveIdentityFromStore(byIdentity, identity, language, range)
126
+ },
127
+ resolveModule(language, nativeModule, range) {
128
+ const records = byNativeModule.get(`${language}\0${nativeModule}`)
129
+
130
+ if (!records) unprovedIdentity(language, nativeModule)
131
+ const identities = new Set(/** @type {StdlibFacadeRecord[]} */ (records).map(({identity}) => identity))
132
+
133
+ if (identities.size != 1) invalidFacade(`Native facade module '${nativeModule}' is ambiguous for '${language}'.`)
134
+ return selectFacadeVersion(new Map(/** @type {StdlibFacadeRecord[]} */ (records).map((record) => [record.version, record])),
135
+ /** @type {StdlibFacadeRecord} */ (records[0]).identity, language, range)
136
+ }
137
+ }))
138
+ }
139
+
140
+ /**
141
+ * Rejects cycles after every versioned dependency has resolved successfully.
142
+ * @param {StdlibFacadeRecord[]} facades - Validated facade records.
143
+ * @param {Map<string, Map<string, StdlibFacadeRecord>>} store - Records by language and identity.
144
+ * @returns {void}
145
+ */
146
+ function validateFacadeDependencyCycles(facades, store) {
147
+ const active = new Set()
148
+ const complete = new Set()
149
+
150
+ /**
151
+ * Visits one exact selected facade version.
152
+ * @param {StdlibFacadeRecord} record - Facade record.
153
+ * @returns {void}
154
+ */
155
+ function visit(record) {
156
+ const key = `${record.language}\0${record.identity}\0${record.version}`
157
+
158
+ if (complete.has(key)) return
159
+ if (active.has(key)) invalidFacade(`Facade dependency cycle includes '${record.identity}'.`)
160
+ active.add(key)
161
+ for (const dependency of record.dependencies) {
162
+ visit(resolveIdentityFromStore(store, dependency.identity, record.language, dependency.range, record.identity))
163
+ }
164
+ active.delete(key)
165
+ complete.add(key)
166
+ }
167
+
168
+ for (const record of facades) visit(record)
169
+ }
170
+
171
+ /**
172
+ * Lists all built-in public and internal facade modules in stable order.
173
+ * @returns {readonly StdlibFacadeRecord[]} Immutable facade definitions.
174
+ */
175
+ export function listStdlibFacades() {
176
+ return stdlibFacadeRegistry.facades
177
+ }
178
+
179
+ /**
180
+ * Resolves one built-in facade from parser-proved native module and symbol identities.
181
+ * @param {string} language - Source language.
182
+ * @param {string} nativeModule - Exact native module identity.
183
+ * @param {string} symbol - Exact imported or qualified symbol.
184
+ * @param {string} [range] - Compatible facade version range.
185
+ * @returns {StdlibFacadeRecord} Immutable facade definition.
186
+ */
187
+ export function resolveStdlibFacade(language, nativeModule, symbol, range) {
188
+ return stdlibFacadeRegistry.resolveFacade(language, nativeModule, symbol, range)
189
+ }
190
+
191
+ /**
192
+ * Resolves a dependency-first, cycle-free facade module closure.
193
+ * @param {StdlibFacadeRecord[]} roots - Parser-selected facade roots.
194
+ * @param {Readonly<StdlibFacadeRegistry>} [registry] - Facade registry.
195
+ * @returns {StdlibFacadeRecord[]} Stable dependency-first closure.
196
+ */
197
+ export function resolveStdlibFacadeClosure(roots, registry = stdlibFacadeRegistry) {
198
+ const active = new Set()
199
+ const complete = new Set()
200
+ /** @type {StdlibFacadeRecord[]} */
201
+ const result = []
202
+
203
+ /**
204
+ * Visits one selected facade and its declared dependencies.
205
+ * @param {StdlibFacadeRecord} record - Facade to visit.
206
+ * @returns {void}
207
+ */
208
+ function visit(record) {
209
+ const key = `${record.language}\0${record.identity}\0${record.version}`
210
+
211
+ if (complete.has(key)) return
212
+ if (active.has(key)) invalidFacade(`Facade dependency cycle includes '${record.identity}'.`)
213
+ active.add(key)
214
+ for (const dependency of record.dependencies) {
215
+ visit(registry.resolveIdentity(dependency.identity, record.language, dependency.range))
216
+ }
217
+ active.delete(key)
218
+ complete.add(key)
219
+ result.push(record)
220
+ }
221
+
222
+ for (const root of roots) visit(root)
223
+ return result
224
+ }
225
+
226
+ /**
227
+ * Creates the detached, deterministic program descriptor for one selected facade closure.
228
+ * @param {import("./semantic/types.js").SemanticLanguage} language - Source language profile.
229
+ * @param {StdlibFacadeRecord[]} facades - Dependency-first selected facade records.
230
+ * @returns {import("./semantic/types.js").StdlibFacadeProgramDescriptor} Plain program descriptor.
231
+ */
232
+ export function stdlibFacadeProgramDescriptor(language, facades) {
233
+ return {
234
+ language,
235
+ modules: facades.map((facade) => ({
236
+ dependencies: facade.dependencies.map((dependency) => ({...dependency})),
237
+ identity: facade.identity,
238
+ nativeModules: facade.nativeModules.map((module) => ({...module,
239
+ ...(module.kind == "builtin" ? {forms: [...module.forms]} : {}), symbols: [...module.symbols]})),
240
+ publicDeclarations: facade.publicDeclarations.map(detachPublicDeclaration),
241
+ requirements: facade.requirements.map((requirement) => ({...requirement, operations: [...requirement.operations]})),
242
+ runtimeProfile: facade.runtimeProfile,
243
+ sourceModule: facade.source.id,
244
+ version: facade.version,
245
+ visibility: facade.visibility
246
+ })),
247
+ schema: "SemantifoldStdlibFacades",
248
+ version: 1
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Derives compiler-owned semantic capability authority from selected facade requirements.
254
+ * The initial executable qualification corpus intentionally targets one canonical module.
255
+ * @param {StdlibFacadeRecord[]} records - Selected facade closure.
256
+ * @returns {{contract: {contractVersion: string, identity: string}, input: import("./semantic/types.js").CapabilityAuthorityInput} | {contracts: {contractVersion: string, identity: string}[], input: import("./semantic/types.js").CapabilityAuthorityInput} | null} Authority input.
257
+ */
258
+ export function facadeCapabilityAuthority(records) {
259
+ const requirements = records.flatMap((record) => record.requirements)
260
+
261
+ if (requirements.length == 0) return null
262
+ const identities = new Set(requirements.map(({module}) => module))
263
+ const ranges = new Set(requirements.map(({range}) => range))
264
+
265
+ const task037 = records.some(({identity}) => identity.startsWith("semantifold.task037."))
266
+
267
+ if (task037) {
268
+ const requirementByModule = new Map()
269
+
270
+ for (const requirement of requirements) {
271
+ const current = requirementByModule.get(requirement.module)
272
+
273
+ if (current && current.range != requirement.range) invalidFacade("Task 037 facade requirements disagree on a canonical range.")
274
+ const operations = new Set(current?.operations ?? [])
275
+
276
+ for (const operation of requirement.operations) operations.add(operation)
277
+ requirementByModule.set(requirement.module, {operations, range: requirement.range})
278
+ }
279
+ const modules = [...requirementByModule.entries()].map(([identity, requirement]) => {
280
+ const contract = resolveStdlibModule(identity, requirement.range)
281
+
282
+ return {
283
+ capabilities: [{
284
+ failures: contract.failures.map(({name}) => ({name})),
285
+ name: canonicalCapabilityName(identity),
286
+ operations: contract.operations.filter(({name}) => requirement.operations.has(name)).map((operation) => ({
287
+ effects: /** @type {["host"]} */ ([...operation.effects]),
288
+ failures: operation.failures.map(detachCanonicalReference),
289
+ name: operation.name,
290
+ parameters: operation.parameters.map((parameter) => ({
291
+ name: parameter.name,
292
+ type: canonicalCapabilityParameterType(parameter.type)
293
+ })),
294
+ resourceFlow: detachResourceFlow(operation.resourceFlow),
295
+ returnType: canonicalCapabilityType(operation.returnType)
296
+ })),
297
+ resources: contract.resources.map(({name}) => ({name}))
298
+ }],
299
+ contractVersion: requirement.range,
300
+ identity
301
+ }
302
+ })
303
+
304
+ return {
305
+ contracts: modules.map(({contractVersion, identity}) => ({contractVersion, identity})),
306
+ input: {id: "semantifold.task037.blocking-tcp", modules, schema: "SemantifoldCapabilityAuthority", schemaVersion: 2}
307
+ }
308
+ }
309
+ if (identities.size != 1 || ranges.size != 1) {
310
+ invalidFacade("The Task 036 qualification facade closure must resolve one canonical module and version range.")
311
+ }
312
+ const identity = requirements[0].module
313
+ const contractVersion = requirements[0].range
314
+ const contract = resolveStdlibModule(identity, contractVersion)
315
+
316
+ return {
317
+ contract: {contractVersion, identity},
318
+ input: {
319
+ capabilities: [{
320
+ failures: contract.failures.map(({name}) => ({name})),
321
+ name: "ResourceProbe",
322
+ operations: contract.operations.map((operation) => ({
323
+ effects: [...operation.effects],
324
+ failures: [...operation.failures],
325
+ name: operation.name,
326
+ parameters: operation.parameters.map((parameter) => ({
327
+ name: parameter.name,
328
+ type: canonicalCapabilityParameterType(parameter.type)
329
+ })),
330
+ resourceFlow: /** @type {import("./semantic/types.js").CapabilityResourceFlowInput} */ ({...operation.resourceFlow}),
331
+ returnType: canonicalCapabilityType(operation.returnType)
332
+ })),
333
+ resources: contract.resources.map(({name}) => ({name}))
334
+ }],
335
+ contractVersion,
336
+ id: identity,
337
+ schema: "SemantifoldCapabilityAuthority",
338
+ schemaVersion: 1
339
+ }
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Converts one registry contract type to a capability-authority input type.
345
+ * @param {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} type - Canonical contract type.
346
+ * @returns {import("./semantic/types.js").FunctionReturnTypeName | {kind: "OwnedResourceType", resource: string | import("./semantic/types.js").CapabilityDeclarationReferenceInput} | {kind: "OptionalType", valueType: import("./semantic/types.js").SemanticTypeName}} Semantic authority type.
347
+ */
348
+ function canonicalCapabilityType(type) {
349
+ if (typeof type != "string") return {kind: "OwnedResourceType", resource: detachCanonicalReference(type)}
350
+ if (type == "void" || type == "boolean" || type == "integer" || type == "string") return type
351
+ if (type.startsWith("optional:")) return {kind: "OptionalType",
352
+ valueType: /** @type {import("./semantic/types.js").SemanticTypeName} */ (type.slice("optional:".length))}
353
+ return {kind: "OwnedResourceType", resource: type}
354
+ }
355
+
356
+ /**
357
+ * Converts a non-void registry parameter type to capability-authority input.
358
+ * @param {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} type - Canonical parameter type.
359
+ * @returns {import("./semantic/types.js").SemanticTypeName | {kind: "OwnedResourceType", resource: string} | {kind: "OptionalType", valueType: import("./semantic/types.js").SemanticTypeName}} Semantic parameter type.
360
+ */
361
+ function canonicalCapabilityParameterType(type) {
362
+ const converted = canonicalCapabilityType(type)
363
+
364
+ if (converted == "void") invalidFacade("Canonical facade requirement parameters cannot have void type.")
365
+ return /** @type {import("./semantic/types.js").SemanticTypeName | {kind: "OwnedResourceType", resource: string} | {kind: "OptionalType", valueType: import("./semantic/types.js").SemanticTypeName}} */ (converted)
366
+ }
367
+
368
+ /**
369
+ * Resolves one dependency identity from a validated registry store.
370
+ * @param {Map<string, Map<string, StdlibFacadeRecord>>} store - Records by language and identity.
371
+ * @param {string} identity - Facade identity.
372
+ * @param {string} language - Source language.
373
+ * @param {string | undefined} range - Compatible range.
374
+ * @param {string} [owner] - Depending facade for diagnostics.
375
+ * @returns {StdlibFacadeRecord} Highest compatible record.
376
+ */
377
+ function resolveIdentityFromStore(store, identity, language, range, owner) {
378
+ const versions = store.get(`${language}\0${identity}`)
379
+
380
+ if (!versions) {
381
+ invalidFacade(owner ? `Facade '${owner}' depends on unknown facade '${identity}' for '${language}'.` :
382
+ `Unknown facade identity '${identity}' for '${language}'.`)
383
+ }
384
+ return selectFacadeVersion(/** @type {Map<string, StdlibFacadeRecord>} */ (versions), identity, language, range)
385
+ }
386
+
387
+ /**
388
+ * Resolves one exact native identity from a validated registry store.
389
+ * @param {Map<string, StdlibFacadeRecord[]>} store - Records by language and native module.
390
+ * @param {string} language - Source language.
391
+ * @param {string} nativeModule - Exact parser-owned native module identity.
392
+ * @param {string} symbol - Exact source-visible symbol.
393
+ * @param {string | undefined} range - Compatible range.
394
+ * @returns {StdlibFacadeRecord} Highest compatible record.
395
+ */
396
+ function resolveNativeFacadeFromStore(store, language, nativeModule, symbol, range) {
397
+ if (!supportedLanguages.has(language) || typeof nativeModule != "string" || nativeModule.length == 0) {
398
+ unprovedIdentity(language, nativeModule)
399
+ }
400
+ const moduleRecords = store.get(`${language}\0${nativeModule}`)
401
+
402
+ if (!moduleRecords) unprovedIdentity(language, nativeModule)
403
+ const symbolRecords = /** @type {StdlibFacadeRecord[]} */ (moduleRecords).filter((record) => record.nativeModules.some((module) =>
404
+ module.identity == nativeModule && module.symbols.includes(symbol)))
405
+
406
+ if (symbolRecords.length == 0) unsupportedMember(language, nativeModule, symbol)
407
+ const identities = new Set(symbolRecords.map(({identity}) => identity))
408
+
409
+ if (identities.size != 1) invalidFacade(`Native facade identity '${nativeModule}#${symbol}' is ambiguous for '${language}'.`)
410
+ const versions = new Map(symbolRecords.map((record) => [record.version, record]))
411
+
412
+ return selectFacadeVersion(versions, symbolRecords[0].identity, language, range)
413
+ }
414
+
415
+ /**
416
+ * Selects the highest facade version satisfying a canonical range.
417
+ * @param {Map<string, StdlibFacadeRecord>} versions - Records by exact version.
418
+ * @param {string} identity - Facade identity.
419
+ * @param {string} language - Source language.
420
+ * @param {string | undefined} range - Compatible range.
421
+ * @returns {StdlibFacadeRecord} Selected record.
422
+ */
423
+ function selectFacadeVersion(versions, identity, language, range) {
424
+ const parsedRange = range === undefined ? {lower: /** @type {[number, number, number]} */ ([0, 0, 0]), upper: null} :
425
+ parseStdlibVersionRange(range)
426
+
427
+ if (!parsedRange) facadeVersionMalformed(language, String(range))
428
+ /** @type {[number, number, number] | undefined} */
429
+ let selected
430
+
431
+ for (const version of versions.keys()) {
432
+ const parsed = /** @type {[number, number, number]} */ (parseStdlibVersion(version))
433
+
434
+ if (stdlibVersionSatisfies(parsed, parsedRange) && (!selected || compareStdlibVersions(parsed, selected) > 0)) selected = parsed
435
+ }
436
+ if (!selected) facadeVersionIncompatible(language, identity)
437
+
438
+ return /** @type {StdlibFacadeRecord} */ (versions.get(selected.join(".")))
439
+ }
440
+
441
+ /**
442
+ * Validates and detaches one executable facade record.
443
+ * @param {unknown} candidate - Candidate record.
444
+ * @returns {StdlibFacadeRecord} Detached frozen record.
445
+ */
446
+ function validateFacadeRecord(candidate) {
447
+ if (!isPlainObject(candidate)) invalidFacade("Every facade record must be a plain object.")
448
+ requireKeys(candidate, ["dependencies", "identity", "language", "nativeModules", "publicDeclarations", "requirements",
449
+ "runtimeProfile", "source", "version", "visibility"], "facade record")
450
+ const identity = requireString(candidate.identity, "Facade identity")
451
+ const language = requireString(candidate.language, "Facade language")
452
+ const version = requireString(candidate.version, "Facade version")
453
+ const runtimeProfile = requireString(candidate.runtimeProfile, "Facade runtime profile")
454
+ const visibility = candidate.visibility
455
+
456
+ if (!facadeIdentityPattern.test(identity)) invalidFacade(`Facade identity '${identity}' is invalid.`)
457
+ if (!supportedLanguages.has(language)) invalidFacade(`Facade language '${language}' is outside the adopted cohort.`)
458
+ if (!parseStdlibVersion(version)) invalidFacade(`Facade version '${version}' is invalid.`)
459
+ if (!/^[a-z][a-z0-9.-]*$/u.test(runtimeProfile)) invalidFacade(`Facade runtime profile '${runtimeProfile}' is invalid.`)
460
+ if (visibility != "public" && visibility != "internal") invalidFacade(`Facade '${identity}' has invalid visibility.`)
461
+ const source = validateSource(candidate.source, identity, language)
462
+ const publicDeclarations = validatePublicDeclarations(candidate.publicDeclarations, identity)
463
+ const nativeModules = validateNativeModules(candidate.nativeModules, identity, publicDeclarations)
464
+ const requirements = validateRequirements(candidate.requirements, identity)
465
+ const dependencies = validateDependencies(candidate.dependencies, identity)
466
+
467
+ if (visibility == "public" && (publicDeclarations.length == 0 || nativeModules.length == 0)) {
468
+ invalidFacade(`Public facade '${identity}' requires declarations and native identities.`)
469
+ }
470
+ if (visibility == "internal" && nativeModules.length > 0) invalidFacade(`Internal facade '${identity}' cannot expose native identities.`)
471
+
472
+ return deepFreeze({
473
+ dependencies,
474
+ identity,
475
+ language: /** @type {import("./semantic/types.js").SemanticLanguage} */ (language),
476
+ nativeModules,
477
+ publicDeclarations,
478
+ requirements,
479
+ runtimeProfile,
480
+ source,
481
+ version,
482
+ visibility: /** @type {"internal" | "public"} */ (visibility)
483
+ })
484
+ }
485
+
486
+ /**
487
+ * Validates one compiler-owned executable facade source.
488
+ * @param {unknown} candidate - Candidate source descriptor.
489
+ * @param {string} identity - Owning facade identity.
490
+ * @param {string} language - Facade source language.
491
+ * @returns {{content: string, filename: string, id: string}} Validated source descriptor.
492
+ */
493
+ function validateSource(candidate, identity, language) {
494
+ if (!isPlainObject(candidate)) invalidFacade(`Facade '${identity}' requires an executable source descriptor.`)
495
+ requireKeys(candidate, ["content", "filename", "id"], `facade '${identity}' source`)
496
+ const content = requireString(candidate.content, `Facade '${identity}' source content`)
497
+ const filename = requireString(candidate.filename, `Facade '${identity}' source filename`)
498
+ const id = requireString(candidate.id, `Facade '${identity}' source module identity`)
499
+
500
+ if (content.length == 0 || !isSafeArtifactPath(filename) || !filename.startsWith(`__semantifold_facades__/${language}/`) ||
501
+ !moduleIdPattern.test(id) || !id.startsWith(`semantifold.facade.${language}.`)) {
502
+ invalidFacade(`Facade '${identity}' has an invalid compiler-owned source descriptor.`)
503
+ }
504
+ return {content, filename, id}
505
+ }
506
+
507
+ /**
508
+ * Validates one facade's closed public declaration surface.
509
+ * @param {unknown} candidate - Candidate declarations.
510
+ * @param {string} identity - Owning facade identity.
511
+ * @returns {StdlibFacadePublicDeclaration[]} Validated declarations.
512
+ */
513
+ function validatePublicDeclarations(candidate, identity) {
514
+ if (!isDenseArray(candidate)) invalidFacade(`Facade '${identity}' public declarations must be a dense array.`)
515
+ const names = new Set()
516
+ return candidate.map((value) => {
517
+ if (!isPlainObject(value)) invalidFacade(`Facade '${identity}' public declarations must be plain objects.`)
518
+ const name = requireString(value.name, `Facade '${identity}' declaration name`)
519
+
520
+ if (!declarationNamePattern.test(name) || names.has(name)) {
521
+ invalidFacade(`Facade '${identity}' has an invalid or duplicate public declaration.`)
522
+ }
523
+ names.add(name)
524
+ if (value.kind == "class") return validatePublicClass(value, identity, name)
525
+ requireKeys(value, ["effects", "failures", "forms", "kind", "name", "ownership", "parameters", "returnType"],
526
+ `facade '${identity}' public declaration`)
527
+ if (value.kind != "function") invalidFacade(`Facade '${identity}' has an invalid public declaration kind.`)
528
+ if (!isDenseArray(value.effects) || !value.effects.every((effect) => effect == "host") || new Set(value.effects).size != value.effects.length ||
529
+ !isDenseArray(value.failures) || !value.failures.every((failure) => typeof failure == "string" && declarationNamePattern.test(failure)) ||
530
+ !isDenseArray(value.forms) || value.forms.length == 0 || !value.forms.every((form) =>
531
+ typeof form == "string" && ["direct-call", "unqualified-call", "receiver-call"].includes(form)) ||
532
+ new Set(value.forms).size != value.forms.length ||
533
+ value.ownership != "not-applicable" ||
534
+ !isDenseArray(value.parameters)) invalidFacade(`Facade '${identity}' declaration '${name}' has an invalid public contract.`)
535
+ const parameters = validateFacadeParameters(value.parameters, identity, name)
536
+ const returnType = requireString(value.returnType, `Facade '${identity}' return type`)
537
+
538
+ if (!isFacadeType(returnType, true)) invalidFacade(`Facade '${identity}' declaration '${name}' has an invalid return type.`)
539
+ return {
540
+ effects: /** @type {string[]} */ ([...value.effects]),
541
+ failures: /** @type {string[]} */ ([...value.failures]),
542
+ forms: /** @type {("direct-call" | "unqualified-call" | "receiver-call")[]} */ ([...value.forms]),
543
+ kind: /** @type {const} */ ("function"),
544
+ name,
545
+ ownership: /** @type {const} */ ("not-applicable"),
546
+ parameters,
547
+ returnType
548
+ }
549
+ })
550
+ }
551
+
552
+ /**
553
+ * Validates the exact native module and symbol identities selecting a facade.
554
+ * @param {unknown} candidate - Candidate native modules.
555
+ * @param {string} identity - Owning facade identity.
556
+ * @param {StdlibFacadePublicDeclaration[]} declarations - Validated public surface.
557
+ * @returns {({identity: string, kind: "module", symbols: string[]} | {forms: ("unqualified-call" | "receiver-call")[], identity: string, kind: "builtin", symbols: string[]})[]} Validated native identities.
558
+ */
559
+ function validateNativeModules(candidate, identity, declarations) {
560
+ if (!isDenseArray(candidate)) invalidFacade(`Facade '${identity}' native modules must be a dense array.`)
561
+ const modules = new Set()
562
+ const publicNames = new Set(declarations.map(({name}) => name))
563
+ return candidate.map((value) => {
564
+ if (!isPlainObject(value)) invalidFacade(`Facade '${identity}' native modules must be plain objects.`)
565
+ const builtin = value.kind == "builtin"
566
+
567
+ requireKeys(value, builtin ? ["forms", "identity", "kind", "symbols"] : ["identity", "kind", "symbols"],
568
+ `facade '${identity}' native module`)
569
+ const moduleIdentity = requireString(value.identity, `Facade '${identity}' native module identity`)
570
+
571
+ if (value.kind != "module" && value.kind != "builtin" || modules.has(moduleIdentity) ||
572
+ !isDenseArray(value.symbols) || value.symbols.length == 0 ||
573
+ !value.symbols.every((symbol) => typeof symbol == "string" && publicNames.has(symbol)) ||
574
+ new Set(value.symbols).size != value.symbols.length) {
575
+ invalidFacade(`Facade '${identity}' has an invalid native module declaration.`)
576
+ }
577
+ if (builtin && (!isDenseArray(value.forms) || value.forms.length == 0 ||
578
+ !value.forms.every((form) => form == "unqualified-call" || form == "receiver-call") ||
579
+ new Set(value.forms).size != value.forms.length)) invalidFacade(`Facade '${identity}' has invalid builtin forms.`)
580
+ modules.add(moduleIdentity)
581
+ return builtin
582
+ ? {forms: /** @type {("unqualified-call" | "receiver-call")[]} */ ([.../** @type {unknown[]} */ (value.forms)]), identity: moduleIdentity,
583
+ kind: /** @type {const} */ ("builtin"), symbols: /** @type {string[]} */ ([...value.symbols])}
584
+ : {identity: moduleIdentity, kind: /** @type {const} */ ("module"), symbols: /** @type {string[]} */ ([...value.symbols])}
585
+ })
586
+ }
587
+
588
+ /**
589
+ * Validates canonical-only facade capability requirements.
590
+ * @param {unknown} candidate - Candidate requirements.
591
+ * @param {string} identity - Owning facade identity.
592
+ * @returns {{module: string, operations: string[], range: string}[]} Validated requirements.
593
+ */
594
+ function validateRequirements(candidate, identity) {
595
+ if (!isDenseArray(candidate)) invalidFacade(`Facade '${identity}' requirements must be a dense array.`)
596
+ const modules = new Set()
597
+ return candidate.map((value) => {
598
+ if (!isPlainObject(value)) invalidFacade(`Facade '${identity}' requirements must be plain objects.`)
599
+ requireKeys(value, ["module", "operations", "range"], `facade '${identity}' requirement`)
600
+ const module = requireString(value.module, `Facade '${identity}' canonical module`)
601
+ const range = requireString(value.range, `Facade '${identity}' canonical range`)
602
+
603
+ if (modules.has(module) || !parseStdlibVersionRange(range) || !isDenseArray(value.operations) || value.operations.length == 0 ||
604
+ !value.operations.every((operation) => typeof operation == "string" && declarationNamePattern.test(operation)) ||
605
+ new Set(value.operations).size != value.operations.length) invalidFacade(`Facade '${identity}' has an invalid canonical requirement.`)
606
+ const contract = resolveStdlibModule(module, range)
607
+ const declared = new Set(contract.operations.map(({name}) => name))
608
+
609
+ if (!/** @type {string[]} */ (value.operations).every((operation) => declared.has(operation))) {
610
+ invalidFacade(`Facade '${identity}' requires an undeclared canonical operation.`)
611
+ }
612
+ modules.add(module)
613
+ return {module, operations: /** @type {string[]} */ ([...value.operations]), range}
614
+ })
615
+ }
616
+
617
+ /**
618
+ * Validates versioned same-language facade dependencies.
619
+ * @param {unknown} candidate - Candidate dependencies.
620
+ * @param {string} identity - Owning facade identity.
621
+ * @returns {{identity: string, range: string}[]} Validated dependencies.
622
+ */
623
+ function validateDependencies(candidate, identity) {
624
+ if (!isDenseArray(candidate)) invalidFacade(`Facade '${identity}' dependencies must be a dense array.`)
625
+ const identities = new Set()
626
+ return candidate.map((value) => {
627
+ if (!isPlainObject(value)) invalidFacade(`Facade '${identity}' dependencies must be plain objects.`)
628
+ requireKeys(value, ["identity", "range"], `facade '${identity}' dependency`)
629
+ const dependencyIdentity = requireString(value.identity, `Facade '${identity}' dependency identity`)
630
+ const range = requireString(value.range, `Facade '${identity}' dependency range`)
631
+
632
+ if (!facadeIdentityPattern.test(dependencyIdentity) || dependencyIdentity == identity || identities.has(dependencyIdentity) ||
633
+ !parseStdlibVersionRange(range)) invalidFacade(`Facade '${identity}' has an invalid dependency.`)
634
+ identities.add(dependencyIdentity)
635
+ return {identity: dependencyIdentity, range}
636
+ })
637
+ }
638
+
639
+ /**
640
+ * Builds the bounded original-five qualification facade definitions.
641
+ * @returns {unknown[]} Unvalidated built-in qualification facade definitions.
642
+ */
643
+ function builtinFacadeRecords() {
644
+ return ["php", "ruby", "javascript", "typescript", "java"].flatMap((language) => builtinLanguageFacades(language))
645
+ .concat(builtinTask037RubyFacades())
646
+ }
647
+
648
+ /**
649
+ * Builds one source language's public, internal, and unreachable qualification facades.
650
+ * @param {string} language - Source language.
651
+ * @returns {unknown[]} Language facade definitions.
652
+ */
653
+ function builtinLanguageFacades(language) {
654
+ const names = facadeNames(language)
655
+ const base = `semantifold.task036.${language}`
656
+ const sourceBase = `semantifold.facade.${language}`
657
+ const sourceDirectory = `__semantifold_facades__/${language}`
658
+ const probeFilename = language == "java" ? `${sourceDirectory}/semantifold/facade/java/probe/Probe.java` :
659
+ `${sourceDirectory}/probe.${names.extension}`
660
+ const runnerFilename = language == "java" ? `${sourceDirectory}/semantifold/facade/java/proberunner/ProbeRunner.java` :
661
+ `${sourceDirectory}/probe-runner.${names.extension}`
662
+ const unusedFilename = language == "java" ? `${sourceDirectory}/semantifold/facade/java/unused/Unused.java` :
663
+ `${sourceDirectory}/unused.${names.extension}`
664
+
665
+ return [{
666
+ dependencies: [{identity: `${base}.probe-runner`, range: "1"}],
667
+ identity: `${base}.probe`,
668
+ language,
669
+ nativeModules: [{identity: names.nativeModule, kind: "module", symbols: [names.publicName]}],
670
+ publicDeclarations: [publicDeclaration(names.publicName)],
671
+ requirements: [],
672
+ runtimeProfile: `${language}-task036-v1`,
673
+ source: {content: names.probeSource, filename: probeFilename, id: `${sourceBase}.probe`},
674
+ version: "1.0.0",
675
+ visibility: "public"
676
+ }, {
677
+ dependencies: [],
678
+ identity: `${base}.probe-runner`,
679
+ language,
680
+ nativeModules: [],
681
+ publicDeclarations: [],
682
+ requirements: [{module: "semantifold.task034.resource-probe", operations: ["probeEffect", "probeTrace"], range: "1"}],
683
+ runtimeProfile: `${language}-task036-v1`,
684
+ source: {content: names.runnerSource, filename: runnerFilename, id: `${sourceBase}.probe_runner`},
685
+ version: "1.0.0",
686
+ visibility: "internal"
687
+ }, {
688
+ dependencies: [],
689
+ identity: `${base}.unused`,
690
+ language,
691
+ nativeModules: [{identity: names.unusedNativeModule, kind: "module", symbols: [names.unusedName]}],
692
+ publicDeclarations: [publicDeclaration(names.unusedName)],
693
+ requirements: [{module: "semantifold.task034.resource-probe", operations: ["probeTrace"], range: "1"}],
694
+ runtimeProfile: `${language}-task036-v1`,
695
+ source: {content: names.unusedSource, filename: unusedFilename, id: `${sourceBase}.unused`},
696
+ version: "1.0.0",
697
+ visibility: "public"
698
+ }]
699
+ }
700
+
701
+ /**
702
+ * Builds the common bounded qualification function declaration.
703
+ * @param {string} name - Source-visible function name.
704
+ * @returns {StdlibFacadePublicDeclaration} Public facade declaration.
705
+ */
706
+ function publicDeclaration(name) {
707
+ return {
708
+ effects: ["host"], failures: [], forms: ["direct-call"], kind: "function", name,
709
+ ownership: "not-applicable", parameters: [{name: "label", type: "string"}], returnType: "string"
710
+ }
711
+ }
712
+
713
+ /**
714
+ * Builds the exact Ruby Task 037 socket and output compatibility facades.
715
+ * @returns {unknown[]} Unvalidated facade records.
716
+ */
717
+ function builtinTask037RubyFacades() {
718
+ return [{
719
+ dependencies: [],
720
+ identity: "semantifold.task037.ruby.socket",
721
+ language: "ruby",
722
+ nativeModules: [{identity: "socket", kind: "module", symbols: ["TCPSocket"]}],
723
+ publicDeclarations: [{
724
+ constructor: {
725
+ effects: ["host"], failures: ["InvalidHost", "InvalidPort", "ConnectionFailure"], ownership: "acquired",
726
+ parameters: [{name: "host", type: "string"}, {name: "port", type: "integer"}]
727
+ },
728
+ forms: ["constructor-call"],
729
+ kind: "class",
730
+ methods: [{
731
+ effects: ["host"], failures: ["ReadFailure", "DecodeFailure", "ResourceClosed"], forms: ["receiver-call"],
732
+ name: "gets", ownership: "borrowed", parameters: [], returnType: "optional:string"
733
+ }, {
734
+ effects: ["host"], failures: ["CloseFailure", "ResourceClosed"], forms: ["receiver-call"],
735
+ name: "close", ownership: "consumed", parameters: [], returnType: "void"
736
+ }],
737
+ name: "TCPSocket",
738
+ ownership: "owned-reference"
739
+ }],
740
+ requirements: [
741
+ {module: "semantifold.socket-client", operations: ["v1_connect"], range: "1"},
742
+ {module: "semantifold.text-stream", operations: ["v1_read_line"], range: "1"},
743
+ {module: "semantifold.resource", operations: ["v1_close"], range: "1"}
744
+ ],
745
+ runtimeProfile: "ruby-task037-socket-v1",
746
+ source: {
747
+ content: `module SemantifoldTask037Socket
748
+ class TCPSocket
749
+ # @param host [String]
750
+ # @param port [Integer]
751
+ def initialize(host, port)
752
+ @resource = v1_connect(host, port)
753
+ end
754
+
755
+ # @return [String?]
756
+ def gets
757
+ return v1_read_line(@resource)
758
+ end
759
+
760
+ # @return [void]
761
+ def close
762
+ v1_close(@resource)
763
+ end
764
+ end
765
+ end
766
+ `,
767
+ filename: "__semantifold_facades__/ruby/socket.rb",
768
+ id: "semantifold.facade.ruby.socket"
769
+ },
770
+ version: "1.0.0",
771
+ visibility: "public"
772
+ }, {
773
+ dependencies: [],
774
+ identity: "semantifold.task037.ruby.output",
775
+ language: "ruby",
776
+ nativeModules: [{forms: ["unqualified-call", "receiver-call"], identity: "ruby:Kernel", kind: "builtin", symbols: ["puts"]}],
777
+ publicDeclarations: [{
778
+ effects: ["host"], failures: ["WriteFailure"], forms: ["unqualified-call", "receiver-call"], kind: "function",
779
+ name: "puts", ownership: "not-applicable", parameters: [{name: "text", type: "string"}], returnType: "void"
780
+ }],
781
+ requirements: [{module: "semantifold.output", operations: ["v1_write_line"], range: "1"}],
782
+ runtimeProfile: "ruby-task037-output-v1",
783
+ source: {
784
+ content: `module SemantifoldTask037Output
785
+ module_function
786
+ # @param text [String]
787
+ # @return [void]
788
+ def puts(text)
789
+ v1_write_line(text)
790
+ return
791
+ end
792
+ end
793
+ `,
794
+ filename: "__semantifold_facades__/ruby/output.rb",
795
+ id: "semantifold.facade.ruby.output"
796
+ },
797
+ version: "1.0.0",
798
+ visibility: "public"
799
+ }]
800
+ }
801
+
802
+ /**
803
+ * Validates one public facade class descriptor.
804
+ * @param {Record<string, unknown>} value - Candidate class.
805
+ * @param {string} identity - Owning facade.
806
+ * @param {string} name - Validated class name.
807
+ * @returns {StdlibFacadeClassDeclaration} Detached class descriptor.
808
+ */
809
+ function validatePublicClass(value, identity, name) {
810
+ requireKeys(value, ["constructor", "forms", "kind", "methods", "name", "ownership"],
811
+ `facade '${identity}' public class`)
812
+ if (!isDenseArray(value.forms) || value.forms.length != 1 || value.forms[0] != "constructor-call" ||
813
+ value.ownership != "owned-reference" || !isPlainObject(value.constructor) || !isDenseArray(value.methods)) {
814
+ invalidFacade(`Facade '${identity}' class '${name}' has an invalid public contract.`)
815
+ }
816
+ const constructor = /** @type {Record<string, unknown>} */ (value.constructor)
817
+
818
+ requireKeys(constructor, ["effects", "failures", "ownership", "parameters"], `facade '${identity}' constructor`)
819
+ if (constructor.ownership != "acquired" || !validFacadeEffects(constructor.effects) ||
820
+ !validFacadeFailures(constructor.failures)) invalidFacade(`Facade '${identity}' class '${name}' has an invalid constructor.`)
821
+ const parameters = validateFacadeParameters(constructor.parameters, identity, `${name}.new`)
822
+ const methodNames = new Set()
823
+ const methods = value.methods.map((method) => {
824
+ if (!isPlainObject(method)) invalidFacade(`Facade '${identity}' class '${name}' has an invalid method.`)
825
+ requireKeys(method, ["effects", "failures", "forms", "name", "ownership", "parameters", "returnType"],
826
+ `facade '${identity}' class method`)
827
+ const methodName = requireString(method.name, `Facade '${identity}' method name`)
828
+ const returnType = requireString(method.returnType, `Facade '${identity}' method return type`)
829
+
830
+ if (!declarationNamePattern.test(methodName) || methodNames.has(methodName) || !validFacadeEffects(method.effects) ||
831
+ !validFacadeFailures(method.failures) || !isDenseArray(method.forms) || method.forms.length != 1 ||
832
+ method.forms[0] != "receiver-call" || method.ownership != "borrowed" && method.ownership != "consumed" ||
833
+ !isFacadeType(returnType, true)) invalidFacade(`Facade '${identity}' class '${name}' has an invalid method.`)
834
+ methodNames.add(methodName)
835
+ return {
836
+ effects: /** @type {string[]} */ ([.../** @type {unknown[]} */ (method.effects)]),
837
+ failures: /** @type {string[]} */ ([.../** @type {unknown[]} */ (method.failures)]),
838
+ forms: /** @type {["receiver-call"]} */ (["receiver-call"]),
839
+ name: methodName,
840
+ ownership: /** @type {"borrowed" | "consumed"} */ (method.ownership),
841
+ parameters: validateFacadeParameters(method.parameters, identity, `${name}.${methodName}`),
842
+ returnType
843
+ }
844
+ })
845
+
846
+ return {
847
+ constructor: {
848
+ effects: /** @type {string[]} */ ([.../** @type {unknown[]} */ (constructor.effects)]),
849
+ failures: /** @type {string[]} */ ([.../** @type {unknown[]} */ (constructor.failures)]),
850
+ ownership: "acquired",
851
+ parameters
852
+ },
853
+ forms: ["constructor-call"],
854
+ kind: "class",
855
+ methods,
856
+ name,
857
+ ownership: "owned-reference"
858
+ }
859
+ }
860
+
861
+ /**
862
+ * Validates facade parameters shared by functions, constructors, and methods.
863
+ * @param {unknown} candidate - Candidate parameters.
864
+ * @param {string} identity - Owning facade.
865
+ * @param {string} callable - Callable name.
866
+ * @returns {{name: string, type: string}[]} Detached parameters.
867
+ */
868
+ function validateFacadeParameters(candidate, identity, callable) {
869
+ if (!isDenseArray(candidate)) invalidFacade(`Facade '${identity}' declaration '${callable}' has invalid parameters.`)
870
+ const names = new Set()
871
+
872
+ return candidate.map((parameter) => {
873
+ if (!isPlainObject(parameter)) invalidFacade(`Facade '${identity}' declaration '${callable}' has an invalid parameter.`)
874
+ requireKeys(parameter, ["name", "type"], `facade '${identity}' declaration parameter`)
875
+ const name = requireString(parameter.name, `Facade '${identity}' parameter name`)
876
+ const type = requireString(parameter.type, `Facade '${identity}' parameter type`)
877
+
878
+ if (!declarationNamePattern.test(name) || names.has(name) || !isFacadeType(type, false)) {
879
+ invalidFacade(`Facade '${identity}' declaration '${callable}' has an invalid parameter.`)
880
+ }
881
+ names.add(name)
882
+ return {name, type}
883
+ })
884
+ }
885
+
886
+ /**
887
+ * Checks one facade effect list.
888
+ * @param {unknown} candidate - Candidate effects.
889
+ * @returns {boolean} Whether effects are exact.
890
+ */
891
+ function validFacadeEffects(candidate) {
892
+ return isDenseArray(candidate) && candidate.every((effect) => effect == "host") && new Set(candidate).size == candidate.length
893
+ }
894
+
895
+ /**
896
+ * Checks one facade failure list.
897
+ * @param {unknown} candidate - Candidate failures.
898
+ * @returns {candidate is string[]} Whether failures are exact.
899
+ */
900
+ function validFacadeFailures(candidate) {
901
+ return isDenseArray(candidate) && candidate.every((failure) => typeof failure == "string" && declarationNamePattern.test(failure)) &&
902
+ new Set(candidate).size == candidate.length
903
+ }
904
+
905
+ /**
906
+ * Checks one facade type spelling.
907
+ * @param {string} type - Candidate type.
908
+ * @param {boolean} allowVoid - Whether void is valid in this position.
909
+ * @returns {boolean} Whether the type is canonical.
910
+ */
911
+ function isFacadeType(type, allowVoid) {
912
+ if (canonicalTypes.has(type)) return allowVoid || type != "void"
913
+ const optional = /^optional:(boolean|integer|string)$/u.exec(type)
914
+
915
+ return optional !== null
916
+ }
917
+
918
+ /**
919
+ * Detaches one descriptor for the public program record.
920
+ * @param {StdlibFacadePublicDeclaration} declaration - Registry declaration.
921
+ * @returns {StdlibFacadePublicDeclaration} Detached declaration.
922
+ */
923
+ function detachPublicDeclaration(declaration) {
924
+ if (declaration.kind == "function") return {...declaration, effects: [...declaration.effects], failures: [...declaration.failures],
925
+ forms: [...declaration.forms], parameters: declaration.parameters.map((parameter) => ({...parameter}))}
926
+ return {...declaration,
927
+ constructor: {...declaration.constructor, effects: [...declaration.constructor.effects], failures: [...declaration.constructor.failures],
928
+ parameters: declaration.constructor.parameters.map((parameter) => ({...parameter}))},
929
+ forms: [...declaration.forms],
930
+ methods: declaration.methods.map((method) => ({...method, effects: [...method.effects], failures: [...method.failures],
931
+ forms: [...method.forms], parameters: method.parameters.map((parameter) => ({...parameter}))}))}
932
+ }
933
+
934
+ /**
935
+ * Detaches a local or dependency-qualified contract reference.
936
+ * @param {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} reference - Contract reference.
937
+ * @returns {string | import("./semantic/types.js").CapabilityDeclarationReferenceInput} Detached reference.
938
+ */
939
+ function detachCanonicalReference(reference) {
940
+ return typeof reference == "string" ? reference : {module: reference.module, name: reference.name}
941
+ }
942
+
943
+ /**
944
+ * Detaches a canonical resource flow for authority construction.
945
+ * @param {object} flow - Canonical resource flow.
946
+ * @returns {import("./semantic/types.js").CapabilityResourceFlowInput} Detached flow.
947
+ */
948
+ function detachResourceFlow(flow) {
949
+ const candidate = /** @type {Record<string, unknown>} */ (flow)
950
+
951
+ if (candidate.kind == "none") return {kind: "none"}
952
+ if (candidate.kind == "acquire") return {kind: "acquire", resource: detachCanonicalReference(
953
+ /** @type {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} */ (candidate.resource))}
954
+ return {
955
+ kind: /** @type {"borrow" | "close"} */ (candidate.kind),
956
+ parameterIndex: /** @type {number} */ (candidate.parameterIndex),
957
+ terminalFailure: detachCanonicalReference(
958
+ /** @type {string | import("./semantic/stdlib.js").CanonicalDeclarationReference} */ (candidate.terminalFailure))
959
+ }
960
+ }
961
+
962
+ /**
963
+ * Maps one canonical module identity to its closed capability name.
964
+ * @param {string} identity - Canonical identity.
965
+ * @returns {string} Capability name.
966
+ */
967
+ function canonicalCapabilityName(identity) {
968
+ /** @type {Readonly<Record<string, string>>} */
969
+ const names = {
970
+ "semantifold.output": "Output",
971
+ "semantifold.resource": "Resource",
972
+ "semantifold.socket-client": "SocketClient",
973
+ "semantifold.task034.resource-probe": "ResourceProbe",
974
+ "semantifold.text-stream": "TextStream"
975
+ }
976
+
977
+ return names[identity] ?? invalidFacade(`Facade requirements name unknown canonical module '${identity}'.`)
978
+ }
979
+
980
+ /**
981
+ * Builds executable source and native identity spellings for one original-five language.
982
+ * @param {string} language - Source language.
983
+ * @returns {FacadeSourceNames} Facade source definitions.
984
+ */
985
+ function facadeNames(language) {
986
+ if (language == "php") return {
987
+ extension: "php", nativeModule: "Semantifold\\Task036\\Probe", publicName: "compatibility_probe",
988
+ unusedName: "unused_probe", unusedNativeModule: "Semantifold\\Task036\\Unused",
989
+ probeSource: `<?php
990
+ declare(strict_types=1);
991
+ namespace Semantifold\\Facade\\Php\\Probe;
992
+ use function Semantifold\\Facade\\Php\\ProbeRunner\\run_compatibility_probe;
993
+ require_once __DIR__ . "/probe-runner.php";
994
+ function compatibility_probe(string $label): string { return run_compatibility_probe($label); }
995
+ `,
996
+ runnerSource: `<?php
997
+ declare(strict_types=1);
998
+ namespace Semantifold\\Facade\\Php\\ProbeRunner;
999
+ function run_compatibility_probe(string $label): string {
1000
+ try {
1001
+ /**
1002
+ * @var int $effect
1003
+ * @semantifold-immutable
1004
+ */
1005
+ $effect = probeEffect($label, 1, false);
1006
+ return probeTrace();
1007
+ }
1008
+ catch (ProbeOperationFailure $error) { return $error->getMessage(); }
1009
+ }
1010
+ `,
1011
+ unusedSource: `<?php
1012
+ declare(strict_types=1);
1013
+ namespace Semantifold\\Facade\\Php\\Unused;
1014
+ function unused_probe(string $label): string { return probeTrace(); }
1015
+ `
1016
+ }
1017
+ if (language == "ruby") return {
1018
+ extension: "rb", nativeModule: "semantifold/task036/probe", publicName: "compatibility_probe",
1019
+ unusedName: "unused_probe", unusedNativeModule: "semantifold/task036/unused",
1020
+ probeSource: `require_relative "probe-runner"
1021
+ module SemantifoldTask036Probe
1022
+ module_function
1023
+ # @param label [String]
1024
+ # @return [String]
1025
+ def compatibility_probe(label)
1026
+ return SemantifoldTask036ProbeRunner.run_compatibility_probe(label)
1027
+ end
1028
+ end
1029
+ `,
1030
+ runnerSource: `module SemantifoldTask036ProbeRunner
1031
+ module_function
1032
+ # @param label [String]
1033
+ # @return [String]
1034
+ def run_compatibility_probe(label)
1035
+ begin
1036
+ # @type [Integer]
1037
+ # @semantifold-immutable
1038
+ effect = probeEffect(label, 1, false)
1039
+ return probeTrace
1040
+ rescue ProbeOperationFailure => error
1041
+ return error.message
1042
+ end
1043
+ end
1044
+ end
1045
+ `,
1046
+ unusedSource: `module SemantifoldTask036Unused
1047
+ module_function
1048
+ # @param label [String]
1049
+ # @return [String]
1050
+ def unused_probe(label)
1051
+ return probeTrace
1052
+ end
1053
+ end
1054
+ `
1055
+ }
1056
+ if (language == "java") return {
1057
+ extension: "java", nativeModule: "semantifold.task036.Probe", publicName: "compatibilityProbe",
1058
+ unusedName: "unusedProbe", unusedNativeModule: "semantifold.task036.Unused",
1059
+ probeSource: `package semantifold.facade.java.probe;
1060
+ import semantifold.facade.java.proberunner.ProbeRunner;
1061
+ public final class Probe {
1062
+ public static String compatibilityProbe(String label) { return ProbeRunner.runCompatibilityProbe(label); }
1063
+ }
1064
+ `,
1065
+ runnerSource: `package semantifold.facade.java.proberunner;
1066
+ public final class ProbeRunner {
1067
+ public static String runCompatibilityProbe(String label) {
1068
+ try { final int effect = probeEffect(label, 1, false); return probeTrace(); }
1069
+ catch (ProbeOperationFailure error) { return error.getMessage(); }
1070
+ }
1071
+ }
1072
+ `,
1073
+ unusedSource: `package semantifold.facade.java.unused;
1074
+ public final class Unused {
1075
+ public static String unusedProbe(String label) { return probeTrace(); }
1076
+ }
1077
+ `
1078
+ }
1079
+ const typed = language == "typescript"
1080
+ const extension = typed ? "ts" : "js"
1081
+ const parameter = typed ? "label: string" : "label"
1082
+ const result = typed ? ": string" : ""
1083
+ const documentation = typed ? "" : `/**
1084
+ * @param {string} label
1085
+ * @returns {string}
1086
+ */
1087
+ `
1088
+
1089
+ return {
1090
+ extension, nativeModule: "semantifold:task036/probe", publicName: "compatibilityProbe",
1091
+ unusedName: "unusedProbe", unusedNativeModule: "semantifold:task036/unused",
1092
+ probeSource: `import {runCompatibilityProbe} from "./probe-runner.js"
1093
+ ${documentation}export function compatibilityProbe(${parameter})${result} { return runCompatibilityProbe(label) }
1094
+ `,
1095
+ runnerSource: `${documentation}export function runCompatibilityProbe(${parameter})${result} {
1096
+ try { ${typed ? "const effect: number" : "/** @type {number} */ const effect"} = probeEffect(label, 1, false); return probeTrace() }
1097
+ catch (error) { if (!(error instanceof ProbeOperationFailure)) { throw error } return error.message }
1098
+ }
1099
+ `,
1100
+ unusedSource: `${documentation}export function unusedProbe(${parameter})${result} { return probeTrace() }
1101
+ `
1102
+ }
1103
+ }
1104
+
1105
+ /**
1106
+ * Requires a closed exact key set.
1107
+ * @param {Record<string, unknown>} value - Plain candidate object.
1108
+ * @param {string[]} keys - Expected keys.
1109
+ * @param {string} subject - Diagnostic subject.
1110
+ * @returns {void}
1111
+ */
1112
+ function requireKeys(value, keys, subject) {
1113
+ if (Object.keys(value).sort().join(",") != [...keys].sort().join(",")) invalidFacade(`Invalid ${subject} fields.`)
1114
+ }
1115
+
1116
+ /**
1117
+ * Requires one non-empty string.
1118
+ * @param {unknown} value - Candidate value.
1119
+ * @param {string} subject - Diagnostic subject.
1120
+ * @returns {string} Validated string.
1121
+ */
1122
+ function requireString(value, subject) {
1123
+ if (typeof value != "string" || value.length == 0) invalidFacade(`${subject} must be a non-empty string.`)
1124
+ return /** @type {string} */ (value)
1125
+ }
1126
+
1127
+ /**
1128
+ * Checks for an ordinary object with no custom prototype.
1129
+ * @param {unknown} value - Candidate value.
1130
+ * @returns {value is Record<string, unknown>} Whether the candidate is plain.
1131
+ */
1132
+ function isPlainObject(value) {
1133
+ return value !== null && typeof value == "object" && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype
1134
+ }
1135
+
1136
+ /**
1137
+ * Recursively freezes one detached facade registry value.
1138
+ * @template {object} T
1139
+ * @param {T} value - Detached object.
1140
+ * @returns {Readonly<T>} Frozen value.
1141
+ */
1142
+ function deepFreeze(value) {
1143
+ for (const child of Object.values(value)) if (child && typeof child == "object" && !Object.isFrozen(child)) deepFreeze(child)
1144
+ return Object.freeze(value)
1145
+ }
1146
+
1147
+ /**
1148
+ * Throws a stable invalid-registry diagnostic.
1149
+ * @param {string} message - Failure detail.
1150
+ * @returns {never} Always throws.
1151
+ */
1152
+ function invalidFacade(message) {
1153
+ throw new SemantifoldDiagnostic({code: "STDLIB_FACADE_INVALID", language: "stdlib", message})
1154
+ }
1155
+
1156
+ /**
1157
+ * Throws when parser evidence does not name a registered native module.
1158
+ * @param {string} language - Source language.
1159
+ * @param {unknown} nativeModule - Unproved module identity.
1160
+ * @returns {never} Always throws.
1161
+ */
1162
+ function unprovedIdentity(language, nativeModule) {
1163
+ throw new SemantifoldDiagnostic({
1164
+ code: "STDLIB_FACADE_IDENTITY_UNPROVED",
1165
+ language: supportedLanguages.has(language) ? language : "stdlib",
1166
+ message: `Native standard-library module '${String(nativeModule)}' is not a registered '${language}' facade identity.`
1167
+ })
1168
+ }
1169
+
1170
+ /**
1171
+ * Throws when a native module member is outside its public facade surface.
1172
+ * @param {string} language - Source language.
1173
+ * @param {string} nativeModule - Exact native module.
1174
+ * @param {string} symbol - Unsupported member.
1175
+ * @returns {never} Always throws.
1176
+ */
1177
+ function unsupportedMember(language, nativeModule, symbol) {
1178
+ throw new SemantifoldDiagnostic({
1179
+ code: "STDLIB_FACADE_MEMBER_UNSUPPORTED",
1180
+ language,
1181
+ message: `Native standard-library symbol '${nativeModule}#${symbol}' is outside the registered facade surface.`
1182
+ })
1183
+ }
1184
+
1185
+ /**
1186
+ * Throws for a malformed facade version range.
1187
+ * @param {string} language - Source language.
1188
+ * @param {string} range - Malformed range.
1189
+ * @returns {never} Always throws.
1190
+ */
1191
+ function facadeVersionMalformed(language, range) {
1192
+ throw new SemantifoldDiagnostic({
1193
+ code: "STDLIB_FACADE_VERSION_MALFORMED", language,
1194
+ message: `Facade version range '${range}' is not canonical.`
1195
+ })
1196
+ }
1197
+
1198
+ /**
1199
+ * Throws when no registered facade version satisfies a range.
1200
+ * @param {string} language - Source language.
1201
+ * @param {string} identity - Facade identity.
1202
+ * @returns {never} Always throws.
1203
+ */
1204
+ function facadeVersionIncompatible(language, identity) {
1205
+ throw new SemantifoldDiagnostic({
1206
+ code: "STDLIB_FACADE_VERSION_INCOMPATIBLE", language,
1207
+ message: `No registered version of facade '${identity}' satisfies the required compatibility range.`
1208
+ })
1209
+ }
1210
+
1211
+ export const stdlibFacadeRegistry = createStdlibFacadeRegistry()