From 439bea6915b6102da90735fd7721c761684bfada Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 3 Sep 2026 06:23:47 -0500 Subject: [PATCH] ui(test): green OK/PASS, red FAIL - terminal-only, NO_COLOR-aware Owner feedback: grep match-highlighting made the word 'policy' red while status words were plain - counter-indicative. Suites + verify now emit ANSI colors (green success, red failure) when stdout is a terminal; piped/machine-parsed output stays plain, honoring NO_COLOR. Word 'ok' promoted to 'OK' for scannability. Verified byte-level via forced-pty run; piped output unchanged; suites 41/24/14 + verify green. --- docs/plans/CURRENT.md | 13 ++++++++----- scripts/test-config.sh | 28 +++++++++++++++++----------- scripts/test-release.sh | 12 +++++++++--- scripts/test-task.sh | 22 ++++++++++++++-------- scripts/verify.sh | 11 +++++++++-- 5 files changed, 57 insertions(+), 29 deletions(-) diff --git a/docs/plans/CURRENT.md b/docs/plans/CURRENT.md index bc2080eb..f1d33917 100644 --- a/docs/plans/CURRENT.md +++ b/docs/plans/CURRENT.md @@ -7,14 +7,14 @@ update this file to the next action). No ambiguity, no re-planning. ## Next action -Owner decision on M9: mission-level capability policy (design sketch: missions may declare default tool sets; tasks inherit unless overridden; conductor validates the merge). Say "next" to proceed or name a different target. +Owner review of M9 (mission capability policy) — then name the next target. ## Queue (ordered, not started) -1. M9: mission-level capability policy -2. Run-record retention/pruning policy -3. Second real adapter (parked — owner focused on Pi) -4. Auto-apply policy for worker patches (deferred until capability policy exists) +1. Run-record retention/pruning policy +2. Second real adapter (parked — owner focused on Pi) +3. Auto-apply policy for worker patches (capability policy now exists as its substrate) +4. Session forking from a common ancestor (pi JSONL trees make this native) ## Rules @@ -33,4 +33,7 @@ Owner decision on M9: mission-level capability policy (design sketch: missions m - 2026-09-03 — M7 run inspection + release 0.0.6 (#24) — merged, activated - 2026-09-03 — M8 conductor loop + worker-built retry (#25, #26, #27) — merged; worker authored retry in 2 refinement rounds, conductor fixed a 3-line interpolation rename; live retry verified - 2026-09-03 — retry lineage + relative mission resolution (#28) — merged, 36/24/14 suites + verify green +- 2026-09-03 — M9 mission capability policy (#30) — merged, least-privilege intersection, 41/36/14 + verify green +- 2026-09-03 — M8 conductor loop + worker-built retry (#25, #26, #27) — merged; worker authored retry in 2 refinement rounds, conductor fixed a 3-line interpolation rename; live retry verified +- 2026-09-03 — retry lineage + relative mission resolution (#28) — merged, 36/24/14 suites + verify green - 2026-09-03 — M8 conductor loop + worker-built retry (#25, #26, #27) — merged; worker authored retry in 2 refinement rounds, conductor fixed a 3-line interpolation rename; live retry verified diff --git a/scripts/test-config.sh b/scripts/test-config.sh index 6aaba50d..2d409a27 100755 --- a/scripts/test-config.sh +++ b/scripts/test-config.sh @@ -10,10 +10,16 @@ SANDBOX="$(mktemp -d)" trap 'rm -rf "$SANDBOX"' EXIT PASS=0 +# Status colors: terminal-only, NO_COLOR-respecting; plain when piped. +if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then + C_OK=$'\033[0;32m'; C_FAIL=$'\033[0;31m'; C_RESET=$'\033[0m' +else + C_OK=""; C_FAIL=""; C_RESET="" +fi FAIL=0 check() { - if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "ok $1"; else FAIL=$((FAIL+1)); echo "FAIL $1"; fi + if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $1"; else FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $1"; fi } # expect_exit NAME EXPECTED_RC -- command... @@ -25,10 +31,10 @@ expect_exit() { rc=$? if [ "$rc" -eq "$expected" ]; then PASS=$((PASS + 1)) - echo "ok $name (exit $rc)" + echo "${C_OK}OK${C_RESET} $name (exit $rc)" else FAIL=$((FAIL + 1)) - echo "FAIL $name (exit $rc, expected $expected)" + echo "${C_FAIL}FAIL${C_RESET} $name (exit $rc, expected $expected)" fi } @@ -62,8 +68,8 @@ check "env exports adapter" $? rm -f "$SANDBOX/config.json" expect_exit "bootstrap creates default when absent" 0 -- \ env MOSAIC_CONFIG="$SANDBOX/config.json" $CONFIG_OP bootstrap -[ -f "$SANDBOX/config.json" ] && { PASS=$((PASS+1)); echo "ok bootstrap wrote config file"; } \ - || { FAIL=$((FAIL+1)); echo "FAIL bootstrap wrote config file"; } +[ -f "$SANDBOX/config.json" ] && { PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} bootstrap wrote config file"; } \ + || { FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} bootstrap wrote config file"; } SUM_BEFORE=$(sha256sum "$SANDBOX/config.json" | cut -d' ' -f1) MTIME_BEFORE=$(stat -c %Y "$SANDBOX/config.json") @@ -73,9 +79,9 @@ expect_exit "bootstrap is idempotent on existing config" 0 -- \ SUM_AFTER=$(sha256sum "$SANDBOX/config.json" | cut -d' ' -f1) MTIME_AFTER=$(stat -c %Y "$SANDBOX/config.json") if [ "$SUM_BEFORE" = "$SUM_AFTER" ] && [ "$MTIME_BEFORE" = "$MTIME_AFTER" ]; then - PASS=$((PASS+1)); echo "ok bootstrap did not rewrite existing config" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} bootstrap did not rewrite existing config" else - FAIL=$((FAIL+1)); echo "FAIL bootstrap rewrote existing config" + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} bootstrap rewrote existing config" fi # --- validate --- @@ -140,9 +146,9 @@ cfg valid.json "$(valid_body "$DATA_ROOT")" EVAL_OUT="$(MOSAIC_CONFIG="$SANDBOX/valid.json" $CONFIG_OP env)" || true if eval "$EVAL_OUT" 2>/dev/null && [ "$MOSAIC_DATA_ROOT" = "$DATA_ROOT" ] \ && [ "$MOSAIC_PROVIDER" = "zai" ] && [ "$MOSAIC_MODEL" = "glm-5.3-flash" ]; then - PASS=$((PASS+1)); echo "ok env exports resolve correctly" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} env exports resolve correctly" else - FAIL=$((FAIL+1)); echo "FAIL env exports resolve correctly" + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} env exports resolve correctly" fi # --- validation must not modify the file --- @@ -150,9 +156,9 @@ SUM_INVALID_BEFORE=$(sha256sum "$SANDBOX/invalid.json" | cut -d' ' -f1) MOSAIC_CONFIG="$SANDBOX/invalid.json" $CONFIG_OP validate >/dev/null 2>&1 SUM_INVALID_AFTER=$(sha256sum "$SANDBOX/invalid.json" | cut -d' ' -f1) if [ "$SUM_INVALID_BEFORE" = "$SUM_INVALID_AFTER" ]; then - PASS=$((PASS+1)); echo "ok failed validation modified nothing" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} failed validation modified nothing" else - FAIL=$((FAIL+1)); echo "FAIL failed validation modified the file" + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} failed validation modified the file" fi echo diff --git a/scripts/test-release.sh b/scripts/test-release.sh index 762da30e..a22e06eb 100755 --- a/scripts/test-release.sh +++ b/scripts/test-release.sh @@ -15,6 +15,12 @@ cp RELEASE "$RELEASE_BACKUP" trap 'cp "$RELEASE_BACKUP" RELEASE 2>/dev/null; rm -rf "$SANDBOX" "$RELEASE_BACKUP"' EXIT PASS=0 +# Status colors: terminal-only, NO_COLOR-respecting; plain when piped. +if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then + C_OK=$'\033[0;32m'; C_FAIL=$'\033[0;31m'; C_RESET=$'\033[0m' +else + C_OK=""; C_FAIL=""; C_RESET="" +fi FAIL=0 expect_exit() { @@ -24,14 +30,14 @@ expect_exit() { "$@" >/dev/null 2>&1 rc=$? if [ "$rc" -eq "$expected" ]; then - PASS=$((PASS+1)); echo "ok $name (exit $rc)" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $name (exit $rc)" else - FAIL=$((FAIL+1)); echo "FAIL $name (exit $rc, expected $expected)" + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $name (exit $rc, expected $expected)" fi } check() { - if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "ok $1"; else FAIL=$((FAIL+1)); echo "FAIL $1"; fi + if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $1"; else FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $1"; fi } # ---------- fast: release identity ---------- diff --git a/scripts/test-task.sh b/scripts/test-task.sh index c3c99d51..53fce5f7 100755 --- a/scripts/test-task.sh +++ b/scripts/test-task.sh @@ -11,6 +11,12 @@ SANDBOX="$(mktemp -d)" trap 'rm -rf "$SANDBOX"' EXIT PASS=0 +# Status colors: terminal-only, NO_COLOR-respecting; plain when piped. +if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then + C_OK=$'\033[0;32m'; C_FAIL=$'\033[0;31m'; C_RESET=$'\033[0m' +else + C_OK=""; C_FAIL=""; C_RESET="" +fi FAIL=0 expect_exit() { @@ -20,14 +26,14 @@ expect_exit() { "$@" >/dev/null 2>&1 rc=$? if [ "$rc" -eq "$expected" ]; then - PASS=$((PASS+1)); echo "ok $name (exit $rc)" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $name (exit $rc)" else - FAIL=$((FAIL+1)); echo "FAIL $name (exit $rc, expected $expected)" + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $name (exit $rc, expected $expected)" fi } check() { - if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "ok $1"; else FAIL=$((FAIL+1)); echo "FAIL $1"; fi + if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $1"; else FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $1"; fi } latest_reason() { @@ -37,7 +43,7 @@ latest_reason() { } check() { - if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "ok $1"; else FAIL=$((FAIL+1)); echo "FAIL $1"; fi + if [ "$2" = "0" ]; then PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} $1"; else FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} $1"; fi } CONFIG="$SANDBOX/config.json" @@ -247,9 +253,9 @@ latest_reason() { if docker info >/dev/null 2>&1; then RUNS1=$(ls "$DATA_ROOT/runs" 2>/dev/null | wc -l) if scripts/run-task.sh run "$SANDBOX/ok.json" >/dev/null 2>&1; then - PASS=$((PASS+1)); echo "ok live hello task succeeds with exact marker" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} live hello task succeeds with exact marker" else - FAIL=$((FAIL+1)); echo "FAIL live hello task succeeds with exact marker" >&2 + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} live hello task succeeds with exact marker" >&2 dump_latest_run fi @@ -266,9 +272,9 @@ process.exit(r.status === "succeeded" && r.response === "MOSAIC_HELLO_OK" && r.e RC=$? WRONG_REASON="$(latest_reason)" if [ "$RC" -eq 1 ] && [ "$WRONG_REASON" = "expect-mismatch" ]; then - PASS=$((PASS+1)); echo "ok wrong expectExact fails with exit 1 (reason: expect-mismatch)" + PASS=$((PASS+1)); echo "${C_OK}OK${C_RESET} wrong expectExact fails with exit 1 (reason: expect-mismatch)" else - FAIL=$((FAIL+1)); echo "FAIL wrong expectExact (exit $RC, reason: '${WRONG_REASON:-none}')" >&2 + FAIL=$((FAIL+1)); echo "${C_FAIL}FAIL${C_RESET} wrong expectExact (exit $RC, reason: '${WRONG_REASON:-none}')" >&2 dump_latest_run fi diff --git a/scripts/verify.sh b/scripts/verify.sh index f807013d..3d057d00 100755 --- a/scripts/verify.sh +++ b/scripts/verify.sh @@ -16,6 +16,13 @@ source scripts/common.sh EXPECTED="${EXPECTED_MARKER:-MOSAIC_HELLO_OK}" +# Status colors: terminal-only, NO_COLOR-respecting; plain when piped. +if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then + C_OK=$'\033[0;32m'; C_FAIL=$'\033[0;31m'; C_RESET=$'\033[0m' +else + C_OK=""; C_FAIL=""; C_RESET="" +fi + load_config load_release IMAGE="$MOSAIC_IMAGE_TAG" @@ -51,11 +58,11 @@ TRIMMED="$(printf '%s' "$RESPONSE" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:] # 4-6. Exact comparison gate. if [ "$TRIMMED" = "$EXPECTED" ]; then - echo "PASS: response matches expected marker" + echo "${C_OK}PASS${C_RESET}: response matches expected marker" exit 0 fi -echo "FAIL: response does not match expected marker" >&2 +echo "${C_FAIL}FAIL${C_RESET}: response does not match expected marker" >&2 printf 'expected: %s\n' "$EXPECTED" >&2 printf 'actual : %s\n' "$TRIMMED" >&2 exit 1