{"record":{"id":"362646183380008b","repo":"Hmbown/CodeWhale","slug":"receipt-and-budget-must-resolve-to-distinct-filesy","errorCode":null,"errorMessage":"receipt and budget must resolve to distinct filesystem paths","messagePattern":"receipt and budget must resolve to distinct filesystem paths","errorType":"validation","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":635,"sourceCode":"        help=\"check an existing measurement JSON instead of compiling\",\n    )\n    parser.add_argument(\n        \"--budget\",\n        type=Path,\n        default=BUDGET_PATH,\n        help=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--update\",\n        action=\"store_true\",\n        help=\"tighten all ceilings to the current receipt; refuses increases\",\n    )\n    args = parser.parse_args(argv)\n\n    try:\n        check_fragment_caps()\n        if args.receipt is not None and args.receipt.resolve() == args.budget.resolve():\n            raise RuntimeContractError(\n                \"receipt and budget must resolve to distinct filesystem paths\"\n            )\n        budget = load_json(args.budget, \"budget\")\n        receipt = (\n            load_json(args.receipt, \"receipt\")\n            if args.receipt is not None\n            else run_measurement()\n        )\n        increases, decreases = compare(receipt, budget)\n    except RuntimeContractError as error:\n        print(f\"[runtime-contract-budget] ERROR: {error}\", file=sys.stderr)\n        return 2\n\n    if increases:\n        print(\"[runtime-contract-budget] FAIL: runtime contract grew:\", file=sys.stderr)\n        for path, label, current, ceiling in increases:\n            print(\n                f\"  {label}: {current} > {ceiling} (+{current - ceiling}) [{path}]\",","sourceCodeStart":617,"sourceCodeEnd":653,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-runtime-contract-budget.py#L617-L653","documentation":"main() refuses to run when --receipt and --budget resolve (Path.resolve()) to the same file. Comparing a receipt against itself would trivially pass every ceiling, and combined with --update the tool would overwrite the receipt with budget JSON, destroying the measurement evidence. Symlinks and './' versus absolute spellings of the same file are caught because resolve() normalizes them.","triggerScenarios":"'--receipt scripts/runtime-contract-budget.json' (identical to the default budget path); '--receipt r.json --budget r.json'; a symlinked receipt pointing at the budget file.","commonSituations":"Copy-pasting commands from docs; scripted invocations that reuse one path variable for both flags; passing a copied budget as a 'receipt' to skip measuring.","solutions":["Pass distinct files: keep the budget at scripts/runtime-contract-budget.json and point --receipt at a freshly measured receipt from measure-runtime-contract.py","If aliasing was accidental (symlink or relative-path normalization), pass the real distinct paths","In wrapper scripts, assert Path(receipt).resolve() != Path(budget).resolve() before invoking the checker"],"exampleFix":"# before\npython3 scripts/check-runtime-contract-budget.py --receipt scripts/runtime-contract-budget.json\n\n# after\npython3 scripts/measure-runtime-contract.py > /tmp/receipt.json\npython3 scripts/check-runtime-contract-budget.py --receipt /tmp/receipt.json","handlingStrategy":"validation","validationCode":"from pathlib import Path\nreceipt, budget = Path(args.receipt), Path(args.budget)\nassert receipt.resolve() != budget.resolve(), \"receipt and budget must be distinct files\"","typeGuard":"def is_runtime_contract_error(exc: BaseException) -> bool:\n    return isinstance(exc, ValueError) and type(exc).__name__ == \"RuntimeContractError\"","tryCatchPattern":"try:\n    rc = main([\"--receipt\", str(receipt)])\nexcept RuntimeContractError as error:\n    print(f\"[gate] {error}\", file=sys.stderr)\n    raise SystemExit(2)","preventionTips":["Always generate a fresh receipt with measure-runtime-contract.py instead of reusing the budget file","In wrappers, resolve() both paths and assert distinctness before invoking","Never combine --receipt pointing at scripts/runtime-contract-budget.json with --update - it would clobber the input"],"tags":["python","cli","paths","validation"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}