Skip to content

feat(cxf): export flat ground scalar model graphs to CXF at RT-2 fixpoint (#141)#175

Merged
jscott3201 merged 2 commits into
developmentfrom
claude/cxf-export-minimal
Jul 22, 2026
Merged

feat(cxf): export flat ground scalar model graphs to CXF at RT-2 fixpoint (#141)#175
jscott3201 merged 2 commits into
developmentfrom
claude/cxf-export-minimal

Conversation

@jscott3201

Copy link
Copy Markdown
Owner

Summary

Rung 5 of the interchange-trio ladder: replaces the R4 ExportUnsupported floor 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 flat ModelGraph; byte-stable exported-bytes golden checked in).

Part of #141do not close; #141 stays open until R7 (arrays + enum-deferral) lands.

Design (ratified + red-team-validated)

  • Plan/build split (export.rs): plan() validates the subset and mints every @id with all offenders collected in deterministic scan order; build() renders the validated plan infallibly.
  • Shape A boundary emission (empirically validated pre-dispatch): synthesized root (urn:open-control:cxf-export:root) with containsBlock in BlockId order; each external_inputs boundary IRI emitted verbatim as a boundary node under root hasInput, wired isConnectedTo → a distinct minted child port. Re-import re-elides the boundary (AD-2), restoring external_inputs and the IRI overwrite bit-exactly.
  • Forced-fractional Reals (ratified): whole-number Reals always emit a fractional part (2.0, never 2) so untagged re-grounding cannot type-flip Real→Integer; bare-int Integers pinned in the reverse direction (y_start0, never 0.0).
  • Shared test renderer: render() extracted verbatim into tests/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.
  • Out-of-subset inputs reject with stable, subject-bearing diagnostics (attrs, enums via specialization-surfaced fixtures, missing 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_BLESS blessable) + 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

jscott3201 and others added 2 commits July 21, 2026 22:33
…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>
@jscott3201
jscott3201 merged commit 0cfd7ef into development Jul 22, 2026
14 checks passed
@jscott3201
jscott3201 deleted the claude/cxf-export-minimal branch July 22, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant