Skip to content

v0.4.0 — M4: standards, authoring, and static assurance

Latest

Choose a tag to compare

@kjpatel kjpatel released this 31 Jul 01:15
caf0eb2

M4 complete: the interchange contract now speaks standards, rule authors have a second surface and a solver, and the toolkit is demonstrably consumable from outside.

Ten capabilities across twenty-five pull requests (#6#30), and the golden corpus was never regenerated once. All 351 receipts replay byte-for-byte from before any of it. Every track's acceptance test was that git diff -- golden/ came back empty, and every one held.

Standards alignment

  • PROV-O JSON-LD export (#9#14) — facts, receipts, and run envelopes expand to W3C PROV triples under external contexts, stored bytes unchanged. The mapping is deliberately partial: bitemporal effective time, confidence, and abstentions have no faithful PROV equivalent. An earlier "lossless mapping" claim was corrected in the process.
  • Ontology conformance gate (#16) — a fact's schemaRef resolves against versioned, immutable LinkML artifacts; a misspelled attribute that previously surfaced only as a rule silently failing to bind now fails ingestion loudly. The hot-path validator interprets a documented LinkML subset rather than importing linkml-runtime, which would drag RDF tooling into the runtime.
  • Pack-embedded calendars (#17) — add_business_days walks a calendar the pack carries, with a coverage window that raises rather than guessing past its edge. "Last Monday in May" became legal content, versioned and receipt-pinned with the rules that use it. The TILA pack now computes the rescission deadline it could previously only certify.

Authoring

  • DMN decision-table compiler (#20) — DMN 1.3+ tables compile to the rule IR; the kernel cannot tell the result from a hand-written pack. It refuses rather than approximates: an uncited row is a compile error, not an invented TODO(verify).
  • Pack-owned decision phrasing (#28) — verdict wording moved from demo/app.py into the pack. Every determination the demo can render is byte-identical before and after; the wording moved without a word of it changing.
  • Rule-ID convention, ids grandfathered (#28) — nothing renamed, because NY-NR-45 sits in 76 golden receipts and a receipt is not editable. A rule id is a handle, not a claim.

Static assurance

  • Z3 static pack verifier (#21) — PROVED-DISJOINT / NOT-PROVED with a witness / OUT-OF-FRAGMENT naming what it declined to encode, plus uncovered input regions. Across six packs: 25 proved disjoint, one genuine overlap (correct — a registered eNote is a promissory note), nine uncovered regions, all intended and now witnessed. validate_pack is deliberately not relaxed.
  • What-if queries (#26) — solve a pack backwards for one freed input. The solver proposes; the kernel disposes: every answer is re-adjudicated, extremals are boundary-verified, and a disagreement raises with both artifacts rather than returning an answer.
  • Marker-gated suites now run in CI (#22) — linkml, z3, and docling had never executed there. The linkml one mattered most: its whole job is checking the ontologies against real tooling, and the pure-Python gate would have gone on passing while the files drifted out of spec.

Reference wiring

  • OR-Tools closing scheduler (#29), first resident of examples/ — CP-SAT plans sign → fund → record, where every hard constraint is a table of days an adjudication permitted and each chosen date cites the receipt ids that constrained it. Compliance opens Saturday 2026-02-21 (Saturdays are business days under the precise § 1026.2(a)(6) calendar); the wire desk is closed Saturdays, so the plan says Monday, and the output names which one bound the date.

Three claims the work corrected

  • The DMN acceptance criterion demanded "the same decision and receipt", which is unachievable: a receipt pins its pack's name and version, so two packs are two identities.
  • That equivalence proof turned out fixture-bounded — a >>= perturbation leaves the whole suite green because no fixture reaches the boundary. This is what motivated pack equivalence in the verifier.
  • "Keep actions outside the kernel" is only half a boundary. An integration can respect it perfectly at the API level and still hold a second copy of the rule ten lines away, invisible at the seam. Detectable only by mutation — which the scheduler now demonstrates rather than asserts.

Numbers at this tag

704 tests passing; 351 golden receipts replaying byte-for-byte; six rule packs across two domains; 1,478 committed facts conforming to their pinned ontologies; 25 same-priority rule pairs proved disjoint.

This tag marks a milestone, not a package release. pyproject.toml deliberately stays at 0.0.1 — nothing is published, and installable distribution is M5 work. The contracts remain v0 and may break until v1.0.

Full notes: CHANGELOG.md
Full diff: v0.3.0...v0.4.0