#!/usr/bin/env bash # check-resident-budget.sh — resident line-count ceiling (R9 / DESIGN §7). # # Budgets the *container* (line count) of the framework-owned files that are # injected into every agent's context by value — the Constitution (L0), the # AGENTS dispatcher, and each runtime RUNTIME.md slice. Gate *wording* is never # capped (a word cap forces paraphrasing law — the exact drift vector P3 killed); # only the file's line count is bounded, so prose creep is caught in review. # # This is the CI-enforceable half of the budget. The per-harness *total* resident # prompt (which also includes user-generated SOUL.md/USER.md and the per-tier # slice) is summed by `mosaic doctor` as a runtime advisory — CI cannot see user # files, so it is deliberately out of scope here (DESIGN §7). # # Usage: check-resident-budget.sh [--self-test] # Exit: 0 = all within budget · 1 = a file exceeds its ceiling · 2 = self-test failed set -uo pipefail FW="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" # packages/mosaic/framework # Per-file ceilings (lines). Headroom above current counts; tighten as files settle. # Format: ":" CEILINGS=( "defaults/CONSTITUTION.md:120" "defaults/AGENTS.md:120" "runtime/claude/RUNTIME.md:90" "runtime/codex/RUNTIME.md:90" "runtime/opencode/RUNTIME.md:90" "runtime/pi/RUNTIME.md:90" ) # check_file → echoes ""; returns 0 if n<=max, 1 otherwise. check_file() { local path="$1" max="$2" n n=$(wc -l <"$path" 2>/dev/null || echo 0) n=$((n + 0)) echo "$n" [ "$n" -le "$max" ] } run_budget() { local fail=0 rel max abs n printf '%-32s %8s %8s %s\n' "FILE" "LINES" "CEILING" "STATUS" for entry in "${CEILINGS[@]}"; do rel="${entry%%:*}" max="${entry##*:}" abs="$FW/$rel" if [ ! -f "$abs" ]; then printf '%-32s %8s %8s %s\n' "$rel" "-" "$max" "MISSING" fail=1 continue fi n=$(check_file "$abs" "$max") if [ "$n" -le "$max" ]; then printf '%-32s %8s %8s %s\n' "$rel" "$n" "$max" "ok" else printf '%-32s %8s %8s %s\n' "$rel" "$n" "$max" "OVER BUDGET" fail=1 fi done return "$fail" } self_test() { local tmp rc tmp=$(mktemp) # 3 lines, ceiling 5 → within budget (rc 0) printf 'a\nb\nc\n' >"$tmp" check_file "$tmp" 5 >/dev/null rc=$? if [ "$rc" -ne 0 ]; then echo "self-test FAIL: under-budget file flagged"; rm -f "$tmp"; return 2; fi # 6 lines, ceiling 5 → over budget (rc 1) printf 'a\nb\nc\nd\ne\nf\n' >"$tmp" check_file "$tmp" 5 >/dev/null rc=$? if [ "$rc" -ne 1 ]; then echo "self-test FAIL: over-budget file not flagged"; rm -f "$tmp"; return 2; fi rm -f "$tmp" echo "self-test OK" return 0 } if [ "${1:-}" = "--self-test" ]; then self_test exit $? fi if run_budget; then echo "Resident budget: all framework-owned resident files within ceiling." exit 0 else echo "Resident budget EXCEEDED — trim prose or raise the ceiling deliberately (see DESIGN §7)." >&2 exit 1 fi