{"record":{"id":"e21ceaaf6d03b975","repo":"Hmbown/CodeWhale","slug":"tui-model-context-fragment-rs-must-re-export-caps","errorCode":null,"errorMessage":"TUI model_context/fragment.rs must re-export caps from codewhale_core::fragments (shared crates/core boundary)","messagePattern":"TUI model_context/fragment\\.rs must re-export caps from codewhale_core::fragments \\(shared crates/core boundary\\)","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":595,"sourceCode":"            \"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:\n        raise RuntimeContractError(\n            \"TUI model_context/fragment.rs must re-export caps from codewhale_core::fragments (shared crates/core boundary)\"\n        )\n    if \"ProjectInstructions\" not in tui_text:\n        raise RuntimeContractError(\n            \"TUI fragment module must include ProjectInstructions variant (unified with core)\"\n        )\n    if \"MAX_FRAGMENT_BYTES\" not in tui_text:\n        raise RuntimeContractError(\n            \"TUI fragment module must enforce MAX_FRAGMENT_BYTES (10K-token ceiling)\"\n        )\n    if \"matches_text\" not in tui_text:\n        raise RuntimeContractError(\n            \"TUI fragment module must expose a matches_text recognizer\"\n        )\n\n\ndef main(argv: Sequence[str] | None = None) -> int:\n    parser = argparse.ArgumentParser(description=__doc__)","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-runtime-contract-budget.py#L577-L613","documentation":"The TUI fragment module must be a thin layer over the core boundary: the substring 'codewhale_core::fragments' (a use/re-export path) must appear in crates/tui/src/model_context/fragment.rs. This prevents the historical regression of a TUI-local duplicate of the fragment caps drifting from crates/core. Renaming the crate, changing the module path, or re-implementing caps locally triggers it.","triggerScenarios":"Removing 'use codewhale_core::fragments::...' in favor of local 'pub const MAX_FRAGMENT_BYTES: usize = 40_000;'; renaming the crate or moving the module so the path becomes codewhale_core::context::fragments.","commonSituations":"Crate or module renames during packaging; 'self-contained tui' experiments; copy-paste fixes that bypass the re-export.","solutions":["Restore 'use codewhale_core::fragments::{...};' (or a pub use) in crates/tui/src/model_context/fragment.rs","Never redefine fragment caps inside the tui crate - import them from core","If the core module path changed, update the Rust imports and the gate string at scripts/check-runtime-contract-budget.py:594 together"],"exampleFix":"// before (crates/tui/src/model_context/fragment.rs)\npub const MAX_FRAGMENT_BYTES: usize = 40_000; // local duplicate\n\n// after\npub use codewhale_core::fragments::{FragmentId, MAX_FRAGMENT_BYTES, DEFAULT_FRAGMENT_MAX_BYTES};","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\ntui = Path(\"crates/tui/src/model_context/fragment.rs\").read_text(encoding=\"utf-8\")\nassert \"codewhale_core::fragments\" in tui, \"TUI must re-export caps from codewhale_core::fragments\"","typeGuard":"def is_runtime_contract_error(exc: BaseException) -> bool:\n    return isinstance(exc, ValueError) and type(exc).__name__ == \"RuntimeContractError\"","tryCatchPattern":"try:\n    check_fragment_caps()\nexcept RuntimeContractError as error:\n    print(f\"[gate] {error}\", file=sys.stderr)\n    raise SystemExit(2)","preventionTips":["Never define fragment caps inside crates/tui - import them from codewhale_core::fragments","On crate or module renames, update Rust imports and the gate substring together","Code-review rule: any 'pub const MAX_FRAGMENT_BYTES' outside crates/core is a defect"],"tags":["python","ci","static-analysis","rust","tui","architecture"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}