#!/usr/bin/env bash # Row 56 deliberate deltas. Outside the seeded data root of byte-check.sh, # list and show change on purpose where a record links out of the data # root, a document isn't a JSON object, a run is a regular file, or the # runs directory can't be read. This prints the baseline and candidate # output for each such case (first stderr line only) so the change is on # record. It asserts nothing; the package tests assert the new behaviour. # Usage: delta-check.sh BASE_TREE CAND_TREE WORK_DIR (WORK_DIR must not exist) set -euo pipefail BASE="$(cd "$1" && pwd)"; CAND="$(cd "$2" && pwd)"; W="$3" [ ! -e "$W" ] || { echo "delta-check: $W exists" >&2; exit 4; } mkdir -p "$W"; W="$(cd "$W" && pwd)" A=r-20260101T000000Z-aaaaaa RESULT='{"runVersion":1,"taskId":"t-out","status":"succeeded","request":"r","response":"s","provider":"p","model":"m","startedAt":"a","finishedAt":"b","durationMs":1,"exitCode":0,"signal":null}' root() { # name -> creates W/name/{data,outside}, writes config, echoes data root mkdir -p "$W/$1/data" "$W/$1/outside" printf '{"configVersion":1,"environment":"development","dataRoot":"%s","execution":{"backend":"docker","provider":"zai","model":"m"}}\n' "$W/$1/data" > "$W/$1/config.json" echo "$W/$1/data" } run_case() { # name op [arg] local name="$1"; shift for tree in base cand; do local dir="$BASE"; [ "$tree" = cand ] && dir="$CAND" local rc=0 out err out="$(cd "$dir" && env MOSAIC_CONFIG="$W/$name/config.json" node scripts/mosaic-task.mjs "$@" 2>"$W/$name/$tree.err")" || rc=$? err="$(head -1 "$W/$name/$tree.err")" printf ' %s: exit %s\n' "$tree" "$rc" [ -z "$out" ] || printf '%s\n' "$out" | sed 's/^/ out| /' [ -z "$err" ] || printf ' err| %s\n' "$err" done } hdr() { printf '\n== %s\n' "$*"; } D="$(root run-link)"; mkdir -p "$D/runs"; printf '%s\n' "$RESULT" > "$W/run-link/outside/result.json"; ln -s "$W/run-link/outside" "$D/runs/$A" hdr "run directory linked out of the data root: list"; run_case run-link list hdr "run directory linked out of the data root: show"; run_case run-link show "$A" D="$(root doc-link)"; mkdir -p "$D/runs/$A"; printf '%s\n' "$RESULT" > "$W/doc-link/outside/result.json"; ln -s "$W/doc-link/outside/result.json" "$D/runs/$A/result.json" hdr "result.json linked out of the data root: list"; run_case doc-link list hdr "result.json linked out of the data root: show"; run_case doc-link show "$A" D="$(root runs-link)"; mkdir -p "$W/runs-link/outside/$A"; printf '%s\n' "$RESULT" > "$W/runs-link/outside/$A/result.json"; ln -s "$W/runs-link/outside" "$D/runs" hdr "runs directory linked out of the data root: list"; run_case runs-link list hdr "runs directory linked out of the data root: show"; run_case runs-link show "$A" D="$(root non-object)"; mkdir -p "$D/runs/$A"; printf '5\n' > "$D/runs/$A/result.json"; printf '[]\n' > "$D/runs/$A/task.json" hdr "result.json is 5 and task.json is []: list"; run_case non-object list hdr "result.json is 5 and task.json is []: show"; run_case non-object show "$A" D="$(root run-file)"; mkdir -p "$D/runs"; printf 'x\n' > "$D/runs/$A" hdr "run is a regular file: show"; run_case run-file show "$A" D="$(root loop)"; mkdir -p "$D/runs"; ln -s r-b "$D/runs/$A"; ln -s "$A" "$D/runs/r-b" hdr "run is a link loop: show"; run_case loop show "$A" if [ "$(id -u)" != 0 ]; then D="$(root unreadable)"; mkdir -p "$D/runs/$A"; chmod 000 "$D/runs" hdr "runs directory unreadable: list"; run_case unreadable list hdr "runs directory unreadable: show"; run_case unreadable show "$A" chmod 755 "$D/runs" D="$(root run-unreadable)"; mkdir -p "$D/runs/$A"; printf '%s\n' "$RESULT" > "$D/runs/$A/result.json"; chmod 000 "$D/runs/$A" hdr "run directory unreadable: show"; run_case run-unreadable show "$A" chmod 755 "$D/runs/$A" fi