#!/usr/bin/env bash # lib/tests/effort-routing.test.sh — wave-2 census of the model-router rows. # Drift lock: every tracked skill/agent row of mods/model-router/routing.json # equals its frontmatter (the off-state floor), except a row the user changed # through the first-use dialog (WARN floor drift: the floor may lag a # confirmed decision); the D3 wiring markers sit in the orchestrators, no # shifter citer survives. # shellcheck disable=SC2015,SC2016 # A && ok || ko is deliberate (ok/ko never fail) set -u R="$(cd "$(dirname "$0")/../.." && pwd)" MOD="$R/mods/model-router" RJ="$MOD/routing.json" REG="$MOD/hooks/register.ts" pass=0; fail=0 ok() { pass=$((pass+1)); } ko() { fail=$((fail+1)); printf 'FAIL %s\n' "$1"; } has() { if grep -qF "$2" "$R/$1"; then ok; else ko "$1 missing: $2"; fi; } lacks() { if grep -qF "$2" "$R/$1"; then ko "$1 must NOT contain: $2"; else ok; fi; } # frontmatter = the lines between the first two '---' lines fm() { awk 'NR==1&&/^---$/{p=1;next} p&&/^---$/{exit} p' "$1"; } fm_val() { fm "$1" | grep -E "^$2: [a-z]+$" | head -1 | cut -d' ' -f2; } # ── routing.json (rows, phases, decisions) and the tier heads ──────────── # dump -> "skills|agents ", "phases

# ", "changed " lines dump() { python3 -I - "$1" <<'PY' import json, sys d = json.load(open(sys.argv[1])) for kind in ("skills", "agents"): for k, v in d.get(kind, {}).items(): print(kind, k, v) for k, v in d.get("phases", {}).items(): print("phases", k, v.get("tier", ""), v.get("effort", "")) for kind in ("skills", "agents"): for k, v in d.get("changed", {}).get(kind, {}).items(): print("changed", kind, k, v["from"], v["to"]) PY } # lookups on a dump text: row_of D kind name · phase_effort D phase · # changed_of D kind name -> "from to" row_of() { printf '%s\n' "$1" | awk -v k="$2" -v n="$3" '$1==k&&$2==n{print $3}'; } phase_effort() { printf '%s\n' "$1" | awk -v p="$2" '$1=="phases"&&$2==p{print $3, $4}'; } changed_of() { printf '%s\n' "$1" | awk -v k="$2" -v n="$3" '$1=="changed"&&$2==k&&$3==n{print $4, $5}'; } # tier_head -> first alias of the tier list tier_head() { awk '/^ tiers: \{/{f=1;next} f&&/^ \},?$/{f=0} f' "$1" \ | sed -nE "s/^ *$2: \['([a-z]+)'.*$/\1/p" } # the fallback copy of the phases inside the mod's code: " " code_phase() { awk '/^ phases: \{/{f=1;next} f&&/^ \},?$/{f=0} f' "$REG" \ | sed -nE "s/^ *$1: \{ tier: '([a-z]+)', effort: '([a-z]+)' \},?$/\1 \2/p" } # field_of -> that phase's frontmatter value field_of() { local pe tier pe="$(phase_effort "$1" "$2")" if [ "$3" = effort ]; then printf '%s\n' "${pe#* }"; return; fi tier="${pe% *}"; tier_head "$REG" "$tier" } # verdict : ok when the # frontmatter equals the row's phase; warn when the row was changed through # the dialog (changed.from is the shipped phase, changed.to the row) and the # frontmatter still holds the shipped value; fail otherwise (a Keep alone, # an empty or unknown value, a hand edit after a change) verdict() { local D="$1" kind="$2" name="$3" field="$4" got="$5" phase="$6" ch from fromval [ -n "$got" ] || { echo fail; return; } [ "$got" = "$(field_of "$D" "$phase" "$field")" ] && { echo ok; return; } ch="$(changed_of "$D" "$kind" "$name")"; from="${ch% *}" [ -n "$ch" ] && [ "${ch#* }" = "$phase" ] || { echo fail; return; } fromval="$(field_of "$D" "$from" "$field")" [ -n "$fromval" ] && [ "$got" = "$fromval" ] && echo warn || echo fail } # floor_check