Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ In an interactive terminal, running bare `interfacectl` with no arguments opens

## Generation-time gating

`interfacectl validate` is the canonical command for contract compliance. Use it to gate changes before merge or deployment. For deterministic, category-based exit codes, use `--exit-codes v2` or set `INTERFACECTL_EXIT_CODES=v2`. The command `enforce --mode fail` runs a structural diff and applies a policy threshold. It is optional and useful when you want to block on diff severity separately from compliance. For the minimal contract format and where contract semantics live in the repo, see [docs/contract-baseline.md](docs/contract-baseline.md).
`interfacectl validate` is the canonical command for contract compliance. Use it to gate changes before merge or deployment. For deterministic, category-based exit codes, use `--exit-codes v2` or set `INTERFACECTL_EXIT_CODES=v2`. The command `enforce --mode fail` runs a structural diff and applies a policy threshold. It is optional and useful when you want to block on diff severity separately from compliance. For the minimal contract format and where contract semantics live in the repo, see [docs/contract-baseline.md](docs/contract-baseline.md). For optional generator-facing authoring metadata, see [docs/authoring-contracts.md](docs/authoring-contracts.md).

## Commands

Expand Down
161 changes: 161 additions & 0 deletions docs/authoring-contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Authoring Contract Metadata

These optional contract fields help agentic UI generators interpret structure, safe edits, responsive behavior, implementation preferences, and external sources of truth for any governed web surface.

The fields are advisory-first in v1:

- `interfacectl validate` checks shape and referential integrity.
- The fields do not add new blocking runtime or CI semantics by themselves.
- Existing contracts remain valid without them.

## Scope

Authoring metadata in v1 is for web surfaces:

- `contract.components[]`
- `sections[].anatomy`
- `sections[].editPolicy`
- `sections[].responsive`
- `surfaces[].viewports`
- `surfaces[].authoring`

Do not treat these fields as first-party patterns. They are generic primitives for any ingested web surface.

## Generator Consumption Order

When both contract metadata and external sources exist, consume them in this order:

1. Use the contract to determine the allowed structure.
2. Respect shell boundaries, section edit policies, and slot constraints.
3. Read `surfaces[].authoring.sourcePriority` to decide which secondary sources to consult next.
4. Resolve `components[].references[]` or other external references only after the contract shape is known.
5. If an external source conflicts with the contract, the contract wins.

Recommended default precedence:

```json
{
"sourcePriority": ["contract", "figma", "code", "story", "url"]
}
```

## Field Summary

- `components[]`: reusable, named building blocks for a surface.
- `components[].slots[]`: machine-editable anatomy for text, media, actions, icons, and nested content.
- `components[].states[]`: explicit UI states such as loading, empty, disabled, or expanded.
- `components[].interactions[]`: navigational or state-changing behaviors that generators must preserve.
- `sections[].anatomy`: section pattern, allowed components, and section-local slots.
- `sections[].editPolicy`: safe mutation boundary for agent edits.
- `sections[].responsive.rules[]`: named viewport behavior for layout and slot reflow.
- `surfaces[].viewports[]`: named breakpoint profiles and width ranges.
- `surfaces[].authoring`: framework, styling, preferred libraries, and source precedence.
- `references[]`: tool-neutral mappings to Figma, code, Storybook, live URLs, or asset systems.

## Marketing Page Example

```json
{
"surfaces": [
{
"id": "marketing-site",
"type": "web",
"viewports": [
{ "id": "mobile", "maxWidthPx": 767 },
{ "id": "desktop", "minWidthPx": 768 }
],
"authoring": {
"framework": "react",
"styling": { "strategy": "design-tokens" },
"sourcePriority": ["contract", "figma", "code", "url"]
}
}
],
"components": [
{
"id": "copy-block",
"intent": "intro copy",
"slots": [
{ "id": "headline", "kind": "text", "required": true },
{ "id": "body", "kind": "richText", "required": true },
{ "id": "primary-action", "kind": "action", "required": false }
]
}
],
"sections": [
{
"id": "page.intro",
"intent": "intro",
"description": "Top-of-page introduction.",
"anatomy": {
"pattern": "copy-block",
"defaultComponent": "copy-block"
},
"editPolicy": {
"mode": "slot-bound",
"allowedOperations": ["update-copy", "swap-variant", "adjust-layout"]
},
"responsive": {
"rules": [
{ "viewport": "mobile", "layoutIntent": "stack" },
{ "viewport": "desktop", "layoutIntent": "columns" }
]
}
}
]
}
```

## Application Screen Example

```json
{
"components": [
{
"id": "results-table",
"intent": "tabular search results",
"slots": [
{ "id": "toolbar", "kind": "container", "required": true },
{ "id": "rows", "kind": "item-list", "required": true, "repeatable": true },
{ "id": "empty-copy", "kind": "text", "required": false }
],
"states": [
{ "id": "loading", "hiddenSlots": ["rows"], "requiredSlots": ["toolbar"] },
{ "id": "empty", "hiddenSlots": ["rows"], "requiredSlots": ["empty-copy"] },
{ "id": "ready", "requiredSlots": ["toolbar", "rows"] }
],
"interactions": [
{
"id": "apply-filter",
"trigger": "submit toolbar filter form",
"effect": "filter",
"resultingState": "ready"
}
]
}
],
"sections": [
{
"id": "screen.results",
"intent": "search-results",
"description": "Primary results screen.",
"anatomy": {
"pattern": "data-panel",
"defaultComponent": "results-table"
},
"editPolicy": {
"mode": "slot-bound",
"allowedOperations": ["bind-data", "wire-interaction", "adjust-layout"]
}
}
]
}
```

## Reference Fixture

The first annotated example lives at:

- `packages/interfacectl-validator/test/fixtures/authoring/reference-target-web.contract.json`

It uses the live `reference-target-web` surface as calibration, but it is expressed only through generic authoring primitives such as copy block, repeated card list, viewport rules, and source precedence.
13 changes: 13 additions & 0 deletions docs/contract-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ Each item in `sections` must include:
- `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 as `locked`, `slot-bound`, or `freeform`.
- `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`.

## Required color policy

The top-level `color` object must include:
Expand Down
2 changes: 1 addition & 1 deletion packages/interfacectl-validator/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ContractStructureValidation {
export declare function validateContractStructure(contractData: unknown, schema: object): ContractStructureValidation;
export declare function evaluateSurfaceCompliance(contract: InterfaceContract, descriptor: SurfaceDescriptor): SurfaceReport;
export declare function evaluateContractCompliance(contract: InterfaceContract, descriptors: SurfaceDescriptor[]): ValidationSummary;
export type { InterfaceContract, ContractSurface, ContractSection, ContractConstraints, ContractTokenPolicies, SurfaceDescriptor, SurfaceSectionDescriptor, SurfaceFontDescriptor, SurfaceColorDescriptor, SurfaceIconDescriptor, SurfaceTokenDescriptor, SurfaceTokenUsage, SurfaceMotionDescriptor, SurfaceLayoutDescriptor, PageFrameLayoutDescriptor, ChromeLayoutDescriptor, ChromePolicyTarget, ChromeShadowKind, LandingPatternDescriptor, SurfacePrimitiveDescriptor, SurfaceReport, DriftViolation, ValidationSummary, DriftViolationType, ContractRef, RuleRef, DiffOutput, DiffEntry, DiffChangeType, DriftRisk, Severity, SafetyLevel, EnforcementPolicy, EnforcementMode, IconPolicy, TokenCategory, TokenMetadata, TokenPolicy, ContractMarketingProfiles, MarketingLayoutProfile, MarketingTypographyProfile, MarketingTypographyRoleProfile, MarketingHeroContainerMode, MarketingHeroVisualPlacement, MarketingSectionDividerMode, MarketingSectionSpacingProfile, MarketingTypographyRole, FlowPolicy, FlowRequirement, FlowTransitionRequirement, LandingPatternPolicy, SurfaceMarketingTypographyDescriptor, SurfaceMarketingTypographyRoleDescriptor, SurfaceFlowDescriptor, SurfaceFlowStepDescriptor, SurfaceFlowTransitionDescriptor, AutofixRule, FixSummary, FixEntry, FixError, } from "./types.js";
export type { InterfaceContract, ContractComponent, ContractSlot, ContractSlotKind, ContractSlotContentRules, ContractComponentVariant, ContractState, ContractInteraction, ContractInteractionEffect, ContractComponentImplementation, ExternalReference, ExternalReferenceSystem, AuthoringSource, SectionAnatomy, SectionEditPolicy, SectionEditMode, SectionAllowedOperation, SectionResponsive, SectionResponsiveRule, ResponsiveLayoutIntent, ResponsiveSlotBehavior, ResponsiveSlotBehaviorKind, ViewportProfile, SurfaceAuthoring, SurfaceAuthoringStyling, SurfaceAuthoringLibraries, ContractSurface, ContractSection, ContractConstraints, ContractTokenPolicies, SurfaceDescriptor, SurfaceSectionDescriptor, SurfaceFontDescriptor, SurfaceColorDescriptor, SurfaceIconDescriptor, SurfaceTokenDescriptor, SurfaceTokenUsage, SurfaceMotionDescriptor, SurfaceLayoutDescriptor, PageFrameLayoutDescriptor, ChromeLayoutDescriptor, ChromePolicyTarget, ChromeShadowKind, LandingPatternDescriptor, SurfacePrimitiveDescriptor, SurfaceReport, DriftViolation, ValidationSummary, DriftViolationType, ContractRef, RuleRef, DiffOutput, DiffEntry, DiffChangeType, DriftRisk, Severity, SafetyLevel, EnforcementPolicy, EnforcementMode, IconPolicy, TokenCategory, TokenMetadata, TokenPolicy, ContractMarketingProfiles, MarketingLayoutProfile, MarketingTypographyProfile, MarketingTypographyRoleProfile, MarketingHeroContainerMode, MarketingHeroVisualPlacement, MarketingSectionDividerMode, MarketingSectionSpacingProfile, MarketingTypographyRole, FlowPolicy, FlowRequirement, FlowTransitionRequirement, LandingPatternPolicy, SurfaceMarketingTypographyDescriptor, SurfaceMarketingTypographyRoleDescriptor, SurfaceFlowDescriptor, SurfaceFlowStepDescriptor, SurfaceFlowTransitionDescriptor, AutofixRule, FixSummary, FixEntry, FixError, } from "./types.js";
export { getBundledDiffSchema, getBundledPolicySchema, getBundledFixSummarySchema, validateDiffOutput, validatePolicy, validateFixSummary, type ValidationResult, } from "./schema-validate.js";
export { normalizeColorValue, normalizeColorValues, } from "./color-policy.js";
export { matchTokenPolicy, normalizeTokenLiteralValue, type TokenPolicyMatch, } from "./token-policy.js";
Expand Down
2 changes: 1 addition & 1 deletion packages/interfacectl-validator/dist/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading