{"record":{"id":"932b128806b723fe","repo":"Hmbown/CodeWhale","slug":"bounded-fragment-module-must-expose-load-project-instruction","errorCode":null,"errorMessage":"bounded fragment module must expose load_project_instruction_fragment (project-instruction import as typed fragment)","messagePattern":"bounded fragment module must expose load_project_instruction_fragment \\(project-instruction import as typed fragment\\)","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":556,"sourceCode":"            if not re.search(rf\"\\b{name}\\b\", text):\n                raise RuntimeContractError(\n                    f\"FragmentId missing required variant {name}\"\n                )\n    # Marker stability — these strings are pinned by tests / prefix cache\n    required_markers = [\n        \"<!-- cw:ctx:workspace -->\",\n        \"<!-- cw:ctx:project_instructions -->\",\n        \"<!-- cw:ctx:constitution -->\",\n    ]\n    for marker in required_markers:\n        if marker not in text:\n            raise RuntimeContractError(\n                f\"bounded fragment module missing required marker {marker!r}\"\n            )\n\n    # Project-instruction import must be a typed fragment, not ad-hoc\n    if \"load_project_instruction_fragment\" not in text:\n        raise RuntimeContractError(\n            \"bounded fragment module must expose load_project_instruction_fragment (project-instruction import as typed fragment)\"\n        )\n    if \"PROJECT_INSTRUCTION_CANDIDATES\" not in text:\n        raise RuntimeContractError(\n            \"bounded fragment module must define PROJECT_INSTRUCTION_CANDIDATES\"\n        )\n    # Required candidate files from #3978\n    required_candidates = [\n        \".cursorrules\",\n        \".clinerules\",\n        \".windsurf/rules\",\n        \".gemini\",\n        \".github/copilot-instructions.md\",\n    ]\n    for candidate in required_candidates:\n        if candidate not in text:\n            raise RuntimeContractError(\n                f\"PROJECT_INSTRUCTION_CANDIDATES missing required entry {candidate!r}\"","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-runtime-contract-budget.py#L538-L574","documentation":"The contract requires that project instructions (e.g. .cursorrules, copilot-instructions.md) are imported through a typed fragment — a dedicated function named load_project_instruction_fragment in the bounded fragment module — rather than injected as ad-hoc text bypassing the byte/count caps. If the function name is absent from fragments.rs, the gate fails because the import path would evade the fragment budget and the audit trail.","triggerScenarios":"Running scripts/check-runtime-contract-budget.py after removing load_project_instruction_fragment from fragments.rs, renaming it, or replacing the typed-fragment import path with an untyped string injection elsewhere in the module.","commonSituations":"Refactoring project-instruction loading into a config layer without the typed fragment wrapper; renaming the function during cleanup; reverting part of the fragment module from an older branch that predates the typed import.","solutions":["Restore (or re-add) `fn load_project_instruction_fragment` in crates/core/src/fragments.rs and route project-instruction imports through it","If the function moved to another module, note the checker only scans fragments.rs — keep an exported definition (or the exact identifier) in that file, or update the script as a reviewed contract change","Also verify PROJECT_INSTRUCTION_CANDIDATES is still defined, as the next gate checks it"],"exampleFix":"// before (ad-hoc import in config layer)\nconfig.push(format!(\"<!-- cw:ctx:project_instructions -->\\n{}\", raw));\n// after (crates/core/src/fragments.rs)\nfn load_project_instruction_fragment() -> Fragment { ... } // typed, capped","handlingStrategy":"validation","validationCode":"src = open('crates/core/src/fragments.rs').read()\nif 'load_project_instruction_fragment' not in src:\n    raise SystemExit('typed project-instruction fragment loader missing')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always import project instructions through the typed fragment path","Grep for ad-hoc `<!-- cw:ctx:project_instructions -->` string building outside the fragment loader during reviews","Keep PROJECT_INSTRUCTION_CANDIDATES and its loader together in fragments.rs"],"tags":["static-check","rust","architecture","ci"],"backgroundTag":"missing-required-argument","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"}