feat(cxf): export flat ground scalar model graphs to CXF at RT-2 fixpoint (#141)#175
Merged
Merged
Conversation
…oint (#141) The minimal exporter replaces the R4 staged floor: a flat, ground, single-root, scalar-parameter, attribute-free ModelGraph now emits a deterministic CXF JSON-LD document whose re-import renders bit-identically to the input (RT-2), with a checked-in byte golden pinning the exact output. The synthesized root reconstructs boundary inputs from each external input's stored IRI (root hasInput -> boundary node -> minted child port), so re-import re-elides them under AD-2. Everything outside the subset - enum/non-finite params, declared connector attrs, IRI-less blocks, empty graphs - stays a typed ExportUnsupported rejection with the owning block as subject, never a panic. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…in every rejection arm (#141) Merge-review round for the minimal exporter. Two new plan-time rejections: a class path already carrying the OBC prefix (it survives the bridge round-trip but can never name a registry class, so its bytes always failed re-import) and any @id collision among emitted nodes (duplicate instance_iris, params named like minted ports) - both typed ExportUnsupported with the owning block as subject, tracked via a membership-only BTreeSet so emission order still derives from vector order alone. Every previously untested rejection arm (bridge oracle, String/Enum connectors, dense-id invariant, backwards connections) now has an exact-triple pin, the direction check names the source owner, and the remaining message pins are full-equality. The accepted emission path is untouched - the checked-in byte golden is byte-identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rung 5 of the interchange-trio ladder: replaces the R4
ExportUnsupportedfloor with a working minimal exporter for the flat / ground-mode / scalar / attr-free subset, at the owner-ratified RT-2 fixpoint contract (re-import of exported bytes reproduces the identical flatModelGraph; byte-stable exported-bytes golden checked in).Part of #141 — do not close; #141 stays open until R7 (arrays + enum-deferral) lands.
Design (ratified + red-team-validated)
export.rs):plan()validates the subset and mints every@idwith all offenders collected in deterministic scan order;build()renders the validated plan infallibly.urn:open-control:cxf-export:root) withcontainsBlockinBlockIdorder; eachexternal_inputsboundary IRI emitted verbatim as a boundary node under roothasInput, wiredisConnectedTo→ a distinct minted child port. Re-import re-elides the boundary (AD-2), restoringexternal_inputsand the IRI overwrite bit-exactly.2.0, never2) so untagged re-grounding cannot type-flip Real→Integer; bare-int Integers pinned in the reverse direction (y_start→0, never0.0).render()extracted verbatim intotests/render/mod.rs, consumed by both the resolver goldens (unchanged byte-for-byte) and the RT-2 fixpoint suite — renderer drift cannot hide an export defect.instance_iri, non-finite Reals, structural inconsistency).Tests
21 new/updated (suite 1222 → 1240): RT-2 fixpoint + second-order byte check, field-by-field import-parity oracle (bit-exact params via
to_bits), checked-in byte golden (OCE_BLESSblessable) + 4-call idempotence + order-stability assertion, both type-flip directions, boundary re-elision + document-shape pin, 13 rejection/edge tests including a never-panics sweep. Three mutation self-checks run → caught → reverted (block-order swap, bare whole-number Reals,Many-for-single wire shape — the last caught by the byte golden alone, exactly why the ratified contract pairs it with the fixpoint).Gates
All green (lead-verified independently in a clean worktree): fmt · clippy
-D warnings· nextest (1240) · doctests · file-size cap · both rustdoc gates (--lib+--bins,-D warnings,--document-private-items) · determinism matrix (448).🤖 Generated with Claude Code