{"record":{"id":"2acbeefa1c0e8b57","repo":"Hmbown/CodeWhale","slug":"budget-schema-version-changed","errorCode":null,"errorMessage":"budget schema_version changed","messagePattern":"budget schema_version changed","errorType":"console","errorClass":"PersistenceBacklogError","httpStatus":null,"severity":"error","filePath":"scripts/check-persistence-backlog-budget.py","lineNumber":246,"sourceCode":"            non_negative_integer(receipt[field], field)\n        before = receipt[\"rss_before_bytes\"]\n        if receipt[\"rss_during_delta_bytes\"] != max(\n            0, receipt[\"rss_during_bytes\"] - before\n        ):\n            raise PersistenceBacklogError(\"rss_during_delta_bytes is inconsistent\")\n        if receipt[\"rss_after_delta_bytes\"] != max(\n            0, receipt[\"rss_after_bytes\"] - before\n        ):\n            raise PersistenceBacklogError(\"rss_after_delta_bytes is inconsistent\")\n    elif any(receipt[field] is not None for field in rss_fields):\n        raise PersistenceBacklogError(\"unsupported RSS fields must be null\")\n\n\ndef validate_budget(budget: dict[str, Any]) -> None:\n    if budget.get(\"document_kind\") != BUDGET_KIND:\n        raise PersistenceBacklogError(f\"budget document_kind must be {BUDGET_KIND}\")\n    if budget.get(\"schema_version\") != SCHEMA_VERSION:\n        raise PersistenceBacklogError(\"budget schema_version changed\")\n    fixture = budget.get(\"fixture\")\n    if not isinstance(fixture, dict) or set(fixture) != set(FIXTURE):\n        raise PersistenceBacklogError(\"budget fixture no longer matches the frozen workload\")\n    for field, expected in FIXTURE.items():\n        if type(fixture[field]) is not type(expected) or fixture[field] != expected:\n            raise PersistenceBacklogError(\n                f\"budget fixture.{field} must remain {expected!r}\"\n            )\n    if budget.get(\"baseline_receipt\") != BASELINE_RECEIPT_REFERENCE:\n        raise PersistenceBacklogError(\"budget baseline_receipt path changed\")\n    ceilings = budget.get(\"ceilings\")\n    baseline = budget.get(\"baseline_observation\")\n    if not isinstance(ceilings, dict) or not isinstance(baseline, dict):\n        raise PersistenceBacklogError(\"budget needs ceilings and baseline_observation objects\")\n    for field in CEILING_FIELDS:\n        ceiling = non_negative_integer(ceilings.get(field), f\"ceilings.{field}\")\n        observed = non_negative_integer(\n            baseline.get(field), f\"baseline_observation.{field}\"","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-persistence-backlog-budget.py#L228-L264","documentation":"validate_budget rejects a budget whose schema_version does not equal SCHEMA_VERSION (2). The checker enforces a one-way schema: an old budget written against schema version 1 (or a future one) is not interpretable under the current contract. This prevents silently comparing a current receipt against a stale budget layout.","triggerScenarios":"compare calls validate_budget on scripts/persistence-backlog-budget.json (or a --budget override) whose schema_version field is absent or not 2, e.g. after the script bumped SCHEMA_VERSION without regenerating the committed budget.","commonSituations":"Pulling new code with an updated schema while an old local budget file remains; editing the budget by hand and dropping the field; cherry-picking a script change without its budget regeneration commit.","solutions":["Update the budget's schema_version to 2 and regenerate its ceilings/baseline_observation per the new schema","Re-run the measurement flow that produces the budget for the current schema","Restore the budget file matching the checked-out script version from git"],"exampleFix":"// before\n{ \"schema_version\": 1, ... }\n// after\n{ \"schema_version\": 2, ... }","handlingStrategy":"validation","validationCode":"budget = json.load(open(\"scripts/persistence-backlog-budget.json\"))\nassert budget.get(\"schema_version\") == 2, f\"budget schema is {budget.get('schema_version')}, script requires 2\"","typeGuard":"def is_current_schema(doc):\n    return isinstance(doc, dict) and doc.get(\"schema_version\") == 2","tryCatchPattern":"try:\n    validate_budget(budget)\nexcept PersistenceBacklogError as e:\n    if \"schema_version changed\" in str(e):\n        print(\"regenerate the budget for the current schema before checking\")\n    raise","preventionTips":["After pulling script changes, regenerate or restore the committed budget in the same step","Check schema_version before hand-editing a budget","Keep budget regeneration and script schema bumps in one commit"],"tags":["validation","budget","schema-version"],"backgroundTag":"schema-validation-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"}