Hmbown/CodeWhale · error · RuntimeContractError

TUI model_context/fragment.rs must re-export caps from codew

Error message

TUI model_context/fragment.rs must re-export caps from codewhale_core::fragments (shared crates/core boundary)

What it means

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.

Source

Thrown at scripts/check-runtime-contract-budget.py:595

            "bounded fragment module must define trait ContextFragment with matches_text"
        )

    # No unbounded fragment — enforce that creation clamps to MAX_FRAGMENT_BYTES
    if "MAX_FRAGMENT_BYTES" not in text or "enforce_byte_cap" not in text:
        raise RuntimeContractError(
            "bounded fragment module must enforce byte caps via enforce_byte_cap and MAX_FRAGMENT_BYTES"
        )

    # TUI must be unified with the core boundary (shared crates/core module)
    tui_fragment = REPO_ROOT / "crates" / "tui" / "src" / "model_context" / "fragment.rs"
    try:
        tui_text = tui_fragment.read_text(encoding="utf-8")
    except FileNotFoundError as error:
        raise RuntimeContractError(
            f"missing TUI fragment module: {tui_fragment} ({error})"
        ) from error
    if "codewhale_core::fragments" not in tui_text:
        raise RuntimeContractError(
            "TUI model_context/fragment.rs must re-export caps from codewhale_core::fragments (shared crates/core boundary)"
        )
    if "ProjectInstructions" not in tui_text:
        raise RuntimeContractError(
            "TUI fragment module must include ProjectInstructions variant (unified with core)"
        )
    if "MAX_FRAGMENT_BYTES" not in tui_text:
        raise RuntimeContractError(
            "TUI fragment module must enforce MAX_FRAGMENT_BYTES (10K-token ceiling)"
        )
    if "matches_text" not in tui_text:
        raise RuntimeContractError(
            "TUI fragment module must expose a matches_text recognizer"
        )


def main(argv: Sequence[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description=__doc__)

View on GitHub (pinned to 8880682c63)

Solutions

  1. Restore 'use codewhale_core::fragments::{...};' (or a pub use) in crates/tui/src/model_context/fragment.rs
  2. Never redefine fragment caps inside the tui crate - import them from core
  3. If the core module path changed, update the Rust imports and the gate string at scripts/check-runtime-contract-budget.py:594 together

Example fix

// before (crates/tui/src/model_context/fragment.rs)
pub const MAX_FRAGMENT_BYTES: usize = 40_000; // local duplicate

// after
pub use codewhale_core::fragments::{FragmentId, MAX_FRAGMENT_BYTES, DEFAULT_FRAGMENT_MAX_BYTES};
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
tui = Path("crates/tui/src/model_context/fragment.rs").read_text(encoding="utf-8")
assert "codewhale_core::fragments" in tui, "TUI must re-export caps from codewhale_core::fragments"

Type guard

def is_runtime_contract_error(exc: BaseException) -> bool:
    return isinstance(exc, ValueError) and type(exc).__name__ == "RuntimeContractError"

Try / catch

try:
    check_fragment_caps()
except RuntimeContractError as error:
    print(f"[gate] {error}", file=sys.stderr)
    raise SystemExit(2)

Prevention

When it happens

Trigger: 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.

Common situations: Crate or module renames during packaging; 'self-contained tui' experiments; copy-paste fixes that bypass the re-export.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/e21ceaaf6d03b975. Report an issue: GitHub.