#!/usr/bin/env bash # ci/conformance.sh — Stage 5: L2 behavioral + L3 fault-injection. # # Per docs/14 + ADR-0011, L2/L3 run as an IN-CLUSTER Chainsaw Job on the dev/test # cluster; CI only *triggers* the Job and *collects* its JUnit + coverage. CI holds # no broad kubeconfig — the Job's own scoped ServiceAccount holds cluster access. # # PHASE 0: no cluster exists. This stage therefore SKIPS (exit 3) — clearly # reported, never faked green (HARD RULE 4). It goes live in Phase 1+ once a # cluster is declared via CLUSTER_AVAILABLE=true. set -euo pipefail CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck disable=SC1091 source "${CI_DIR}/lib.sh" log "Stage: L2/L3 conformance (in-cluster Chainsaw Job)" mkartifacts if ! cluster_available; then skip "no cluster configured (CLUSTER_AVAILABLE!=true) — L2/L3 NOT RUN. Phase 0: expected." skip "these requirements remain UNVERIFIED until a dev/test cluster exists (Phase 1)." summary "- conformance-l2-l3: **SKIPPED — cluster required** (Phase 0; not a pass)" exit 3 fi if ! entrypoint_ready "$CONFORMANCE_CMD"; then die "CLUSTER_AVAILABLE=true but conformance runner '${CONFORMANCE_CMD}' is missing (T-0.4)" fi # Touched-requirement subset (R-TEST-03) — the merge gate runs only the tagged # subset the change touches, not the whole suite. mapfile -t reqs < <("${CI_DIR}/touched-requirements.sh" || true) req_args=() if [ "${#reqs[@]}" -gt 0 ]; then log "touched requirements: ${reqs[*]}" req_args=(--requirements "$(IFS=,; echo "${reqs[*]}")") else log "no touched requirements detected — running full L2/L3 subset as a safety net" fi # Contract we ASSUME of conformance/run.sh (flag for PM to reconcile): # --layer l2,l3 behavioral + fault-injection layers # --trigger in-cluster-job create/await the in-cluster Chainsaw Job (Job holds # cluster creds via its scoped SA; CI uses only a # narrow trigger credential, referenced by SECRET NAME # in the workflow: CONFORMANCE_TRIGGER_KUBECONFIG) # --requirements R-A,R-B touched subset (R-TEST-03) # --junit --coverage collected artifacts feed the gate "$CONFORMANCE_CMD" \ --layer l2,l3 \ --trigger in-cluster-job \ "${req_args[@]}" \ --junit "${JUNIT_DIR}/l2l3.junit.xml" \ --coverage "${COVERAGE_DIR}" ok "L2/L3 conformance passed for touched subset" summary "- conformance-l2-l3: **passed**"