Hmbown/CodeWhale · error · RuntimeContractError

{kind} field `{'.'.join(path)}` must be a lowercase SHA-256

Error message

{kind} field `{'.'.join(path)}` must be a lowercase SHA-256 digest

What it means

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.

Source

Thrown at scripts/check-runtime-contract-budget.py:243

            count = metric_value(document, (*base, "tools"), kind)
            if count != len(names):
                raise RuntimeContractError(
                    f"{kind} metric `{'.'.join((*base, 'tools'))}` must equal the "
                    f"owned tool_names length ({len(names)})"
                )
            digest = required_value(document, (*base, "identity_sha256"), kind)
            expected = tool_identity_digest(names)
            if digest != expected:
                raise RuntimeContractError(
                    f"{kind} field `{'.'.join((*base, 'identity_sha256'))}` must "
                    "match the owned sorted tool_names"
                )

    for stage, _label in REPRESENTATIVE_STAGES:
        path = ("representative_context", "stages", stage, "identity_sha256")
        digest = required_value(document, path, kind)
        if not isinstance(digest, str) or re.fullmatch(r"[0-9a-f]{64}", digest) is None:
            raise RuntimeContractError(
                f"{kind} field `{'.'.join(path)}` must be a lowercase SHA-256 digest"
            )


def validate_receipt(receipt: dict[str, Any]) -> None:
    validate_document(receipt, RECEIPT_KIND, "receipt")
    skill_discovery = receipt.get("skill_discovery")
    identical = (
        skill_discovery.get("prompts_byte_identical")
        if isinstance(skill_discovery, dict)
        else None
    )
    if identical is not True:
        raise RuntimeContractError(
            "receipt metric `skill_discovery.prompts_byte_identical` must be true"
        )
    representative = receipt.get("representative_context")
    fixture_id = (

View on GitHub (pinned to 8880682c63)

Solutions

  1. Replace the value with the full 64-character lowercase hex digest of the stage's prompt bytes
  2. 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
  3. Validate the file shape first: python3 -m json.tool scripts/runtime-contract-budget.json

Example fix

// before
"identity_sha256": "E1BBB7A700C2ED6E..."

// after - 64 lowercase hex chars, no prefix
"identity_sha256": "e1bbb7a700c2ed6eea8d2aad15e60c86d0ac386f0583afc659cfc2527db8ce58"
Defensive patterns

Strategy: validation

Validate before calling

import re

STAGES = ("base", "project", "instructions", "skill", "memory", "goal", "handoff")
SHA256_RE = re.compile(r"[0-9a-f]{64}")


def stage_digests_wellformed(doc: dict) -> bool:
    stages = doc.get("representative_context", {}).get("stages", {})
    for stage in STAGES:
        digest = stages.get(stage, {}).get("identity_sha256")
        if not isinstance(digest, str) or SHA256_RE.fullmatch(digest) is None:
            return False
    return True

Type guard

import re

def is_lowercase_sha256(value: object) -> bool:
    return isinstance(value, str) and re.fullmatch(r"[0-9a-f]{64}", value) is not None

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/2e5b808ac3250d8c. Report an issue: GitHub.