{"record":{"id":"2e5b808ac3250d8c","repo":"Hmbown/CodeWhale","slug":"kind-field-join-path-must-be-a-lowercas","errorCode":null,"errorMessage":"{kind} field `{'.'.join(path)}` must be a lowercase SHA-256 digest","messagePattern":"(.+?) field `(.+?)` must be a lowercase SHA-256 digest","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":243,"sourceCode":"            count = metric_value(document, (*base, \"tools\"), kind)\n            if count != len(names):\n                raise RuntimeContractError(\n                    f\"{kind} metric `{'.'.join((*base, 'tools'))}` must equal the \"\n                    f\"owned tool_names length ({len(names)})\"\n                )\n            digest = required_value(document, (*base, \"identity_sha256\"), kind)\n            expected = tool_identity_digest(names)\n            if digest != expected:\n                raise RuntimeContractError(\n                    f\"{kind} field `{'.'.join((*base, 'identity_sha256'))}` must \"\n                    \"match the owned sorted tool_names\"\n                )\n\n    for stage, _label in REPRESENTATIVE_STAGES:\n        path = (\"representative_context\", \"stages\", stage, \"identity_sha256\")\n        digest = required_value(document, path, kind)\n        if not isinstance(digest, str) or re.fullmatch(r\"[0-9a-f]{64}\", digest) is None:\n            raise RuntimeContractError(\n                f\"{kind} field `{'.'.join(path)}` must be a lowercase SHA-256 digest\"\n            )\n\n\ndef validate_receipt(receipt: dict[str, Any]) -> None:\n    validate_document(receipt, RECEIPT_KIND, \"receipt\")\n    skill_discovery = receipt.get(\"skill_discovery\")\n    identical = (\n        skill_discovery.get(\"prompts_byte_identical\")\n        if isinstance(skill_discovery, dict)\n        else None\n    )\n    if identical is not True:\n        raise RuntimeContractError(\n            \"receipt metric `skill_discovery.prompts_byte_identical` must be true\"\n        )\n    representative = receipt.get(\"representative_context\")\n    fixture_id = (","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-runtime-contract-budget.py#L225-L261","documentation":"Each representative stage (base, project, instructions, skill, memory, goal, handoff) must store representative_context.stages.<stage>.identity_sha256 as a 64-character lowercase hex SHA-256 (re.fullmatch(r\"[0-9a-f]{64}\")). This is a format-only check - unlike error 202 it does not recompute the hash because the stage prompt is not part of the document. It guarantees the value can be compared byte-wise by compare()'s identity loop.","triggerScenarios":"A stage digest that is uppercase hex, shorter or longer than 64 chars, a placeholder like \"TODO\" or \"sha256:...\", a non-string (number/null), or a missing field surfaced through required_value and then type-checked here. Hit in validate_receipt/validate_budget/compare/budget_from_receipt.","commonSituations":"Hand-authoring a test receipt and stubbing digests; a git merge that truncates a line of the budget JSON; tooling that base64-encodes or prefixes digests (sha256:, git-style).","solutions":["Replace the value with the full 64-character lowercase hex digest of the stage's prompt bytes","If the stage prompt legitimately changed, re-measure so the harness recomputes every stage digest, then record the new values in the budget as one decision","Validate the file shape first: python3 -m json.tool scripts/runtime-contract-budget.json"],"exampleFix":"// before\n\"identity_sha256\": \"E1BBB7A700C2ED6E...\"\n\n// after - 64 lowercase hex chars, no prefix\n\"identity_sha256\": \"e1bbb7a700c2ed6eea8d2aad15e60c86d0ac386f0583afc659cfc2527db8ce58\"","handlingStrategy":"validation","validationCode":"import re\n\nSTAGES = (\"base\", \"project\", \"instructions\", \"skill\", \"memory\", \"goal\", \"handoff\")\nSHA256_RE = re.compile(r\"[0-9a-f]{64}\")\n\n\ndef stage_digests_wellformed(doc: dict) -> bool:\n    stages = doc.get(\"representative_context\", {}).get(\"stages\", {})\n    for stage in STAGES:\n        digest = stages.get(stage, {}).get(\"identity_sha256\")\n        if not isinstance(digest, str) or SHA256_RE.fullmatch(digest) is None:\n            return False\n    return True","typeGuard":"import re\n\ndef is_lowercase_sha256(value: object) -> bool:\n    return isinstance(value, str) and re.fullmatch(r\"[0-9a-f]{64}\", value) is not None","tryCatchPattern":null,"preventionTips":["Always copy full 64-char digests from measure output; never retype or truncate them","Avoid `sha256:`-style prefixes in this file - the checker wants bare lowercase hex","Validate edited budget files with a fullmatch regex before committing"],"tags":["python","sha256","regex","validation","system-prompt"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}