The pairing room was quiet except for a laptop fan. A coding-model patch sat in the working tree: a retry helper, a JSON parser tweak, and a new file named bench.js. The script fired two hundred GETs at /v1/items, printed a mean latency, and asserted that the mean stayed under 300 milliseconds. The unit suite was green. The senior did not type merge.
The junior had treated the green run as evidence. The senior treated it as a story the runner could tell about itself. Green on a shared laptop is not a contract. It is a mood.
What the senior asked before anyone reran the script
The questions were small. They were also enough to stop the merge.
- Which machine is 300ms measured on, and what else is running there?
- What is the recorded baseline for this endpoint, on this commit, with this payload?
- Does the script fail if the server returns 200 with an empty body?
- Does it fail if
Content-Typedrifts fromapplication/jsontotext/plain? - Who signs a change if the body shape moves but the mean latency stays pretty?
None of those had answers in bench.js. The file measured a feeling. It did not measure the bytes on the socket.
Dead end 1: a concurrent hammer with no oracle
The rejected script looked like the block below. It is the pairing artifact that did not survive, not a recommended tool.
// rejected pairing artifact: bench.js
// synthetic load plus a laptop SLA; body bytes are discarded
import http from "node:http";
const N = 200;
const started = Date.now();
let ok = 0;
await Promise.all(
Array.from({ length: N }, () =>
new Promise((resolve, reject) => {
http.get("http://127.0.0.1:3000/v1/items", (res) => {
res.resume();
if (res.statusCode === 200) ok += 1;
resolve();
}).on("error", reject);
})
)
);
const mean = (Date.now() - started) / N;
if (ok !== N) throw new Error(`only ${ok}/${N} succeeded`);
if (mean > 300) throw new Error(`mean ${mean}ms exceeds 300ms`);
console.log(`mean ${mean.toFixed(1)}ms`);
The script never read a byte of the body. res.resume() drained the socket so the process could exit. A handler that returned {} still passed. A truncated list still passed. A cold start on a noisy CI runner could fail for reasons that had nothing to do with the patch.
The senior asked for the body. The next model turn offered to log res.headers. Headers in a console are not an oracle. They are more noise in the same shape as the original assert.
Dead end 2: the threshold became the patch
The second attempt did not fix the measurement. It moved the number.
The model raised 300ms to 800ms "to stabilize CI". Then it wrapped the assert in a retry. Then it suggested skipping the bench on Darwin. Each change made the suite greener. Each change also made the gate less able to see a broken /v1/items.
This is a routine failure when a generator is scored on green runs. The test becomes a knob. The product contract does not. A pairing session that keeps chasing green will eventually merge a knob.
Dead end 3: a unit test that never left the process
The third suggestion was a mocked http.get. The mock returned a fixture object. The parser test went green in a few milliseconds. The live handler could still serialize undefined as a missing key, drop a pagination cursor, or switch the error envelope from { error } to { message }.
The senior kept the mock out of the merge gate. Mocks are fine for parser branches. They are not a substitute for one real response from the process that will run in production. The pair needed a wire, not a stand-in.
The decision the pairing session kept
The pair threw out the load script. They kept a single recorded request against the local server, plus a digest of the bytes that came back.
The gate is deliberately boring:
- Start the app the same way CI starts it.
- Send one request with a frozen method, path, and body.
- Record status,
content-type, and a SHA-256 of the raw body. - Compare those three fields to a committed snapshot.
- Record elapsed time only as a coarse bucket (
fast,ok,slow), never as a millisecond SLA. - Require a pairing signature in the snapshot file if any of the three fields change.
Latency stays in the log. It does not get a vote. A slow runner cannot veto a correct body. A fast runner cannot hide a wrong one.
Worked example: wire_digest_gate.mjs
The following is a labeled, runnable sketch. It is not a published benchmark. It does not claim a latency number for any host.
// worked example: wire_digest_gate.mjs
import http from "node:http";
import { createHash } from "node:crypto";
import { readFileSync, writeFileSync, existsSync } from "node:fs";
const SNAP_PATH = new URL("./wire.snap.json", import.meta.url);
const REQ = {
method: "GET",
path: "/v1/items?limit=10",
headers: { accept: "application/json" },
};
function bucket(ms) {
if (ms < 50) return "fast";
if (ms < 500) return "ok";
return "slow";
}
function fetchOnce() {
const t0 = Date.now();
return new Promise((resolve, reject) => {
const req = http.request(
{
hostname: "127.0.0.1",
port: 3000,
path: REQ.path,
method: REQ.method,
headers: REQ.headers,
},
(res) => {
const chunks = [];
res.on("data", (c) => chunks.push(c));
res.on("end", () => {
const body = Buffer.concat(chunks);
const elapsedMs = Date.now() - t0;
resolve({
status: res.statusCode,
contentType: String(res.headers["content-type"] || ""),
sha256: createHash("sha256").update(body).digest("hex"),
bytes: body.length,
elapsedMs,
latencyBucket: bucket(elapsedMs),
});
});
}
);
req.on("error", reject);
req.end();
});
}
const observed = await fetchOnce();
const record = {
request: REQ,
status: observed.status,
contentType: observed.contentType,
sha256: observed.sha256,
bytes: observed.bytes,
lastLatencyBucket: observed.latencyBucket,
pairingSignature: null,
};
if (process.argv.includes("--update")) {
if (!process.env.PAIRING_SIG) {
throw new Error("refusing to update snapshot without PAIRING_SIG");
}
record.pairingSignature = process.env.PAIRING_SIG;
writeFileSync(SNAP_PATH, JSON.stringify(record, null, 2) + "\n");
console.log("snapshot updated", record.sha256);
process.exit(0);
}
if (!existsSync(SNAP_PATH)) {
throw new Error("no snapshot; run with --update after a pairing review");
}
const snap = JSON.parse(readFileSync(SNAP_PATH, "utf8"));
const fields = ["status", "contentType", "sha256"];
const drift = fields.filter((k) => snap[k] !== record[k]);
console.log(
JSON.stringify(
{
observed: record,
snapshotSha: snap.sha256,
drift,
latencyBucket: observed.latencyBucket,
},
null,
2
)
);
if (drift.length) {
throw new Error(
`wire digest drift on ${drift.join(", ")}. re-record with PAIRING_SIG after a pairing pass`
);
}
A matching snapshot is tiny. It names the humans who accepted the bytes. The hash below is a placeholder, not a measured result.
{
"request": {
"method": "GET",
"path": "/v1/items?limit=10",
"headers": { "accept": "application/json" }
},
"status": 200,
"contentType": "application/json; charset=utf-8",
"sha256": "replace-with-live-body-digest",
"bytes": 1842,
"lastLatencyBucket": "ok",
"pairingSignature": "a-chen + m-okonkwo, 2026-09-21, items list envelope v3"
}
A real run fills sha256 from the live body. Until then the file is not a gate. It is a reminder that someone still has to look.
Commands used in the session
They started the app with the same command CI uses. They hit the gate once. The first snapshot was written only after both people paged the raw body.
# terminal 1 — same entrypoint CI uses
node server.js
# terminal 2 — first record after reading the body
PAIRING_SIG="a-chen + m-okonkwo, 2026-09-21, items list envelope v3" \
node wire_digest_gate.mjs --update
# every later attempt, including model-authored patches
node wire_digest_gate.mjs
When a later model patch "simplified" the list handler, the SHA-256 moved. Status stayed 200. Mean latency would have stayed under 300ms on that laptop. The gate failed. That was the point of the pairing block.
Where a free eval host belongs
A laptop is a bad source of truth for anything that looks like performance. It is also a bad place to paste production responses into a chat window. The pair needed the same command on a machine that was not the pairing laptop, without handing the snapshot to a model to rewrite.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode's free model access and free server option fit one narrow job in this workflow: boot the app and rerun wire_digest_gate.mjs against the committed snapshot. The models may propose a patch. The server may run the gate. Neither path is allowed to update the snapshot. --update still requires PAIRING_SIG from the people in the session.
The product is not the gate. The gate is a short script and a JSON file. If the models are unavailable, the pair still has a merge rule. If the free server is busy, the same command runs on any host that can reach 127.0.0.1:3000. Teams that want the models and the app to share a host can park that rerun there. The snapshot still has to be committed by people.
What this gate does not claim
The pairing notes were explicit about the edges. A small gate that pretends to be a platform will get discarded in the next incident review.
- It is not a load test. Two hundred concurrent sockets were the thing being rejected.
- It is not an SLO. The latency bucket is a log line, not a pass/fail.
- It is not a substitute for auth checks, multi-tenant fixtures, or streaming checks. A SHA-256 of a full body is the wrong tool for an unbounded SSE stream.
- It will fail noisily if the payload contains timestamps, random IDs, or unordered maps. Canonicalize first, or the snapshot becomes a flake generator.
- It does not prove the patch is correct. It proves the wire did not change without a signature.
Teams that already run contract suites (OpenAPI snapshot tests, Pact, property checks against a schema) should not add this as a second religion. Use it when the current suite is green and a model can still change the bytes on the socket. People who need a published p95 should build a real performance harness with a dedicated environment, a warmup, and a baseline commit. That work is out of scope for a pairing block.
Who should not use this approach
- Anyone treating a coding model as the owner of
--update. - Anyone without permission to run the app locally or on an isolated eval host.
- Anyone whose endpoint is non-deterministic and who refuses to canonicalize.
- Anyone hoping an eval box will replace staging.
- Anyone trying to turn a pairing signature into a substitute for code review on auth or data-loss paths.
Those cases need a different tool. This one only answers a smaller question: did the socket still say the same thing after the model touched the handler.
The decision, written down
The pair kept three things and discarded one.
Kept:
- one live request
- status + content-type + body digest
- a pairing signature for snapshot edits
Discarded:
- a model-authored load script with a laptop millisecond budget
The merge message did not mention tokens, winners, or mean latency. It mentioned the digest and the two initials on the snapshot. That is a smaller claim. It is also one a later reader can replay without trusting the machine that happened to be in the room.












