From ef9d23ab62b84df19d92d114cb44b005a3c2f2eb Mon Sep 17 00:00:00 2001 From: coder-mos1 Date: Sat, 1 Aug 2026 08:35:29 -0500 Subject: [PATCH] test(ci): register RM-61 terminal-green contract cases --- .woodpecker/ci.yml | 29 +------ .../1000-rm-61-ci-contract-exemption.md | 27 ++++++- .../test-terminal-green-contract.sh | 77 +++++++++++++++++++ 3 files changed, 105 insertions(+), 28 deletions(-) create mode 100644 packages/mosaic/framework/tools/woodpecker/test-terminal-green-contract.sh diff --git a/.woodpecker/ci.yml b/.woodpecker/ci.yml index c11e9052..c02f3f1c 100644 --- a/.woodpecker/ci.yml +++ b/.woodpecker/ci.yml @@ -125,19 +125,10 @@ steps: echo "ci-postgres did not become ready" >&2 exit 1 fi - # RM-61 negative control 2/2: arm a real post-readiness database crash, - # then continuously query until the service loss is observed. - - psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c 'CREATE TABLE rm61_crash_armed (armed boolean NOT NULL)' - - | - for i in $(seq 1 60); do - if ! psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c 'SELECT 1'; then - echo "RM-61 control observed the armed PostgreSQL crash" >&2 - exit 61 - fi - sleep 1 - done - echo "RM-61 control did not observe the armed PostgreSQL crash" >&2 - exit 62 + # Run migrations (DATABASE_URL is set in environment above) + - pnpm --filter @mosaicstack/db run db:migrate + # Run all tests + - pnpm test depends_on: - typecheck @@ -148,15 +139,3 @@ services: POSTGRES_USER: mosaic POSTGRES_PASSWORD: mosaic POSTGRES_DB: mosaic - PGPASSWORD: mosaic - entrypoint: - - /bin/sh - - -c - - | - docker-entrypoint.sh postgres & - postgres_pid=$$! - until pg_isready -h 127.0.0.1 -p 5432 -U mosaic; do sleep 1; done - until [ "$$(psql -h 127.0.0.1 -U mosaic -d mosaic -Atqc "SELECT to_regclass('public.rm61_crash_armed')")" = "rm61_crash_armed" ]; do sleep 1; done - echo "RM-61 control killing ready PostgreSQL postmaster $$postgres_pid" >&2 - kill -KILL "$$postgres_pid" - wait "$$postgres_pid" diff --git a/docs/scratchpads/1000-rm-61-ci-contract-exemption.md b/docs/scratchpads/1000-rm-61-ci-contract-exemption.md index 4955df24..2818566a 100644 --- a/docs/scratchpads/1000-rm-61-ci-contract-exemption.md +++ b/docs/scratchpads/1000-rm-61-ci-contract-exemption.md @@ -34,9 +34,9 @@ Historical JSON saved locally under `.evidence/rm-61/` (not for commit). Supplie - [x] Requirements and kill criterion recorded before control implementation. - [x] Historical full-JSON records captured. - [x] Startup-failure control observed terminal. -- [ ] Post-readiness crash control observed terminal. -- [ ] Discrimination verdict recorded. -- [ ] Conditional exemption implementation (only if verdict permits). +- [x] Post-readiness crash control observed terminal. +- [x] Discrimination verdict recorded: Option B may proceed. +- [ ] Conditional exemption implementation. ## Tests / evidence @@ -51,6 +51,27 @@ Historical JSON saved locally under `.evidence/rm-61/` (not for commit). Supplie This control is red and its service record differs from #1000 (`exit_code=0` plus pod-not-found). It proves the startup-failure direction only. It does not settle the dangerous post-readiness crash/garbage-collection path. +### Control 2 — real post-readiness crash + +- Commit: `25ac59715a94dd1b52ef42577472eb44ecc4b446` +- Pipeline: #2191, exact commit match. +- Full JSON child scan: 9 total — 7 success, 2 failure, 0 skipped/pending/running. +- Service log proves PostgreSQL reached `database system is ready to accept connections`, the test created the arm table, and the service then killed postmaster PID 7. +- Test log proves a successful `SELECT 1` followed by `Connection refused`; it exited the pre-registered control code 61. +- `ci-postgres`: `state=failure`, `exit_code=137`, `error=null`, with a 203-second execution window. +- `test`: `state=failure`, `exit_code=61`. +- Pipeline/workflow: terminal `failure`. + +This is the dangerous post-readiness crash path. Its service record is not pod-not-found and therefore differs from #1000 independently of the dependent test failure. + +### Discrimination verdict + +Both real failures are provider-visible as process exits (`exit_code=1` startup; `exit_code=137` crash) with no pod-not-found error. The seven observed #1000 artifacts are provider reconciliation misses (`exit_code=0` plus the exact pod-not-found error). The declared kill criterion did not fire, so Option B may proceed with a matcher requiring the full conjunction. This evidence does **not** prove every future Kubernetes failure is distinguishable; it proves these two concrete real-failure classes remain blocking and bounds the exemption to the observed reconciliation shape. + +### Unit red-first checkpoint + +The nine-case contract harness was written before the verifier. First execution exited 1 because `verify-terminal-green.py` did not exist; no exemption implementation was live. Cases pre-register ordinary green, the exact artifact, both provider controls, near-miss signatures, an independent failure, and a skipped step. + ### Control 2 setup attempt — invalid, excluded from evidence - Commit: `9455cd6a2650b2b7e70f746c07933d96e5cb3d20` diff --git a/packages/mosaic/framework/tools/woodpecker/test-terminal-green-contract.sh b/packages/mosaic/framework/tools/woodpecker/test-terminal-green-contract.sh new file mode 100644 index 00000000..3fcdd806 --- /dev/null +++ b/packages/mosaic/framework/tools/woodpecker/test-terminal-green-contract.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# Red-first contract harness for RM-61 / #1000. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +VERIFIER="$SCRIPT_DIR/verify-terminal-green.py" +TMP=$(mktemp -d) +trap 'rm -rf "$TMP"' EXIT + +write_fixture() { + local file="$1" pipeline_status="$2" postgres_state="$3" postgres_exit="$4" postgres_error="$5" test_state="$6" + python3 - "$file" "$pipeline_status" "$postgres_state" "$postgres_exit" "$postgres_error" "$test_state" <<'PY' +import json, sys +path, pipeline_status, pg_state, pg_exit, pg_error, test_state = sys.argv[1:] +steps = [ + {"name": "clone", "type": "clone", "state": "success", "exit_code": 0, "error": None}, + {"name": "ci-postgres", "type": "service", "state": pg_state, "exit_code": int(pg_exit), "error": pg_error or None}, + {"name": "test", "type": "commands", "state": test_state, "exit_code": 0 if test_state == "success" else 1, "error": None}, +] +json.dump({ + "number": 9999, + "status": pipeline_status, + "commit": "a" * 40, + "workflows": [{"name": "ci", "state": pipeline_status, "children": steps}], +}, open(path, "w")) +PY +} + +expect_exit() { + local expected="$1" label="$2" file="$3" + shift 3 + set +e + output=$(python3 "$VERIFIER" "$file" "$@" 2>&1) + actual=$? + set -e + if [[ "$actual" -ne "$expected" ]]; then + printf 'FAIL %s: expected exit %s, got %s\n%s\n' "$label" "$expected" "$actual" "$output" >&2 + exit 1 + fi + printf 'PASS %s\n' "$label" + printf '%s' "$output" +} + +# Ordinary terminal green. +write_fixture "$TMP/green.json" success success 0 '' success +out=$(expect_exit 0 green "$TMP/green.json") +grep -q '"total_steps": 3' <<<"$out" +grep -q '"exempted_steps": 0' <<<"$out" + +# Exact, named #1000 teardown artifact: the only permitted non-success child. +artifact='pods "wp-svc-01kyxzjhdf6w81swsnbfzh85z9-ci-postgres" not found' +write_fixture "$TMP/artifact.json" success failure 0 "$artifact" success +out=$(expect_exit 0 exact-artifact "$TMP/artifact.json") +grep -q '"exemption_id": "WP-K8S-1000-CI-POSTGRES-TEARDOWN"' <<<"$out" +grep -q '"exempted_steps": 1' <<<"$out" + +# Negative controls: both real PostgreSQL failures must remain red. +write_fixture "$TMP/startup.json" failure failure 1 '' failure +expect_exit 1 startup-failure "$TMP/startup.json" >/dev/null +write_fixture "$TMP/crash.json" failure failure 137 '' failure +expect_exit 1 post-readiness-crash "$TMP/crash.json" >/dev/null + +# The exemption is signature-scoped, not step-scoped. +write_fixture "$TMP/wrong-error.json" success failure 0 'connection refused' success +expect_exit 1 other-postgres-error "$TMP/wrong-error.json" >/dev/null +write_fixture "$TMP/wrong-pod.json" success failure 0 'pods "other-ci-postgres" not found' success +expect_exit 1 wrong-pod-signature "$TMP/wrong-pod.json" >/dev/null +write_fixture "$TMP/nonzero-artifact.json" success failure 137 "$artifact" success +expect_exit 1 nonzero-with-artifact-text "$TMP/nonzero-artifact.json" >/dev/null + +# Exact artifact cannot mask any independent failure or non-success pipeline. +write_fixture "$TMP/artifact-plus-failure.json" failure failure 0 "$artifact" failure +expect_exit 1 artifact-plus-real-failure "$TMP/artifact-plus-failure.json" >/dev/null +write_fixture "$TMP/skipped.json" success success 0 '' skipped +expect_exit 1 skipped-step "$TMP/skipped.json" >/dev/null + +printf 'terminal-green contract harness: PASS (9 cases)\n'