1.13.0: measure + evidence compose; value-graph now a registry dep
CI / test (push) Successful in 24s
CI / publish (push) Failing after 10s

- DSLValueGraph integrates the evidence DSL with @arbiter/value-graph: measures
  become typed value-graph nodes; attach() wires runtime.measure through the graph.
- DSLRuntime.check() now retrieves required MEASURE values and injects them as
  value-carrying self-edges, so an evidence comparator over a measure (e.g.
  budget_used(user) <= budget_limit(user)) evaluates — measure and evidence
  compose (provider-sourced AND value-graph-sourced), with 3 new composition tests.
- BUILTIN_TYPES: bigint → buffer (the value-graph wire is JSON-free/bigint-free).
- @arbiter/value-graph: file:../value-graph → ^0.1.0 (registry); CI auth adds
  @push-stream-std registry for the transitive dep.
- rigor core ^3.1.2 / probe ^0.0.8.
This commit is contained in:
2026-08-04 17:51:13 -07:00
parent b145c979ab
commit 7898a7990a
14 changed files with 1421 additions and 87 deletions
+36
View File
@@ -194,4 +194,40 @@ describe('DSLRuntime extended', () => {
assert.ok(!rt.arbiter.relationConfigs.has('owns'));
assert.ok(rt.arbiter.relationConfigs.has('can_share'));
});
it('indexes measures and resolves them via a registered provider', async () => {
const rt = new DSLRuntime(new Arbiter()).compile(`
definition Employee { id: string? }
definition Project { id: string? }
measure budget_available(tenant: Employee, feature: string) { } PROVIDES number
measure clearance(user: Employee) { } PROVIDES string
`, 'rt-measures');
// Schema exposes measures with their return type.
const schema = rt.getSchema();
const budget = schema.measures.find(m => m.name === 'budget_available');
assert.ok(budget);
assert.equal(budget.returnType, 'number');
assert.deepEqual(budget.params.map(p => p.name), ['tenant', 'feature']);
assert.ok(rt.relationNames().includes('clearance'));
// No provider yet → resolution fails loudly.
await assert.rejects(() => rt.measure('budget_available', { tenant: 'tenant:acme', feature: 'tokens_in:gpt-4' }), /no provider registered/);
// Register a provider (the ARRA adapter would bridge the value-graph).
rt.registerMeasure('budget_available', async ({ tenant, feature }) => {
assert.equal(tenant, 'tenant:acme');
assert.equal(feature, 'tokens_in:gpt-4');
return { value: 1250, unit: 'tokens' };
});
const resolved = await rt.measure('budget_available', { tenant: 'tenant:acme', feature: 'tokens_in:gpt-4' });
assert.equal(resolved.value, 1250);
assert.equal(resolved.unit, 'tokens');
// Positional args bind by param order for unary measures.
rt.registerMeasure('clearance', async () => ({ value: 'secret' }));
assert.equal((await rt.measure('clearance', ['user:alice'])).value, 'secret');
// registerMeasure rejects undeclared names.
assert.throws(() => rt.registerMeasure('nope', async () => 1), /not a declared measure/);
});
});