A chain step of the form { rule: <config>, conditionStep: true } is a
condition-gated hop instead of an edge traversal. It is valid only as the
FINAL step: the object is known, so the engine verifies the referenced rule
at (intermediate, object) for each current path. Enables a chain's object-side
hop to reference a defeasible/logical evidence (e.g.
member_of(user,*g){ gated(g,doc) } where gated is WHEN/UNLESS).
- RuleEvaluator wires the ChainRule with itself so condition steps can
evaluate sub-rules recursively.
- ChainRule constructor accepts the ruleEvaluator; the traversal loop handles
a final condition step (min-combined possibility, reliability product,
threshold respect). Non-final condition steps return condition_step_not_final.
- The rule config is part of the chain cache key (JSON.stringify of steps).
Tests: chain-condition-step (grant/deny/missing-edge/non-final/parallel-max).
The Evidence DSL (ADR-000) compiles a natural DSL into core rule
configurations — it is a separate concern from the engine. The AST had
zero runtime coupling to the core (DSLCompiler takes the arbiter as a
duck-typed argument; ip-utils were the only shared code, now local to
the DSL package). This extraction removes the DSL surface from the core
artifact entirely:
- src/ast/ (748K, ~60 files) moved to @arbiter/evidence-dsl@1.0.0
- ip-utils moved with it (only the DSL consumed them)
- generate-parser script + peggy devDep moved to the DSL package
- the 8 DSL-consuming tests now import from @arbiter/evidence-dsl
(deep-path exports: DSLCompiler, parser/*, generator/*, validation/*,
interpreter/*)
- package.json gains the devDependency, drops build:ast/generate:parser
Tarball: AST-free. Rigor 251/251, full suite 838/776/0.
The now parameter (and partialGraph.now) replaced the need for global
Date.now patching in tests. The ttl-expiry parity campaign's module-scope
patch and the relational-comparator Time-Based Decay tests' before/after
patches now pass the clock explicitly through check options — no global
mutation, no restore-order fragility, and the pinned-clock cache bypass
keeps every evaluation honest. No stale references to the removed
compiled evaluator or useCompiled option remain in the test suite.
The full suite intermittently failed (pass counts 725-735, fail 0-1) under
parallel node --test execution. The reachability integration test asserted
a single-shot 100ms quick-failure bound and big-graph-optimized a 1s load
bound — both are regression smoke checks that can blow on a GC pause or
CPU contention spike while other files' campaigns run concurrently.
Both now re-measure once before failing, keeping the tight regression
signal while eliminating load-induced flakes. Full suite is now stable at
735 pass / 0 fail / 62 skipped across repeated runs.