The Constraint That Stopped Firing
A value that should have been rejected is sitting in a table. The governed model is explicit about that field: multiples of ten, strictly greater than zero. The schema the platform actually validates against says `integer`. Nobody deleted the rule on purpose. It was lost in translation months earlier, when a person hand-converted the model into the shape a Synapse registered schema can carry — and nothing, anywhere, recorded that it had been lost.
The Constraint That Stopped Firing
A value that should have been rejected is sitting in a table. The governed model is explicit about that field: multiples of ten, strictly greater than zero. The schema the platform actually validates against says integer. Nobody deleted the rule on purpose. It was lost in translation months earlier, when a person hand-converted the model into the shape a Synapse registered schema can carry — and nothing, anywhere, recorded that it had been lost.
That silence is the reason we built the synapse profile in CoreModels. Not the conversion; the conversion is the easy part. The silence.
Synapse models a subset, on purpose
Sage Bionetworks' Synapse validates entities against registered JSON Schemas. Those schemas are draft-07 — but not all of draft-07. Synapse's JsonSchema REST object has a defined set of fields, and that field set is what a registered schema can carry. It is a generous neighborhood: type, properties, required, enum, const, pattern, minLength and maxLength, minimum and maximum, minItems, maxItems, uniqueItems, format, items, definitions, $ref, the combinators, if/then/else, contains, additionalProperties, default, title, description.
It is also a bounded one. multipleOf is not there. Neither is exclusiveMinimum or exclusiveMaximum, patternProperties, dependencies, propertyNames, minProperties, or the newer additions a modern authoring tool emits by default — $defs, prefixItems, unevaluatedProperties.
That boundary is a sensible platform decision. A service binding entities to schemas at scale has every reason to model a stable, documented object rather than chase every draft. The problem is not the boundary. The problem is that your canonical model almost never lives inside it, and moving the model across that line is manual work with silent failure modes.
In 2026, crossing that line stopped being optional
For years most teams never faced the boundary directly, because tooling stood in front of it. The open-source schematic toolchain compiled a CSV data model into the artifacts curation ran on, the Data Curator App gave contributors a front end, and the subset was somebody else's problem. That buffer is now being dismantled on a schedule. The schematic repository was archived in April 2026 with a deprecation notice naming the end of the year; the Data Curator App is being replaced by Synapse-native Curator; and the designated path forward is JSON-Schema-based curation — data models registered with Synapse as JSON Schemas, authored against the documented draft-07 subset. The path is manual: Sage publishes a guide for the Curator-era data model and a tutorial for schema authoring, not a migrator. Every data coordinating center built on schematic is now doing the translation this article is about, by hand, with a deadline — which turns the failure modes below from a cautionary tale into a checklist.
Failure one: constraints that evaporate without an error
A stripped keyword produces no complaint. There is no line in a log that says "the numeric step constraint you wrote will not be enforced here." The schema registers, entities bind, validation runs — and runs less strictly than the author believed. You discover the gap the way the opening paragraph discovers it: from a value that should not exist.
The keywords most likely to disappear are exactly the ones that carried real rules. A bound that was exclusive becomes inclusive, or vanishes. A step constraint disappears. A conditional dependency between two properties stops being checked. Meanwhile the annotations you would happily lose — $comment, examples, readOnly — go too, and nobody minds those. The trouble is that both categories leave by the same door and neither leaves a receipt.
Failure two: an identity that has to be exactly right
A registered schema is named by a $id with a strict shape: the registered-schema base URL, then an organization segment, a name segment, and a semantic version, joined by hyphens. Every part of that is a trap for a careful person in a hurry.
The organization has to be a real, pre-created, unique Synapse Organization — and org.sagebionetworks is reserved for Synapse's own core models, so it is not available to you. Because a hyphen delimits the parts of the identifier, a version like 1.0.0-rc1 cannot be expressed there at all; the version has to be a plain major.minor.patch. And Synapse will not let you re-register a version that already exists, so every meaningful change requires a deliberate bump — while an accidental bump quietly creates two versions of something that should have been one.
Then there is dialect drift. A schema authored in a current tool typically declares 2020-12 and keeps its subschemas under $defs, with every internal reference pointing at #/$defs/.... Getting that into Synapse's world means renaming the container to definitions and rewriting every pointer that referenced it — including the ones buried inside allOf/anyOf/oneOf members and inside tuple-form items arrays. Miss one and you have a schema with a dangling reference that looks perfectly fine to the eye.
Failure three: the deliverable nobody counts
A Synapse schema rarely travels alone. Curators work from tabular manifests: an entry grid with one column per field, and a dictionary saying what each column means, whether it is required, and which controlled vocabulary drives it. That surface is what curation-stack tools generate and render, and it is what a contributor actually fills in.
In most teams the grid and the dictionary are maintained by hand, next to the schema, from the same mental picture. Which means they are correct on the day they are made and slightly wrong a month later. A field is renamed in the schema and not in the sheet. A vocabulary gains a term the dictionary never hears about. Two artifacts that describe the same records, drifting apart at the speed of ordinary work.
The underlying problem is the absence of a record
Every one of these failures shares a shape: something changed during the translation, and no artifact captured the change. The subset is learned by rejection and surprise. The identity rules are learned by having a registration refused at an inconvenient hour. The manifest drift is learned when a curator's upload fails validation for a reason the curator cannot see.
None of that is a Synapse defect or a modeling defect. It is a translation defect — and translation should not depend on a person remembering a keyword list.
What we built instead
In CoreModels, synapse is an export format. You govern the model once, then project it: out comes the draft-07 subset the JsonSchema REST object models, with the dialect declared, the $id composed from the organization, name, and version you supply (sanitized into legal segments, with a plain fallback and an explicit note when a version is not a clean major.minor.patch), $defs renamed to definitions with every internal pointer rewritten to match, and string enumerations carrying the type: string that Synapse's own publicly registered example schemas carry. From the same governed model, the companion manifest CSVs — the blank entry grid and the column dictionary with its value-set section — are generated rather than transcribed.
And the part that answers the opening paragraph: every keyword stripped, every type approximated, every construct that has no home in the subset comes back as a typed record with a path and a plain-English explanation. A stripped multipleOf is reported as a relaxed constraint. A dropped $comment is reported as a structural drop. A nullable field, whose representation the public documentation does not settle, is reported rather than guessed at. You read that list before you register.
The constraint that stopped firing did not have to be a mystery. It only had to be written down.
If you have a schema headed for a Synapse registered-schema service, the transform quickstart in the CoreModels documentation walks the export end to end.