@aster-cloud/aster-lang-ts 1.0.30 → 1.0.32

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 (297) hide show
  1. package/dist/scripts/aster.js +11 -26
  2. package/dist/scripts/aster.js.map +1 -1
  3. package/dist/scripts/corpus-loader.d.ts +17 -0
  4. package/dist/scripts/corpus-loader.d.ts.map +1 -0
  5. package/dist/scripts/corpus-loader.js +60 -0
  6. package/dist/scripts/corpus-loader.js.map +1 -0
  7. package/dist/scripts/emit-classfiles-core.js +5 -13
  8. package/dist/scripts/emit-classfiles-core.js.map +1 -1
  9. package/dist/scripts/emit-classfiles.js +7 -12
  10. package/dist/scripts/emit-classfiles.js.map +1 -1
  11. package/dist/scripts/generate_error_codes.js +2 -0
  12. package/dist/scripts/generate_error_codes.js.map +1 -1
  13. package/dist/scripts/golden.js +4 -1
  14. package/dist/scripts/golden.js.map +1 -1
  15. package/dist/scripts/test-lossless-golden.js +2 -1
  16. package/dist/scripts/test-lossless-golden.js.map +1 -1
  17. package/dist/scripts/validate_error_codes.js +1 -0
  18. package/dist/scripts/validate_error_codes.js.map +1 -1
  19. package/dist/scripts/verify-lexicon-sync.js +5 -1
  20. package/dist/scripts/verify-lexicon-sync.js.map +1 -1
  21. package/dist/src/ast/ast.d.ts +1 -1
  22. package/dist/src/ast/ast.d.ts.map +1 -1
  23. package/dist/src/ast/ast.js +2 -1
  24. package/dist/src/ast/ast.js.map +1 -1
  25. package/dist/src/browser.d.ts +7 -0
  26. package/dist/src/browser.d.ts.map +1 -1
  27. package/dist/src/browser.js +4 -0
  28. package/dist/src/browser.js.map +1 -1
  29. package/dist/src/cli/utils/gradle-env.d.ts +9 -0
  30. package/dist/src/cli/utils/gradle-env.d.ts.map +1 -0
  31. package/dist/src/cli/utils/gradle-env.js +18 -0
  32. package/dist/src/cli/utils/gradle-env.js.map +1 -0
  33. package/dist/src/cli/utils/out-dir.d.ts +18 -0
  34. package/dist/src/cli/utils/out-dir.d.ts.map +1 -0
  35. package/dist/src/cli/utils/out-dir.js +49 -0
  36. package/dist/src/cli/utils/out-dir.js.map +1 -0
  37. package/dist/src/cnl-printer.d.ts +10 -0
  38. package/dist/src/cnl-printer.d.ts.map +1 -0
  39. package/dist/src/cnl-printer.js +360 -0
  40. package/dist/src/cnl-printer.js.map +1 -0
  41. package/dist/src/config/lexicons/de-DE.d.ts.map +1 -1
  42. package/dist/src/config/lexicons/de-DE.js +8 -2
  43. package/dist/src/config/lexicons/de-DE.js.map +1 -1
  44. package/dist/src/config/lexicons/en-US.d.ts.map +1 -1
  45. package/dist/src/config/lexicons/en-US.js +8 -4
  46. package/dist/src/config/lexicons/en-US.js.map +1 -1
  47. package/dist/src/config/lexicons/hi-IN.d.ts.map +1 -1
  48. package/dist/src/config/lexicons/hi-IN.js +8 -2
  49. package/dist/src/config/lexicons/hi-IN.js.map +1 -1
  50. package/dist/src/config/lexicons/template.d.ts.map +1 -1
  51. package/dist/src/config/lexicons/template.js +12 -0
  52. package/dist/src/config/lexicons/template.js.map +1 -1
  53. package/dist/src/config/lexicons/zh-CN.d.ts.map +1 -1
  54. package/dist/src/config/lexicons/zh-CN.js +9 -3
  55. package/dist/src/config/lexicons/zh-CN.js.map +1 -1
  56. package/dist/src/config/semantic.d.ts +6 -0
  57. package/dist/src/config/semantic.d.ts.map +1 -1
  58. package/dist/src/config/semantic.js +8 -0
  59. package/dist/src/config/semantic.js.map +1 -1
  60. package/dist/src/config/token-kind.d.ts +12 -0
  61. package/dist/src/config/token-kind.d.ts.map +1 -1
  62. package/dist/src/config/token-kind.js +18 -0
  63. package/dist/src/config/token-kind.js.map +1 -1
  64. package/dist/src/core/core_ir.d.ts +1 -1
  65. package/dist/src/core/core_ir.d.ts.map +1 -1
  66. package/dist/src/core/core_ir.js +3 -1
  67. package/dist/src/core/core_ir.js.map +1 -1
  68. package/dist/src/core/interpreter.d.ts.map +1 -1
  69. package/dist/src/core/interpreter.js +222 -18
  70. package/dist/src/core/interpreter.js.map +1 -1
  71. package/dist/src/cst/cst_printer.d.ts.map +1 -1
  72. package/dist/src/cst/cst_printer.js +66 -32
  73. package/dist/src/cst/cst_printer.js.map +1 -1
  74. package/dist/src/diagnostics/diagnostics.d.ts +1 -0
  75. package/dist/src/diagnostics/diagnostics.d.ts.map +1 -1
  76. package/dist/src/diagnostics/diagnostics.js +1 -0
  77. package/dist/src/diagnostics/diagnostics.js.map +1 -1
  78. package/dist/src/diagnostics/error_codes.d.ts +10 -2
  79. package/dist/src/diagnostics/error_codes.d.ts.map +1 -1
  80. package/dist/src/diagnostics/error_codes.js +64 -0
  81. package/dist/src/diagnostics/error_codes.js.map +1 -1
  82. package/dist/src/effects/effect_inference.js +1 -1
  83. package/dist/src/effects/effect_inference.js.map +1 -1
  84. package/dist/src/formatter.d.ts +3 -0
  85. package/dist/src/formatter.d.ts.map +1 -1
  86. package/dist/src/formatter.js +8 -261
  87. package/dist/src/formatter.js.map +1 -1
  88. package/dist/src/frontend/transformers.d.ts.map +1 -1
  89. package/dist/src/frontend/transformers.js +10 -2
  90. package/dist/src/frontend/transformers.js.map +1 -1
  91. package/dist/src/governance/controls-registry.data.d.ts +40 -0
  92. package/dist/src/governance/controls-registry.data.d.ts.map +1 -0
  93. package/dist/src/governance/controls-registry.data.js +35 -0
  94. package/dist/src/governance/controls-registry.data.js.map +1 -0
  95. package/dist/src/governance/controls.d.ts +23 -0
  96. package/dist/src/governance/controls.d.ts.map +1 -0
  97. package/dist/src/governance/controls.js +77 -0
  98. package/dist/src/governance/controls.js.map +1 -0
  99. package/dist/src/index.d.ts +4 -0
  100. package/dist/src/index.d.ts.map +1 -1
  101. package/dist/src/index.js +2 -0
  102. package/dist/src/index.js.map +1 -1
  103. package/dist/src/lower_to_core.js +1 -1
  104. package/dist/src/lower_to_core.js.map +1 -1
  105. package/dist/src/lsp/completion.d.ts +22 -1
  106. package/dist/src/lsp/completion.d.ts.map +1 -1
  107. package/dist/src/lsp/completion.js +42 -1
  108. package/dist/src/lsp/completion.js.map +1 -1
  109. package/dist/src/lsp/debounce-map.d.ts +16 -0
  110. package/dist/src/lsp/debounce-map.d.ts.map +1 -0
  111. package/dist/src/lsp/debounce-map.js +32 -0
  112. package/dist/src/lsp/debounce-map.js.map +1 -0
  113. package/dist/src/lsp/server.js +6 -8
  114. package/dist/src/lsp/server.js.map +1 -1
  115. package/dist/src/lsp/utils.d.ts.map +1 -1
  116. package/dist/src/lsp/utils.js +2 -0
  117. package/dist/src/lsp/utils.js.map +1 -1
  118. package/dist/src/lsp/workspace/file-watcher.d.ts +1 -0
  119. package/dist/src/lsp/workspace/file-watcher.d.ts.map +1 -1
  120. package/dist/src/lsp/workspace/file-watcher.js +24 -14
  121. package/dist/src/lsp/workspace/file-watcher.js.map +1 -1
  122. package/dist/src/manifest.d.ts +2 -0
  123. package/dist/src/manifest.d.ts.map +1 -1
  124. package/dist/src/manifest.js.map +1 -1
  125. package/dist/src/package/manifest-parser.d.ts +10 -0
  126. package/dist/src/package/manifest-parser.d.ts.map +1 -1
  127. package/dist/src/package/manifest-parser.js +27 -28
  128. package/dist/src/package/manifest-parser.js.map +1 -1
  129. package/dist/src/package/manifest-schema.d.ts +15 -0
  130. package/dist/src/package/manifest-schema.d.ts.map +1 -0
  131. package/dist/src/package/manifest-schema.js +116 -0
  132. package/dist/src/package/manifest-schema.js.map +1 -0
  133. package/dist/src/parser/context.d.ts +2 -0
  134. package/dist/src/parser/context.d.ts.map +1 -1
  135. package/dist/src/parser/context.js +1 -0
  136. package/dist/src/parser/context.js.map +1 -1
  137. package/dist/src/parser/decl-parser.d.ts.map +1 -1
  138. package/dist/src/parser/decl-parser.js +26 -10
  139. package/dist/src/parser/decl-parser.js.map +1 -1
  140. package/dist/src/parser/expr-stmt-parser.d.ts +4 -1
  141. package/dist/src/parser/expr-stmt-parser.d.ts.map +1 -1
  142. package/dist/src/parser/expr-stmt-parser.js +199 -6
  143. package/dist/src/parser/expr-stmt-parser.js.map +1 -1
  144. package/dist/src/parser/import-parser.d.ts +12 -0
  145. package/dist/src/parser/import-parser.d.ts.map +1 -1
  146. package/dist/src/parser/import-parser.js +28 -0
  147. package/dist/src/parser/import-parser.js.map +1 -1
  148. package/dist/src/parser.js +1 -1
  149. package/dist/src/parser.js.map +1 -1
  150. package/dist/src/typecheck/browser.d.ts +3 -0
  151. package/dist/src/typecheck/browser.d.ts.map +1 -1
  152. package/dist/src/typecheck/browser.js +10 -1
  153. package/dist/src/typecheck/browser.js.map +1 -1
  154. package/dist/src/typecheck/context.d.ts +3 -0
  155. package/dist/src/typecheck/context.d.ts.map +1 -1
  156. package/dist/src/typecheck/context.js.map +1 -1
  157. package/dist/src/typecheck/expression.d.ts +6 -0
  158. package/dist/src/typecheck/expression.d.ts.map +1 -1
  159. package/dist/src/typecheck/expression.js +54 -2
  160. package/dist/src/typecheck/expression.js.map +1 -1
  161. package/dist/src/typecheck/generics.d.ts.map +1 -1
  162. package/dist/src/typecheck/generics.js +3 -0
  163. package/dist/src/typecheck/generics.js.map +1 -1
  164. package/dist/src/typecheck/governance.d.ts +43 -0
  165. package/dist/src/typecheck/governance.d.ts.map +1 -0
  166. package/dist/src/typecheck/governance.js +162 -0
  167. package/dist/src/typecheck/governance.js.map +1 -0
  168. package/dist/src/typecheck/module.d.ts.map +1 -1
  169. package/dist/src/typecheck/module.js +10 -1
  170. package/dist/src/typecheck/module.js.map +1 -1
  171. package/dist/src/typecheck/statement.d.ts.map +1 -1
  172. package/dist/src/typecheck/statement.js +2 -2
  173. package/dist/src/typecheck/statement.js.map +1 -1
  174. package/dist/src/typecheck/type_system.d.ts.map +1 -1
  175. package/dist/src/typecheck/type_system.js +4 -0
  176. package/dist/src/typecheck/type_system.js.map +1 -1
  177. package/dist/src/typecheck/verdict_signatures.d.ts +19 -0
  178. package/dist/src/typecheck/verdict_signatures.d.ts.map +1 -0
  179. package/dist/src/typecheck/verdict_signatures.js +23 -0
  180. package/dist/src/typecheck/verdict_signatures.js.map +1 -0
  181. package/dist/src/types/base.d.ts +2 -0
  182. package/dist/src/types/base.d.ts.map +1 -1
  183. package/dist/test/helpers/sibling-source.d.ts +10 -0
  184. package/dist/test/helpers/sibling-source.d.ts.map +1 -0
  185. package/dist/test/helpers/sibling-source.js +20 -0
  186. package/dist/test/helpers/sibling-source.js.map +1 -0
  187. package/dist/test/unit/allocation-budget.test.d.ts +2 -0
  188. package/dist/test/unit/allocation-budget.test.d.ts.map +1 -0
  189. package/dist/test/unit/allocation-budget.test.js +160 -0
  190. package/dist/test/unit/allocation-budget.test.js.map +1 -0
  191. package/dist/test/unit/apply-call.test.js +5 -0
  192. package/dist/test/unit/apply-call.test.js.map +1 -1
  193. package/dist/test/unit/canonicalizer/possessive-anchor.test.js +10 -0
  194. package/dist/test/unit/canonicalizer/possessive-anchor.test.js.map +1 -1
  195. package/dist/test/unit/cli/gradle-env-guard.test.d.ts +2 -0
  196. package/dist/test/unit/cli/gradle-env-guard.test.d.ts.map +1 -0
  197. package/dist/test/unit/cli/gradle-env-guard.test.js +53 -0
  198. package/dist/test/unit/cli/gradle-env-guard.test.js.map +1 -0
  199. package/dist/test/unit/cli/gradle-env.test.d.ts +2 -0
  200. package/dist/test/unit/cli/gradle-env.test.d.ts.map +1 -0
  201. package/dist/test/unit/cli/gradle-env.test.js +31 -0
  202. package/dist/test/unit/cli/gradle-env.test.js.map +1 -0
  203. package/dist/test/unit/cli/out-dir.test.d.ts +2 -0
  204. package/dist/test/unit/cli/out-dir.test.d.ts.map +1 -0
  205. package/dist/test/unit/cli/out-dir.test.js +96 -0
  206. package/dist/test/unit/cli/out-dir.test.js.map +1 -0
  207. package/dist/test/unit/eval-regression-poker-straight-high.test.d.ts +2 -0
  208. package/dist/test/unit/eval-regression-poker-straight-high.test.d.ts.map +1 -0
  209. package/dist/test/unit/eval-regression-poker-straight-high.test.js +61 -0
  210. package/dist/test/unit/eval-regression-poker-straight-high.test.js.map +1 -0
  211. package/dist/test/unit/formatter-corpus-roundtrip.test.d.ts +2 -0
  212. package/dist/test/unit/formatter-corpus-roundtrip.test.d.ts.map +1 -0
  213. package/dist/test/unit/formatter-corpus-roundtrip.test.js +190 -0
  214. package/dist/test/unit/formatter-corpus-roundtrip.test.js.map +1 -0
  215. package/dist/test/unit/formatter-roundtrip.test.d.ts +2 -0
  216. package/dist/test/unit/formatter-roundtrip.test.d.ts.map +1 -0
  217. package/dist/test/unit/formatter-roundtrip.test.js +125 -0
  218. package/dist/test/unit/formatter-roundtrip.test.js.map +1 -0
  219. package/dist/test/unit/governance/controls-registry-parity.test.d.ts +2 -0
  220. package/dist/test/unit/governance/controls-registry-parity.test.d.ts.map +1 -0
  221. package/dist/test/unit/governance/controls-registry-parity.test.js +28 -0
  222. package/dist/test/unit/governance/controls-registry-parity.test.js.map +1 -0
  223. package/dist/test/unit/governance/controls-registry-profiles.test.d.ts +2 -0
  224. package/dist/test/unit/governance/controls-registry-profiles.test.d.ts.map +1 -0
  225. package/dist/test/unit/governance/controls-registry-profiles.test.js +106 -0
  226. package/dist/test/unit/governance/controls-registry-profiles.test.js.map +1 -0
  227. package/dist/test/unit/governance/governance-check.test.d.ts +2 -0
  228. package/dist/test/unit/governance/governance-check.test.d.ts.map +1 -0
  229. package/dist/test/unit/governance/governance-check.test.js +169 -0
  230. package/dist/test/unit/governance/governance-check.test.js.map +1 -0
  231. package/dist/test/unit/governance/profile-check.test.d.ts +2 -0
  232. package/dist/test/unit/governance/profile-check.test.d.ts.map +1 -0
  233. package/dist/test/unit/governance/profile-check.test.js +139 -0
  234. package/dist/test/unit/governance/profile-check.test.js.map +1 -0
  235. package/dist/test/unit/governance/verdict-typecheck.test.d.ts +2 -0
  236. package/dist/test/unit/governance/verdict-typecheck.test.d.ts.map +1 -0
  237. package/dist/test/unit/governance/verdict-typecheck.test.js +80 -0
  238. package/dist/test/unit/governance/verdict-typecheck.test.js.map +1 -0
  239. package/dist/test/unit/interpreter/verdict-builtins.test.d.ts +2 -0
  240. package/dist/test/unit/interpreter/verdict-builtins.test.d.ts.map +1 -0
  241. package/dist/test/unit/interpreter/verdict-builtins.test.js +72 -0
  242. package/dist/test/unit/interpreter/verdict-builtins.test.js.map +1 -0
  243. package/dist/test/unit/list-numeric-fail-loud.test.d.ts +2 -0
  244. package/dist/test/unit/list-numeric-fail-loud.test.d.ts.map +1 -0
  245. package/dist/test/unit/list-numeric-fail-loud.test.js +83 -0
  246. package/dist/test/unit/list-numeric-fail-loud.test.js.map +1 -0
  247. package/dist/test/unit/lossless-mirror.test.d.ts +2 -0
  248. package/dist/test/unit/lossless-mirror.test.d.ts.map +1 -0
  249. package/dist/test/unit/lossless-mirror.test.js +41 -0
  250. package/dist/test/unit/lossless-mirror.test.js.map +1 -0
  251. package/dist/test/unit/lossless-reflow.test.d.ts +2 -0
  252. package/dist/test/unit/lossless-reflow.test.d.ts.map +1 -0
  253. package/dist/test/unit/lossless-reflow.test.js +84 -0
  254. package/dist/test/unit/lossless-reflow.test.js.map +1 -0
  255. package/dist/test/unit/lowering/lowering.test.js +35 -35
  256. package/dist/test/unit/lowering/lowering.test.js.map +1 -1
  257. package/dist/test/unit/lsp/control-completion.test.d.ts +2 -0
  258. package/dist/test/unit/lsp/control-completion.test.d.ts.map +1 -0
  259. package/dist/test/unit/lsp/control-completion.test.js +46 -0
  260. package/dist/test/unit/lsp/control-completion.test.js.map +1 -0
  261. package/dist/test/unit/lsp/debounce-map.test.d.ts +2 -0
  262. package/dist/test/unit/lsp/debounce-map.test.d.ts.map +1 -0
  263. package/dist/test/unit/lsp/debounce-map.test.js +47 -0
  264. package/dist/test/unit/lsp/debounce-map.test.js.map +1 -0
  265. package/dist/test/unit/lsp/file-watcher-restart.test.d.ts +2 -0
  266. package/dist/test/unit/lsp/file-watcher-restart.test.d.ts.map +1 -0
  267. package/dist/test/unit/lsp/file-watcher-restart.test.js +40 -0
  268. package/dist/test/unit/lsp/file-watcher-restart.test.js.map +1 -0
  269. package/dist/test/unit/manifest-parser.test.js +8 -0
  270. package/dist/test/unit/manifest-parser.test.js.map +1 -1
  271. package/dist/test/unit/manifest-schema.test.d.ts +7 -5
  272. package/dist/test/unit/manifest-schema.test.d.ts.map +1 -1
  273. package/dist/test/unit/manifest-schema.test.js +48 -10
  274. package/dist/test/unit/manifest-schema.test.js.map +1 -1
  275. package/dist/test/unit/mapping/redos-budget.test.js +60 -23
  276. package/dist/test/unit/mapping/redos-budget.test.js.map +1 -1
  277. package/dist/test/unit/parser/governance-sugar.test.d.ts +2 -0
  278. package/dist/test/unit/parser/governance-sugar.test.d.ts.map +1 -0
  279. package/dist/test/unit/parser/governance-sugar.test.js +258 -0
  280. package/dist/test/unit/parser/governance-sugar.test.js.map +1 -0
  281. package/dist/test/unit/parser/module-header.test.d.ts +2 -0
  282. package/dist/test/unit/parser/module-header.test.d.ts.map +1 -0
  283. package/dist/test/unit/parser/module-header.test.js +25 -0
  284. package/dist/test/unit/parser/module-header.test.js.map +1 -0
  285. package/dist/test/unit/parser/positional-annotation-args.test.d.ts +2 -0
  286. package/dist/test/unit/parser/positional-annotation-args.test.d.ts.map +1 -0
  287. package/dist/test/unit/parser/positional-annotation-args.test.js +26 -0
  288. package/dist/test/unit/parser/positional-annotation-args.test.js.map +1 -0
  289. package/dist/test/unit/parser/prefix-operator-call.test.d.ts +2 -0
  290. package/dist/test/unit/parser/prefix-operator-call.test.d.ts.map +1 -0
  291. package/dist/test/unit/parser/prefix-operator-call.test.js +185 -0
  292. package/dist/test/unit/parser/prefix-operator-call.test.js.map +1 -0
  293. package/dist/test/unit/scripts/corpus-loader.test.d.ts +2 -0
  294. package/dist/test/unit/scripts/corpus-loader.test.d.ts.map +1 -0
  295. package/dist/test/unit/scripts/corpus-loader.test.js +85 -0
  296. package/dist/test/unit/scripts/corpus-loader.test.js.map +1 -0
  297. package/package.json +1 -1
@@ -0,0 +1,169 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { canonicalize } from '../../../src/frontend/canonicalizer.js';
6
+ import { lex } from '../../../src/frontend/lexer.js';
7
+ import { parse } from '../../../src/parser.js';
8
+ import { lowerModule } from '../../../src/lower_to_core.js';
9
+ import { typecheckModule } from '../../../src/typecheck.js';
10
+ import { typecheckBrowser } from '../../../src/typecheck/browser.js';
11
+ import { compileAndTypecheck } from '../../../src/browser.js';
12
+ import { Core } from '../../../src/core/core_ir.js';
13
+ import { checkGovernance, controls, returnsVerdict, ruleId } from '../../../src/typecheck/governance.js';
14
+ function coreOf(body) {
15
+ const src = `Module probe.\n${body}\n`;
16
+ const ast = parse(lex(canonicalize(src))).ast;
17
+ return lowerModule(ast);
18
+ }
19
+ function diagnoseFull(body) {
20
+ return typecheckModule(coreOf(body));
21
+ }
22
+ function diagnose(body) {
23
+ return diagnoseFull(body).map((d) => String(d.code));
24
+ }
25
+ /** 手工构造一个规则函数,用于覆盖 CNL 语法难以产出的 Core 形态。 */
26
+ function handFunc(name, body, annotations = []) {
27
+ return Core.Func(name, [], [], Core.TypeName('Unknown'), [], body, [], false, undefined, undefined, annotations);
28
+ }
29
+ const VERDICT_RULE = 'Rule main produce Verdict:\n Return Verdict.allow().';
30
+ test('返回 Verdict 且无 @id 报 W700', () => {
31
+ assert.ok(diagnose(VERDICT_RULE).includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
32
+ });
33
+ test('未声明返回类型但返回 Verdict 调用也报 W700', () => {
34
+ assert.ok(diagnose('Rule main produce:\n Return Verdict.deny("no").').includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
35
+ });
36
+ test('有 @id 不报 W700', () => {
37
+ assert.ok(!diagnose(`@id("R-1")\n${VERDICT_RULE}`).includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
38
+ });
39
+ test('返回 Bool 不报 W700', () => {
40
+ assert.ok(!diagnose('Rule main produce Bool:\n Return true.').includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
41
+ });
42
+ test('重复 @id 报恰好一个 E701,列出全部规则', () => {
43
+ const diags = diagnoseFull('@id("R-1")\nRule alpha produce Verdict:\n Return Verdict.allow().\n\n@id("R-1")\nRule beta produce Verdict:\n Return Verdict.allow().');
44
+ const dup = diags.filter((d) => d.code === "E701" /* ErrorCode.GOV_DUPLICATE_RULE_ID */);
45
+ assert.equal(dup.length, 1, diags.map((d) => d.code).join(','));
46
+ assert.equal(dup[0].data.rules, 'alpha, beta');
47
+ assert.equal(dup[0].data.id, 'R-1');
48
+ });
49
+ test('@id 非字符串报 E702', () => {
50
+ assert.ok(diagnose(`@id(42)\n${VERDICT_RULE}`).includes("E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */));
51
+ });
52
+ test('@id 命名参数报 E702', () => {
53
+ assert.ok(diagnose(`@id(value: "R-1")\n${VERDICT_RULE}`).includes("E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */));
54
+ });
55
+ test('@control 可重复', () => {
56
+ const codes = diagnose(`@id("R-1")\n@control("EU_AI_ACT:ART14")\n@control("GDPR:ART6")\n${VERDICT_RULE}`);
57
+ assert.equal(codes.filter((c) => c === 'W700' || c === 'E701' || c === 'E702').length, 0, codes.join(','));
58
+ });
59
+ test('用户 Define Verdict 报 DUPLICATE_SYMBOL', () => {
60
+ assert.ok(diagnose('Define Verdict has approved.\n\nRule main produce Bool:\n Return true.').includes("E104" /* ErrorCode.DUPLICATE_SYMBOL */));
61
+ });
62
+ test('空白 @id("") 报 E702 且同时报 W700', () => {
63
+ const codes = diagnose(`@id("")\n${VERDICT_RULE}`);
64
+ assert.ok(codes.includes("E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */), codes.join(','));
65
+ assert.ok(codes.includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), codes.join(','));
66
+ });
67
+ test('同一规则多个 @id 报 E702,ruleId 为空', () => {
68
+ const m = coreOf(`@id("A")\n@id("B")\n${VERDICT_RULE}`);
69
+ const diags = typecheckModule(m);
70
+ const e702 = diags.filter((d) => d.code === "E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */);
71
+ assert.equal(e702.length, 1, diags.map((d) => d.code).join(','));
72
+ assert.equal(e702[0].data.annotation, 'id');
73
+ const func = m.decls.find((d) => d.kind === 'Func');
74
+ assert.equal(ruleId(func), undefined);
75
+ });
76
+ test('@reason 非字符串报 E702', () => {
77
+ const diags = diagnoseFull(`@id("R-1")\n@reason(42)\n${VERDICT_RULE}`);
78
+ const e702 = diags.filter((d) => d.code === "E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */);
79
+ assert.equal(e702.length, 1, diags.map((d) => d.code).join(','));
80
+ assert.equal(e702[0].data.annotation, 'reason');
81
+ });
82
+ test('ruleId / controls 读取合法注解值', () => {
83
+ const m = coreOf(`@id("R-1")\n@control("EU_AI_ACT:ART14")\n@control("GDPR:ART6")\n@control("")\n${VERDICT_RULE}`);
84
+ const func = m.decls.find((d) => d.kind === 'Func');
85
+ assert.equal(ruleId(func), 'R-1');
86
+ assert.deepEqual(controls(func), ['EU_AI_ACT:ART14', 'GDPR:ART6']);
87
+ });
88
+ test('returnsVerdict 穿透 Block → Scope → Return(手工构造 Core IR)', () => {
89
+ const ret = Core.Return(Core.Call(Core.Name('Verdict.deny'), [Core.String('no')]));
90
+ const func = handFunc('main', Core.Block([Core.Scope([ret])]));
91
+ assert.equal(returnsVerdict(func), true);
92
+ const codes = checkGovernance({ name: 'probe', decls: [func] }).map((d) => d.code);
93
+ assert.deepEqual(codes, ["W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */]);
94
+ });
95
+ test('returnsVerdict 不经由变量判定', () => {
96
+ const body = Core.Block([
97
+ Core.Let('v', Core.Call(Core.Name('Verdict.allow'), [])),
98
+ Core.Return(Core.Name('v')),
99
+ ]);
100
+ assert.equal(returnsVerdict(handFunc('main', body)), false);
101
+ });
102
+ test('注解 name 为 null/undefined 不抛异常', () => {
103
+ const bogus = [{ name: null }, { name: undefined }];
104
+ const func = handFunc('main', Core.Block([Core.Return(Core.Bool(true))]), bogus);
105
+ assert.doesNotThrow(() => checkGovernance({ name: 'probe', decls: [func] }));
106
+ assert.deepEqual(checkGovernance({ name: 'probe', decls: [func] }), []);
107
+ assert.equal(ruleId(func), undefined);
108
+ assert.deepEqual(controls(func), []);
109
+ });
110
+ test('浏览器路径同样报 W700', () => {
111
+ const codes = typecheckBrowser(coreOf(VERDICT_RULE)).map((d) => String(d.code));
112
+ assert.ok(codes.includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), codes.join(','));
113
+ });
114
+ test('已登记控制点无 W704', () => {
115
+ const codes = diagnose(`@id("R-1")\n@control("EU_AI_ACT:ART14")\n${VERDICT_RULE}`);
116
+ assert.equal(codes.filter((c) => c === 'W704').length, 0, codes.join(','));
117
+ });
118
+ test('未登记与形态非法都报 W704,同键只报一次', () => {
119
+ const codes = diagnose(`@id("R-1")\n@control("ACME:ART1")\n@control("ACME:ART1")\n@control("eu_ai_act:art14")\n${VERDICT_RULE}`);
120
+ assert.equal(codes.filter((c) => c === 'W704').length, 2, codes.join(','));
121
+ });
122
+ test('注入空注册表时已登记键也报 W704', () => {
123
+ const empty = { version: '0.0.0', has: () => false };
124
+ const fn = handFunc('main', Core.Block([]), [
125
+ { name: 'id', args: [{ name: '$0', value: 'R-1' }] },
126
+ { name: 'control', args: [{ name: '$0', value: 'EU_AI_ACT:ART14' }] },
127
+ ]);
128
+ const diags = checkGovernance({ name: 'probe', decls: [fn] }, { controls: empty });
129
+ assert.ok(diags.some((d) => d.code === 'W704'), JSON.stringify(diags));
130
+ });
131
+ test('注入的注册表放行一切时形态非法键仍报 W704', () => {
132
+ const permissive = { version: 'x', has: () => true };
133
+ const body = `@id("R-1")\n@control("eu_ai_act:art14")\n${VERDICT_RULE}`;
134
+ const diags = typecheckModule(coreOf(body), { controls: permissive });
135
+ const w704 = diags.filter((d) => d.code === "W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */);
136
+ assert.equal(w704.length, 1, JSON.stringify(diags));
137
+ });
138
+ test('注入的注册表沿 Node / 浏览器 / compileAndTypecheck 透传', () => {
139
+ const empty = { version: '0.0.0', has: () => false };
140
+ const body = `@id("R-1")\n@control("EU_AI_ACT:ART14")\n${VERDICT_RULE}`;
141
+ const nodeCodes = typecheckModule(coreOf(body), { controls: empty }).map((d) => String(d.code));
142
+ const browserCodes = typecheckBrowser(coreOf(body), { controls: empty }).map((d) => String(d.code));
143
+ const compiled = compileAndTypecheck(`Module probe.\n${body}\n`, { controls: empty });
144
+ const compiledCodes = compiled.typeErrors.map((d) => String(d.code));
145
+ for (const codes of [nodeCodes, browserCodes, compiledCodes]) {
146
+ assert.ok(codes.includes("W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */), codes.join(','));
147
+ }
148
+ });
149
+ // 诊断黄金(ADR 0045 §3):源文在 aster-lang-test tier3 type-checker 桶,期望在本仓 expected/;
150
+ // 既有 golden 回归脚本读 npm 版语料,新源文发布前读不到,故直读兄弟仓(本地 ../ 或 CI 工作区 ./)。
151
+ // CI 的 test job 会 checkout aster-lang-test,因此 CI 中缺失即失败;仅本地未并列 checkout 时跳过。
152
+ test('W704 诊断黄金与期望文件一致', (t) => {
153
+ const name = 'governance_control_unregistered';
154
+ const relative = ['corpus', 'tier3-fixtures', 'type-checker', `${name}.aster`];
155
+ const source = [
156
+ join(process.cwd(), '..', 'aster-lang-test', ...relative),
157
+ join(process.cwd(), 'aster-lang-test', ...relative),
158
+ ].find((c) => existsSync(c));
159
+ if (source === undefined) {
160
+ assert.ok(!process.env.CI, 'CI 中须 checkout aster-lang-test(见 .github/workflows/ci.yml test job)');
161
+ return t.skip('aster-lang-test 未并列 checkout');
162
+ }
163
+ const ast = parse(lex(canonicalize(readFileSync(source, 'utf8')))).ast;
164
+ const actual = typecheckModule(lowerModule(ast)).map(({ code, severity, message }) => ({ code, severity, message }));
165
+ const expectedPath = join(process.cwd(), 'test', 'type-checker', 'expected', `${name}.errors.json`);
166
+ const expected = JSON.parse(readFileSync(expectedPath, 'utf8')).diagnostics;
167
+ assert.deepEqual(actual, expected);
168
+ });
169
+ //# sourceMappingURL=governance-check.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance-check.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/governance-check.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=profile-check.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-check.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/profile-check.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,139 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { canonicalize } from '../../../src/frontend/canonicalizer.js';
4
+ import { lex } from '../../../src/frontend/lexer.js';
5
+ import { parse } from '../../../src/parser.js';
6
+ import { lowerModule } from '../../../src/lower_to_core.js';
7
+ import { typecheckModule } from '../../../src/typecheck.js';
8
+ import { typecheckBrowser } from '../../../src/typecheck/browser.js';
9
+ import { controlRegistryFrom, defaultControlRegistry } from '../../../src/governance/controls.js';
10
+ // ADR 0046 §4:档案检查。场景与 Java ProfileCheckTest 逐条对应(源码、错误码、数量、消息子串一致)。
11
+ function diagnoseSource(src, controls) {
12
+ const ast = parse(lex(canonicalize(src))).ast;
13
+ return typecheckModule(lowerModule(ast), controls ? { controls } : {});
14
+ }
15
+ /** 声明了档案的探针模块源码。 */
16
+ function profiled(id, body) {
17
+ return `Module probe.\nProfile "${id}".\n\n${body}\n`;
18
+ }
19
+ function count(d, code) {
20
+ return d.filter((x) => x.code === code).length;
21
+ }
22
+ /** 拼接某错误码的全部消息,便于断言包含关系。 */
23
+ function messages(d, code) {
24
+ return d.filter((x) => x.code === code).map((x) => x.message).join('\n');
25
+ }
26
+ const show = (d) => JSON.stringify(d.map(({ code, message }) => ({ code, message })));
27
+ test('未知档案报 E705', () => {
28
+ const diags = diagnoseSource('Module m.\nProfile "nope".\n\nRule r produce Int:\n Return 1.\n');
29
+ assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
30
+ assert.ok(messages(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).includes("unknown profile 'nope' (controls registry 1.1.0)"));
31
+ const e705 = diags.find((d) => d.code === "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */);
32
+ assert.equal(e705.span?.start.line, 1, 'E705 应定位到 Module 声明行');
33
+ });
34
+ test('缺 @id 报 E706 且 W700 照常', () => {
35
+ const diags = diagnoseSource(profiled('governed', 'Rule r produce Verdict:\n Return Verdict.allow().'));
36
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 1, show(diags));
37
+ assert.equal(count(diags, "W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), 1);
38
+ assert.ok(messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */).includes("Rule 'r' violates profile 'governed': missing @id"));
39
+ const e706 = diags.find((d) => d.code === "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */);
40
+ assert.ok(e706.span !== undefined, 'E706 应定位到规则');
41
+ });
42
+ test('未登记控制点报 E706', () => {
43
+ const diags = diagnoseSource(profiled('governed', '@id("R-1")\n@control("ACME:ART1")\nRule r produce Verdict:\n Return Verdict.allow().'));
44
+ assert.ok(messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */).includes('unregistered control ACME:ART1'), show(diags));
45
+ assert.equal(count(diags, "W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */), 1);
46
+ });
47
+ test('重复控制点每条要求只报一次', () => {
48
+ const diags = diagnoseSource(profiled('governed', '@id("R-1")\n@control("ACME:ART1")\n@control("ACME:ART1")\nRule r produce Verdict:\n Return Verdict.allow().'));
49
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 1, show(diags));
50
+ });
51
+ test('缺所需框架控制点报 E706', () => {
52
+ const diags = diagnoseSource(profiled('eu-ai-act-high-risk', '@id("R-1")\n@control("GDPR:ART6")\nRule r produce Verdict:\n Return Verdict.allow().'));
53
+ assert.ok(messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */).includes('no registered control from framework EU_AI_ACT'), show(diags));
54
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 1);
55
+ });
56
+ test('合规规则零 E70x', () => {
57
+ const diags = diagnoseSource(profiled('eu-ai-act-high-risk', '@id("R-1")\n@control("EU_AI_ACT:ART14")\nRule r produce Verdict:\n Return Verdict.allow().'));
58
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */) + count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 0, show(diags));
59
+ });
60
+ test('非 Verdict 规则不受档案约束', () => {
61
+ const diags = diagnoseSource(profiled('governed', 'Rule helper produce Int:\n Return 1.'));
62
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 0, show(diags));
63
+ });
64
+ test('未声明档案的模块零 E70x', () => {
65
+ const diags = diagnoseSource('Module m.\n\nRule r produce Verdict:\n Return Verdict.allow().\n');
66
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */) + count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 0, show(diags));
67
+ });
68
+ test('未知档案下缺 @id 的 Verdict 规则只报 E705 与 W700', () => {
69
+ const diags = diagnoseSource('Module m.\nProfile "nope".\n\nRule r produce Verdict:\n Return Verdict.allow().\n');
70
+ assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
71
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 0, show(diags));
72
+ assert.equal(count(diags, "W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), 1, show(diags));
73
+ });
74
+ test('高风险档案下未登记的同框架键同时违反两条要求', () => {
75
+ const diags = diagnoseSource(profiled('eu-ai-act-high-risk', '@id("R-1")\n@control("EU_AI_ACT:ART99")\nRule r produce Verdict:\n Return Verdict.allow().'));
76
+ const e706 = messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */);
77
+ assert.ok(e706.includes('unregistered control EU_AI_ACT:ART99'), show(diags));
78
+ assert.ok(e706.includes('no registered control from framework EU_AI_ACT'), show(diags));
79
+ assert.equal(count(diags, "W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */), 1, show(diags));
80
+ });
81
+ test('注入的注册表携带自定义档案与框架', () => {
82
+ const custom = controlRegistryFrom({
83
+ version: '9.9.9',
84
+ // 档案引用的框架须在根 frameworks 中登记,否则档案不登记
85
+ frameworks: [
86
+ { id: 'ACME', title: { en: 'a', zh: 'a', de: 'a' } },
87
+ { id: 'SOX', title: { en: 's', zh: 's', de: 's' } },
88
+ ],
89
+ controls: [
90
+ { key: 'ACME:ART1', framework: 'ACME', article: '1', title: { en: 'a', zh: 'a', de: 'a' } },
91
+ { key: 'acme:bad', framework: 'ACME', article: 'x', title: { en: 'b', zh: 'b', de: 'b' } },
92
+ ],
93
+ clauses: [],
94
+ profiles: [
95
+ { id: 'acme', title: { en: 'a', zh: 'a', de: 'a' }, requires: { ruleId: false, registeredControls: true, frameworks: ['ACME', 'SOX'] } },
96
+ ],
97
+ });
98
+ const ok = diagnoseSource(profiled('acme', '@control("ACME:ART1")\nRule r produce Verdict:\n Return Verdict.allow().'), custom);
99
+ assert.equal(count(ok, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */) + count(ok, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 0, show(ok));
100
+ // 形态非法键即便在注入数据中登记也不算已登记,亦不覆盖框架
101
+ const bad = diagnoseSource(profiled('acme', '@control("acme:bad")\nRule r produce Verdict:\n Return Verdict.allow().'), custom);
102
+ const e706 = messages(bad, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */);
103
+ assert.ok(e706.includes('unregistered control acme:bad'), show(bad));
104
+ assert.ok(e706.includes('no registered control from framework ACME, SOX'), show(bad));
105
+ // 默认档案在自定义注册表中不存在
106
+ const unknown = diagnoseSource(profiled('governed', 'Rule h produce Int:\n Return 1.'), custom);
107
+ assert.ok(messages(unknown, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).includes("unknown profile 'governed' (controls registry 9.9.9)"), show(unknown));
108
+ });
109
+ test('只含 version/has 的手写注册表视为无档案', () => {
110
+ const minimal = { version: '0.1.0', has: (k) => defaultControlRegistry.has(k) };
111
+ const diags = diagnoseSource(profiled('governed', '@id("R-1")\nRule r produce Verdict:\n Return Verdict.allow().'), minimal);
112
+ assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
113
+ assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 0, show(diags));
114
+ });
115
+ test('默认注册表含档案与框架归属', () => {
116
+ assert.equal(defaultControlRegistry.version, '1.1.0');
117
+ assert.deepEqual(defaultControlRegistry.profile?.('governed'), { id: 'governed', ruleId: true, registeredControls: true, frameworks: [] });
118
+ assert.deepEqual(defaultControlRegistry.profile?.('eu-ai-act-high-risk')?.frameworks, ['EU_AI_ACT']);
119
+ assert.equal(defaultControlRegistry.profile?.('nope'), undefined);
120
+ assert.equal(defaultControlRegistry.frameworkOf?.('EU_AI_ACT:ART14'), 'EU_AI_ACT');
121
+ });
122
+ test('缺 profiles 的输入视为空档案', () => {
123
+ const r = controlRegistryFrom({
124
+ version: '9',
125
+ frameworks: [],
126
+ controls: [{ key: 'A:B', framework: 'A', article: 'B', title: { en: 'a', zh: 'a', de: 'a' } }],
127
+ clauses: [],
128
+ });
129
+ assert.equal(r.profile?.('governed'), undefined);
130
+ assert.equal(r.has('A:B'), true);
131
+ });
132
+ test('浏览器类型检查路径同样报 E705', () => {
133
+ const src = 'Module m.\nProfile "nope".\n\nRule r produce Int:\n Return 1.\n';
134
+ const core = lowerModule(parse(lex(canonicalize(src))).ast);
135
+ const diags = typecheckBrowser(core);
136
+ assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
137
+ assert.ok(messages(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).includes("unknown profile 'nope' (controls registry 1.1.0)"));
138
+ });
139
+ //# sourceMappingURL=profile-check.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-check.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/profile-check.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verdict-typecheck.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-typecheck.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/verdict-typecheck.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,80 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { canonicalize } from '../../../src/frontend/canonicalizer.js';
4
+ import { lex } from '../../../src/frontend/lexer.js';
5
+ import { parse } from '../../../src/parser.js';
6
+ import { lowerModule } from '../../../src/lower_to_core.js';
7
+ import { typecheckModule } from '../../../src/typecheck.js';
8
+ function diagnose(body) {
9
+ const src = `Module probe.\n${body}\n`;
10
+ const ast = parse(lex(canonicalize(src))).ast;
11
+ const core = lowerModule(ast);
12
+ return typecheckModule(core).map((d) => String(d.code));
13
+ }
14
+ test('produce Verdict 不被当成类型参数,allow 通过', () => {
15
+ const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.allow().');
16
+ assert.ok(!codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
17
+ assert.ok(!codes.includes("E212" /* ErrorCode.EFF_INFER_UNKNOWN_BUILTIN */), codes.join(','));
18
+ });
19
+ test('produce Bool 返回 Verdict 报 E003', () => {
20
+ const codes = diagnose('@id("R-1")\nRule main produce Bool:\n Return Verdict.allow().');
21
+ assert.ok(codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
22
+ });
23
+ test('两个分支类型不一致报错', () => {
24
+ // 两引擎均在 If 分支汇合处报不一致(与 Java 侧裁定一致),返回 then 分支类型
25
+ const codes = diagnose('@id("R-1")\nRule main given x, produce Verdict:\n If x equals to 1:\n Return Verdict.allow().\n Otherwise:\n Return true.');
26
+ assert.ok(codes.includes("E008" /* ErrorCode.IF_BRANCH_MISMATCH */) || codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
27
+ });
28
+ test('deny 缺参数报 E703', () => {
29
+ const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.deny().');
30
+ assert.ok(codes.includes("E703" /* ErrorCode.GOV_VERDICT_CALL_ARITY */), codes.join(','));
31
+ });
32
+ test('deny 非 Text 参数报类型不匹配', () => {
33
+ const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.deny(42).');
34
+ assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
35
+ });
36
+ test('require_approval 两个 Text 通过', () => {
37
+ const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.require_approval("Senior Underwriter", "over cap").');
38
+ assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
39
+ });
40
+ // ===== Verdict 不可当布尔用(ADR 0039 §2.2,评审 C1;Java VerdictTypeCheckTest 镜像)=====
41
+ test('If 条件为 Verdict 报类型不匹配', () => {
42
+ const codes = diagnose('@id("R-1")\nRule main produce Text:\n Let v be Verdict.deny("x").\n If v:\n Return "yes".\n Return "no".');
43
+ assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
44
+ });
45
+ test('not 作用于 Verdict 报类型不匹配', () => {
46
+ const codes = diagnose('@id("R-1")\nRule main produce Bool:\n Let v be Verdict.deny("x").\n Return not v.');
47
+ assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
48
+ });
49
+ test('Verdict 与 true 相等比较报类型不匹配', () => {
50
+ const codes = diagnose('@id("R-1")\nRule main produce Bool:\n Let v be Verdict.deny("x").\n Return v equals to true.');
51
+ assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
52
+ });
53
+ // ===== Text 形参可作 reason/role(评审 I1)=====
54
+ test('Text 形参作 reason 通过', () => {
55
+ const codes = diagnose('@id("R-1")\nRule main given reason as Text, produce Verdict:\n Return Verdict.deny(reason).');
56
+ assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
57
+ });
58
+ test('Text 形参作 role 与 reason 通过', () => {
59
+ const codes = diagnose('@id("R-1")\nRule main given role as Text, reason as Text, produce Verdict:\n Return Verdict.require_approval(role, reason).');
60
+ assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
61
+ });
62
+ test('个数不符时仍检查参数内未定义名', () => {
63
+ const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.allow(missing_name).');
64
+ assert.ok(codes.includes("E703" /* ErrorCode.GOV_VERDICT_CALL_ARITY */), codes.join(','));
65
+ assert.ok(codes.includes("E101" /* ErrorCode.UNDEFINED_VARIABLE */), codes.join(','));
66
+ });
67
+ // ===== Verdict 字段 outcome/role/reason 为 Text(评审 I2)=====
68
+ test('读取 outcome 得到 Text', () => {
69
+ const codes = diagnose('Rule main produce Text:\n Let d be Verdict.deny("x").\n Return d.outcome.');
70
+ assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
71
+ });
72
+ test('Verdict 字段类型为 Text 而非 Unknown', () => {
73
+ const codes = diagnose('Rule main produce Int:\n Let d be Verdict.require_approval("r", "x").\n Return d.role.');
74
+ assert.ok(codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
75
+ });
76
+ test('Verdict 未知字段仍报 E011', () => {
77
+ const codes = diagnose('Rule main produce Text:\n Let d be Verdict.deny("x").\n Return d.verdict.');
78
+ assert.ok(codes.includes("E011" /* ErrorCode.UNKNOWN_FIELD */), codes.join(','));
79
+ });
80
+ //# sourceMappingURL=verdict-typecheck.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-typecheck.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/verdict-typecheck.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verdict-builtins.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-builtins.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/interpreter/verdict-builtins.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { compile } from '../../../src/browser.js';
4
+ import { evaluate } from '../../../src/core/interpreter.js';
5
+ function run(body, context = {}) {
6
+ const m = compile(`Module probe.\n@id("R-1")\n${body}\n`);
7
+ assert.ok(m.core, JSON.stringify(m));
8
+ return evaluate(m.core, 'main', context, { maxSteps: 10_000 });
9
+ }
10
+ test('allow 形状与键序', () => {
11
+ const ev = run('Rule main produce Verdict:\n Return Verdict.allow().');
12
+ assert.equal(ev.success, true);
13
+ assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"ALLOW"}');
14
+ });
15
+ test('deny 带 reason', () => {
16
+ const ev = run('Rule main produce Verdict:\n Return Verdict.deny("no consent").');
17
+ assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"DENY","reason":"no consent"}');
18
+ });
19
+ test('require_approval 键序 role 在 reason 前', () => {
20
+ const ev = run('Rule main produce Verdict:\n Return Verdict.require_approval("Senior Underwriter", "over cap").');
21
+ assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"REQUIRE_APPROVAL","role":"Senior Underwriter","reason":"over cap"}');
22
+ });
23
+ test('escalate', () => {
24
+ const ev = run('Rule main produce Verdict:\n Return Verdict.escalate("low confidence").');
25
+ assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"ESCALATE","reason":"low confidence"}');
26
+ });
27
+ test('空 reason 运行时失败', () => {
28
+ const ev = run('Rule main produce Verdict:\n Return Verdict.deny("").');
29
+ assert.equal(ev.success, false);
30
+ assert.match(String(ev.error), /Verdict\.deny/);
31
+ });
32
+ test('reason 为非 Text 变量时运行时失败', () => {
33
+ const ev = run('Rule main given n, produce Verdict:\n Return Verdict.deny(n).', { n: 42 });
34
+ assert.equal(ev.success, false);
35
+ assert.match(String(ev.error), /Verdict\.deny/);
36
+ });
37
+ test('空白 reason/role 运行时失败', () => {
38
+ const deny = run('Rule main produce Verdict:\n Return Verdict.deny(" ").');
39
+ assert.equal(deny.success, false);
40
+ assert.match(String(deny.error), /Verdict\.deny: reason must not be empty/);
41
+ const approval = run('Rule main given role as Text, produce Verdict:\n Return Verdict.require_approval(role, "over cap").', { role: ' \t' });
42
+ assert.equal(approval.success, false);
43
+ assert.match(String(approval.error), /Verdict\.require_approval: role must not be empty/);
44
+ });
45
+ // ===== Verdict 在布尔上下文 fail-closed(ADR 0039 §2.2,评审 C1;truffle VerdictBuiltinsTest 镜像)=====
46
+ // 类型检查会拒绝这些程序;此处直接构造 Core IR 绕过检查器,验证运行时这道最后防线。
47
+ function runCore(statements) {
48
+ const core = {
49
+ kind: 'Module', name: 'probe', decls: [{
50
+ kind: 'Func', name: 'main', typeParams: [], params: [], ret: { kind: 'TypeName', name: 'Text' },
51
+ effects: [], effectCaps: [], effectCapsExplicit: false, body: { kind: 'Block', statements },
52
+ }],
53
+ };
54
+ return evaluate(core, 'main', {}, { maxSteps: 10_000 });
55
+ }
56
+ const letDeny = { kind: 'Let', name: 'v', expr: { kind: 'Call', target: { kind: 'Name', name: 'Verdict.deny' }, args: [{ kind: 'String', value: 'no consent' }] } };
57
+ const ret = (value) => ({ kind: 'Return', expr: { kind: 'String', value } });
58
+ test('If 条件为 Verdict 时求值失败而非放行', () => {
59
+ const ev = runCore([
60
+ letDeny,
61
+ { kind: 'If', cond: { kind: 'Name', name: 'v' }, thenBlock: { kind: 'Block', statements: [ret('approved')] }, elseBlock: null },
62
+ ret('rejected'),
63
+ ]);
64
+ assert.equal(ev.success, false);
65
+ assert.match(String(ev.error), /Verdict cannot be used as Bool/);
66
+ });
67
+ test('not 作用于 Verdict 时求值失败', () => {
68
+ const ev = runCore([letDeny, { kind: 'Return', expr: { kind: 'Call', target: { kind: 'Name', name: 'not' }, args: [{ kind: 'Name', name: 'v' }] } }]);
69
+ assert.equal(ev.success, false);
70
+ assert.match(String(ev.error), /Verdict cannot be used as Bool/);
71
+ });
72
+ //# sourceMappingURL=verdict-builtins.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-builtins.test.js","sourceRoot":"","sources":["../../../../test/unit/interpreter/verdict-builtins.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=list-numeric-fail-loud.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-numeric-fail-loud.test.d.ts","sourceRoot":"","sources":["../../../test/unit/list-numeric-fail-loud.test.ts"],"names":[],"mappings":""}