The higher-order DSL+Core wrapper now covers the full contract the DSL
informs, beyond the typed mutations already present:
- getSchema(): serializable introspection of the compiled type system —
entity types/fields, facts (params + injectable flag), evidence (with
transitive dependsOn), and registered providers. relationNames() lists all
declared relations. (The DSL's type system was always present; this exposes
it programmatically.)
- registerFact(relation, fn) / unregisterFact / registeredFacts: per-relation
async providers that retrieve missing partial-graph edges; per-check
factProviders merge OVER registered ones.
- Bounded fixed-point provider retrieval loop (maxProviderRounds): each round
invokes providers for required facts whose edges are not yet injected. A
provider may return edges for relations other than its own — those satisfy
the other required facts and can unblock later rounds.
- check() now type-validates FACT relations too (not just evidence); edge
normalization preserves a provider edge's own relation name.
- removeNode / removeRelation passthroughs; require() throws on denial for
middleware.
- Field typing extended to the DSL's full value-type universe
(timestamp/duration accept number or string; object/any accept anything).
Tests: DSLRuntimeExt (schema, registration, merge, fixed-point, require,
removal, fact-check validation, timestamp typing).