JSON Schema logoGovernance

The Second Import Is Where Trust Is Won

Anyone can survive the first import. You feed a JSON Schema into a tool, something appears on the other side, and it looks broadly right. The interesting moment is the second — six weeks later, when the schema has changed, other people depend on the model, and a quiet alteration would propagate into a warehouse table, a partner contract, and a validation rule before anybody noticed.

The Second Import Is Where Trust Is Won

Anyone can survive the first import. You feed a JSON Schema into a tool, something appears on the other side, and it looks broadly right. The interesting moment is the second — six weeks later, when the schema has changed, other people depend on the model, and a quiet alteration would propagate into a warehouse table, a partner contract, and a validation rule before anybody noticed.

Governance is what makes the second import boring. For JSON Schema in CoreModels it comes down to five commitments, each a design decision rather than a paragraph in a policy document.

1. Import adds; it never edits your document

Bringing a JSON Schema into CoreModels writes Types, Elements, and Taxonomies into a project. It does not reach back into your repository, rewrite your file, or decide that your $schema declaration should be a different dialect. Keywords the model does not represent structurally are preserved verbatim — dialect declarations, description prose, format hints, your own extensions — and re-emitted exactly on the way out. Our suite asserts that a clean schema round-trips with an empty lossiness report; the file you get back is the file you put in.

Importing requires Admin on the target project; reading and exporting require Viewer. The stateless calls — mapping a schema onto another, replaying a stored plan, converting records — write nothing to the graph at all. That is not a configuration option you can forget to set; it is what those endpoints are.

2. Changes of meaning are human acts

Reshaping structure and deciding what something means are different acts, and the second belongs to people.

The carrier of meaning in a CoreModels JSON Schema is the x-maps-to annotation: a standard and a term URI, attached to a Type or an Element. Nothing infers it for you. When you use ontology lookup to find candidate terms, the response says plainly that suggestions are advisory only and that nothing was written; binding a chosen term is a separate, explicit, admin-level act. An inference engine can propose that two fields correspond; it cannot promote that proposal into an authoritative statement about your business.

The same rule holds for mapping. A schema mapping call is inherently a dry run — nothing is written, and what comes back is the transformed schema plus the plan. When you want a mapping written into the project, the endpoint takes a dry-run flag and the discipline is explicit in our own documentation: run the dry run, read the lossiness, then import. Review is a step in the workflow, not something you have to remember.

3. An AI proposal earns no shortcut

We offer an AI mapping strategy, and we are precise about what it is: a server-side model proposes a plan, and that plan goes through the identical validation gate as a hand-authored one. Not a similar gate. The same one.

If the gate rejects the proposal, the engine may attempt exactly one repair, and a rejected repair is a rejection — the gate is never relaxed. Plan operations may carry a self-reported confidence value; it is advisory, and the gate does not consult it. The strategy requires Editor or Admin membership and a server-configured key; without one, the request is declined honestly rather than falling back to something that looks like it worked. Because that strategy sends your schema content to an external API, we say so in the API documentation and in the tool's own open-world annotation, where an agent client can see it before calling.

Hand-authored guides get their own protection: an unknown key in a mapping guide is rejected with a path-carrying error rather than ignored, because a silently dropped typo executes a plan you did not intend.

4. Lossiness is a result, not an apology

Every import, export, and mapping call returns a ledger of what could not be carried exactly. Each entry has a kind, the exact path, and a plain-language explanation. The kinds are: StructuralDrop (it had no home in the target and was left out), TypeApproximation (a close-but-not-exact type was used), ConstraintRelaxation (a rule such as required, max length, or an enum could not be enforced), and SemanticNarrowing (meaning was narrowed or guessed).

The line we consider the most important sentence in our own API documentation: success: true does not mean "nothing changed." It means "it ran." Always read the lossiness.

JSON Schema's conditional combinators are the clearest case. anyOf, oneOf, if/then/else, and not express logic the model deliberately does not represent as structure. We refuse to guess a flattening. The importer records a SemanticNarrowing entry at the precise path, explains that conditional logic cannot be modeled as structure — and preserves the raw JSON so the export re-emits it untouched. You get both halves: an admission of what was not modeled, and a guarantee that nothing was destroyed.

The smaller cases work the same way. A property with no recognized type is approximated as a string and recorded as a TypeApproximation. A rich-text element on the way out becomes a plain JSON string and says so. Nothing is smuggled.

5. Drift becomes evidence

Because a stored plan replays deterministically — the same plan against the same source produces the same output, which our tests assert — a comparison stops being an argument.

Regenerate the JSON Schema from the governed model and diff it against the file checked into the repository. If they differ, that difference is a fact with a path attached, not one engineer's recollection of what was agreed in a meeting. Put it in the pull request. The same property makes a stored mapping plan reviewable like code: you can read what it does, keep it in version control, and replay it against next quarter's file to see whether the world moved.

Why this shape

Every one of these commitments costs us something. Honest lossiness makes our output look less magical than a tool that flattens an anyOf and reports success. Dry-run-first adds a step. Refusing to relax the gate means we sometimes say "this plan did not validate" instead of shipping something plausible.

We think that trade is the entire product. A schema conversion you cannot audit is a rumor about your data. One that adds rather than overwrites, keeps meaning changes in human hands, names what it could not preserve, and produces the same answer twice is something you can build a governance process on.

The four lossiness kinds and the response envelope are documented in full in the schema transformation guide in the CoreModels docs.