@aster-cloud/aster-lang-ts 1.0.34 → 1.0.36

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 (45) hide show
  1. package/dist/src/core/inferred_fields.d.ts +6 -0
  2. package/dist/src/core/inferred_fields.d.ts.map +1 -0
  3. package/dist/src/core/inferred_fields.js +29 -0
  4. package/dist/src/core/inferred_fields.js.map +1 -0
  5. package/dist/src/index.d.ts +14 -0
  6. package/dist/src/index.d.ts.map +1 -1
  7. package/dist/src/index.js +11 -0
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/lower_to_core.d.ts.map +1 -1
  10. package/dist/src/lower_to_core.js +12 -5
  11. package/dist/src/lower_to_core.js.map +1 -1
  12. package/dist/src/mapping/pipeline.d.ts +87 -0
  13. package/dist/src/mapping/pipeline.d.ts.map +1 -0
  14. package/dist/src/mapping/pipeline.js +145 -0
  15. package/dist/src/mapping/pipeline.js.map +1 -0
  16. package/dist/src/mapping/quantity-ir.js +68 -5
  17. package/dist/src/mapping/quantity-ir.js.map +1 -1
  18. package/dist/src/mapping/review-queue.d.ts +92 -0
  19. package/dist/src/mapping/review-queue.d.ts.map +1 -0
  20. package/dist/src/mapping/review-queue.js +105 -0
  21. package/dist/src/mapping/review-queue.js.map +1 -0
  22. package/dist/src/typecheck/expression.d.ts.map +1 -1
  23. package/dist/src/typecheck/expression.js +6 -1
  24. package/dist/src/typecheck/expression.js.map +1 -1
  25. package/dist/test/unit/mapping/bridge-parity.test.d.ts +2 -0
  26. package/dist/test/unit/mapping/bridge-parity.test.d.ts.map +1 -0
  27. package/dist/test/unit/mapping/bridge-parity.test.js +74 -0
  28. package/dist/test/unit/mapping/bridge-parity.test.js.map +1 -0
  29. package/dist/test/unit/mapping/pipeline.test.d.ts +2 -0
  30. package/dist/test/unit/mapping/pipeline.test.d.ts.map +1 -0
  31. package/dist/test/unit/mapping/pipeline.test.js +108 -0
  32. package/dist/test/unit/mapping/pipeline.test.js.map +1 -0
  33. package/dist/test/unit/mapping/review-queue.test.d.ts +2 -0
  34. package/dist/test/unit/mapping/review-queue.test.d.ts.map +1 -0
  35. package/dist/test/unit/mapping/review-queue.test.js +112 -0
  36. package/dist/test/unit/mapping/review-queue.test.js.map +1 -0
  37. package/dist/test/unit/mapping/verdict-parity.test.d.ts +2 -0
  38. package/dist/test/unit/mapping/verdict-parity.test.d.ts.map +1 -0
  39. package/dist/test/unit/mapping/verdict-parity.test.js +85 -0
  40. package/dist/test/unit/mapping/verdict-parity.test.js.map +1 -0
  41. package/dist/test/unit/typecheck/untyped-field-dynamic.test.d.ts +2 -0
  42. package/dist/test/unit/typecheck/untyped-field-dynamic.test.d.ts.map +1 -0
  43. package/dist/test/unit/typecheck/untyped-field-dynamic.test.js +172 -0
  44. package/dist/test/unit/typecheck/untyped-field-dynamic.test.js.map +1 -0
  45. package/package.json +1 -1
@@ -0,0 +1,112 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { buildReviewQueue, recordHumanProof } from '../../../src/mapping/review-queue.js';
4
+ import { isApplicableTo } from '../../../src/mapping/proof-ir.js';
5
+ /**
6
+ * 三段式第③段:人工复核队列(ADR 0037 §3)。
7
+ *
8
+ * <p>核心契约:**机器只做前两段,Proof 只能由人产出**。
9
+ */
10
+ const DOC = [
11
+ 'Module policy.payment.',
12
+ '',
13
+ 'Rule approve, produce:',
14
+ ' Return 10000.',
15
+ '',
16
+ ].join('\n');
17
+ /** 假 provider:返回预置 JSON,记录收到的请求。 */
18
+ function fakeProvider(reply) {
19
+ const p = {
20
+ calls: 0,
21
+ async generate(_req) {
22
+ p.calls++;
23
+ return {
24
+ content: reply, model: 'test-model',
25
+ usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
26
+ };
27
+ },
28
+ getName: () => 'fake',
29
+ getModel: () => 'test-model',
30
+ };
31
+ return p;
32
+ }
33
+ describe('复核队列 — 不传 provider(LLM 是可选增强)', () => {
34
+ it('★没有 LLM 时整条链路照样跑', () => {
35
+ // ★LLM 不得成为主链路依赖。没有它,映射类验证仍然完整。
36
+ return buildReviewQueue(DOC).then(q => {
37
+ assert.ok(q.counts.verified >= 1, `应有已证明的候选,实际 ${JSON.stringify(q.counts)}`);
38
+ assert.strictEqual(q.items.filter(i => i.source.kind === 'ENTITY').length, 0, '未传 provider 时不应有 Entity 类待复核项。');
39
+ });
40
+ });
41
+ });
42
+ describe('复核队列 — 传 provider(三段式完整)', () => {
43
+ it('★LLM 候选必须落在待复核队列,而不是被当成结论', () => {
44
+ // ADR §3:AI 可以提出映射,但不能定义什么叫正确。
45
+ const reply = JSON.stringify([
46
+ { text: 'approve', kind: 'Role', start: DOC.indexOf('approve') },
47
+ ]);
48
+ const p = fakeProvider(reply);
49
+ return buildReviewQueue(DOC, p).then(q => {
50
+ assert.strictEqual(p.calls, 1, 'provider 应被调用一次。');
51
+ const entities = q.items.filter(i => i.source.kind === 'ENTITY');
52
+ assert.strictEqual(entities.length, 1, `LLM 候选应进入待复核队列,实际 ${JSON.stringify(q.items)}`);
53
+ assert.match(entities[0].reason, /语义/, '待复核理由应说明这是语义判断(机器证不了)。');
54
+ });
55
+ });
56
+ it('★LLM 的幻觉必须被拦下并**如实报告**,不得静默丢弃', () => {
57
+ // 位置错的候选——最常见也最危险的幻觉(会让双向导航跳错位置)。
58
+ const reply = JSON.stringify([{ text: 'approve', kind: 'Role', start: 0 }]);
59
+ const p = fakeProvider(reply);
60
+ return buildReviewQueue(DOC, p).then(q => {
61
+ assert.strictEqual(q.items.filter(i => i.source.kind === 'ENTITY').length, 0, '位置错的候选必须被丢弃。');
62
+ assert.ok(q.diagnostics.some(d => d.includes('LLM 提案被丢弃')), `丢弃必须如实报告——那是评估模型可靠性最重要的信号。实际:${JSON.stringify(q.diagnostics)}`);
63
+ });
64
+ });
65
+ it('★LLM 失败不得让整条链路失败', () => {
66
+ // ★降级而非全盘失败:映射类结果与 LLM 无关,必须保留。
67
+ const broken = {
68
+ async generate() { throw new Error('connection refused'); },
69
+ getName: () => 'broken',
70
+ getModel: () => 'x',
71
+ };
72
+ return buildReviewQueue(DOC, broken).then(q => {
73
+ assert.ok(q.counts.verified >= 1, 'LLM 挂了,但映射类验证结果必须仍然有效。');
74
+ assert.ok(q.diagnostics.some(d => d.includes('Entity 提出失败')), '必须说明 LLM 为何没跑。');
75
+ });
76
+ });
77
+ });
78
+ describe('人工复核 — Proof 只能由人产出', () => {
79
+ const item = {
80
+ text: '10000',
81
+ span: { start: 0, end: 5 },
82
+ reason: '需人工确认',
83
+ source: { kind: 'MAPPING', nodeId: '$.decls{approve}.body.statements[0].expr' },
84
+ };
85
+ it('★产出的 Proof 必须锚定到真实节点的 contentHash', () => {
86
+ const proof = recordHumanProof(DOC, item, item.source.nodeId, { kind: 'DOMAIN_EXPERT', by: 'alice@example.com' }, 'VERIFIED', '该金额与业务规则一致,已与财务核对。', '2026-09-14T00:00:00Z');
87
+ assert.strictEqual(proof.subject.kind, 'DOMAIN_EXPERT');
88
+ assert.ok(proof.verifiedAgainst.contentHash.length === 64, `contentHash 应是 SHA-256 十六进制,实际 ${proof.verifiedAgainst.contentHash}`);
89
+ assert.strictEqual(proof.recordedAt, '2026-09-14T00:00:00Z', '时间必须由调用方传入——取系统时钟会让同一输入产出不同记录,无法复现。');
90
+ });
91
+ it('★空理由必须被拒绝(没有理由的批准等于没有复核)', () => {
92
+ assert.throws(() => recordHumanProof(DOC, item, item.source.nodeId, { kind: 'ENGINEER', by: 'bob' }, 'VERIFIED', ' ', '2026-09-14T00:00:00Z'), /理由不得为空/, '空壳 proof 没有任何审计价值,必须拒绝记录。');
93
+ });
94
+ it('★不存在的节点必须被拒绝', () => {
95
+ assert.throws(() => recordHumanProof(DOC, item, '$.nope', { kind: 'ENGINEER', by: 'bob' }, 'VERIFIED', '理由', '2026-09-14T00:00:00Z'), /节点不存在/, 'proof 必须锚定真实节点,否则它记录的是一个不存在之物的结论。');
96
+ });
97
+ it('★内容变了以后,旧 proof 必须被判为不再适用(而非悄悄沿用)', () => {
98
+ // ★这是 ProofIR 不可变设计的意义:proof 本身永不修改,
99
+ // "还适不适用"是**算出来**的。
100
+ const proof = recordHumanProof(DOC, item, item.source.nodeId, { kind: 'DOMAIN_EXPERT', by: 'alice' }, 'VERIFIED', '已核对。', '2026-09-14T00:00:00Z');
101
+ const same = isApplicableTo(proof, () => proof.verifiedAgainst.contentHash);
102
+ assert.strictEqual(same.applicable, true, '内容未变时应仍适用。');
103
+ const changed = isApplicableTo(proof, () => 'f'.repeat(64));
104
+ assert.strictEqual(changed.applicable, false, '内容变了必须判不适用。');
105
+ if (!changed.applicable) {
106
+ assert.strictEqual(changed.why, 'CONTENT_CHANGED');
107
+ }
108
+ const gone = isApplicableTo(proof, () => undefined);
109
+ assert.strictEqual(gone.applicable, false, '节点没了必须判不适用。');
110
+ });
111
+ });
112
+ //# sourceMappingURL=review-queue.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-queue.test.js","sourceRoot":"","sources":["../../../../test/unit/mapping/review-queue.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verdict-parity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-parity.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/mapping/verdict-parity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFileSync, existsSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, resolve } from 'node:path';
6
+ import { verifyMapping } from '../../../src/mapping/mapping-ir.js';
7
+ /**
8
+ * 双引擎 verifier 判定一致性(ADR 0037 §7)—— **TS 侧**。
9
+ *
10
+ * <h2>★§7 的要求是有区分的</h2>
11
+ *
12
+ * <pre>
13
+ * LLM 生成的 candidate → **不要求**一致
14
+ * Verifier 的结果 → **必须**一致
15
+ * </pre>
16
+ *
17
+ * 故本文件只钉 `verdict`,**不钉 `reason`**(后者含自然语言,两侧措辞允许不同)。
18
+ *
19
+ * <h2>语料是**共享**的</h2>
20
+ *
21
+ * 用例来自 `aster-lang-test/corpus/mapping-verdict/cases.json`,
22
+ * Java 侧 `MappingIrVerdictParityTest` 读**同一个文件**。
23
+ * ★这是"单源"——若两侧各抄一份,语料会各自漂移,而"一致性门禁"
24
+ * 本身就变成了两个互不相干的测试(本仓记过这个坑)。
25
+ */
26
+ const HERE = dirname(fileURLToPath(import.meta.url));
27
+ /**
28
+ * 共享语料路径。★**两种布局都要支持**:
29
+ *
30
+ * - **本地开发**:兄弟仓并列 → `<repo>/../aster-lang-test/...`
31
+ * - **CI**:`checkout-sibling` 用 `path: aster-lang-test` 把它检出到
32
+ * **工作区内** → `<repo>/aster-lang-test/...`
33
+ *
34
+ * ★路径从**编译产物** `dist/test/unit/mapping` 起算(不是源码目录)。
35
+ * 我第一版按源码目录数了 4 级、且只考虑了本地布局——前者当场红,
36
+ * 后者**本地通过但 CI 上必然失败**。路径类的东西必须实测,不能数目录。
37
+ */
38
+ const CORPUS = (() => {
39
+ const rel = 'corpus/mapping-verdict/cases.json';
40
+ for (const base of [
41
+ resolve(HERE, '../../../../aster-lang-test'), // CI:检出到工作区内
42
+ resolve(HERE, '../../../../../aster-lang-test'), // 本地:兄弟仓并列
43
+ ]) {
44
+ const p = resolve(base, rel);
45
+ if (existsSync(p))
46
+ return p;
47
+ }
48
+ // 都找不到时返回本地布局路径,让"语料必须存在"那条报出明确的缺失信息。
49
+ return resolve(HERE, '../../../../../aster-lang-test', rel);
50
+ })();
51
+ describe('双引擎 verifier 判定一致性 — TS 侧', () => {
52
+ it('★语料文件必须存在(缺失即门禁失效,不得静默跳过)', () => {
53
+ // ★若语料路径漂了而测试"跳过",这条门禁就会在无人察觉的情况下消失。
54
+ // 本仓记过「跳过看起来像通过」——此处显式断言存在性。
55
+ assert.ok(existsSync(CORPUS), `共享语料不存在:${CORPUS}\n`
56
+ + '★这条门禁依赖 aster-lang-test 作为兄弟仓 checkout。'
57
+ + '若路径变了必须同步修改两侧(Java 侧同名测试读同一文件)。');
58
+ });
59
+ it('★每条用例的判定必须与语料声明一致', () => {
60
+ const raw = JSON.parse(readFileSync(CORPUS, 'utf8'));
61
+ assert.ok(raw.cases.length >= 10, `语料用例过少(${raw.cases.length})——覆盖不了三种 verdict 的各种成因。`);
62
+ const seen = new Set();
63
+ for (const c of raw.cases) {
64
+ const node = c.node === null
65
+ ? undefined
66
+ : {
67
+ kind: c.node.kind,
68
+ ...(c.node.value === undefined ? {} : { value: c.node.value }),
69
+ ...(c.node.name === undefined ? {} : { name: c.node.name }),
70
+ };
71
+ const r = verifyMapping(c.mapping, () => node);
72
+ assert.strictEqual(r.verdict, c.expect, `用例「${c.name}」判定不符。\n`
73
+ + ` 期望 ${c.expect},实际 ${r.verdict}\n`
74
+ + ` 理由:${r.reason}\n`
75
+ + '★若 Java 侧同用例判定不同,即违反 ADR §7「Verifier 结果必须一致」。');
76
+ seen.add(r.verdict);
77
+ }
78
+ // ★反向守卫:三种 verdict 都必须被覆盖到,否则语料不足以证明一致性。
79
+ // 只覆盖 VERIFIED 的语料,挡不住"把所有输入都判 VERIFIED"这种实现。
80
+ for (const v of ['VERIFIED', 'REVIEW_REQUIRED', 'REJECTED']) {
81
+ assert.ok(seen.has(v), `语料未覆盖 ${v} —— 一致性门禁存在盲区。已覆盖:${[...seen].join(', ')}`);
82
+ }
83
+ });
84
+ });
85
+ //# sourceMappingURL=verdict-parity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict-parity.test.js","sourceRoot":"","sources":["../../../../test/unit/mapping/verdict-parity.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=untyped-field-dynamic.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"untyped-field-dynamic.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/typecheck/untyped-field-dynamic.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,172 @@
1
+ import { describe, test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFileSync } from 'node:fs';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { canonicalize } from '../../../src/frontend/canonicalizer.js';
7
+ import { lex } from '../../../src/frontend/lexer.js';
8
+ import { parse } from '../../../src/parser.js';
9
+ import { lowerModule } from '../../../src/lower_to_core.js';
10
+ import { typecheckModule } from '../../../src/typecheck.js';
11
+ import { compile } from '../../../src/browser.js';
12
+ import { evaluate } from '../../../src/core/interpreter.js';
13
+ import { Core } from '../../../src/core/core_ir.js';
14
+ import { typeOfExpr } from '../../../src/typecheck/expression.js';
15
+ import { SymbolTable } from '../../../src/typecheck/symbol_table.js';
16
+ import { DiagnosticBuilder } from '../../../src/typecheck/diagnostics.js';
17
+ import { isUnknown } from '../../../src/typecheck/pure.js';
18
+ /**
19
+ * 未声明类型的 data 字段(`Define X has a, b.`,没有 `as <Type>`)在成员访问时按动态类型处理。
20
+ *
21
+ * 背景:Action Guard 的 `context` 按设计是无类型 map(ADR 0040 §2.2),`req.context.amount`
22
+ * 需要通过类型检查。Java 引擎(aster-lang-core BaseTypeChecker)对点号名一律给 Unknown、
23
+ * 从不在成员访问上报 E011;TS 此前把无类型字段按命名推断成 Text,再对 `Text.amount` 报 E011,
24
+ * 导致同一程序 Java 接受、TS 拒绝。这里固定:无类型字段经成员访问得到 Unknown(不级联报错),
25
+ * 显式声明类型的字段仍保留 E011;运行时行为不变。
26
+ */
27
+ const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..');
28
+ const sample = readFileSync(join(repoRoot, 'test', 'fixtures', 'untyped-field', 'guard-cedar-sample.aster'), 'utf8');
29
+ function runTypecheck(source) {
30
+ const core = lowerModule(parse(lex(canonicalize(source))).ast);
31
+ return typecheckModule(core);
32
+ }
33
+ /** 在只含 `req: GuardRequest` 的作用域里求表达式类型,用于直接断言推断结果。 */
34
+ function typeOfDotted(core, dotted) {
35
+ const datas = new Map();
36
+ for (const d of core.decls)
37
+ if (d.kind === 'Data')
38
+ datas.set(d.name, d);
39
+ const ctx = {
40
+ datas,
41
+ enums: new Map(),
42
+ imports: new Map(),
43
+ funcSignatures: new Map(),
44
+ importedEffects: new Map(),
45
+ moduleSearchPaths: [],
46
+ };
47
+ const symbols = new SymbolTable();
48
+ symbols.define('req', Core.TypeName('GuardRequest'), 'param');
49
+ const diagnostics = new DiagnosticBuilder();
50
+ const type = typeOfExpr(ctx, symbols, Core.Name(dotted), diagnostics);
51
+ return { type, diags: diagnostics.getDiagnostics() };
52
+ }
53
+ function lowerSample() {
54
+ return lowerModule(parse(lex(canonicalize(sample))).ast);
55
+ }
56
+ function errors(diags) {
57
+ return diags.filter(d => d.severity === 'error');
58
+ }
59
+ describe('无类型字段按动态类型处理(与 Java 对齐)', () => {
60
+ test('guard-cedar-sample 类型检查零诊断', () => {
61
+ const diags = runTypecheck(sample);
62
+ assert.deepEqual(diags.map(d => `${d.code}: ${d.message}`), []);
63
+ });
64
+ test('显式类型的 record 访问未知字段仍报 E011', () => {
65
+ const diags = runTypecheck(`
66
+ Module test.typecheck.typed_unknown_field.
67
+
68
+ Define Req has action as Text, amount as Int.
69
+
70
+ Rule decide given req as Req, produce Bool:
71
+ Return req.nickname equals to "x".
72
+ `);
73
+ assert.equal(diags.some(d => d.code === "E011" /* ErrorCode.UNKNOWN_FIELD */), true);
74
+ });
75
+ test('显式 Text 字段上的成员访问仍报 E011', () => {
76
+ const diags = runTypecheck(`
77
+ Module test.typecheck.typed_text_member.
78
+
79
+ Define Req has context as Text.
80
+
81
+ Rule decide given req as Req, produce Bool:
82
+ Return req.context.amount at least 10000.
83
+ `);
84
+ assert.equal(diags.some(d => d.code === "E011" /* ErrorCode.UNKNOWN_FIELD */), true);
85
+ });
86
+ test('无类型标记不进入 Core IR(golden 与 TS↔Java 指纹不变)', () => {
87
+ const core = lowerModule(parse(lex(canonicalize(sample))).ast);
88
+ assert.equal(JSON.stringify(core).includes('typeInferred'), false);
89
+ });
90
+ test('req.context.amount 推断为 Unknown(钉住类型而非仅无诊断)', () => {
91
+ const { type, diags } = typeOfDotted(lowerSample(), 'req.context.amount');
92
+ assert.equal(isUnknown(type), true, JSON.stringify(type));
93
+ assert.deepEqual(diags, []);
94
+ });
95
+ test('无类型字段作为 Int 规则的返回值不报 E003', () => {
96
+ const diags = runTypecheck(`
97
+ Module test.typecheck.untyped_return.
98
+
99
+ Define Req has action, context.
100
+
101
+ Rule decide given req as Req, produce Int:
102
+ Return req.action.
103
+ `);
104
+ assert.deepEqual(errors(diags).map(d => `${d.code}: ${d.message}`), []);
105
+ });
106
+ test('无类型字段的成员访问作为 If 条件不报 E011', () => {
107
+ const diags = runTypecheck(`
108
+ Module test.typecheck.untyped_condition.
109
+
110
+ Define Req has action, context.
111
+
112
+ Rule decide given req as Req, produce Bool:
113
+ If req.context.flag:
114
+ Return true.
115
+ Return false.
116
+ `);
117
+ assert.deepEqual(errors(diags).map(d => `${d.code}: ${d.message}`), []);
118
+ });
119
+ test('JSON 往返后标记丢失,退回按推断类型检查(身份索引设计的已知局限)', () => {
120
+ const roundTripped = JSON.parse(JSON.stringify(lowerSample()));
121
+ const { diags } = typeOfDotted(roundTripped, 'req.context.amount');
122
+ assert.equal(diags.some(d => d.code === "E011" /* ErrorCode.UNKNOWN_FIELD */), true);
123
+ });
124
+ test('无类型字段用于比较、算术与 List.contains 均无错误', () => {
125
+ const diags = runTypecheck(`
126
+ Module test.typecheck.untyped_dynamic.
127
+
128
+ Define Req has principal_roles, context.
129
+
130
+ Rule decide given req as Req, produce Bool:
131
+ Let total be req.context.amount plus req.context.fee.
132
+ Let large be req.context.limits.refund at least 10000.
133
+ If List.contains(req.principal_roles, "x"):
134
+ Return large.
135
+ Return total greater than 5.
136
+ `);
137
+ assert.deepEqual(errors(diags).map(d => `${d.code}: ${d.message}`), []);
138
+ });
139
+ });
140
+ describe('guard-cedar-sample 运行时行为不变', () => {
141
+ const compiled = compile(sample);
142
+ assert.ok(compiled.core, JSON.stringify(compiled.diagnostics ?? []));
143
+ function outcome(req) {
144
+ const ev = evaluate(compiled.core, 'decide', {
145
+ req: {
146
+ principal_id: 'u1',
147
+ principal_type: 'User',
148
+ principal_roles: [],
149
+ resource_type: 'Order',
150
+ resource_id: 'o1',
151
+ agent_model: 'm',
152
+ context: { amount: 0 },
153
+ ...req,
154
+ },
155
+ }, { maxSteps: 10_000 });
156
+ assert.equal(ev.success, true, String(ev.error));
157
+ return ev.value.outcome;
158
+ }
159
+ test('删除客户记录需审批', () => {
160
+ assert.equal(outcome({ action: 'delete_customer_record' }), 'REQUIRE_APPROVAL');
161
+ });
162
+ test('被停用的主体拒绝', () => {
163
+ assert.equal(outcome({ action: 'read', principal_roles: ['suspended'] }), 'DENY');
164
+ });
165
+ test('大额退款升级', () => {
166
+ assert.equal(outcome({ action: 'refund', context: { amount: 20000 } }), 'ESCALATE');
167
+ });
168
+ test('小额退款放行', () => {
169
+ assert.equal(outcome({ action: 'refund', context: { amount: 50 } }), 'ALLOW');
170
+ });
171
+ });
172
+ //# sourceMappingURL=untyped-field-dynamic.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"untyped-field-dynamic.test.js","sourceRoot":"","sources":["../../../../test/unit/typecheck/untyped-field-dynamic.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aster-cloud/aster-lang-ts",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
4
4
  "description": "Aster CNL (Controlled Natural Language) TypeScript Compiler - Lexer, Parser, AST, Core IR, Type Checker",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",