{"record":{"id":"d1ca70d207bd8414","repo":"Hmbown/CodeWhale","slug":"bounded-fragment-module-must-define-trait-contextfragment","errorCode":null,"errorMessage":"bounded fragment module must define trait ContextFragment with matches_text","messagePattern":"bounded fragment module must define trait ContextFragment with matches_text","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":583,"sourceCode":"        \".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}\"\n            )\n\n    # matches_text recognizer must exist on the fragment trait\n    if \"fn matches_text\" not in text:\n        raise RuntimeContractError(\n            \"bounded fragment module must define a matches_text recognizer on the fragment trait\"\n        )\n    if \"trait ContextFragment\" not in text:\n        raise RuntimeContractError(\n            \"bounded fragment module must define trait ContextFragment with matches_text\"\n        )\n\n    # No unbounded fragment — enforce that creation clamps to MAX_FRAGMENT_BYTES\n    if \"MAX_FRAGMENT_BYTES\" not in text or \"enforce_byte_cap\" not in text:\n        raise RuntimeContractError(\n            \"bounded fragment module must enforce byte caps via enforce_byte_cap and MAX_FRAGMENT_BYTES\"\n        )\n\n    # TUI must be unified with the core boundary (shared crates/core module)\n    tui_fragment = REPO_ROOT / \"crates\" / \"tui\" / \"src\" / \"model_context\" / \"fragment.rs\"\n    try:\n        tui_text = tui_fragment.read_text(encoding=\"utf-8\")\n    except FileNotFoundError as error:\n        raise RuntimeContractError(\n            f\"missing TUI fragment module: {tui_fragment} ({error})\"\n        ) from error\n    if \"codewhale_core::fragments\" not in tui_text:","sourceCodeStart":565,"sourceCodeEnd":601,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-runtime-contract-budget.py#L565-L601","documentation":"check_fragment_caps requires crates/core/src/fragments.rs to declare `trait ContextFragment` (with matches_text), making fragments a typed trait rather than ad-hoc strings. If the literal 'trait ContextFragment' is missing from the module text the check raises this error. This pins the fragment abstraction to its canonical trait name in the shared core crate.","triggerScenarios":"Running the contract check when fragments.rs contains matches_text but no `trait ContextFragment` declaration — the trait was renamed (e.g. to Fragment), moved to another module, or the file only has impls for a trait defined elsewhere.","commonSituations":"A trait rename during refactor; trait hoisted into a new fragments/ directory module leaving fragments.rs without the declaration; a generated or templated module scaffold missing the trait; git revert dropping the trait block.","solutions":["Declare `pub trait ContextFragment` in crates/core/src/fragments.rs, including a `fn matches_text` method.","If the trait was renamed, revert the rename or re-introduce `trait ContextFragment` as the canonical name in fragments.rs.","Keep both the trait and its matches_text method in the same file — the checker greps fragments.rs only."],"exampleFix":"// before (fragments.rs — trait living in another module)\npub use crate::context::Fragment as ContextFragment;\n\n// after\npub trait ContextFragment {\n    fn matches_text(&self, text: &str) -> bool;\n}","handlingStrategy":"validation","validationCode":"text = open('crates/core/src/fragments.rs').read()\nassert 'trait ContextFragment' in text, 'fragments.rs must declare trait ContextFragment'","typeGuard":"def has_context_fragment_trait(module_text: str) -> bool:\n    return 'trait ContextFragment' in module_text","tryCatchPattern":"try:\n    check_fragment_caps()\nexcept RuntimeContractError as e:\n    if 'trait ContextFragment' in str(e):\n        declare_context_fragment_trait_in_fragments_rs()","preventionTips":["Keep the ContextFragment trait declaration and its matches_text method in the same file (crates/core/src/fragments.rs).","When introducing a fragments/ directory, keep fragments.rs as the canonical location or update the checker's FRAGMENT_MODULE path in the same change.","Grep for 'ContextFragment' in the scripts/ directory before any trait rename."],"tags":["rust","static-analysis","contract-check","fragments"],"backgroundTag":"method-not-implemented","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"}