Hmbown/CodeWhale · error · RuntimeContractError
bounded fragment module must expose load_project_instruction
Error message
bounded fragment module must expose load_project_instruction_fragment (project-instruction import as typed fragment)
What it means
The gate enforces that importing project-instruction files goes through the typed fragment API: the substring 'load_project_instruction_fragment' must appear in crates/core/src/fragments.rs. The public wrapper of that name delegates to load_project_instruction_fragment_from_candidates (which also satisfies the substring check), so this error means the typed import path was renamed, moved, or replaced by ad-hoc loading.
Source
Thrown at scripts/check-runtime-contract-budget.py:549
if not re.search(rf"\b{name}\b", text):
raise RuntimeContractError(
f"FragmentId missing required variant {name}"
)
# Marker stability — these strings are pinned by tests / prefix cache
required_markers = [
"<!-- cw:ctx:workspace -->",
"<!-- cw:ctx:project_instructions -->",
"<!-- cw:ctx:constitution -->",
]
for marker in required_markers:
if marker not in text:
raise RuntimeContractError(
f"bounded fragment module missing required marker {marker!r}"
)
# Project-instruction import must be a typed fragment, not ad-hoc
if "load_project_instruction_fragment" not in text:
raise RuntimeContractError(
"bounded fragment module must expose load_project_instruction_fragment (project-instruction import as typed fragment)"
)
if "PROJECT_INSTRUCTION_CANDIDATES" not in text:
raise RuntimeContractError(
"bounded fragment module must define PROJECT_INSTRUCTION_CANDIDATES"
)
# Required candidate files from #3978
required_candidates = [
".cursorrules",
".clinerules",
".windsurf/rules",
".gemini",
".github/copilot-instructions.md",
]
for candidate in required_candidates:
if candidate not in text:
raise RuntimeContractError(
f"PROJECT_INSTRUCTION_CANDIDATES missing required entry {candidate!r}"View on GitHub (pinned to 8880682c63)
Solutions
- Keep or re-expose 'pub fn load_project_instruction_fragment(...)' in crates/core/src/fragments.rs - it may simply delegate to *_from_candidates
- If the loader moved, add a re-export or rename the new function back - the gate matches the exact substring
- Verify: 'grep -n load_project_instruction_fragment crates/core/src/fragments.rs'
Example fix
// before (crates/core/src/fragments.rs)
fn scan_instruction_files(workspace: &Path) -> Option<Fragment> { /* ad-hoc scan */ }
// after
fn scan_instruction_files(workspace: &Path) -> Option<Fragment> {
load_project_instruction_fragment_from_candidates(workspace, PROJECT_INSTRUCTION_CANDIDATES)
} Defensive patterns
Strategy: try-catch
Validate before calling
from pathlib import Path
text = Path("crates/core/src/fragments.rs").read_text(encoding="utf-8")
assert "load_project_instruction_fragment" in text, "typed project-instruction import missing" 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
- Always load project instructions through load_project_instruction_fragment(_from_candidates), never ad-hoc fs scans
- If moving the loader, leave a re-export with the exact name in fragments.rs
- Grep for the function name in any refactor touching instruction loading
When it happens
Trigger: Renaming or deleting load_project_instruction_fragment(_from_candidates); inlining candidate scanning into the context builder; moving the loader into another crate/module so the name no longer occurs in fragments.rs.
Common situations: Refactors relocating instruction loading into tui or a new crate; deleting the 'legacy' wrapper and keeping only a differently-named internal helper.
Related errors
- bounded fragment module must define a matches_text recognize
- DEFAULT_FRAGMENT_MAX_BYTES ({default_bytes}) must not exceed
- DEFAULT_FRAGMENT_MAX_BYTES definition not found
- MAX_FRAGMENTS_PER_CONTEXT must be {FRAGMENT_MAX_COUNT_CEILIN
- MAX_FRAGMENTS_PER_CONTEXT ({max_count}) must not exceed {FRA
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/932b128806b723fe.
Report an issue: GitHub.