blocksmith.blocks.v1

The block graph — the packet on the wire

A block is one addressable unit of design truth: a token, a component, a guideline, an agent rule, or a prose page. A graph is the set of blocks for one product. That is the entire surface area of the format — everything else (versions, locks, promotion) layers on top.

Block

BlocksmithBlockV1
{
  "id": "token:color:accent",
  "type": "token",
  "title": "Accent",
  "version": 1,
  "status": "finalized",
  "source": { "file": "src/styles/tokens.css", "line": 14, "ingest": "scan" },
  "content": {
    "value": "#d97757",
    "cssVar": "--color-accent",
    "summary": "Primary CTA color"
  },
  "updatedAt": "2026-06-04T12:00:00.000Z",
  "finalizedAt": "2026-06-04T12:00:00.000Z",
  "editedBy": "ingest",
  "contentHash": "sha256:a40ae6c94ffbaeff0ee94d459043a971"
}
FieldRule
idStable, lowercase, ^[a-z0-9][a-z0-9:_-]*$ — convention: type:category:name (e.g. token:color:accent, component:button-primary)
typecomponent · token · guideline · agent-rule · page
versionInteger ≥ 1, monotonic per id. New content = new version. Never reused.
statusdraft (staging, never served to agents) · finalized (promoted) · stale (source vanished) · conflict (sources disagree)
sourceWhere this truth came from: file, optional line, optional ingest adapter name
contentType-specific payload. Tokens: value/cssVar. Components: role/radius/description. Rules: text. Guidelines: items[]
contentHashsha256: + first 32 hex of sha256("id type canonicalJson(content)") — see hashing below

Graph

BlocksmithGraphV1
{
  "schema": "blocksmith.blocks.v1",
  "docRef": "upload:scan-acme-mobile-app.md",
  "systemId": "acme-mobile-app",
  "contentHash": "sha256:afffd0184ad0a9a1d184f247916216c1",
  "blocks": [ /* BlocksmithBlockV1[] */ ]
}

contentHash at graph level is order-independent: lines <id>@<version>:<contentHash> sorted, joined with \n, sha256, first 32 hex. Two emitters producing the same blocks in any order produce the same hash — that property is what makes lock staleness detection possible.

Canonical hashing (constitutional)

@blocksmith/protocol
import { blockContentHash, graphHash, canonicalJson } from "@blocksmith/protocol";

// canonicalJson: object keys sorted recursively, arrays order-preserved,
// undefined dropped. {a:1,b:2} and {b:2,a:1} hash identically.
blockContentHash("token:color:accent", "token", { value: "#d97757" });
// → "sha256:…32 hex…"
Hash semantics are law. Changing them is a blocks.v2 spec bump with migration notes — never a refactor. The conformance suite carries golden vectors; if your implementation can't reproduce them byte-for-byte, it does not speak blocks.v1.

The official-graph rule

A graph served to agents, CI, packages, or devices must contain only promoted versions — no draft, no conflict. Validators enforce this with validateGraph(g, { officialOnly: true }). Staging graphs (wiki previews) may carry anything.

Downloads

JSON Schema · conformance fixtures — the example above is a real fixture; recompute its hashes and compare.