4 Commits

Author SHA1 Message Date
John Dvorak 2a7f4c315b feat: sources wired as recency-gated injectables; transitive closure, NOT scoping, recompile-scope uninstall; targeted parse errors
CI / test (push) Successful in 20s
CI / publish (push) Has been skipped
BEHAVES AS transitive now emits bounded multi_hop configs (direct checks and
evidence references), fixing a silent no-op. NOT builds keep _subjectAsObject
scoping so unary predicates negate the right node, and value-typed evidence
objects gate by exact edge value. Recompiling a scope uninstalls its stale
relation configs (compileMultiple coexistence preserved). Sources become
injectable relations honored by requiredFacts with a within-X recency gate.
Duplicate definition fields and three common declaration mistakes (within on a
fact, two BEHAVES clauses, limit on a non-pattern body) now produce targeted
errors. Provider edges referencing unknown nodes are warned and dropped.
2026-08-03 20:27:13 -07:00
John Dvorak 9111c4b20d feat: duration seconds; required fields; type-validated insertions/updates/retrievals
CI / publish (push) Successful in 9s
CI / test (push) Successful in 19s
- Duration literals now accept s/m/h/d/w (was m/h/d/w): 'BEHAVES { ttl 30s }'
  is 30s, and 'within 30s' temporal expressions parse.
- Definition fields are REQUIRED by default ('field: type'); 'field: type?'
  marks a field optional. addNode enforces presence on insert, getSchema
  exposes per-field requiredness, and updateNodeData still validates the
  provided fields' types.
- Provider-returned edges are validated against the fact's declared typing:
  a value-carrying fact must return { value, possibility } with a value of the
  declared type (bare-number shorthand is rejected); a non-value fact must not
  carry a value; and every possibility must lie in [0, 1]. Violations throw a
  clear provider-authoring error instead of silently injecting malformed edges.

Tests: DSLRuntimeTyping (duration units, required-field enforcement, schema
requiredness, value-type + shape + possibility validation).
2026-08-03 16:00:49 -07:00
John Dvorak ad365a65a9 feat: direct fact checks consult registered providers
CI / test (push) Successful in 19s
CI / publish (push) Successful in 9s
Checking a FACT relation directly (rt.check('u:1', 'owns', 'doc:9')) now
runs the provider-retrieval pipeline instead of returning 0 without ever
consulting the registered provider. The retrieval set for a direct fact
check is the fact itself (plus, for evidence checks, the injectable deps as
before). The result reports requiredFacts/providedFacts/missingFacts for the
fact, and missingFacts surfaces 'no_provider' when neither a provider nor an
edge can satisfy the check.
2026-08-03 15:25:33 -07:00
John Dvorak fe162251fc feat: DSLRuntime schema introspection, per-relation providers, retrieval loop
CI / publish (push) Successful in 10s
CI / test (push) Successful in 20s
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).
2026-08-03 12:45:16 -07:00