This document defines the minimal authoritative interface contract enforced by interfacectl. It is a human-readable baseline; the schema remains the source of truth.
Every contract must include:
contractId(string, non-empty): contract identifier used for traceability.version(string): semantic version, patternX.Y.Z.surfaces(array, at least one item): governed surfaces.sections(array, at least one item): section catalog.constraints(object): currently requiresmotionwithallowedDurationsMsandallowedTimingFunctions.color(object): required unified color policy withpolicyandallowedValues.tokens(object, optional): allowlisted UI token categories for typography, layout, and motion.
Each item in surfaces must include:
id(string): lowercase alphanumeric and hyphens.displayName(string, non-empty)type("web"or"cli")requiredSections(array of section ids)allowedFonts(array of strings)layout.maxContentWidth(number, minimum 1)
Optional surface layout fields:
layout.requiredContainers(array of strings)layout.pageFrame(when present, enforced by validator)layout.pageFrame.containerMinWidthPx(optional): exact deterministic min-width check in px for[data-contract="page-container"].
layout.chromePolicy(when present, enforced by validator)- Shared
generate-contractcan seed this conservatively from portable contract markers.
- Shared
Portable chrome extraction is opt-in and deterministic. Shared interfacectl only observes actual elements carrying contract-aware markers; it does not infer wrapper intent from generic DOM structure.
- Use
.contract-containeron governed layout containers. This is the recommended portablelayout-containersignal. - Use top-level
data-contract-section="<id>"wrappers for governed sections. Nested sections do not count toward chrome extraction. - Use
data-contract="page-container"only when the repo wants explicit page-frame semantics. It remains optional. data-contract-containerremains supported for backward compatibility, but.contract-containeris the recommended path for new adopters.- Dynamic radius/shadow values, unresolved custom properties, and runtime-only expressions are treated as ambiguous and will suppress generated
chromePolicyseeding.
Optional per-surface icon policy (web surfaces):
icons.policy: one of"off","warn","strict".icons.allowedSources: array of allowed icon source libraries (for examplelucide-react,@heroicons/react/24/outline).
Optional top-level UI token policies:
tokens.typography: allowlisted font and type-scale tokens used in font-family, font-size, line-height, and letter-spacing declarations.tokens.layout: allowlisted spacing, width, sizing, and radius tokens used in layout declarations.tokens.motion: allowlisted duration and easing tokens used in transition and animation declarations.tokens.<category>.allowedTokens: canonical token refs used for enforcement.tokens.<category>.tokenMetadata(optional): generated metadata for canonical tokens, including normalized values, observed attributes, and collapsed aliases.
Each item in sections must include:
id(string)intent(string, non-empty)description(string, non-empty)
Optional authoring metadata for web surfaces:
components[]: reusable component library for agentic generation and adaptation.sections[*].anatomy: generic section pattern, allowed/default components, and section-local slots.sections[*].editPolicy: safe mutation boundary such aslocked,slot-bound, orfreeform.sections[*].responsive: named viewport rules for layout intent and slot reflow.surfaces[*].viewports: named breakpoint profiles with min/max widths.surfaces[*].authoring: implementation preferences and source precedence across contract, Figma, code, stories, and live URLs.
These fields are advisory-first in v1. interfacectl validate checks structure and referential integrity, but they do not add new compliance violations on their own beyond malformed metadata.
For generator consumption order and end-to-end examples, see docs/authoring-contracts.md.
The top-level color object must include:
policy: one of"off","warn","strict".allowedValues: array of exact canonical color values allowed across the contract.
Enforcement semantics:
off: skip color enforcement.warn: emit warning findings for disallowed values.strict: emit error findings for disallowed values.
Violation contract:
- Validator violation type:
color-not-allowed - CLI finding code:
color.disallowed
When surfaces[*].icons is present for a web surface:
off: skip icon source enforcement.warn: emit warning findings for disallowed icon sources.strict: emit error findings for disallowed icon sources.
Violation contract:
- Validator violation type:
icon-source-not-allowed - CLI finding code:
icon.source-disallowed
When a shell owns global primitives:
- Top-level
shell.owns: shell-owned primitives (nav,header,sidebar, etc.). - Per-surface
mustNotEmit: explicit surface bans. If omitted, generators/validators can default toshell.owns.
The following legacy fields are not accepted by the active schema:
surfaces[*].allowedColorscolor.sourceOfTruthcolor.rawValues
For migration, use:
interfacectl migrate-color-policy --contract <path>- Schema:
packages/interfacectl-validator/src/schema/web.surface.contract.schema.json - Structure validation:
validateContractStructureinpackages/interfacectl-validator/src/index.ts - Compliance evaluation:
evaluateContractComplianceinpackages/interfacectl-validator/src/index.ts - CLI validate command:
packages/interfacectl-cli/src/commands/validate.ts - Descriptor extraction:
packages/interfacectl-cli/src/descriptors/static-analysis.ts