ontoref-code/scripts/bond-dispatch-test.sh
Jesús Pérez a163e0d23b
test(adr-077): dispatch invariants + ci-full wiring
bond-dispatch-test.sh asserts the two-path gate: bond-only activates, bare
refuses, a repo_kind project activates identically with/without a carrier (the
Hard bond-path-is-purely-additive invariant), and a bond rescues a non-matching
repo_kind. Wired into ci-full via ci-bond-dispatch (skips when no data dir,
same pattern as the smoke tests).
2026-07-21 11:46:35 +01:00

121 lines
4.5 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# adr-077 dispatch invariants — behavioural test for the two-path domain
# activation gate in install/ontoref-global (_dispatch_domain).
#
# Asserts, against the SOURCE wrapper (not the installed copy):
# T1 bond path — a bond-only consumer (carrier, NO manifest) activates.
# T2 refusal — a bare project (no manifest, no carrier) is refused.
# T3 additive Hard — a repo_kind-matching project activates IDENTICALLY with
# and without a carrier present (constraint
# `bond-path-is-purely-additive`: the carrier never alters
# an outcome the repo_kind path already granted).
# T4 bond rescues — a manifest whose repo_kind does NOT match is refused
# without a carrier, and activates WITH one.
#
# "Activated" = the dispatch passed the gate and proceeded to run the domain's
# commands.nu; the gate's refusal line is absent. The command itself may then
# fail on its own logic (the fixtures are not real rustelo sites) — that failure
# is BEYOND the gate and is exactly what proves the gate let it through.
set -euo pipefail
cd "$(dirname "$0")/.."
WRAPPER="install/ontoref-global"
DOMAIN="rustelo" # a real installed domain with repo_kinds.txt = RusteloApp
REFUSAL="not available for this project"
# ── locate a data dir (ONTOREF_ROOT) so domains/ + dispatcher resolve ─────────
DD=""
for candidate in "$HOME/Library/Application Support/ontoref" "$HOME/.local/share/ontoref"; do
if [[ -d "$candidate/domains/$DOMAIN" ]]; then DD="$candidate"; break; fi
done
if [[ -z "$DD" ]]; then
echo "bond-dispatch-test: no installed data dir with domains/$DOMAIN — run 'just install-daemon' first" >&2
exit 3
fi
echo "== adr-077 dispatch invariants =="
echo " wrapper=$WRAPPER data_dir=$DD domain=$DOMAIN"
echo
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
PASS=0
FAIL=0
# Run the source wrapper against a project root; echo combined output.
run_dispatch() {
local root="$1"
ONTOREF_ROOT="$DD" ONTOREF_PROJECT_ROOT="$root" bash "$WRAPPER" "$DOMAIN" routes 2>&1 || true
}
# assert_activated <label> <project_root>
assert_activated() {
local label="$1" root="$2" out
out="$(run_dispatch "$root")"
if echo "$out" | grep -qF "$REFUSAL"; then
echo " FAIL $label — gate REFUSED (expected activation)"; FAIL=$((FAIL + 1))
else
echo " pass $label — gate passed"; PASS=$((PASS + 1))
fi
}
# assert_refused <label> <project_root>
assert_refused() {
local label="$1" root="$2" out
out="$(run_dispatch "$root")"
if echo "$out" | grep -qF "$REFUSAL"; then
echo " pass $label — gate refused"; PASS=$((PASS + 1))
else
echo " FAIL $label — gate ACTIVATED (expected refusal)"; FAIL=$((FAIL + 1))
fi
}
# ── fixtures ──────────────────────────────────────────────────────────────────
make_carrier() {
local root="$1"
mkdir -p "$root/.domains-ontoref/$DOMAIN"
cat > "$root/.domains-ontoref/$DOMAIN/bonds.ncl" <<EOF
let s = import "bond.ncl" in
{
domain = "$DOMAIN",
bonds = [
{ id = "test-to-$DOMAIN", from = "test", to = "$DOMAIN", axis = 'Dependency, state = 'Linked, dep_kind = 'Conformist, mutual = false, plane = "$DOMAIN" },
],
} | s.BondSet
EOF
}
make_manifest() {
local root="$1" kind="$2"
mkdir -p "$root/.ontoref/ontology"
printf 'let m = import "manifest" in\n{ project = "t", repo_kind = %s }\n' "'$kind" \
> "$root/.ontoref/ontology/manifest.ncl"
}
# T1 — bond-only consumer (carrier, no manifest)
BOND_ONLY="$TMP/bond-only"; mkdir -p "$BOND_ONLY"; make_carrier "$BOND_ONLY"
assert_activated "T1 bond-only (carrier, no manifest)" "$BOND_ONLY"
# T2 — bare project (no manifest, no carrier)
BARE="$TMP/bare"; mkdir -p "$BARE"
assert_refused "T2 bare (no manifest, no carrier)" "$BARE"
# T3 — additive Hard: repo_kind match, with vs without carrier → both activate
MANAGED="$TMP/managed"; make_manifest "$MANAGED" "RusteloApp"
assert_activated "T3a managed repo_kind, no carrier" "$MANAGED"
make_carrier "$MANAGED"
assert_activated "T3b managed repo_kind, WITH carrier (additive)" "$MANAGED"
# T4 — bond rescues a non-matching repo_kind
WRONG="$TMP/wrong-kind"; make_manifest "$WRONG" "SomeOtherKind"
assert_refused "T4a wrong repo_kind, no carrier" "$WRONG"
make_carrier "$WRONG"
assert_activated "T4b wrong repo_kind, WITH carrier (bond rescues)" "$WRONG"
echo
echo "== summary: $PASS passed, $FAIL failed =="
[[ "$FAIL" -eq 0 ]] || exit 1