The Interface Specification
machine-readable contracts; loud vs silent failures.
machine-readable contracts; loud vs silent failures.
The Concept
Think about USB. A USB-C cable looks simple because the mess is hidden in the specification: voltage ranges, pin layout, protocol negotiation, data lanes, power roles. If that specification did not exist, every device maker would ship a connector that looked almost right and failed in slightly different ways. Your phone might charge but not transfer data. Your monitor might flicker only at one resolution. Your keyboard might work until it goes through a hub.
Those are the worst failures. Not total failure. Partial failure that wastes hours and survives every shape check you can think of.
Composable model systems need the same thing. In Project 33: Fusing Independently Trained Specialists, we saw that specialists compose only when they share an internal coordinate system. That phrase can sound vague, so let's pin it down.
A coordinate system here means the rules that give meaning to a hidden state. A hidden state is the list of numbers passed from one layer of a model to the next. If d_model = 768, then each token is represented at that boundary by 768 floating-point numbers. Those numbers are not random. Their scale matters, their ordering matters, the normalization applied to them matters, the positional encoding scheme matters, the way attention heads are arranged matters, and the vocabulary matters too if you expect outputs to line up.
If two specialists share weights up to some boundary, then branch off, then later get recombined, you need a formal promise about that boundary: what shape comes in, what shape goes out, what normalization has already happened, what positional encoding was assumed when those numbers were produced, what attention head layout the downstream module expects, and what vocabulary the logits refer to. Without that promise, "compatible" becomes guesswork. The first time I watched a cooperative fusion run produce fluent-but-wrong outputs, I assumed for a full afternoon that the issue was the router. It was not. It was a one-character difference in how two specialists declared their normalization.
Here is the analogy that makes this click. Imagine three translators working for the same newsroom. They all receive a note from the editor that says: BANK CLOSED AFTER FLOOD. One translator assumes "bank" means financial institution. Another assumes riverbank. A third assumes the note already includes location metadata from earlier in the conversation. All three can produce fluent English. All three can work well alone. But if translator A writes the first half of a paragraph and translator B continues without sharing assumptions, the combined output can be nonsense.
The problem is not grammar. The problem is incompatible hidden context. That is what an interface specification fixes: at this boundary, "bank" has to arrive in this format, with this context encoding, under these assumptions.
Now the engineering version. A versioned interface specification for composable specialists is a written contract that says:
- Hidden state dimension:
d_model = 768 - Normalization type:
RMSNorm - Norm epsilon:
1e-5 - Residual convention: pre-norm or post-norm
- Attention head configuration:
H = 12, head dimensiond_head = 64 - Positional encoding:
RoPEwith specific base and scaling - Vocabulary: exact tokenizer and vocabulary file hash
- Output boundary: logits over vocabulary
V = 50,304or hidden state only - Checkpoint metadata: version string, architecture fingerprint, training origin
This sounds bureaucratic until you see the alternative. The alternative is silent garbage.
A model with LayerNorm at the specialist boundary can often still produce tensors of the correct shape. No crash, no red warning, no obvious stack trace. The numbers even look normal if you inspect mean and standard deviation. But they no longer mean the same thing as the tensors expected by a system built around RMSNorm. That is the core lesson of this chapter: shared weights are not enough. Shared contracts are what make composition dependable.
I will be honest about a bias here. Years of federal-procurement work at Procore, where FedRAMP and SOC 2 governance treat every interface as a written contract subject to a Change Advisory Board, have made me allergic to "we just trust the shape." It is not paranoia. It is the only style of work I have seen survive auditors and time. Figure 19.1 shows the contract structure that enforces this explicitly.

Why It Matters
Without an interface specification, you cannot tell the difference between these four situations: the specialist is genuinely bad; the specialist is good but the fusion system is bad; the specialist and fusion system are both good but the boundary assumptions differ; or the system mostly works only because one accidental mismatch has not bitten you yet.
That ambiguity destroys engineering progress. If a specialist plugs into the fusion system and outputs garbage, what do you do next? Retrain longer? Change the router? Add more data? Tune the learning rate? Replace the expert? Without a contract and a compliance test, you are debugging in the dark. I have wasted whole afternoons on the wrong layer of this question, and the lesson was always the same.
This matters even more once multiple people work independently. Suppose one person trains a code specialist, another trains a multilingual specialist, a third builds the fusion stack, and a fourth writes evaluation. If each person makes one "reasonable" architectural choice on their own, you can end up with four modules that all work in isolation and fail together.
Worse, they may fail softly. Perplexity rises a bit. Accuracy drops only on long contexts. Responses become vague instead of obviously broken. Those are the failures that survive demos and poison production. In a past role on a multi-state SaaS platform, the multi-party API integrations across DMV, DCF, banking, and payment systems were all "compatible" on shape and protocol. The failures that cost real money were always semantic. A field that meant dollars in one system meant cents in another, a date that meant local time on one end meant UTC on the other, and nothing in the wire format would tell you.
A good interface specification gives you three things: coordination without constant meetings, fast rejection of incompatible checkpoints, and blame assignment when something breaks. That last one matters. If the compliance test says:
- expected
RMSNorm, foundLayerNorm - expected
rope_theta=10000, foundrope_theta=500000 - expected tokenizer hash
abc123, founde91f2d
then the mystery evaporates. You are not "tuning composition." You are fixing a contract violation. Same reason APIs have versions, schemas, and compatibility checks. An API that returns a JSON object where price silently changes from dollars to cents without changing the version number is broken even if the endpoint still returns 200 OK. I lived this exact bug on an enterprise healthcare eligibility integration; the endpoint was happy, the auditor was not. A specialist that silently changes boundary normalization is broken in the same way. The spec is not paperwork. It turns invisible incompatibility into an engineering error you can see.
The Build
build.py$python projects/34_the-interface-specification/build.py --tiny
"""
Project 34: The Interface Specification
Canonical runnable build for this project. Generated by tools/extract_code.py
from the book's chapter markdown — re-run that tool to regenerate.
"""
# === Step 5: Make specialists declare what they are ===
ckpt["interface"] = {
"interface_name": "COMPOSE-LLM-IFACE",
"interface_version": "1.0",
"base_model_id": "trunk-init-2026-03",
"shared_prefix_depth": 8,
"d_model": 768,
"n_heads": 12,
"norm_type": "RMSNorm",
"norm_eps": 1e-5,
"positional_encoding": "RoPE",
"rope_theta": 10000,
"tokenizer_hash": "sha256:..."
}
# === Step 6: Inspect the actual module, not just the metadata ===
import torch
def check_norm_type(module: torch.nn.Module, expected: str) -> None:
actual = type(module.norm).__name__
if actual != expected:
raise ValueError(f"Norm mismatch: expected {expected}, found {actual}")
def check_d_model(module: torch.nn.Module, expected: int) -> None:
actual = module.attn.q_proj.weight.shape[1]
if actual != expected:
raise ValueError(f"d_model mismatch: expected {expected}, found {actual}")
def check_vocab_size(module: torch.nn.Module, expected: int) -> None:
actual = module.lm_head.weight.shape[0]
if actual != expected:
raise ValueError(f"Vocab mismatch: expected {expected}, found {actual}")
# === Step 7: Check behavior, not just structure ===
with torch.no_grad():
x = reference_hidden_state # fixed saved tensor [B, T, 768]
y = specialist(x)
if torch.isnan(y).any():
raise ValueError("Dynamic check failed: NaNs in output")
rms = y.pow(2).mean().sqrt().item()
if not (0.1 < rms < 10.0):
raise ValueError(f"Dynamic check failed: output RMS out of range: {rms:.4f}")
# === Step 10: Build the compliance script ===
def run_compliance(spec: dict, ckpt_path: str) -> tuple[list, list]:
model, metadata = load_specialist(ckpt_path)
failures = []
warnings = []
# Declaration checks
if metadata["interface_name"] != spec["interface_name"]:
failures.append((
"interface_name",
spec["interface_name"],
metadata["interface_name"],
))
# Structural checks
actual_norm = detect_boundary_norm(model)
expected_norm = spec["normalization"]["type"]
if actual_norm != expected_norm:
failures.append(("normalization.type", expected_norm, actual_norm))
actual_d_model = detect_d_model(model)
if actual_d_model != spec["boundary"]["d_model"]:
failures.append((
"boundary.d_model",
spec["boundary"]["d_model"],
actual_d_model,
))
# Dynamic checks
dyn_msg = run_probe(model, spec)
if dyn_msg is not None:
failures.append(("dynamic_probe", "pass", dyn_msg))
return failures, warnings
The Steps
4 reference filesEach step is the code for one piece, in isolation — read them as the book introduces them. They assemble into build.py above.
Step 05Make Specialists Declare What They Arestep_05_make-specialists-declare-what-they-are.py
"""
Project 34: Step 5 — Make specialists declare what they are
Pedagogical reference: this file shows the code for this step in isolation.
For the full assembled, runnable build, use build.py in this same folder.
"""
ckpt["interface"] = {
"interface_name": "COMPOSE-LLM-IFACE",
"interface_version": "1.0",
"base_model_id": "trunk-init-2026-03",
"shared_prefix_depth": 8,
"d_model": 768,
"n_heads": 12,
"norm_type": "RMSNorm",
"norm_eps": 1e-5,
"positional_encoding": "RoPE",
"rope_theta": 10000,
"tokenizer_hash": "sha256:..."
}
Step 06Inspect The Actual Module Not Just The Metadatastep_06_inspect-the-actual-module-not-just-the-metadata.py
"""
Project 34: Step 6 — Inspect the actual module, not just the metadata
Pedagogical reference: this file shows the code for this step in isolation.
For the full assembled, runnable build, use build.py in this same folder.
"""
import torch
def check_norm_type(module: torch.nn.Module, expected: str) -> None:
actual = type(module.norm).__name__
if actual != expected:
raise ValueError(f"Norm mismatch: expected {expected}, found {actual}")
def check_d_model(module: torch.nn.Module, expected: int) -> None:
actual = module.attn.q_proj.weight.shape[1]
if actual != expected:
raise ValueError(f"d_model mismatch: expected {expected}, found {actual}")
def check_vocab_size(module: torch.nn.Module, expected: int) -> None:
actual = module.lm_head.weight.shape[0]
if actual != expected:
raise ValueError(f"Vocab mismatch: expected {expected}, found {actual}")
Step 07Check Behavior Not Just Structurestep_07_check-behavior-not-just-structure.py
"""
Project 34: Step 7 — Check behavior, not just structure
Pedagogical reference: this file shows the code for this step in isolation.
For the full assembled, runnable build, use build.py in this same folder.
"""
with torch.no_grad():
x = reference_hidden_state # fixed saved tensor [B, T, 768]
y = specialist(x)
if torch.isnan(y).any():
raise ValueError("Dynamic check failed: NaNs in output")
rms = y.pow(2).mean().sqrt().item()
if not (0.1 < rms < 10.0):
raise ValueError(f"Dynamic check failed: output RMS out of range: {rms:.4f}")
Step 10Build The Compliance Scriptstep_10_build-the-compliance-script.py
"""
Project 34: Step 10 — Build the compliance script
Pedagogical reference: this file shows the code for this step in isolation.
For the full assembled, runnable build, use build.py in this same folder.
"""
def run_compliance(spec: dict, ckpt_path: str) -> tuple[list, list]:
model, metadata = load_specialist(ckpt_path)
failures = []
warnings = []
# Declaration checks
if metadata["interface_name"] != spec["interface_name"]:
failures.append((
"interface_name",
spec["interface_name"],
metadata["interface_name"],
))
# Structural checks
actual_norm = detect_boundary_norm(model)
expected_norm = spec["normalization"]["type"]
if actual_norm != expected_norm:
failures.append(("normalization.type", expected_norm, actual_norm))
actual_d_model = detect_d_model(model)
if actual_d_model != spec["boundary"]["d_model"]:
failures.append((
"boundary.d_model",
spec["boundary"]["d_model"],
actual_d_model,
))
# Dynamic checks
dyn_msg = run_probe(model, spec)
if dyn_msg is not None:
failures.append(("dynamic_probe", "pass", dyn_msg))
return failures, warnings
Break It
break_it.py$python projects/34_the-interface-specification/break_it.py --tiny
"""
Project 34: BREAK IT experiment.
Deliberately sabotages one mechanism from build.py to show what happens
when it's removed. Compare outputs to the working version.
"""
def parse_headers(raw: bytes) -> dict[str, str]:
headers = {}
for line in raw.decode().split("\r\n"):
if not line or ":" not in line:
continue
k, v = line.split(":", 1)
headers[k.strip().lower()] = v.strip()
return headers
def parse_headers(raw):
line = raw.split(headers)
if ":" in line:
return line.items()
return header
self.norm1 = RMSNorm(d_model, eps=1e-5)
self.norm2 = RMSNorm(d_model, eps=1e-5)
self.norm1 = nn.LayerNorm(d_model, eps=1e-5)
self.norm2 = nn.LayerNorm(d_model, eps=1e-5)
Read it in the book
This page ships the code. The full derivation — why the chain rule is mechanical not magical, what the computational graph buys you, the long-form reasoning — lives in Chapter 34 of Under the Hood.
Get the book →