{"record":{"id":"066658bc4fb2c7d4","repo":"JuliusBrussee/caveman","slug":"adapter-specific-build-sha256-values-must-differ","errorCode":null,"errorMessage":"adapter-specific build_sha256 values must differ","messagePattern":"adapter-specific build_sha256 values must differ","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/contracts/scripts/validate-schemas.mjs","lineNumber":79,"sourceCode":"if (claude.harness !== \"claude\" || pi.harness !== \"pi\") {\n  throw new Error(\"agent conformance fixtures must cover claude and pi\");\n}\n\nfor (const key of [\n  \"normalized_context_digest\",\n  \"plan_sha256\",\n  \"ordered_transform_ids\",\n  \"provider_visible_digest\",\n  \"recovery_handles\",\n  \"accounting_method\",\n  \"failure_fallback\",\n]) {\n  if (JSON.stringify(claude[key]) !== JSON.stringify(pi[key])) {\n    throw new Error(`agent conformance mismatch: ${key}`);\n  }\n}\nif (claude.build_sha256 === pi.build_sha256) {\n  throw new Error(\"adapter-specific build_sha256 values must differ\");\n}\nif (claude.failure_fallback !== \"original\") {\n  throw new Error(\"unknown adapter failure must preserve original bytes\");\n}\n\nconst middleware = JSON.parse(await readFile(path.join(packageRoot, \"..\", \"..\", \"sdk\", \"parity\", \"middleware.fixtures.json\"), \"utf8\"));\nfor (const [field, schemaName] of Object.entries({ capabilities: \"capabilities\", request: \"optimize\", plan: \"plan\", page: \"page\" })) {\n  const validate = ajv.getSchema(`https://caveman.so/schemas/middleware-${schemaName}.schema.json`);\n  if (!validate?.(middleware[field])) throw new Error(`middleware ${field}: ${ajv.errorsText(validate?.errors)}`);\n}\n\nconsole.log(\n  `validated ${files.length} JSON schemas and ${fixtureFiles.length} static agent contract fixtures (not executable parity)`,\n);\n","sourceCodeStart":61,"sourceCodeEnd":94,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/shared/contracts/scripts/validate-schemas.mjs#L61-L94","documentation":"The validator asserts that the two adapter fixtures' build_sha256 values are DIFFERENT (`if (claude.build_sha256 === pi.build_sha256) throw`). Each harness has its own build artifact, so identical hashes mean the fixture was copy-pasted, a placeholder value was reused, or the digest computation is wrong. This is an anti-collapse check complementing the field-equality checks for the shared contract keys.","triggerScenarios":"Running the contracts validation script when: build_sha256 in pi-conformance.json was copied from claude-conformance.json (or vice versa) while templating; both fixtures were regenerated with a script that hashed the same artifact; a placeholder/zero hash was pasted into both files; fixtures were merged and one file's distinct hash got overwritten with the other's.","commonSituations":"Creating a new fixture by duplicating the sibling file and forgetting to swap build_sha256; generating fixtures in CI from a single artifact by mistake; a bot auto-filling missing fields with the previously seen value; a bad sed/replace that normalized both hashes.","solutions":["Compute the real build artifact hash for each harness separately and put each one in its own fixture's build_sha256.","If a fixture was copy-pasted, verify every adapter-specific field (harness, build_sha256, upstream_version) after duplication.","If builds genuinely produce identical artifacts, investigate the build pipeline — the adapters should produce distinct build_sha256 values per harness.","Re-run the validation script to confirm the hashes now differ."],"exampleFix":"// before (pi-conformance.json)\n\"build_sha256\": \"19ca7cd98e52d928f70839a303e48ef3d7d8b0fb84d4ea0725f2a1ef307c98a7\"\n\n// after\n\"build_sha256\": \"76287b2d2d18e4a69aaae9f7f65a32f9eb34dc4a4bfa24d86d10a5f948a4ed31\"","handlingStrategy":"validation","validationCode":"const [a, b] = fixtures;\nif (a.build_sha256 === b.build_sha256) {\n  throw new Error(\"build_sha256 identical; recompute per-harness artifact hashes\");\n}","typeGuard":"function hasDistinctBuilds(fixtures) {\n  return new Set(fixtures.map(f => f.build_sha256)).size === fixtures.length;\n}","tryCatchPattern":"try {\n  await runValidationScript();\n} catch (err) {\n  if (err.message === \"adapter-specific build_sha256 values must differ\") {\n    console.error(\"A build_sha256 was copy-pasted between fixtures; recompute each harness's hash.\");\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Never duplicate one fixture as a template without replacing every adapter-specific field (harness, build_sha256, upstream_version).","Generate build_sha256 from each harness's actual build artifact in CI, not manually.","Review fixture diffs for identical hash values before merging."],"tags":["build","fixtures","checksum","contract-parity"],"backgroundTag":"checksum-mismatch","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}