@principles/core 1.161.0 → 1.163.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.
- package/dist/runtime-v2/__tests__/adversarial-loop.test.js +24 -78
- package/dist/runtime-v2/__tests__/adversarial-loop.test.js.map +1 -1
- package/dist/runtime-v2/__tests__/architecture-regression.test.js +9 -5
- package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js +32 -80
- package/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js.map +1 -1
- package/dist/runtime-v2/__tests__/full-chain-real-llm.test.js +2 -2
- package/dist/runtime-v2/__tests__/full-chain-real-llm.test.js.map +1 -1
- package/dist/runtime-v2/__tests__/principle-compiler-core.test.js +7 -7
- package/dist/runtime-v2/__tests__/principle-compiler-core.test.js.map +1 -1
- package/dist/runtime-v2/activation/__tests__/production-gate-deps.test.js +24 -1
- package/dist/runtime-v2/activation/__tests__/production-gate-deps.test.js.map +1 -1
- package/dist/runtime-v2/activation/production-gate-deps.d.ts.map +1 -1
- package/dist/runtime-v2/activation/production-gate-deps.js +18 -1
- package/dist/runtime-v2/activation/production-gate-deps.js.map +1 -1
- package/dist/runtime-v2/adapter/__tests__/artificer-l2-adapter.test.js +277 -475
- package/dist/runtime-v2/adapter/__tests__/artificer-l2-adapter.test.js.map +1 -1
- package/dist/runtime-v2/adapter/artificer-l2-adapter.d.ts +14 -34
- package/dist/runtime-v2/adapter/artificer-l2-adapter.d.ts.map +1 -1
- package/dist/runtime-v2/adapter/artificer-l2-adapter.js +182 -222
- package/dist/runtime-v2/adapter/artificer-l2-adapter.js.map +1 -1
- package/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +2 -2
- package/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
- package/dist/runtime-v2/adversarial-loop.d.ts.map +1 -1
- package/dist/runtime-v2/adversarial-loop.js +5 -27
- package/dist/runtime-v2/adversarial-loop.js.map +1 -1
- package/dist/runtime-v2/golden-trace-replay-validator.d.ts +8 -0
- package/dist/runtime-v2/golden-trace-replay-validator.d.ts.map +1 -1
- package/dist/runtime-v2/golden-trace-replay-validator.js +3 -3
- package/dist/runtime-v2/golden-trace-replay-validator.js.map +1 -1
- package/dist/runtime-v2/golden-trace.d.ts +16 -1
- package/dist/runtime-v2/golden-trace.d.ts.map +1 -1
- package/dist/runtime-v2/golden-trace.js +13 -4
- package/dist/runtime-v2/golden-trace.js.map +1 -1
- package/dist/runtime-v2/index.d.ts +8 -5
- package/dist/runtime-v2/index.d.ts.map +1 -1
- package/dist/runtime-v2/index.js +11 -4
- package/dist/runtime-v2/index.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js +3 -2
- package/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.d.ts +2 -0
- package/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/{artificer-output-v2.test.js → artificer-rule-output.test.js} +126 -127
- package/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/rule-code-dialect.test.d.ts +2 -0
- package/dist/runtime-v2/internalization/__tests__/rule-code-dialect.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/rule-code-dialect.test.js +270 -0
- package/dist/runtime-v2/internalization/__tests__/rule-code-dialect.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.d.ts +2 -0
- package/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.js +180 -0
- package/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.js.map +1 -0
- package/dist/runtime-v2/internalization/artificer-output.d.ts +33 -51
- package/dist/runtime-v2/internalization/artificer-output.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-output.js +48 -87
- package/dist/runtime-v2/internalization/artificer-output.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.js +5 -17
- package/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.d.ts +8 -8
- package/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.js +5 -5
- package/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.d.ts +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.js +2 -2
- package/dist/runtime-v2/internalization/index.d.ts +9 -4
- package/dist/runtime-v2/internalization/index.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/index.js +8 -3
- package/dist/runtime-v2/internalization/index.js.map +1 -1
- package/dist/runtime-v2/internalization/rule-code-validator.d.ts +16 -0
- package/dist/runtime-v2/internalization/rule-code-validator.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/rule-code-validator.js +50 -1
- package/dist/runtime-v2/internalization/rule-code-validator.js.map +1 -1
- package/dist/runtime-v2/internalization/rule-host-input-builder.d.ts +62 -0
- package/dist/runtime-v2/internalization/rule-host-input-builder.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/rule-host-input-builder.js +182 -0
- package/dist/runtime-v2/internalization/rule-host-input-builder.js.map +1 -0
- package/dist/runtime-v2/internalization/rule-host-validator.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/rule-host-validator.js +22 -1
- package/dist/runtime-v2/internalization/rule-host-validator.js.map +1 -1
- package/dist/runtime-v2/internalization/template-generator.d.ts +7 -2
- package/dist/runtime-v2/internalization/template-generator.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/template-generator.js +10 -5
- package/dist/runtime-v2/internalization/template-generator.js.map +1 -1
- package/dist/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.d.ts +2 -0
- package/dist/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.d.ts.map +1 -0
- package/dist/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.js +322 -0
- package/dist/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.js.map +1 -0
- package/dist/runtime-v2/tools/__tests__/artificer-output-typebox.test.d.ts +2 -0
- package/dist/runtime-v2/tools/__tests__/artificer-output-typebox.test.d.ts.map +1 -0
- package/dist/runtime-v2/tools/__tests__/artificer-output-typebox.test.js +149 -0
- package/dist/runtime-v2/tools/__tests__/artificer-output-typebox.test.js.map +1 -0
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.d.ts +72 -0
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.d.ts.map +1 -0
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.js +275 -0
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.js.map +1 -0
- package/dist/runtime-v2/tools/artificer-output-typebox.d.ts +78 -0
- package/dist/runtime-v2/tools/artificer-output-typebox.d.ts.map +1 -0
- package/dist/runtime-v2/tools/artificer-output-typebox.js +70 -0
- package/dist/runtime-v2/tools/artificer-output-typebox.js.map +1 -0
- package/dist/telemetry-event.d.ts +2 -2
- package/dist/telemetry-event.d.ts.map +1 -1
- package/dist/telemetry-event.js +5 -3
- package/dist/telemetry-event.js.map +1 -1
- package/package.json +1 -1
- package/dist/runtime-v2/internalization/__tests__/artificer-output-v2.test.d.ts +0 -2
- package/dist/runtime-v2/internalization/__tests__/artificer-output-v2.test.d.ts.map +0 -1
- package/dist/runtime-v2/internalization/__tests__/artificer-output-v2.test.js.map +0 -1
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-439 Phase 4 — artificer-l2-tool-contract unit tests.
|
|
3
|
+
*
|
|
4
|
+
* Verifies the 4 Artificer L2 tool definitions, the whitelist, and the
|
|
5
|
+
* submit_rulecode capture + validator behavior. Pure — uses in-memory fakes,
|
|
6
|
+
* no I/O, no real LLM calls.
|
|
7
|
+
*
|
|
8
|
+
* ERR checklist:
|
|
9
|
+
* - EP-01 Trust Boundary: submit_rulecode validates params via the injected
|
|
10
|
+
* validator before storing (Runtime Contract Rule 1/2).
|
|
11
|
+
* - EP-03 Fail Loud: validate_rulecode and replay_rulecode surface specific
|
|
12
|
+
* violations, never silent empty results (Runtime Contract Rule 9).
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect } from 'vitest';
|
|
15
|
+
import { buildArtificerL2Tools, ARTIFICER_L2_TOOL_WHITELIST, } from '../artificer-l2-tool-contract.js';
|
|
16
|
+
import { DefaultArtificerValidator } from '../../internalization/artificer-output.js';
|
|
17
|
+
const TASK_ID = 'task-artificer-l2-001';
|
|
18
|
+
/** A valid ArtificerRuleOutput the model might submit. */
|
|
19
|
+
function makeRuleOutput(overrides = {}) {
|
|
20
|
+
return {
|
|
21
|
+
taskId: TASK_ID,
|
|
22
|
+
sourceScribeArtifactId: 'pi-art-scribe-001',
|
|
23
|
+
implementationCode: 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }',
|
|
24
|
+
goldenTraceCases: [
|
|
25
|
+
{ caseId: 'negative-1', kind: 'negative', toolName: 'edit', params: { path: '/etc/x' }, expectedDecision: 'block' },
|
|
26
|
+
{ caseId: 'positive-1', kind: 'positive', toolName: 'read', params: { path: '/tmp/y' }, expectedDecision: 'allow' },
|
|
27
|
+
],
|
|
28
|
+
affectedTools: ['edit'],
|
|
29
|
+
implementationSummary: 'Block writes to system dirs',
|
|
30
|
+
risks: [],
|
|
31
|
+
sourceTrace: { scribeArtifactId: 'pi-art-scribe-001' },
|
|
32
|
+
generatedAt: '2026-06-17T00:00:00.000Z',
|
|
33
|
+
...overrides,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Build a gateDeps whose sandbox always accepts (replay passes). */
|
|
37
|
+
function makeAlwaysPassGateDeps() {
|
|
38
|
+
const passingResult = {
|
|
39
|
+
success: true,
|
|
40
|
+
failedCases: [],
|
|
41
|
+
executionTimeMs: 1,
|
|
42
|
+
forbiddenPatternViolations: [],
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
evaluateInSandbox: (_code, _trace, _opts) => passingResult,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Build a gateDeps whose sandbox always fails with the given result. */
|
|
49
|
+
function makeFailingGateDeps(result) {
|
|
50
|
+
return {
|
|
51
|
+
evaluateInSandbox: (_code, _trace, _opts) => result,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function makeContext(overrides = {}) {
|
|
55
|
+
const outputCapture = { output: null };
|
|
56
|
+
return {
|
|
57
|
+
gateDeps: makeAlwaysPassGateDeps(),
|
|
58
|
+
validator: new DefaultArtificerValidator(),
|
|
59
|
+
taskId: TASK_ID,
|
|
60
|
+
outputCapture,
|
|
61
|
+
...overrides,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Type-safe text extraction from a tool result's content. */
|
|
65
|
+
function resultText(result) {
|
|
66
|
+
const textPart = result.content.find((c) => c.type === 'text');
|
|
67
|
+
if (!textPart || typeof textPart.text !== 'string') {
|
|
68
|
+
throw new Error('expected a text content part in tool result');
|
|
69
|
+
}
|
|
70
|
+
return textPart.text;
|
|
71
|
+
}
|
|
72
|
+
/** Find a tool by name. */
|
|
73
|
+
function findTool(tools, name) {
|
|
74
|
+
const tool = tools.find((t) => t.name === name);
|
|
75
|
+
if (!tool) {
|
|
76
|
+
throw new Error(`tool '${name}' not found in built tool set`);
|
|
77
|
+
}
|
|
78
|
+
return tool;
|
|
79
|
+
}
|
|
80
|
+
describe('PRI-439 buildArtificerL2Tools — tool set shape', () => {
|
|
81
|
+
it('builds exactly four tools', () => {
|
|
82
|
+
const tools = buildArtificerL2Tools(makeContext());
|
|
83
|
+
expect(tools).toHaveLength(4);
|
|
84
|
+
const names = tools.map((t) => t.name).sort();
|
|
85
|
+
expect(names).toEqual(['read_rulecode_spec', 'replay_rulecode', 'submit_rulecode', 'validate_rulecode']);
|
|
86
|
+
});
|
|
87
|
+
it('every tool has a typebox parameter schema, non-empty description, and execute function', () => {
|
|
88
|
+
const tools = buildArtificerL2Tools(makeContext());
|
|
89
|
+
for (const tool of tools) {
|
|
90
|
+
expect(typeof tool.name).toBe('string');
|
|
91
|
+
expect(tool.name.length).toBeGreaterThan(0);
|
|
92
|
+
expect(typeof tool.description).toBe('string');
|
|
93
|
+
expect(tool.description.length).toBeGreaterThan(0);
|
|
94
|
+
expect(tool.parameters).toBeTypeOf('object');
|
|
95
|
+
expect(typeof tool.execute).toBe('function');
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
it('the whitelist contains exactly the four tool names', () => {
|
|
99
|
+
expect(ARTIFICER_L2_TOOL_WHITELIST.size).toBe(4);
|
|
100
|
+
expect(ARTIFICER_L2_TOOL_WHITELIST.has('read_rulecode_spec')).toBe(true);
|
|
101
|
+
expect(ARTIFICER_L2_TOOL_WHITELIST.has('validate_rulecode')).toBe(true);
|
|
102
|
+
expect(ARTIFICER_L2_TOOL_WHITELIST.has('replay_rulecode')).toBe(true);
|
|
103
|
+
expect(ARTIFICER_L2_TOOL_WHITELIST.has('submit_rulecode')).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('PRI-439 read_rulecode_spec tool', () => {
|
|
107
|
+
it('returns the RuleCode dialect spec text', async () => {
|
|
108
|
+
const ctx = makeContext();
|
|
109
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
110
|
+
const tool = findTool(tools, 'read_rulecode_spec');
|
|
111
|
+
const result = await tool.execute('call-1', {});
|
|
112
|
+
const text = resultText(result);
|
|
113
|
+
// Spec must mention the canonical form, forbidden patterns, and matched=false rule.
|
|
114
|
+
expect(text).toContain('function evaluate(input, helpers)');
|
|
115
|
+
expect(text).toContain('FORBIDDEN PATTERNS');
|
|
116
|
+
expect(text).toContain('require');
|
|
117
|
+
expect(text).toContain('export');
|
|
118
|
+
expect(text).toContain('MATCHED=FALSE RULE');
|
|
119
|
+
expect(text).toContain('GOLDEN TRACE CASES');
|
|
120
|
+
});
|
|
121
|
+
it('emits telemetry on success', async () => {
|
|
122
|
+
const calls = [];
|
|
123
|
+
const ctx = makeContext({
|
|
124
|
+
onToolExecution: (info) => calls.push({ toolName: info.toolName, ok: info.ok }),
|
|
125
|
+
});
|
|
126
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
127
|
+
const tool = findTool(tools, 'read_rulecode_spec');
|
|
128
|
+
await tool.execute('call-1', {});
|
|
129
|
+
expect(calls).toEqual([{ toolName: 'read_rulecode_spec', ok: true }]);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('PRI-439 validate_rulecode tool', () => {
|
|
133
|
+
it('returns VALID for clean code', async () => {
|
|
134
|
+
const ctx = makeContext();
|
|
135
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
136
|
+
const tool = findTool(tools, 'validate_rulecode');
|
|
137
|
+
const code = 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
138
|
+
const result = await tool.execute('call-1', { code });
|
|
139
|
+
const text = resultText(result);
|
|
140
|
+
expect(text).toContain('VALID');
|
|
141
|
+
});
|
|
142
|
+
it('returns INVALID for code with forbidden pattern (require)', async () => {
|
|
143
|
+
const ctx = makeContext();
|
|
144
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
145
|
+
const tool = findTool(tools, 'validate_rulecode');
|
|
146
|
+
const code = 'function evaluate(input, helpers) { require("fs"); return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
147
|
+
const result = await tool.execute('call-1', { code });
|
|
148
|
+
const text = resultText(result);
|
|
149
|
+
expect(text).toContain('INVALID');
|
|
150
|
+
expect(text).toContain('require');
|
|
151
|
+
});
|
|
152
|
+
it('returns INVALID for code with export keyword', async () => {
|
|
153
|
+
const ctx = makeContext();
|
|
154
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
155
|
+
const tool = findTool(tools, 'validate_rulecode');
|
|
156
|
+
const code = 'export function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
157
|
+
const result = await tool.execute('call-1', { code });
|
|
158
|
+
const text = resultText(result);
|
|
159
|
+
expect(text).toContain('INVALID');
|
|
160
|
+
expect(text).toContain('export');
|
|
161
|
+
});
|
|
162
|
+
it('returns INVALID for return statement missing required fields', async () => {
|
|
163
|
+
const ctx = makeContext();
|
|
164
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
165
|
+
const tool = findTool(tools, 'validate_rulecode');
|
|
166
|
+
const code = 'function evaluate(input, helpers) { return { matched: false }; }';
|
|
167
|
+
const result = await tool.execute('call-1', { code });
|
|
168
|
+
const text = resultText(result);
|
|
169
|
+
expect(text).toContain('INVALID');
|
|
170
|
+
expect(text).toContain('decision');
|
|
171
|
+
});
|
|
172
|
+
it('returns INVALID for matched=false with decision=block', async () => {
|
|
173
|
+
const ctx = makeContext();
|
|
174
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
175
|
+
const tool = findTool(tools, 'validate_rulecode');
|
|
176
|
+
const code = 'function evaluate(input, helpers) { return { decision: "block", matched: false, reason: "x" }; }';
|
|
177
|
+
const result = await tool.execute('call-1', { code });
|
|
178
|
+
const text = resultText(result);
|
|
179
|
+
expect(text).toContain('INVALID');
|
|
180
|
+
expect(text).toContain('matched=false');
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
describe('PRI-439 replay_rulecode tool', () => {
|
|
184
|
+
it('returns PASSED when sandbox accepts', async () => {
|
|
185
|
+
const ctx = makeContext();
|
|
186
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
187
|
+
const tool = findTool(tools, 'replay_rulecode');
|
|
188
|
+
const code = 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
189
|
+
const result = await tool.execute('call-1', {
|
|
190
|
+
code,
|
|
191
|
+
goldenTraceCases: makeRuleOutput().goldenTraceCases,
|
|
192
|
+
});
|
|
193
|
+
const text = resultText(result);
|
|
194
|
+
expect(text).toContain('PASSED');
|
|
195
|
+
});
|
|
196
|
+
it('returns FAILED when sandbox rejects with runtime_error', async () => {
|
|
197
|
+
const failingResult = {
|
|
198
|
+
success: false,
|
|
199
|
+
failedCases: [{ caseId: 'negative-1', errorType: 'runtime_error', message: 'TypeError: x is undefined' }],
|
|
200
|
+
executionTimeMs: 1,
|
|
201
|
+
forbiddenPatternViolations: [],
|
|
202
|
+
};
|
|
203
|
+
const ctx = makeContext({ gateDeps: makeFailingGateDeps(failingResult) });
|
|
204
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
205
|
+
const tool = findTool(tools, 'replay_rulecode');
|
|
206
|
+
const code = 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
207
|
+
const result = await tool.execute('call-1', {
|
|
208
|
+
code,
|
|
209
|
+
goldenTraceCases: makeRuleOutput().goldenTraceCases,
|
|
210
|
+
});
|
|
211
|
+
const text = resultText(result);
|
|
212
|
+
expect(text).toContain('FAILED');
|
|
213
|
+
expect(text).toContain('TypeError: x is undefined');
|
|
214
|
+
});
|
|
215
|
+
it('returns FAILED when sandbox detects forbidden pattern', async () => {
|
|
216
|
+
const failingResult = {
|
|
217
|
+
success: false,
|
|
218
|
+
failedCases: [{ caseId: '__sandbox__', errorType: 'forbidden_pattern', message: 'require() detected' }],
|
|
219
|
+
executionTimeMs: 1,
|
|
220
|
+
forbiddenPatternViolations: ['require'],
|
|
221
|
+
};
|
|
222
|
+
const ctx = makeContext({ gateDeps: makeFailingGateDeps(failingResult) });
|
|
223
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
224
|
+
const tool = findTool(tools, 'replay_rulecode');
|
|
225
|
+
const code = 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
226
|
+
const result = await tool.execute('call-1', {
|
|
227
|
+
code,
|
|
228
|
+
goldenTraceCases: makeRuleOutput().goldenTraceCases,
|
|
229
|
+
});
|
|
230
|
+
const text = resultText(result);
|
|
231
|
+
expect(text).toContain('FAILED');
|
|
232
|
+
expect(text).toContain('require');
|
|
233
|
+
});
|
|
234
|
+
it('returns FAILED when golden trace build fails (only 1 case)', async () => {
|
|
235
|
+
const ctx = makeContext();
|
|
236
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
237
|
+
const tool = findTool(tools, 'replay_rulecode');
|
|
238
|
+
const code = 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }';
|
|
239
|
+
const result = await tool.execute('call-1', {
|
|
240
|
+
code,
|
|
241
|
+
goldenTraceCases: [
|
|
242
|
+
{ caseId: 'negative-1', kind: 'negative', toolName: 'edit', params: { path: '/etc/x' }, expectedDecision: 'block' },
|
|
243
|
+
],
|
|
244
|
+
});
|
|
245
|
+
const text = resultText(result);
|
|
246
|
+
expect(text).toContain('FAILED');
|
|
247
|
+
expect(text).toContain('golden trace build failed');
|
|
248
|
+
});
|
|
249
|
+
it('emits telemetry with ok=true on pass and ok=false on fail', async () => {
|
|
250
|
+
const calls = [];
|
|
251
|
+
const failingResult = {
|
|
252
|
+
success: false,
|
|
253
|
+
failedCases: [{ caseId: 'negative-1', errorType: 'runtime_error', message: 'err' }],
|
|
254
|
+
executionTimeMs: 1,
|
|
255
|
+
forbiddenPatternViolations: [],
|
|
256
|
+
};
|
|
257
|
+
const ctx = makeContext({
|
|
258
|
+
gateDeps: makeFailingGateDeps(failingResult),
|
|
259
|
+
onToolExecution: (info) => calls.push({ toolName: info.toolName, ok: info.ok }),
|
|
260
|
+
});
|
|
261
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
262
|
+
const tool = findTool(tools, 'replay_rulecode');
|
|
263
|
+
await tool.execute('call-1', {
|
|
264
|
+
code: 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }',
|
|
265
|
+
goldenTraceCases: makeRuleOutput().goldenTraceCases,
|
|
266
|
+
});
|
|
267
|
+
expect(calls).toEqual([{ toolName: 'replay_rulecode', ok: false }]);
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
describe('PRI-439 submit_rulecode tool', () => {
|
|
271
|
+
it('stores the output in outputCapture when validation passes', async () => {
|
|
272
|
+
const ctx = makeContext();
|
|
273
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
274
|
+
const tool = findTool(tools, 'submit_rulecode');
|
|
275
|
+
const output = makeRuleOutput();
|
|
276
|
+
const result = await tool.execute('call-1', output);
|
|
277
|
+
const text = resultText(result);
|
|
278
|
+
expect(text).toContain('submitted');
|
|
279
|
+
expect(ctx.outputCapture.output).toEqual(output);
|
|
280
|
+
});
|
|
281
|
+
it('returns terminate=true hint on successful submit', async () => {
|
|
282
|
+
const ctx = makeContext();
|
|
283
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
284
|
+
const tool = findTool(tools, 'submit_rulecode');
|
|
285
|
+
const result = await tool.execute('call-1', makeRuleOutput());
|
|
286
|
+
expect(result.terminate).toBe(true);
|
|
287
|
+
});
|
|
288
|
+
it('REJECTS and does NOT store when validator fails (missing affectedTools)', async () => {
|
|
289
|
+
const ctx = makeContext();
|
|
290
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
291
|
+
const tool = findTool(tools, 'submit_rulecode');
|
|
292
|
+
const bad = makeRuleOutput();
|
|
293
|
+
delete bad.affectedTools;
|
|
294
|
+
const result = await tool.execute('call-1', bad);
|
|
295
|
+
const text = resultText(result);
|
|
296
|
+
expect(text).toContain('REJECTED');
|
|
297
|
+
expect(ctx.outputCapture.output).toBeNull();
|
|
298
|
+
});
|
|
299
|
+
it('REJECTS and does NOT store when taskId mismatches', async () => {
|
|
300
|
+
const ctx = makeContext();
|
|
301
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
302
|
+
const tool = findTool(tools, 'submit_rulecode');
|
|
303
|
+
const bad = makeRuleOutput({ taskId: 'wrong-task-id' });
|
|
304
|
+
const result = await tool.execute('call-1', bad);
|
|
305
|
+
const text = resultText(result);
|
|
306
|
+
expect(text).toContain('REJECTED');
|
|
307
|
+
expect(ctx.outputCapture.output).toBeNull();
|
|
308
|
+
});
|
|
309
|
+
it('emits telemetry with ok=false on validator rejection', async () => {
|
|
310
|
+
const calls = [];
|
|
311
|
+
const ctx = makeContext({
|
|
312
|
+
onToolExecution: (info) => calls.push({ toolName: info.toolName, ok: info.ok }),
|
|
313
|
+
});
|
|
314
|
+
const tools = buildArtificerL2Tools(ctx);
|
|
315
|
+
const tool = findTool(tools, 'submit_rulecode');
|
|
316
|
+
const bad = makeRuleOutput();
|
|
317
|
+
delete bad.affectedTools;
|
|
318
|
+
await tool.execute('call-1', bad);
|
|
319
|
+
expect(calls).toEqual([{ toolName: 'submit_rulecode', ok: false }]);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
//# sourceMappingURL=artificer-l2-tool-contract.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artificer-l2-tool-contract.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artificer-output-typebox.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/tools/__tests__/artificer-output-typebox.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-439 — consistency proof: artificer-output-typebox.ts (typebox) matches
|
|
3
|
+
* artificer-output.ts (@sinclair/typebox) ArtificerRuleOutputSchema.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors dreamer-output-typebox.test.ts: for a shared sample set (valid +
|
|
6
|
+
* invalid candidates), both schemas must accept/reject the same shapes. No `as`,
|
|
7
|
+
* no cast — the proof is behavioural.
|
|
8
|
+
*
|
|
9
|
+
* Boundary: pure test, no I/O.
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect } from 'vitest';
|
|
12
|
+
import { Value as SinclairValue } from '@sinclair/typebox/value';
|
|
13
|
+
import { Value as TypeboxValue } from 'typebox/value';
|
|
14
|
+
import { ArtificerRuleOutputSchema } from '../../internalization/artificer-output.js';
|
|
15
|
+
import { ArtificerRuleOutputTypebox, GoldenTraceCaseInputTypebox, } from '../artificer-output-typebox.js';
|
|
16
|
+
// Minimal valid sample — extended/modified per test case.
|
|
17
|
+
const VALID_OUTPUT = {
|
|
18
|
+
taskId: 'task-001',
|
|
19
|
+
sourceScribeArtifactId: 'pi-art-scribe-001',
|
|
20
|
+
implementationCode: 'function evaluate(input, helpers) { return { decision: "allow", matched: false, reason: "ok" }; }',
|
|
21
|
+
goldenTraceCases: [
|
|
22
|
+
{ caseId: 'negative-1', kind: 'negative', toolName: 'edit', params: { path: '/etc/x' }, expectedDecision: 'block' },
|
|
23
|
+
{ caseId: 'positive-1', kind: 'positive', toolName: 'read', params: { path: '/tmp/y' }, expectedDecision: 'allow' },
|
|
24
|
+
],
|
|
25
|
+
affectedTools: ['edit'],
|
|
26
|
+
implementationSummary: 'Block writes to system dirs',
|
|
27
|
+
risks: [],
|
|
28
|
+
sourceTrace: { scribeArtifactId: 'pi-art-scribe-001' },
|
|
29
|
+
generatedAt: '2026-06-17T00:00:00.000Z',
|
|
30
|
+
};
|
|
31
|
+
function checkSinclair(value) {
|
|
32
|
+
return SinclairValue.Check(ArtificerRuleOutputSchema, value);
|
|
33
|
+
}
|
|
34
|
+
function checkTypebox(value) {
|
|
35
|
+
return TypeboxValue.Check(ArtificerRuleOutputTypebox, value);
|
|
36
|
+
}
|
|
37
|
+
describe('PRI-439 artificer-output-typebox consistency with @sinclair/typebox schema', () => {
|
|
38
|
+
it('both schemas accept the valid sample', () => {
|
|
39
|
+
expect(checkSinclair(VALID_OUTPUT)).toBe(true);
|
|
40
|
+
expect(checkTypebox(VALID_OUTPUT)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
it('both schemas reject missing implementationCode', () => {
|
|
43
|
+
const bad = { ...VALID_OUTPUT, implementationCode: undefined };
|
|
44
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
45
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
it('both schemas reject empty implementationCode', () => {
|
|
48
|
+
const bad = { ...VALID_OUTPUT, implementationCode: '' };
|
|
49
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
50
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
it('both schemas reject missing taskId', () => {
|
|
53
|
+
const bad = { ...VALID_OUTPUT, taskId: undefined };
|
|
54
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
55
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
it('both schemas reject empty affectedTools', () => {
|
|
58
|
+
const bad = { ...VALID_OUTPUT, affectedTools: [] };
|
|
59
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
60
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
it('both schemas reject fewer than 2 goldenTraceCases', () => {
|
|
63
|
+
const bad = { ...VALID_OUTPUT, goldenTraceCases: [VALID_OUTPUT.goldenTraceCases[0]] };
|
|
64
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
65
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
it('both schemas reject more than 10 goldenTraceCases', () => {
|
|
68
|
+
const cases = Array.from({ length: 11 }, (_, i) => ({
|
|
69
|
+
caseId: `case-${i}`,
|
|
70
|
+
kind: i % 2 === 0 ? 'positive' : 'negative',
|
|
71
|
+
toolName: 'edit',
|
|
72
|
+
params: { path: `/p/${i}` },
|
|
73
|
+
expectedDecision: i % 2 === 0 ? 'allow' : 'block',
|
|
74
|
+
}));
|
|
75
|
+
const bad = { ...VALID_OUTPUT, goldenTraceCases: cases };
|
|
76
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
77
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
it('both schemas reject invalid kind', () => {
|
|
80
|
+
const bad = {
|
|
81
|
+
...VALID_OUTPUT,
|
|
82
|
+
goldenTraceCases: [
|
|
83
|
+
{ ...VALID_OUTPUT.goldenTraceCases[0], kind: 'invalid' },
|
|
84
|
+
VALID_OUTPUT.goldenTraceCases[1],
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
88
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
it('both schemas reject invalid expectedDecision', () => {
|
|
91
|
+
const bad = {
|
|
92
|
+
...VALID_OUTPUT,
|
|
93
|
+
goldenTraceCases: [
|
|
94
|
+
{ ...VALID_OUTPUT.goldenTraceCases[0], expectedDecision: 'invalid' },
|
|
95
|
+
VALID_OUTPUT.goldenTraceCases[1],
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
99
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
it('both schemas reject missing sourceTrace', () => {
|
|
102
|
+
const bad = { ...VALID_OUTPUT, sourceTrace: undefined };
|
|
103
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
104
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
it('both schemas reject missing implementationSummary', () => {
|
|
107
|
+
const bad = { ...VALID_OUTPUT, implementationSummary: undefined };
|
|
108
|
+
expect(checkSinclair(bad)).toBe(false);
|
|
109
|
+
expect(checkTypebox(bad)).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
it('both schemas accept optional philosopherArtifactId in sourceTrace', () => {
|
|
112
|
+
const good = {
|
|
113
|
+
...VALID_OUTPUT,
|
|
114
|
+
sourceTrace: { scribeArtifactId: 'pi-art-scribe-001', philosopherArtifactId: 'pi-art-phil-001' },
|
|
115
|
+
};
|
|
116
|
+
expect(checkSinclair(good)).toBe(true);
|
|
117
|
+
expect(checkTypebox(good)).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
it('both schemas accept optional expectedProposedParams + expectedApplicationMode on a case', () => {
|
|
120
|
+
const good = {
|
|
121
|
+
...VALID_OUTPUT,
|
|
122
|
+
goldenTraceCases: [
|
|
123
|
+
...VALID_OUTPUT.goldenTraceCases,
|
|
124
|
+
{
|
|
125
|
+
caseId: 'correction-1',
|
|
126
|
+
kind: 'negative',
|
|
127
|
+
toolName: 'edit',
|
|
128
|
+
params: { path: '/tmp/z' },
|
|
129
|
+
expectedDecision: 'propose_correction',
|
|
130
|
+
expectedProposedParams: { path: '/workspace/z' },
|
|
131
|
+
expectedApplicationMode: 'shadow',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
expect(checkSinclair(good)).toBe(true);
|
|
136
|
+
expect(checkTypebox(good)).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('PRI-439 GoldenTraceCaseInputTypebox standalone', () => {
|
|
140
|
+
it('accepts a valid case', () => {
|
|
141
|
+
const valid = VALID_OUTPUT.goldenTraceCases[0];
|
|
142
|
+
expect(TypeboxValue.Check(GoldenTraceCaseInputTypebox, valid)).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
it('rejects a case missing caseId', () => {
|
|
145
|
+
const bad = { ...VALID_OUTPUT.goldenTraceCases[0], caseId: undefined };
|
|
146
|
+
expect(TypeboxValue.Check(GoldenTraceCaseInputTypebox, bad)).toBe(false);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
//# sourceMappingURL=artificer-output-typebox.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artificer-output-typebox.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/tools/__tests__/artificer-output-typebox.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRI-439 §Phase 4 — Artificer L2 agent tool contract (core, pure logic).
|
|
3
|
+
*
|
|
4
|
+
* Defines the 4 tools the Artificer L2 agent loop can call, plus the context
|
|
5
|
+
* interface that injects the sandbox + validator. This file is PURE: it holds
|
|
6
|
+
* tool definitions (name / description / typebox parameter schema) and a factory
|
|
7
|
+
* that wires them to an injected context. No I/O, no `node:*` imports.
|
|
8
|
+
*
|
|
9
|
+
* Tool set (artificer, PRI-439 Phase 4):
|
|
10
|
+
* - read_rulecode_spec : returns the RuleCode dialect spec (canonical form,
|
|
11
|
+
* forbidden patterns, return shape, golden trace rules)
|
|
12
|
+
* - validate_rulecode : runs STATIC validation (forbidden patterns + return
|
|
13
|
+
* statement checks + matched=false decision check) on
|
|
14
|
+
* a code string. No VM, no sandbox.
|
|
15
|
+
* - replay_rulecode : runs SANDBOX replay of code against a golden trace
|
|
16
|
+
* using the injected RefinerRuleHostGateDeps.
|
|
17
|
+
* - submit_rulecode : the model's final ArtificerRuleOutput submission.
|
|
18
|
+
* Stores into outputCapture; the adapter's
|
|
19
|
+
* shouldStopAfterTurn detects the capture and stops.
|
|
20
|
+
*
|
|
21
|
+
* The submit_rulecode tool does NOT terminate the loop via `terminate` alone
|
|
22
|
+
* (that is unreliable — agent-loop uses .every() over the whole tool batch,
|
|
23
|
+
* see l2-agent-loop-adapter.ts header comment). Loop termination is driven by
|
|
24
|
+
* shouldStopAfterTurn detecting the captured output.
|
|
25
|
+
*
|
|
26
|
+
* Boundary: pure logic, no I/O. Lives in core. No `node:*` imports.
|
|
27
|
+
*/
|
|
28
|
+
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
29
|
+
import { ArtificerRuleOutputTypebox } from './artificer-output-typebox.js';
|
|
30
|
+
import type { RefinerRuleHostGateDeps } from '../internalization/refiner-rulehost-gate.js';
|
|
31
|
+
import type { ArtificerValidator } from '../internalization/artificer-output.js';
|
|
32
|
+
export interface ArtificerL2OutputCapture {
|
|
33
|
+
output: unknown | null;
|
|
34
|
+
}
|
|
35
|
+
export interface ArtificerL2ToolContext {
|
|
36
|
+
/** Sandbox replay deps (real or test double). */
|
|
37
|
+
gateDeps: RefinerRuleHostGateDeps;
|
|
38
|
+
/** Artificer output validator (used by submit_rulecode for runtime validation). */
|
|
39
|
+
validator: ArtificerValidator;
|
|
40
|
+
/** The taskId the loop is running for (lineage consistency check in submit). */
|
|
41
|
+
taskId: string;
|
|
42
|
+
/** The capture container the submit_rulecode tool writes into. */
|
|
43
|
+
outputCapture: ArtificerL2OutputCapture;
|
|
44
|
+
/** Telemetry sink: called once per tool execution (toolName + ok/error). */
|
|
45
|
+
onToolExecution?: (info: {
|
|
46
|
+
toolName: string;
|
|
47
|
+
ok: boolean;
|
|
48
|
+
error?: string;
|
|
49
|
+
}) => void;
|
|
50
|
+
}
|
|
51
|
+
export { ArtificerRuleOutputTypebox as SubmitRulecodeSchema };
|
|
52
|
+
/**
|
|
53
|
+
* The RuleCode dialect spec returned by read_rulecode_spec. Pure text so the
|
|
54
|
+
* model can reference it during the loop. Mirrors the constraints in
|
|
55
|
+
* ARTIFICER_PROTOCOL_INSTRUCTION + checkForbiddenPatterns + the matched=false
|
|
56
|
+
* decision rule.
|
|
57
|
+
*
|
|
58
|
+
* Exported so the `pd rulecode spec` CLI command (PRI-439 Phase 5) can return
|
|
59
|
+
* the same canonical text the Artificer L2 agent sees — single source of truth.
|
|
60
|
+
*/
|
|
61
|
+
export declare const RULECODE_SPEC_TEXT: string;
|
|
62
|
+
/**
|
|
63
|
+
* Build the Artificer L2 tool set bound to an injected context.
|
|
64
|
+
*
|
|
65
|
+
* Returns AgentTool[] suitable for assignment to AgentContext.tools. Tools are
|
|
66
|
+
* read-only by construction (validate/replay do not mutate state; submit writes
|
|
67
|
+
* only into the adapter-owned outputCapture).
|
|
68
|
+
*/
|
|
69
|
+
export declare function buildArtificerL2Tools(ctx: ArtificerL2ToolContext): AgentTool[];
|
|
70
|
+
/** Allow-list of tool names the Artificer L2 loop may execute (defense-in-depth for beforeToolCall). */
|
|
71
|
+
export declare const ARTIFICER_L2_TOOL_WHITELIST: ReadonlySet<string>;
|
|
72
|
+
//# sourceMappingURL=artificer-l2-tool-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artificer-l2-tool-contract.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/tools/artificer-l2-tool-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,+BAA+B,CAAC;AAEhF,OAAO,EAAE,0BAA0B,EAA+B,MAAM,+BAA+B,CAAC;AAExG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAE3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAOjF,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACxB;AAID,MAAM,WAAW,sBAAsB;IACrC,iDAAiD;IACjD,QAAQ,EAAE,uBAAuB,CAAC;IAClC,mFAAmF;IACnF,SAAS,EAAE,kBAAkB,CAAC;IAC9B,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,aAAa,EAAE,wBAAwB,CAAC;IACxC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACrF;AAoBD,OAAO,EAAE,0BAA0B,IAAI,oBAAoB,EAAE,CAAC;AAI9D;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,QA4DnB,CAAC;AAIb;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,sBAAsB,GAAG,SAAS,EAAE,CA0L9E;AAED,wGAAwG;AACxG,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAK1D,CAAC"}
|