Skip to main content

SVG normalization and version contracts

Diagram.zip accepts SVG from renderers with different structures, palettes, and release cycles. A shared pipeline turns that output into safe, predictable artifacts.

renderer SVG
-> sanitization
-> canonical normalization
-> appearance materialization
-> final SVG

The renderer owns source interpretation and layout. Later stages preserve diagram geometry while adding safety, semantic paint roles, and optional presentation bounds.

Editable SVG contract

An editable export is still a normal visible SVG. It embeds a versioned Diagram.zip document in <metadata> and uses data-* attributes for compact per-element and root bindings. The document records the source type, source, renderer options, presentation, title, and description.

The metadata contract is versioned independently from rendering contracts. An importer must validate the schema, required fields, size limit, and deterministic reconstruction before it creates a draft. The current input limit is 5 MiB.

The importer accepts a validated enriched SVG from a local file, drag and drop, pasted SVG text, or an HTTP(S) or data URL. It rejects ordinary SVG, ambiguous metadata, unsupported schema versions, and any input that would lose source or presentation information. It does not infer a source language from visible shapes.

Save as File exports the enriched SVG without server persistence. Publish and Encrypt & Publish persist aliases separately from the file export.

Artifact stages

StageContract
Renderer SVGOutput from one identified renderer build.
Canonical SVGSanitized SVG with normalized metadata, bounds, and supported semantic roles.
Materialized SVGCanonical geometry combined with one explicit appearance, palette, and optional frame.

Materialization does not run the renderer again. Light, dark, transparent, and framed artifacts reuse the same canonical geometry.

Framed appearances may expand the outer view box for standard padding and the frame. They do not reroute connectors or reflow labels.

Appearance contract

The appearance name is a closed enum:

raw
auto-transparent
light-transparent
dark-transparent
auto-framed
light-framed
dark-framed

raw preserves the safe renderer appearance. It does not promise byte-for-byte preservation because sanitization and deterministic serialization still apply.

Automatic appearances embed both palettes and select one with prefers-color-scheme. They do not depend on styles from the embedding page.

Transparent appearances omit the outer canvas. Diagram objects may retain opaque surfaces when those surfaces are required for readable labels.

Framed appearances add a matching canvas, standard padding, and a border. They remain readable independently of the embedding page.

The editor offers only appearances advertised by the active profile. raw is always available.

Capability levels

ConformanceMeaningExpected appearance support
semanticStable renderer meaning maps directly to shared visual roles.All audited appearances.
adaptiveKnown structure and neutral paint adapt while authored color remains intact.All audited appearances.
presentation-onlyThe authored drawing stays unchanged while Diagram.zip owns the outer presentation.Raw and audited framed appearances.
rawThe SVG is safe, but no themed adaptation is claimed.Raw only.

An authored non-neutral color may remain unchanged in a semantic or adaptive profile. Normalization does not erase meaningful source styling.

How renderer versions select a profile

Each engine catalog entry pins a renderer version and an audited normalization profile. Compatibility belongs to that tested pair, not only to the engine name.

HTTP renderers identify their output with these response headers:

HeaderPurpose
X-Diagram-Engine-VersionIdentifies the underlying engine release.
X-Renderer-BuildIdentifies the Diagram.zip renderer build.

Every renderer provides the same version identity through its catalog entry and HTTP response. Diagram.zip uses this identity before it assigns semantic roles.

An unknown or upgraded renderer build does not inherit an older profile automatically. It falls back to safe-raw-1, which supports only raw.

This fail-closed behavior prevents rules for one renderer structure from changing unrelated elements in another structure.

Version identifiers are opaque contract values. Consumers should compare complete values and must not infer compatibility from embedded numbers.

The renderer catalog reports every engine version, known loss, and active normalization capability.

Independently versioned contracts

ContractExample identifierChanges when
Canonical schema1The canonical SVG structure changes incompatibly.
Normalizersvg-normalizer-2Sanitization, annotation, or serialization behavior changes.
Profileneutral-svg-semantic-2Renderer recognition or role assignment changes.
Palettediagramzip-palette-1Materialized role colors change.
Materializersvg-materializer-2Appearance rules, padding, frame, or output assembly changes.
RendererCatalog version and buildEngine output or its integration changes.

These versions advance independently. A renderer upgrade does not require a schema change, and a palette update does not require new geometry.

Any component that changes pixels or bounds must change the relevant build identifier. Cache identity must include every component that affected the artifact.

Root SVG metadata

Canonical and materialized SVG expose their active contract through data-dz-* attributes on the root element.

AttributeMeaning
data-dz-schemaCanonical SVG schema.
data-dz-normalizerNormalizer build.
data-dz-engineRenderer engine identifier.
data-dz-profileSelected normalization profile.
data-dz-paletterenderer for raw SVG, or the selected Diagram.zip palette build.
data-dz-appearanceMaterialized appearance.
data-dz-conformanceActive capability level.
data-dz-appearancesSupported non-raw appearances, separated by spaces.
data-dz-boundsCanonical diagram bounds as x y width height.
data-dz-materializerMaterializer build, present after non-raw materialization.

Normalized elements may also use data-dz-fill, data-dz-stroke, and data-dz-role. These attributes separate semantic intent from concrete palette values.

<svg
data-dz-schema="1"
data-dz-normalizer="svg-normalizer-2"
data-dz-engine="mermaid"
data-dz-profile="neutral-svg-semantic-2"
data-dz-palette="renderer"
data-dz-appearance="raw"
data-dz-conformance="adaptive"
data-dz-appearances="auto-transparent light-transparent dark-transparent auto-framed light-framed dark-framed"
data-dz-bounds="0 0 320 180">
</svg>

The identifiers above are examples. Inspect the artifact or catalog instead of hard-coding them.

Consumers should treat data-dz-appearances as an allowlist. Adding an unsupported value by hand does not create a supported artifact.

Consumer guarantees

A normalized SVG has these guarantees:

  • It is valid, sanitized, deterministic SVG with no unapproved network dependency.
  • It is self-contained after materialization and does not require embedding-page CSS.
  • It preserves renderer geometry, except for presentation bounds added by a frame.
  • It applies palette rules only to elements assigned a supported semantic role.
  • It preserves authored paint when the profile cannot adapt that paint honestly.
  • It rejects unsupported appearance materialization instead of applying heuristic theming.

Cache keys must include source identity, renderer options, renderer builds, schema, normalizer, profile, palette, materializer, and appearance.

Do not key a cache only by source and engine name. That can return artifacts created under an incompatible renderer or presentation contract.

Upgrade expectations

A renderer upgrade is a new output contract until the representative test corpus passes. The existing profile may then add compatibility, or a new profile may replace it.

Tests cover safety, determinism, raw fidelity, geometry stability, contrast, transparent canvases, frames, authored colors, and hostile resource attempts.

See the full engineering contract for profile design, semantic roles, validation rules, and caching details.