Skip to main content

Extension Types

Extension types provide finer-grained modelling for graphs that need it. They use the same contract shape as foundation, decision, domain, and policy nodes — the type value is what distinguishes them.

Available Extensions

TypePurposeWhen to Use
design_tokenVisual tokens: colors, typography, spacing, shadowsWhen visual consistency matters and design decisions are load-bearing
ui_contractUI component contracts: props, states, variantsWhen component interfaces need to be specified
api_contractREST, GraphQL, or event contractsWhen API boundaries need formal specification
data_modelDatabase schemas, migrations, invariantsWhen data structure decisions are load-bearing
artifactContent-addressed external artifactWhen external assets (Figma tokens, config files) must be pinned
equivalence_contractFormal definition of "same system"When you need an explicit equivalence definition
pipelineManifestation pipeline steps and gatesWhen the build/deploy process must be specified

Schema

All extension types use the same contract shape:

{
"id": "DT-TASKCARD-01",
"type": "design_token",
"title": "Task Card Design Token",
"statement": "Visual specification for task cards on the board.",
"constraints": [
"Card: white background, 1px border-muted, 8px radius, 12px padding",
"Title: 14px semibold",
"Priority badge: top-right, colored dot (critical=red, high=orange, medium=blue, low=gray)"
],
"verification": [
{
"kind": "observation",
"description": "Visual inspection: task cards match spec in all four columns"
}
],
"links": {
"constrains": ["TASKBOARD-02"]
}
}

Design Tokens

Design tokens capture the visual language of the system — colors, typography, spacing, shadows, radii.

{
"type": "design_token",
"title": "Primary Color Palette",
"statement": "Primary interactive color is oklch(59.59% 0.24 275.75).",
"constraints": [
"All interactive elements use the primary palette",
"Primary-hover is oklch(52.85% 0.24 275.75)"
],
"verification": ["CSS audit: no hardcoded colors outside the token system"]
}

Use when: visual consistency matters and the design system is a load-bearing part of the spec.

API Contracts

API contracts specify the interface between services or modules.

{
"type": "api_contract",
"title": "Auth API Contract",
"statement": "POST /api/auth/login accepts {email, password} and returns {token, user}.",
"constraints": [
"Returns 401 on invalid credentials",
"Returns 429 after 5 failed attempts in 15 minutes"
],
"verification": [
{
"kind": "http",
"method": "POST",
"url": "http://localhost:3000/api/auth/login",
"expectStatus": 200
}
]
}

Artifacts

Artifact nodes pin external inputs (Figma exports, config files, etc.) by content hash so that manifestation can be reproduced later.

{
"id": "ART-DS-01",
"type": "artifact",
"title": "Design Tokens Export (Pinned)",
"statement": "Pinned design token export used as an input to derived nodes.",
"artifact": {
"sha256": "0000000000000000000000000000000000000000000000000000000000000000",
"source": "figma://file/abc123?node-id=...",
"format": "tokens-studio-json"
},
"verification": ["specgraph verify-artifacts --id ART-DS-01"]
}

Pins for derived_from

When a node is derived from an artifact, use links.derived_from plus pins so tooling can detect staleness:

{
"id": "DT-TASKCARD-01",
"type": "design_token",
"title": "Task Card Design Token",
"statement": "Visual specification for task cards on the board.",
"verification": [{ "kind": "observation", "description": "Visual inspection: matches spec" }],
"pins": [{ "id": "ART-DS-01", "sha256": "0000000000000000000000000000000000000000000000000000000000000000" }],
"links": { "derived_from": ["ART-DS-01"] }
}

Equivalence Contracts

An equivalence contract formally declares what "same system" means for this graph.

{
"type": "equivalence_contract",
"title": "System Equivalence Definition",
"statement": "Two manifestations are equivalent if all unit tests pass, all integration tests pass, Lighthouse performance scores exceed thresholds, and all policy nodes are satisfied.",
"constraints": [
"Unit test suite must achieve 100% pass rate",
"Integration tests must cover all behavior nodes",
"Lighthouse FCP < 1.5s, LCP < 2.5s"
],
"verification": [
{ "kind": "command", "command": "go test ./... -run TestSystemEquivalence" },
{ "kind": "command", "command": "python -m pytest tests/integration/test_equivalence.py" },
{ "kind": "command", "command": "pnpm exec lighthouse --preset=perf http://localhost:3000" }
]
}

When to Use Extensions

Extensions follow the same minimality test as core types:

"If I removed this, could a competent implementing agent make a choice I wouldn't want?"

Start with core types. Add extensions when you discover that core types don't provide enough precision for a specific dimension. For most projects, the seven core types are sufficient.

Progressive Addition

A typical extension adoption path:

  1. Start with core types only (feature, layer, foundation, behavior, decision, domain, policy)
  2. Add design_token when visual inconsistency between features becomes a problem
  3. Add api_contract when service boundaries need formal specification
  4. Add data_model when database schema decisions are load-bearing
  5. Add equivalence_contract when you need reproducible re-manifestation