diff --git a/justfiles/ci.just b/justfiles/ci.just index 462dcb2..7d513c6 100644 --- a/justfiles/ci.just +++ b/justfiles/ci.just @@ -34,7 +34,7 @@ help: @echo " just clean - Clean build artifacts" # Run all CI checks -ci-full: ci-lint-rust ci-fmt-toml ci-lint-toml ci-lint-nickel ci-lint-markdown ci-lint-prose ci-lint-adr-refs ci-test ci-secrets-error-fixtures ci-secrets-smoke ci-vault-lock-smoke ci-audit ci-audit-protocol ci-check-config-sync ci-docs +ci-full: ci-lint-rust ci-fmt-toml ci-lint-toml ci-lint-nickel ci-lint-markdown ci-lint-prose ci-lint-adr-refs ci-test ci-bond-dispatch ci-secrets-error-fixtures ci-secrets-smoke ci-vault-lock-smoke ci-audit ci-audit-protocol ci-check-config-sync ci-docs @echo "✅ All CI checks passed!" # ============================================================================== @@ -126,6 +126,23 @@ ci-test-coverage: @echo "📊 Running tests with coverage..." cargo llvm-cov --all-features --lcov --output-path lcov.info +# adr-077 two-path domain-activation dispatch invariants (repo_kind ⊕ bond). +# Needs an installed data dir (domains/rustelo); skipped on workers without one, +# same skip-when-unavailable behavior as the smoke tests below. +ci-bond-dispatch: + #!/usr/bin/env bash + set -euo pipefail + dd="" + for c in "$HOME/Library/Application Support/ontoref" "$HOME/.local/share/ontoref"; do + [[ -d "$c/domains/rustelo" ]] && { dd="$c"; break; } + done + if [[ -z "$dd" ]]; then + echo "🔗 ci-bond-dispatch: skipped (no installed data dir — run just install-daemon)" + exit 0 + fi + echo "🔗 Running adr-077 bond dispatch invariants..." + bash scripts/bond-dispatch-test.sh + # End-to-end credential chain smoke (ADR-017 + ADR-019). # Pushes a throwaway vault to ZOT, pulls it back from an isolated HOME, decrypts. # Skipped automatically when ZOT credentials are not exported — keeps `ci-full` diff --git a/scripts/bond-dispatch-test.sh b/scripts/bond-dispatch-test.sh new file mode 100755 index 0000000..b18f1af --- /dev/null +++ b/scripts/bond-dispatch-test.sh @@ -0,0 +1,121 @@ +#!/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