An evidence may now reference another derived evidence as a sub-rule
(WHEN can_read(user, doc) where can_read is itself an evidence). Resolution
is a compile-time linker pass: after every evidence config is generated, each
direct reference to an evidence is inlined with that evidence's own (resolved)
config, so the engine evaluates a fully-resolved, acyclic config tree.
- resolveEvidenceReferences(): post-generation pass over evidence configs,
recursing into logical/defeasible containers (when/unless/never/always/
requires/union/intersection), always.direct nests, and comparator operands.
- Forward references resolve (all configs exist before the pass runs).
- Cycles and self-references are compile-time errors.
- _subjectAsObject scoping is preserved through inlining.
- dependsOn is recomputed after resolution, so partial-graph requirements
reach transitively through composed evidence.
- buildDirectRule/buildPredicateRule now apply subject-scoping to top-level
PredicateCall evidence bodies (latent gap, previously missed).
- validation: reject relation names shared across facts/sources/evidence/
measures (a collision silently overwrote configs and read as a false cycle).
Tests: EvidenceComposition (9), DSLRuntime transitive requiredFacts, oracle
campaign composition construct, illegal-mutations cycle + cross-kind cases.