{"record":{"id":"e8ac6c5a5fdebbd3","repo":"Hmbown/CodeWhale","slug":"receipt-source-dirty-must-be-boolean","errorCode":null,"errorMessage":"receipt source_dirty must be boolean","messagePattern":"receipt source_dirty must be boolean","errorType":"validation","errorClass":"PersistenceBacklogError","httpStatus":null,"severity":"error","filePath":"scripts/check-persistence-backlog-budget.py","lineNumber":158,"sourceCode":"    require_clean_source: bool = False,\n) -> None:\n    missing = [field for field in REQUIRED_RECEIPT_FIELDS if field not in receipt]\n    if missing:\n        raise PersistenceBacklogError(\n            \"receipt missing required field(s): \" + \", \".join(missing)\n        )\n    if receipt[\"document_kind\"] != RECEIPT_KIND:\n        raise PersistenceBacklogError(f\"receipt document_kind must be {RECEIPT_KIND}\")\n    if receipt[\"schema_version\"] != SCHEMA_VERSION:\n        raise PersistenceBacklogError(\"receipt schema_version changed\")\n    for field, expected in FIXTURE.items():\n        validate_frozen_field(field, receipt[field], expected)\n    if not isinstance(receipt[\"source_sha\"], str) or not SOURCE_SHA_PATTERN.fullmatch(\n        receipt[\"source_sha\"]\n    ):\n        raise PersistenceBacklogError(\"receipt source_sha must be an exact lowercase Git SHA\")\n    if type(receipt[\"source_dirty\"]) is not bool:\n        raise PersistenceBacklogError(\"receipt source_dirty must be boolean\")\n    for field, prefix in ((\"rustc_version\", \"rustc \"), (\"cargo_version\", \"cargo \")):\n        if not isinstance(receipt[field], str) or not receipt[field].startswith(prefix):\n            raise PersistenceBacklogError(f\"receipt {field} must be a version string\")\n    validate_frozen_field(\"build_profile\", receipt[\"build_profile\"], \"test\")\n    validate_frozen_field(\"sample_count\", receipt[\"sample_count\"], 1)\n    if expected_source is not None:\n        for field in (\n            \"source_sha\",\n            \"source_dirty\",\n            \"rustc_version\",\n            \"cargo_version\",\n            \"build_profile\",\n            \"sample_count\",\n        ):\n            if receipt[field] != expected_source[field]:\n                raise PersistenceBacklogError(\n                    f\"receipt {field} does not match the checked source\"\n                )","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-persistence-backlog-budget.py#L140-L176","documentation":"`receipt.source_dirty` must be a JSON boolean (`type(...) is bool`). This field records whether the git working tree had uncommitted changes when the measurement ran, and it is used both for provenance matching and for the clean-tree requirement (`require_clean_source`). Strings like \"false\", integers 0/1, or null are all rejected because they would break strict provenance comparison.","triggerScenarios":"A hand-edited receipt sets `\"source_dirty\": \"false\"` or `0`; a JSON producer serializes a Python truthy value without casting to bool; the field is null.","commonSituations":"Manually authoring receipts and typing the value as a string; an older generator emitting 0/1 from a shell exit code; editing JSON in a templating language where booleans render as strings.","solutions":["Change the field to a JSON boolean: `\"source_dirty\": false` (or true)","Recompute it with `git status --porcelain` and store `bool(output.strip())`","Regenerate the receipt via the measurement script rather than editing by hand"],"exampleFix":"// before\n\"source_dirty\": \"false\"\n// after\n\"source_dirty\": false","handlingStrategy":"type-guard","validationCode":"assert type(receipt.get(\"source_dirty\")) is bool, repr(receipt.get(\"source_dirty\"))","typeGuard":"def is_strict_bool(v):\n    return type(v) is bool  # rejects 0/1 and \"false\"","tryCatchPattern":"try:\n    validate_receipt(receipt)\nexcept PersistenceBacklogError as e:\n    if \"source_dirty must be boolean\" in str(e):\n        receipt[\"source_dirty\"] = bool(receipt[\"source_dirty\"]) in (True, False) and receipt[\"source_dirty\"] is not None","preventionTips":["Serialize booleans as JSON true/false, never \"true\"/\"false\" strings or 0/1","Compute source_dirty with bool(git_status_output) at generation time","Validate receipts at generation time, not only at check time"],"tags":["json","type-mismatch","validation","receipt"],"backgroundTag":"config-type-mismatch","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}