Chapter 02
Surface contracts
A surface contract is the JSON document that tells Holonograph what an evaluation surface should look like — its dimensions, cohort tags, substrate columns, and vendor routings — before any real traffic hits it. Everything downstream (event ingest, snapshot queries, topology gap-finding) reads from the contract you registered here.
What it is
A surface is the operator's unit of evaluation — one addressable thing your agent calls, with a stable id and a shape you expect it to satisfy. A contract is the versioned declaration of that shape.
Contracts declare four things per surface:
- Dimensions — the scoring axes an evaluation returns (e.g.
correctness,tone,schema-conformance). - Cohort tags — the discrete labels you use to slice results (e.g.
customer-tier=enterprise,fix_tier=tool-input-schema). - Substrate columns — the named columns Holonograph captures with every call, so a later reading can be attributed to what changed about your deployment. See Substrate columns.
- Routings — which vendor(s) this surface calls, including multiplex arrays for head-to-head comparison. See The multiplexer.
Contracts are versioned by replacement, not mutation: you register a new contract, the agent identifier stays, and Holonograph records a versionId so past events remain readable against the shape they were captured under.
Why it matters
Two things become possible once a contract exists:
- The lens knows what to expect. Ingested events are validated against the contract's declared dimensions and columns; anything that doesn't match is flagged, not silently accepted.
- Coverage becomes measurable. The topology scanner (Chapter 09) compares what you declared against what the lens observed and surfaces the gaps — declared-but-never-observed dimensions, observed-but-never-declared ones, retirement candidates. That whole comparison exists because there is a contract to compare against.
How to use it
Register or replace
Send the contract JSON via the SDK or directly to the endpoint. Registration replaces the previous version for the same agentId; the response returns a ContractSummary reflecting the newly-active shape.
// SDK
const summary = await client.contract.register({
agentId: "billing-triage",
surfaces: [
{
id: "classify-intent",
dimensions: [
{ id: "correctness", type: "score" },
{ id: "schema-conformance", type: "boolean" }
],
cohortTags: ["customer-tier", "fix_tier"],
substrateColumns: [
{ id: "prompt_hash", control: "operator", visibility: "transparent", semantic: "deployment-state" },
{ id: "tool_schema_version", control: "operator", visibility: "transparent", semantic: "deployment-state" }
],
routings: [
{ surfaceId: "classify-intent", lightSourceId: "anthropic/claude-sonnet-5" }
]
}
]
});
Or over HTTP:
POST /holonograph/contract
Authorization: Bearer <token>
x-holonograph-run-mode: production
Content-Type: application/json
{ "agentId": "billing-triage", "surfaces": [ ... ] }
Read back the active contract
GET /holonograph/contract returns the same ContractSummary shape as the register response — useful for reconciliation in CI or a startup check.
Reading the output
A ContractSummary is the compact readback of what's actually in effect. It's the shape you'd diff in a code review of a contract change.
| Field | Shape | What it tells you |
|---|---|---|
agentId | string | The registered agent identifier. |
versionId | string (opt) | The version this summary reflects. Absent on first registration. |
surfaces[] | array | One entry per surface in the contract. |
surfaces[].id | string | The surface identifier. |
surfaces[].status | enum | Whether the surface is active, forward-declared, or retired. |
surfaces[].dimensionCount | number | Count of declared dimensions. |
surfaces[].cohortTagCount | number | Count of declared cohort tags. |
surfaces[].substrateColumnCount | number | Count of substrate columns declared for this surface. |
surfaces[].gatedDimensionIds[] | string[] | Dimensions currently under a governance hold. |
surfaces[].removedDimensions[] | array | Dimensions removed in this or a prior version, each with a supersededBy reference. |
surfaces[].removedCohortTags[] | array | Cohort tags removed, each with a supersededBy reference. |
pricing | object (opt) | Per-surface pricing declarations, if configured. |
systemSurfaces | object (opt) | System-managed surfaces the contract enables (e.g. drafter, judge). |
The supersededBy reference on removed dimensions and cohort tags carries the altitude of the change (surface, dimension, tag) and, where applicable, the id of the replacement — so a later readback of history can tell a promotion from a retirement without ambiguity.
Reference
Endpoints
| Method & path | Purpose |
|---|---|
POST /holonograph/contract | Register or replace the active surface contract for an agent. |
GET /holonograph/contract | Read back the active ContractSummary. |
Headers
Authorization: Bearer <token>— when the deployment enables bearer auth.x-holonograph-run-mode: <mode>— the run mode this call belongs to; see Run modes.
Error envelope
Every error response follows the same shape:
{
"error": "human message",
"code": "error_code",
"details": { }
}
4xx covers validation, auth, and not-found. 5xx is internal. 501 means the feature isn't wired on this deployment.