{"record":{"id":"296882440a24ab0f","repo":"Hmbown/CodeWhale","slug":"persistence-measurement-source-tree-is-dirty","errorCode":null,"errorMessage":"persistence measurement source tree is dirty","messagePattern":"persistence measurement source tree is dirty","errorType":"validation","errorClass":"PersistenceBacklogError","httpStatus":null,"severity":"error","filePath":"scripts/check-persistence-backlog-budget.py","lineNumber":178,"sourceCode":"        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                )\n    if require_clean_source and receipt[\"source_dirty\"]:\n        raise PersistenceBacklogError(\"persistence measurement source tree is dirty\")\n    platform = receipt[\"platform\"]\n    if not isinstance(platform, str) or platform not in SUPPORTED_PLATFORMS:\n        raise PersistenceBacklogError(\"receipt platform is unsupported\")\n\n    attempted = non_negative_integer(receipt[\"requests_attempted\"], \"requests_attempted\")\n    accepted = non_negative_integer(receipt[\"accepted_requests\"], \"accepted_requests\")\n    if accepted != attempted:\n        raise PersistenceBacklogError(\n            \"accepted_requests must equal requests_attempted; sender rejection is not backlog improvement\"\n        )\n    retained = non_negative_integer(\n        receipt[\"retained_queued_requests\"], \"retained_queued_requests\"\n    )\n    if retained > accepted:\n        raise PersistenceBacklogError(\"retained_queued_requests exceeds accepted_requests\")\n    for field in (\"estimated_retained_payload_bytes\", \"enqueue_elapsed_ns\"):\n        non_negative_integer(receipt[field], field)\n    if retained == 0 or receipt[\"estimated_retained_payload_bytes\"] == 0:","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-persistence-backlog-budget.py#L160-L196","documentation":"When the checker runs with `require_clean_source=True` (always in main for the measured/receipt check), the receipt's `source_dirty` flag must be false. A dirty tree means the measurement may not correspond to any committed source revision, so performance numbers are not reproducible and the budget comparison would be untrustworthy. The error fires when the receipt records uncommitted changes at measurement time.","triggerScenarios":"Running the checker with uncommitted edits in the working tree; a receipt generated on a dirty tree is later validated with require_clean_source; untracked files present when `git status --porcelain --untracked-files=normal` runs (untracked files count as dirty).","commonSituations":"Editing code, then running the persistence check before committing; CI artifacts (logs, build outputs) left in the tree; checking out a receipt generated during local experimentation.","solutions":["Commit or stash all changes (including untracked files, or add them to .gitignore) and re-run the measurement so source_dirty is false","Regenerate the receipt on a clean tree: `git status --porcelain` must output nothing before measuring","Remove or ignore stray generated files that make `git status` non-empty"],"exampleFix":"// before\n$ git status --porcelain\n M crates/tui/src/main.rs\n$ python scripts/check-persistence-backlog-budget.py\nERROR: persistence measurement source tree is dirty\n// after\n$ git stash -u\n$ python scripts/check-persistence-backlog-budget.py\nPASS: one-way ceilings respected","handlingStrategy":"validation","validationCode":"import subprocess\ndirty = bool(subprocess.run([\"git\",\"status\",\"--porcelain\",\"--untracked-files=normal\"], capture_output=True, text=True).stdout.strip())\nassert not dirty, \"commit/stash changes before measuring\"","typeGuard":null,"tryCatchPattern":"try:\n    compare(receipt, budget, require_clean_source=True)\nexcept PersistenceBacklogError as e:\n    if \"source tree is dirty\" in str(e):\n        stash_or_commit_then_remeasure()","preventionTips":["Run `git status --porcelain` before measuring; require empty output","Commit or stash -u before running budget checks (untracked files count as dirty)","Add generated artifacts to .gitignore so they do not dirty the tree","Make the clean-tree check part of CI so local dirt never produces receipts"],"tags":["git","clean-tree","reproducibility","validation"],"backgroundTag":"git-command-failed","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"}