Surface build parity
The failure class: Driftless has three client surfaces (API, MCP adapter, CLI) built from one repo but deployed independently — the MCP adapter can run mounted inside the API process or as its own service. After a deploy, one surface can silently keep serving an older build than the others. It happened: the production MCP served a stale broker tool for days, undetected until an agent hit the old behavior. Schema-level drift between surfaces is caught at CI time by the cross-surface drift guard; a deployed-build skew is invisible to CI by definition — it only exists at runtime. The mechanism (exposure, not enforcement):- API —
GET /version(public) returns the deployedcommit(RENDER_GIT_COMMIT→COMMIT_SHA→unknown, 7-char). - MCP —
GET /mcp/healthreturns the samecommit, andserverInfo.versioncarries it as semver build metadata (0.4.0+abc1234), so any MCP client sees which build it is talking to atinitialize— no extra call. - Doctor —
driftless doctorfetches both and reports one line:ok api abc1234 · mcp abc1234when they match, a loudBUILD SKEW — api serves X, mcp serves Ywarning when they diverge. A standalone MCP deployment is reached viaDRIFTLESS_MCP_URL; without build metadata (local dev) the check reports itself skipped.
apps/api/src/ops/ops.controller.ts and apps/mcp/src/build-info.ts, or the
comparison lies.
Together with the CI schema guard this closes the whole “works on my surface”
class: schema parity before merge, build parity after deploy.