Normalization rules
This section defines how Tropos and other producers transform source tool structures into Forma. These rules exist to ensure that equivalent source inputs yield equivalent Forma output.
Rule 1 · Stable identifiers
Node identifiers must be stable across re-exports when the source node identity is stable. Source ids may be mapped directly or normalized into a deterministic id function.
Recommended derivation (interoperability guidance):
- Prefer a source tool’s stable node id when available (e.g. Figma node id), optionally prefixed by a short type hint.
- If a stable source id is not available, derive an id from a stable path: (document/file id, ancestor ids, local index among siblings), then hash and encode (e.g. base32/base64url) to keep ids short.
- The derivation MUST be deterministic and MUST NOT depend on transient values (export time, random seeds, memory addresses).
- When the derivation is lossy (hashing), producers SHOULD retain a source.nodeId reference on the node to preserve traceability.
Rule 2 · Layout precedence
When a container can be represented as directional flow, producers must emit flex or stack rather than absolute. Absolute is a fallback, not a default.
When emitting layout.type of absolute, producers MUST provide a positioning basis via layout.frame (x/y/width/height) or layout.insets (top/right/bottom/left). Coordinates are interpreted in the parent’s coordinate space with origin at the parent’s top-left.
Rule 3 · Token resolution
When a style value matches a declared token exactly, producers must emit the token reference. Literal values are only allowed when no stable token mapping exists.
Token references use the canonical form {token.key.path}. The value inside the braces MUST match a key in the document-level tokens dictionary when that dictionary is present.
Token reference format
A token reference is a string of the form {token.key.path}, where token.key.path is a dot-delimited key. Producers MUST NOT emit bare token keys without braces in style or layout fields.
Token scope in v1 is document-global. Token overrides (per-screen, per-component, theme modes, etc.) are not standardized in the core spec; producers SHOULD model overrides using the optional extensions.token_overrides container or vendor-specific metadata.
Token matching
The requirement “matches a declared token exactly” is evaluated against the producer’s own token dictionary and normalization pipeline. When tokens is present:
- Producers MUST treat the token value as authoritative and SHOULD use it to map equivalent source values to the token reference.
- Producers MUST NOT emit a token reference to a token key that is missing from tokens.
- If a source tool value cannot be represented without loss using an existing token, producers MAY emit a literal and SHOULD emit an issue or flag when the loss is relevant.
| Normalization area | Required behavior | Fallback |
|---|---|---|
| Parent-child structure | Preserve logical hierarchy and child order | Emit issue if source structure is malformed |
| Component instances | Normalize reusable elements to component nodes with variant metadata when available | Emit as container with flag instance_unresolved |
| Layout | Prefer flex or stack for auto-layout-like patterns | Emit absolute with layout_fallback |
| Spacing | Normalize padding and gap into token references when available | Emit literal number or string |
| Semantic role | Emit the most specific justified role | Emit no role plus ambiguity issue |
| Text | Emit text content on text nodes | Emit issue if text content is missing |
Role inference guidance
- Use explicit source metadata first.
- Then use normalized naming and component set semantics.
- Then use layout, style, and child-pattern heuristics.
- When uncertainty remains, omit role and emit an ambiguity issue.
Confidence scoring
Confidence reflects certainty in inferred fields, not overall document quality.
- Explicit source semantics: high confidence
- Pattern-based inference: medium confidence
- Heuristic fallback: low confidence plus flags