Compare commits

..
Author SHA1 Message Date
Jason WoltjeandClaude Fable 5 68bdeba758 style(wake): prettier-normalize denominator artifact — whitespace-only (#973)
ci/woodpecker/pr/ci Pipeline was successful
Pipeline 2136's sole red step: pnpm format:check flags the frozen
denominator JSON (Python-emitted formatting vs prettier style). Reformat
with the repo-pinned prettier 3.9.6. Verified before commit: git diff -w
empty across the whole commit (whitespace-only), json.load before/after
compare EQUAL AS OBJECTS (A1 consumes the parsed object, never the
bytes), check-973.py expected==static still 261/261, no other path
touched. test step at prior head 5e98419d was green — all ten wake
suites ran converted and passed in CI.

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 03:24:39 -05:00
Jason WoltjeandClaude Fable 5 5e98419d0e chore(wake): manifest 0.7.2 — #973 three-valued grep verdicts
ci/woodpecker/pr/ci Pipeline failed
Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 02:14:47 -05:00
Jason WoltjeandClaude Fable 5 bd57ef0c74 test(wake): #973 validation harness — trace/inventory/arm evidence chain
validate-973.sh produces the complete evidence chain in one run:

  0  instrument self-test (microtest, now C1-C11) before any evidence
  1  expected set: 261 coordinates from the frozen denominator artifact
     (+3 header shift), count declared BEFORE any suite runs
  2  static inventory re-derived from SOURCE TEXT == expected set — the
     ledger is an execution trace, not an inventory, so the inventory leg
     comes from the text (mos-dt amendment ONE)
  3  green instrumented run: ten suites, per-suite pinned sentinels
     (preimage's divergent format included), exit codes reported per file
  4  trace arithmetic on coordinate SETS: trace-minus-expected must be
     empty; expected-minus-trace (converted-but-never-executed) is
     enumerated and every entry must match a row in the committed
     unexecuted-sites-dispositions.txt, with stale dispositions rejected
     symmetrically
  5  21 forced-error arms (19 denominator canaries + E-form store-ack:736,
     the A6 $(count_lines) shape + F-form quarantine:563, the multi-grep
     pipeline capture): each must emit ARMED, abort naming the site, exit
     non-zero, emit NO sentinel, and have its ledger row already landed
  6  residual sweep with the denominator's own classifier: zero unconverted
     verdict greps, six per-form plants found in the same run

The nine unexecuted sites are the FAILED-branch summary lines, structurally
unreachable in a green run; microtest C11 executes the exact template on a
deterministically red mini-suite so their dispositions cite a measured
execution, not an inference.

First full run: OK — 252 executed + 9 dispositioned = 261, all arms fired,
sweep clean.

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 02:13:23 -05:00
Jason WoltjeandClaude Fable 5 8cb5866a3d test(wake): pin the BASH_LINENO continuation convention at runtime (#973)
The denominator artifact's site coordinates assume a backslash-continuation
helper call reports at its FIRST physical line. That convention was measured
on a developer bash (5.3.x, Fedora); CI runs the bash baked into ci-base
(node:24-alpine), which rebuilds only on push-to-main or tag — so the CI bash
version floats silently between rebuilds, and an artifact validated only
against a developer bash is unverified in the place the gate actually runs.

wake_assert_init now runs a probe under the SAME bash binary executing the
suite (subshell + continuation, the real call shape) and aborts loudly if the
convention does not hold, instead of letting coordinates skew by one line
under everyone. Microtest C10 proves the pin's abort arm fires, via a
test-only WAKE_ASSERT_PIN_BASH interpreter override ($BASH itself cannot be
spoofed — bash resets it at startup): a pin whose failure arm was never seen
firing is an undertaking, not a control.

Prompted by mos-dt's CI-bash-float finding (prereg addendum 4, ddea1bc7b).

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 02:04:56 -05:00
Jason WoltjeandClaude Fable 5 10a7fe43c5 wake/#973: convert all 261 grep-verdict sites to has_match/count_lines
Mechanical conversion driven by the frozen denominator artifact
(validate-973/convert-973.py, committed for auditability): every row is
byte-verified against the worktree BEFORE any edit — a conversion applied to
a line the denominator did not measure would be the umbrella defect wearing
the converter's clothes — then 233 sites become has_match and 28 grep -c
sites become count_lines, and each suite gains three header lines (source
_wake-common.sh + wake_assert_init) directly after its SCRIPT_DIR line, a
uniform +3 shift for every site coordinate.

Env prefixes are kept (LC_ALL=C has_match — the prefix reaches the grep
child, microtest C8). The two multi-grep pipeline sites
(digest-quarantine:560, install:420) convert BOTH greps: each element is
measurement-bearing, and under pipefail an rc=2 on the left is masked by an
rc=1 on the right — the same defect one pipe deeper. Call-site 2>/dev/null
redirects (the preimage canaries) are kept: ordinary grep noise stays
suppressed, while an abort writes to the wake_assert_init-saved real stderr.

Diff arithmetic: +291/-261 = 261 one-for-one line replacements + 30 header
lines (10 suites x 3). Nothing in this commit is not the conversion.

All ten suites run green after conversion. Per the review pre-registration
(A9) that green is NON-EVIDENCE for this change: a suite that was green
before conversion and green after witnesses nothing about whether the sites
were converted — the counted-ledger equality in the validation harness is
the evidence.

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 01:58:26 -05:00
Jason WoltjeandClaude Fable 5 6109f81769 wake/#973: three-valued grep assertion helpers + instrument micro-test
has_match/count_lines in _wake-common.sh: rc 0 -> match, rc 1 -> no-match,
anything else -> loud abort naming the call site, the raw exit code, and the
arguments — an error never becomes a verdict. The abort escapes subshells,
pipelines, and $() substitutions by signalling the suite's main shell, so
the suite dies verdict-less; loudness survives call-site 2>/dev/null via a
wake_assert_init-saved stderr fd (dynamically allocated >= 10, no collision
with the wake lock fd 8 or detector run-loop fd 9).

Validate instrumentation (evidence only, inert in production):
WAKE_ASSERT_LEDGER appends "<helper> <file>:<line>" BEFORE the grep runs, so
an aborting site's row has already landed and the counted ledger can never
go quiet in the one condition it exists to report.
WAKE_ASSERT_FORCE_GREP_ERROR_AT=<file>:<line> routes exactly that call site
through a REAL grep driven onto its real error path (rc 2) and emits a
positive ARMED confirmation first, so arm-never-matched (no ARMED line) and
error-path-broken (ARMED line, no abort) are separable on stderr alone.

validate-973/microtest-wake-assert.sh: nine checks (C1..C9) proving the
instrument before any conversion trusts it — ledger set equality across two
files, truncation detection behind an early exit, per-shape abort proofs
(subshell, 2>/dev/null canary shape, $() count capture, pipeline tail),
count-of-zero on grep rc 1, env-prefix reaching the grep child, and a
no-match arm loud by omission. All nine pass; C1 pins BASH_LINENO's
first-physical-line convention for backslash continuations, matching the
denominator artifact's coordinates.

Production tools (store.sh, ack.sh) source this file but call none of the
new helpers.

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 01:52:56 -05:00
Jason WoltjeandClaude Fable 5 7833ddbf4e chore(wake): #973 frozen denominator at branch base — 261 grep-verdict sites, 19 credential canaries
The conversion target, frozen BEFORE any conversion so completeness can be
asserted by set equality against a list that predates the batch (a control
keyed on the post-fix source can only agree with it). Derived per the amended
charter A1: frozen 257 @ 8d1d6e5 forward-mapped with per-row drift disposition
(214 unchanged / 43 moved / 0 deleted / 0 text-changed, byte-verified) UNION a
fresh six-form derivation at 089615f (self-checked by exact 257 reproduction at
8d1d6e5). Delta = exactly the four T17 sites introduced by 47f8689 (#967),
independently derived twice. A 204 (167 OR / 37 AND-inverted), count-capture 28,
B 6, C 10, D-if 9, F 4. Canaries 19 (9 same-line, 3 continuation, 7 if-form),
all AND-polarity: every one fails toward GREEN on grep error.

Charter: jarvis-brain docs/journal/fleet/charter-973-has-match__mos-dt.md @ fa551c2d0.

Written-by: pepper (sb-it-1-dt)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
2026-07-31 01:28:43 -05:00
23 changed files with 81 additions and 895 deletions
-5
View File
@@ -41,11 +41,6 @@ steps:
# (Constitution + dispatcher + each RUNTIME.md slice). See DESIGN §7 / R9.
- bash packages/mosaic/framework/tools/quality/scripts/check-resident-budget.sh --self-test
- bash packages/mosaic/framework/tools/quality/scripts/check-resident-budget.sh
# Test-membership guard (#1017): also first link of test:framework-shell.
# Invoked from BOTH surfaces it audits (F2, PR #1018) — the guard is link
# [0] of the pnpm chain, so severing that chain would silence it together
# with everything it guards; this direct line keeps one instrument running.
- bash packages/mosaic/framework/tools/quality/scripts/check-test-enumeration.sh
# Blocking gate (#791): a framework upgrade must never write or delete an
# operator-owned path. The HARD GATE proves an unanticipated operator sentinel
@@ -34,18 +34,12 @@ EOF
# get_remote_host and get_gitea_token are provided by detect-platform.sh
get_state_from_status_json() {
# Capture piped JSON BEFORE invoking `python3 - <<PY`. The heredoc binds
# stdin to the Python program text — so json.load(sys.stdin) inside would
# try to re-read stdin after `-` already consumed it for the program,
# yielding EOF and returning "unknown" every time. Pass payload via env.
local payload
payload=$(cat)
CI_QUEUE_STATUS_JSON="$payload" python3 - <<'PY'
python3 - <<'PY'
import json
import os
import sys
try:
payload = json.loads(os.environ.get("CI_QUEUE_STATUS_JSON", ""))
payload = json.load(sys.stdin)
except Exception:
print("unknown")
raise SystemExit(0)
@@ -89,15 +83,12 @@ PY
}
print_pending_contexts() {
# Same stdin hazard as get_state_from_status_json above — pass payload via env.
local payload
payload=$(cat)
CI_QUEUE_STATUS_JSON="$payload" python3 - <<'PY'
python3 - <<'PY'
import json
import os
import sys
try:
payload = json.loads(os.environ.get("CI_QUEUE_STATUS_JSON", ""))
payload = json.load(sys.stdin)
except Exception:
print("[ci-queue-wait] unable to decode status payload")
raise SystemExit(0)
@@ -109,55 +109,6 @@ else
detect_platform >/dev/null
fi
# Render the provider's own explanation for a failed request, for appending to
# an error message (#1004). Every HTTP arm in this file already has the response
# body on disk; without this it was discarded unread at exactly the moment the
# caller needed it, which pushes an operator toward re-issuing the request by
# hand to find out what the server said. Gitea returns {"message": "..."} on a
# refusal; anything unparseable falls back to a truncated raw first line so a
# proxy's HTML error page still says something. Prints "" when there is nothing
# to add, so callers can interpolate unconditionally.
#
# Args: $1 = path to the response body file.
gitea_error_detail() {
local body_file="$1"
[[ -s "$body_file" ]] || return 0
python3 - "$body_file" <<'PY' 2>/dev/null || true
import json
import sys
LIMIT = 300
try:
with open(sys.argv[1], encoding="utf-8", errors="replace") as response:
raw = response.read().strip()
except OSError:
raise SystemExit(0)
if not raw:
raise SystemExit(0)
detail = ""
try:
parsed = json.loads(raw)
if isinstance(parsed, dict):
for key in ("message", "error", "errors"):
value = parsed.get(key)
if isinstance(value, str) and value.strip():
detail = value.strip()
break
if isinstance(value, list) and value:
detail = "; ".join(str(item) for item in value).strip()
break
except ValueError:
pass
if not detail:
detail = raw.splitlines()[0].strip()
if not detail:
raise SystemExit(0)
if len(detail) > LIMIT:
detail = detail[:LIMIT] + "..."
print(f" — provider said: {detail}")
PY
}
# Post a comment to a Gitea PR (PR comments ARE issue comments) via the
# supported REST API and verify it against a PROVIDER-RETURNED created id. The
# write is a direct POST that returns the created comment object, so we learn
@@ -199,7 +150,7 @@ print(json.dumps({"body": os.environ["COMMENT_BODY"]}))
return 1
fi
if [[ "$write_status" != "201" ]]; then
echo "Error: Gitea comment write failed with HTTP $write_status$(gitea_error_detail "$write_file")" >&2
echo "Error: Gitea comment write failed with HTTP $write_status" >&2
return 1
fi
@@ -228,7 +179,7 @@ PY
return 1
fi
if [[ "$readback_status" != "200" ]]; then
echo "Error: Gitea comment read-back failed with HTTP $readback_status$(gitea_error_detail "$readback_file")" >&2
echo "Error: Gitea comment read-back failed with HTTP $readback_status" >&2
return 1
fi
@@ -419,7 +370,7 @@ gitea_authenticated_login() {
return 1
fi
if [[ "$status" != "200" ]]; then
echo "Error: Gitea authenticated-identity read failed with HTTP $status$(gitea_error_detail "$response_file")" >&2
echo "Error: Gitea authenticated-identity read failed with HTTP $status" >&2
return 1
fi
@@ -456,7 +407,7 @@ gitea_read_pr_head_into() {
return 1
fi
if [[ "$status" != "200" ]]; then
echo "Error: Gitea PR head read failed with HTTP $status$(gitea_error_detail "$pr_file")" >&2
echo "Error: Gitea PR head read failed with HTTP $status" >&2
return 1
fi
python3 - "$pr_file" <<'PY'
@@ -546,7 +497,7 @@ print(json.dumps({
fi
# Gitea returns 200 (occasionally 201) with the created review object.
if [[ "$write_status" != "200" && "$write_status" != "201" ]]; then
echo "Error: Gitea review submit failed with HTTP $write_status$(gitea_error_detail "$write_file")" >&2
echo "Error: Gitea review submit failed with HTTP $write_status (#865: no durable review created)" >&2
return 1
fi
@@ -575,7 +526,7 @@ PY
return 1
fi
if [[ "$readback_status" != "200" ]]; then
echo "Error: Gitea review read-back failed with HTTP $readback_status$(gitea_error_detail "$readback_file")" >&2
echo "Error: Gitea review read-back failed with HTTP $readback_status" >&2
return 1
fi
@@ -1,205 +0,0 @@
#!/usr/bin/env bash
# Regression suite for #1019: ci-queue-wait.sh's status parser must return a
# state DERIVED FROM ITS INPUT.
#
# The defect this pins: both python sites piped a payload into `python3 - <<'PY'`.
# The heredoc binds stdin to the Python program text, so json.load(sys.stdin) saw
# EOF, the bare `except` fired, and the function returned "unknown" for every input
# — success, pending and failure alike. "unknown" then reaches an `exit 0` arm, so
# the gate-6 queue guard passed unconditionally on both the gitea and github paths.
#
# Every assertion below is on the RETURNED STATE STRING. A test that asserted only
# `rc=0` would have passed against the broken build, which is why this bug survived.
#
# The functions are extracted from the shipped wrapper rather than reimplemented, so
# this suite measures the code that actually runs.
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Overridable so a mutation test can point the suite at a deliberately-broken copy
# without touching the tracked file. The earlier version of this suite required
# `git stash` + `git checkout` to do that, which left a repo-global stash entry
# that any sibling worktree could have popped onto an unrelated branch.
WRAPPER="${CI_QUEUE_WAIT_WRAPPER:-$SCRIPT_DIR/ci-queue-wait.sh}"
PASS=0
FAIL=0
pass() { printf ' PASS %s\n' "$1"; PASS=$((PASS + 1)); }
fail() { printf ' FAIL %s\n' "$1"; FAIL=$((FAIL + 1)); }
if [[ ! -f "$WRAPPER" ]]; then
printf 'FATAL: wrapper not found at %s\n' "$WRAPPER" >&2
exit 1
fi
TMPDIR_T="$(mktemp -d)"
trap 'rm -rf "$TMPDIR_T"' EXIT
extract_fn() {
# $1 = function name, $2 = source file, $3 = destination
sed -n "/^$1()/,/^}/p" "$2" > "$3"
[[ -s "$3" ]] || { printf 'FATAL: could not extract %s from %s\n' "$1" "$2" >&2; exit 1; }
}
extract_fn get_state_from_status_json "$WRAPPER" "$TMPDIR_T/state.sh"
extract_fn print_pending_contexts "$WRAPPER" "$TMPDIR_T/contexts.sh"
state_of() {
# shellcheck disable=SC1091
( source "$TMPDIR_T/state.sh"; printf '%s' "$1" | get_state_from_status_json )
}
expect_state() {
local label="$1" payload="$2" want="$3" got
got="$(state_of "$payload")"
if [[ "$got" == "$want" ]]; then
pass "$label -> $want"
else
fail "$label -> got '$got', want '$want'"
fi
}
echo "=== parser returns a state derived from its input (#1019) ==="
expect_state "success payload" \
'{"state":"success","statuses":[{"status":"success","context":"ci/build"}]}' \
'terminal-success'
expect_state "pending payload" \
'{"state":"pending","statuses":[{"status":"pending","context":"ci/build"}]}' \
'pending'
expect_state "failure payload" \
'{"state":"failure","statuses":[{"status":"failure","context":"ci/build"}]}' \
'terminal-failure'
expect_state "mixed success+pending is pending" \
'{"state":"pending","statuses":[{"status":"success"},{"status":"pending"}]}' \
'pending'
expect_state "running counts as pending" \
'{"state":"pending","statuses":[{"status":"running"}]}' \
'pending'
expect_state "error counts as failure" \
'{"state":"failure","statuses":[{"status":"error"}]}' \
'terminal-failure'
expect_state "empty status set is no-status" \
'{"state":"","statuses":[]}' \
'no-status'
# Control. This is the ONE input for which "unknown" is correct. Without it, a
# regression that hardcoded "unknown" again would still fail the cases above but
# the suite would give no signal that "unknown" remains reachable when it should be.
expect_state "undecodable payload stays unknown" \
'not json at all' \
'unknown'
expect_state "unrecognised status vocabulary is unknown" \
'{"state":"weird","statuses":[{"status":"weird"}]}' \
'unknown'
echo "=== pending contexts are reported to the operator ==="
contexts_of() {
# shellcheck disable=SC1091
( source "$TMPDIR_T/contexts.sh"; printf '%s' "$1" | print_pending_contexts )
}
out="$(contexts_of '{"statuses":[{"status":"pending","context":"ci/alpha"},{"status":"pending","context":"ci/beta"}]}')"
if grep -q 'ci/alpha' <<<"$out" && grep -q 'ci/beta' <<<"$out"; then
pass "both pending contexts emitted"
else
fail "pending contexts not emitted; got: $out"
fi
out="$(contexts_of '{"statuses":[{"status":"success","context":"ci/alpha"}]}')"
# Assert the POSITIVE message, not merely the absence of the context name. Absence
# alone is satisfied by total silence — and the pre-fix build was silent, so an
# absence-only assertion passed against the very defect this suite exists to catch.
if grep -q 'ci/alpha' <<<"$out"; then
fail "a non-pending context was emitted; got: $out"
elif grep -q 'no pending contexts' <<<"$out"; then
pass "non-pending context suppressed, and reported as 'no pending contexts'"
else
fail "expected an explicit 'no pending contexts' report; got: $out"
fi
echo "=== needle: the broken construct is caught, not merely absent today ==="
# Rebuild the pre-fix form and assert this suite would have failed against it.
# Without this, the suite proves the current file is correct but not that it can
# detect the defect returning.
BROKEN="$TMPDIR_T/broken.sh"
cat > "$BROKEN" <<'BROKEN_EOF'
get_state_from_status_json() {
python3 - <<'PY'
import json
import sys
try:
payload = json.load(sys.stdin)
except Exception:
print("unknown")
raise SystemExit(0)
print("terminal-success" if (payload.get("state") or "") == "success" else "pending")
PY
}
BROKEN_EOF
broken_got="$( ( source "$BROKEN"; printf '%s' '{"state":"success","statuses":[]}' | get_state_from_status_json ) )"
if [[ "$broken_got" == "unknown" ]]; then
pass "[NEEDLE ] pre-fix construct reproduces the defect (returns 'unknown' for a success payload)"
else
fail "[NEEDLE ] pre-fix construct did NOT reproduce the defect; got '$broken_got' — the needle no longer pins anything"
fi
# And assert the shipped wrapper does not contain that construct.
#
# The check must have HEREDOC SEMANTICS, not merely match the text. `json.load(sys.stdin)`
# is perfectly correct under `python3 -c '...'` — there the program comes from argv, so
# stdin really is the payload, and ci-queue-wait.sh uses that form legitimately in
# gitea_get_branch_head_sha. Only `python3 - <<DELIM` is defective, because `-` has
# already bound stdin to the program text.
#
# A flat `grep json\.load\(sys\.stdin\)` therefore fails on correct code. It did: the
# first version of this needle flagged the innocent `python3 -c` site. Same shape as
# #1018 F1 (a regex over raw text has no syntax semantics) reproduced inside the needle
# written to pin a different instance of it.
heredoc_stdin_sites() {
awk '
/python3[[:space:]]+-[[:space:]]*<</ {
d = $0
sub(/.*<<[[:space:]]*/, "", d)
gsub(/['"'"'"]/, "", d)
delim = d; inhd = 1; next
}
inhd && $0 == delim { inhd = 0; next }
inhd {
line = $0
sub(/[[:space:]]*#.*$/, "", line)
if (line ~ /sys\.stdin/) printf "%d: %s\n", FNR, $0
}
' "$1"
}
# Positive control FIRST. An empty result from a broken scanner looks exactly like a
# clean file, so the scanner is proven to fire before its silence is trusted.
if [[ -n "$(heredoc_stdin_sites "$BROKEN")" ]]; then
pass "[NEEDLE ] scanner detects a stdin read inside a python3-heredoc"
else
fail "[NEEDLE ] scanner did NOT fire on the known-broken form — its silence proves nothing"
fi
sites="$(heredoc_stdin_sites "$WRAPPER")"
if [[ -n "$sites" ]]; then
fail "[NEEDLE ] wrapper reads stdin inside a python3-heredoc at: $sites"
else
pass "[NEEDLE ] wrapper has no stdin read inside any python3-heredoc"
fi
printf '\nci-queue-wait parse: %d passed, %d failed\n' "$PASS" "$FAIL"
[[ "$FAIL" -eq 0 ]] || exit 1
@@ -58,9 +58,6 @@ CREDENTIALS_FILE="$WORK_DIR/credentials.json"
# A dedicated scratch dir the wrapper is pointed at via TMPDIR, so the leak
# check can assert every POST/GET body + metadata temp file is cleaned up.
TMP_SCRATCH="$WORK_DIR/scratch"
# Sandboxed HOME so nothing under the real $HOME (notably the per-slot Gitea token
# store at ~/.config/mosaic/secrets/gitea-tokens/) is reachable from the wrapper.
HOME_DIR="$WORK_DIR/home"
cleanup() {
rm -rf "$WORK_DIR"
@@ -81,18 +78,9 @@ OVERRIDE_TOKEN="override-token-placeholder"
CROSS_HOST_LOGIN="foreign-host-reviewer"
CROSS_HOST_TOKEN="cross-host-token-placeholder"
mkdir -p "$REPO_DIR" "$BIN_DIR" "$XDG_DIR" "$STATE_DIR" "$TMP_SCRATCH" "$HOME_DIR"
mkdir -p "$REPO_DIR" "$BIN_DIR" "$XDG_DIR" "$STATE_DIR" "$TMP_SCRATCH"
git -C "$REPO_DIR" init -q
git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git
# HERMETICITY: get_gitea_token() step 0 resolves a per-agent identity from
# `git config --get mosaic.gitIdentity`, which on a provisioned agent seat is set
# GLOBALLY and therefore leaks into this fresh repo. It then reads a REAL per-slot
# token from $HOME and returns it WITHOUT ever consulting MOSAIC_CREDENTIALS_FILE,
# so the fixture credentials below are silently ignored and the suite runs against
# production credentials. An empty repo-local value shadows the global one and reads
# back as empty at rc=0, restoring the shared-credential path this suite intends to
# exercise. Paired with the sandboxed HOME in run_review().
git -C "$REPO_DIR" config mosaic.gitIdentity ""
# tea config: the override login carries its own token here. The default login
# name ("mosaicstack") is deliberately absent, so the no-override default path
@@ -278,24 +266,6 @@ submitted = json.loads(os.environ["PR_REVIEW_PAYLOAD"])
with open(state_path, encoding="utf-8") as handle:
reviews = json.load(handle)
# review-refused-422 (#1004): the server REFUSES the submit outright with a
# definite, correct, machine-readable reason in the body — the shape Gitea
# returns when the acting credential authored the PR. Nothing is created. The
# wrapper must surface what the server said and must NOT relabel this as the
# #865 silent-no-op defect class, which is precisely what it is not.
if mode == "review-refused-422":
print("422")
print(json.dumps({"message": "Cannot approve your own pull request"}))
raise SystemExit(0)
# review-refused-html (#1004): a non-JSON error body, as a fronting proxy or
# gateway emits. The detail extraction must degrade to the first raw line rather
# than silently dropping the only explanation available.
if mode == "review-refused-html":
print("502")
print("<html><head><title>502 Bad Gateway</title></head>\n<body>nginx</body></html>")
raise SystemExit(0)
# no-op-concurrent-review: the wrapper's own submit is SUPPRESSED (200, no
# created object) even though a concurrent same-identity, same-state review at
# the same head already exists. Nothing is persisted; no created id to verify.
@@ -547,8 +517,6 @@ run_review() {
cd "$REPO_DIR"
PATH="$BIN_DIR:$PATH" \
TMPDIR="$TMP_SCRATCH" \
HOME="$HOME_DIR" \
MOSAIC_GIT_IDENTITY="" \
XDG_CONFIG_HOME="$XDG_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
PR_REVIEW_TEA_LOG="$TEA_LOG" \
@@ -972,44 +940,4 @@ if grep -q 'Approved and verified' "$OUTPUT_FILE"; then
fi
assert_no_temp_leak "review-body-null"
# Case 19 (#1004): an outright server REFUSAL must report the provider's own
# reason and must NOT be relabelled as the #865 silent-no-op defect class. The
# old arm hardcoded "(#865: no durable review created)" for EVERY non-2xx, so a
# 422/403/404 — all of them definite, correct refusals the server explained in
# the discarded body — arrived at the caller wearing the name of the one defect
# they are not. That misdirection is what makes an operator re-issue the request
# by hand against the live object to find out what actually happened.
if run_review review-refused-422 approve; then
echo "FAIL: approve reported success when the server refused the submit" >&2
cat "$OUTPUT_FILE" >&2
exit 1
fi
grep -q 'HTTP 422' "$OUTPUT_FILE"
if ! grep -q 'Cannot approve your own pull request' "$OUTPUT_FILE"; then
echo "FAIL: the provider's stated reason was discarded (#1004)" >&2
cat "$OUTPUT_FILE" >&2
exit 1
fi
if grep -q '#865: no durable review created' "$OUTPUT_FILE"; then
echo "FAIL: a server refusal was misattributed to the #865 defect class (#1004)" >&2
cat "$OUTPUT_FILE" >&2
exit 1
fi
assert_no_temp_leak "review-refused-422"
# Case 20 (#1004): a non-JSON error body (a fronting proxy's HTML page) must
# still yield something the caller can act on, rather than a bare status code.
if run_review review-refused-html approve; then
echo "FAIL: approve reported success on a 502" >&2
cat "$OUTPUT_FILE" >&2
exit 1
fi
grep -q 'HTTP 502' "$OUTPUT_FILE"
if ! grep -q '502 Bad Gateway' "$OUTPUT_FILE"; then
echo "FAIL: a non-JSON error body was dropped instead of degrading to its first line (#1004)" >&2
cat "$OUTPUT_FILE" >&2
exit 1
fi
assert_no_temp_leak "review-refused-html"
echo "pr-review.sh REST review + comment create/read-back regression passed"
@@ -1,165 +0,0 @@
#!/usr/bin/env bash
# check-test-enumeration.sh — CI test-membership guard (#1017).
#
# CI reaches shell suites through two hand-enumerated surfaces:
# S1 packages/mosaic/package.json scripts."test:framework-shell"
# S2 .woodpecker/ci.yml direct `bash packages/mosaic/framework/tools/...` commands
#
# A hand-enumerated allowlist re-arms its own gap: a new suite never auto-joins,
# so the list silently under-runs the disk (17 of 39 suites were invisible when
# #1017 was filed). This guard makes that under-run impossible to do silently:
#
# FAIL when a suite-shaped file exists on disk and is neither enumerated on
# the UNION of both surfaces nor listed in the exclusions file.
# ("Enumerated", deliberately — F1/F2 on PR #1018 proved this guard sees
# NAMING, not reachability, and its words must not claim otherwise.)
# FAIL when either surface names a path that does not exist on disk
# (a rename manufactures a stale entry silently — checked BOTH directions).
# FAIL when an exclusion entry has no reason, names a path that is gone,
# names a path that is also enumerated (contradiction), or names a path
# outside the population (dead weight that looks like coverage).
#
# POPULATION PATTERN — a deliberate decision, stated per #1017's record:
# basename matches *test*.sh (contains "test", ends ".sh"). Deliberately BROAD:
# the strict `test-*.sh` prefix cannot even name three real boundary files
# (tmux/agent-send.test.sh — CI-run; orchestrator/smoke-test.sh;
# wake/validate-973/microtest-wake-assert.sh), and three independent censuses
# handled that last file three different ways with no trace of the judgement.
# The broad pattern makes such files MEMBERS, so their disposition must be a
# signed exclusion, not an accident of the glob. The SAME pattern is applied to
# both sides of the comparison (disk and enumeration) — a comparison globbed two
# ways runs on two different populations. Scripts outside the pattern on both
# sides symmetrically (e.g. check-resident-budget.sh, verify-sanitized.sh) are
# check-scripts, not suites; their existence is still verified via the
# both-directions rule because every surface-named path must exist on disk.
#
# The surfaces are PARSED, never line-ranged: three seats independently
# mis-scoped hand-written line ranges against these files (#1017 thread). S1 is
# read via JSON + command-chain tokenization; S2 by extracting every
# packages/mosaic/framework/tools/ token wherever it appears in the file.
#
# Exclusions file format (framework/tools/quality/test-enumeration-exclusions.txt):
# <repo-relative-path> | <non-empty reason>
# Lines starting with # and blank lines are ignored. An exclusion is a recorded
# decision someone signed, not an omission nobody made.
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$(cd "$SCRIPT_DIR/../../../../../.." && pwd)"
while (( $# )); do
case "$1" in
--root) ROOT="$(cd "$2" && pwd)"; shift 2 ;;
*) echo "usage: check-test-enumeration.sh [--root <repo-root>]" >&2; exit 2 ;;
esac
done
PKG_JSON="$ROOT/packages/mosaic/package.json"
CI_YML="$ROOT/.woodpecker/ci.yml"
TOOLS_DIR="$ROOT/packages/mosaic/framework/tools"
EXCLUSIONS="$TOOLS_DIR/quality/test-enumeration-exclusions.txt"
for f in "$PKG_JSON" "$CI_YML"; do
[[ -f "$f" ]] || { echo "FAIL: required surface file missing: $f" >&2; exit 2; }
done
[[ -d "$TOOLS_DIR" ]] || { echo "FAIL: tools dir missing: $TOOLS_DIR" >&2; exit 2; }
fail_count=0
fail() { printf 'FAIL %s\n' "$1"; fail_count=$(( fail_count + 1 )); }
# in_population <repo-relative path> — the single pattern, used for BOTH sides.
in_population() {
local base; base="$(basename "$1")"
[[ "$base" == *test*.sh ]]
}
# --- Surface 1: package.json test:framework-shell, parsed, repo-relative -----
# Tokens are script paths iff they contain "/" and end .sh/.py; interpreter
# names and flags are skipped. Paths are relative to packages/mosaic/.
mapfile -t S1 < <(python3 - "$PKG_JSON" <<'PY'
import json, shlex, sys
cmd = json.load(open(sys.argv[1]))["scripts"].get("test:framework-shell", "")
seen = []
for seg in cmd.split("&&"):
for tok in shlex.split(seg):
if "/" in tok and (tok.endswith(".sh") or tok.endswith(".py")):
path = "packages/mosaic/" + tok
if path not in seen:
seen.append(path)
print("\n".join(seen))
PY
)
# --- Surface 2: ci.yml, every framework/tools token wherever it appears ------
# Comment lines (first non-whitespace char is #) are skipped BEFORE matching:
# commenting an invocation out is the most common way a suite actually gets
# disabled, and a raw-text regex would keep calling it enumerated (F1, 20155 on
# PR #1018 — demonstrated, not argued). Known residual limit: a path named only
# in a TRAILING comment on a live line still matches; no such line exists today
# and full fidelity would need a YAML parser the CI image does not ship.
mapfile -t S2 < <(grep -vE '^[[:space:]]*#' "$CI_YML" \
| grep -oE 'packages/mosaic/framework/tools/[A-Za-z0-9_./-]+\.(sh|py)' | sort -u)
# --- Union, and its population-restricted view -------------------------------
declare -A ENUM=() ENUM_POP=()
for p in "${S1[@]:-}" "${S2[@]:-}"; do
[[ -n "$p" ]] || continue
ENUM["$p"]=1
in_population "$p" && ENUM_POP["$p"]=1
done
# --- Direction B: every surface-named path must exist on disk ----------------
for p in "${!ENUM[@]}"; do
[[ -f "$ROOT/$p" ]] || fail "STALE ENUMERATION: surfaces name '$p' but it does not exist on disk"
done
# --- Exclusions: parsed with the same rigor the enumeration gets -------------
declare -A EXCLUDED=()
if [[ -f "$EXCLUSIONS" ]]; then
lineno=0
while IFS= read -r line; do
lineno=$(( lineno + 1 ))
[[ "$line" =~ ^[[:space:]]*(#|$) ]] && continue
path="${line%%|*}"; reason="${line#*|}"
path="$(echo "$path" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
reason="$(echo "$reason" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
if [[ "$line" != *"|"* || -z "$reason" ]]; then
fail "EXCLUSION MISSING REASON: line $lineno ('$path') — an exclusion is a recorded decision someone signed"
continue
fi
if [[ ! -f "$ROOT/$path" ]]; then
fail "STALE EXCLUSION: line $lineno excludes '$path' which does not exist on disk"
continue
fi
if ! in_population "$path"; then
fail "EXCLUSION OUTSIDE POPULATION: line $lineno excludes '$path' which the population pattern does not name — dead weight that reads as coverage"
continue
fi
if [[ -n "${ENUM[$path]:-}" ]]; then
fail "CONTRADICTORY EXCLUSION: line $lineno excludes '$path' which the surfaces already enumerate"
continue
fi
EXCLUDED["$path"]=1
done < "$EXCLUSIONS"
fi
# --- Direction A: disk population must be enumerated or signed-excluded ------
disk_total=0
unlisted=0
while IFS= read -r f; do
rel="${f#"$ROOT"/}"
in_population "$rel" || continue
disk_total=$(( disk_total + 1 ))
if [[ -z "${ENUM_POP[$rel]:-}" && -z "${EXCLUDED[$rel]:-}" ]]; then
fail "UNENUMERATED: '$rel' exists on disk but is neither enumerated on any CI surface nor signed in the exclusions file"
unlisted=$(( unlisted + 1 ))
fi
done < <(find "$TOOLS_DIR" -type f -name '*.sh' | sort)
if (( fail_count > 0 )); then
printf 'enumeration guard: %d failure(s) — population %d, enumerated (in-population) %d, excluded %d\n' \
"$fail_count" "$disk_total" "${#ENUM_POP[@]}" "${#EXCLUDED[@]}"
exit 1
fi
printf 'enumeration guard: OK — population %d, enumerated (in-population) %d, excluded (signed) %d, surfaces name %d path(s), all present on disk\n' \
"$disk_total" "${#ENUM_POP[@]}" "${#EXCLUDED[@]}" "${#ENUM[@]}"
@@ -1,166 +0,0 @@
#!/usr/bin/env bash
# test-check-test-enumeration.sh — needles for the enumeration guard (#1017).
#
# Every failure mode the guard promises gets BOTH polarities:
# NEEDLE a fixture that MUST trip the guard, asserted on the guard's OWN
# words (--out) — exit 1 alone cannot distinguish "caught the rogue
# file" from "choked on the fixture".
# CONTROL a fixture that MUST pass. A guard that failed unconditionally
# would satisfy every needle here — the null-case defect the guard's
# own subject matter (#1017) exists to make impossible.
#
# The needles encode the specific errors that produced #1017's thread:
# n6 is the 20124 boundary file (a suite the strict prefix cannot name);
# n2b proves surface 2 is PARSED, not line-ranged (three seats mis-scoped
# hand-written ranges against ci.yml);
# n5/n7 keep the exclusions file honest so it cannot become the next silent cap;
# n8/c4 are F1 (20155): a commented-out ci.yml line is NOT enumeration —
# commenting-out is the most common way a suite actually gets disabled,
# and it must fail loud in one direction without false-staling the other.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GUARD="$HERE/check-test-enumeration.sh"
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
PASS=0; FAIL=0
# fixture <name> — a minimal repo root the guard accepts via --root:
# one suite enumerated on S1 (plus a naming-outlier suite, so the S1 parser's
# handling of non-prefix names is always exercised), one on S2, one check-script
# named on S2 that is outside the population, and an empty exclusions file.
fixture() {
local r="$TMP/$1"
mkdir -p "$r/packages/mosaic/framework/tools/git" \
"$r/packages/mosaic/framework/tools/tmux" \
"$r/packages/mosaic/framework/tools/quality/scripts" \
"$r/.woodpecker"
printf '#!/usr/bin/env bash\nexit 0\n' > "$r/packages/mosaic/framework/tools/git/test-a.sh"
printf '#!/usr/bin/env bash\nexit 0\n' > "$r/packages/mosaic/framework/tools/tmux/outlier.test.sh"
printf '#!/usr/bin/env bash\nexit 0\n' > "$r/packages/mosaic/framework/tools/quality/scripts/test-ci.sh"
printf '#!/usr/bin/env bash\nexit 0\n' > "$r/packages/mosaic/framework/tools/quality/scripts/verify-thing.sh"
cat > "$r/packages/mosaic/package.json" <<'JSON'
{"scripts": {"test:framework-shell": "bash framework/tools/git/test-a.sh && bash framework/tools/tmux/outlier.test.sh"}}
JSON
cat > "$r/.woodpecker/ci.yml" <<'YML'
steps:
sanitize:
commands:
- bash packages/mosaic/framework/tools/quality/scripts/verify-thing.sh
guard:
commands:
- bash packages/mosaic/framework/tools/quality/scripts/test-ci.sh
YML
: > "$r/packages/mosaic/framework/tools/quality/test-enumeration-exclusions.txt"
printf '%s' "$r"
}
# expect <kind> <want-exit> <desc> [--out <substring>] -- <root>
expect() {
local kind="$1" want="$2" desc="$3"; shift 3
local need_out=""
while (( $# )); do
case "$1" in
--out) need_out="$2"; shift 2 ;;
--) shift; break ;;
esac
done
local root="$1" got=0 out
out="$(bash "$GUARD" --root "$root" 2>&1)" || got=$?
local why=""
[[ "$got" == "$want" ]] || why="wanted exit $want, got $got"
if [[ -z "$why" && -n "$need_out" && "$out" != *"$need_out"* ]]; then
why="exit $got as expected, but output never said: $need_out"
fi
if [[ -z "$why" ]]; then
printf ' PASS [%-7s] %s (exit %s)\n' "$kind" "$desc" "$got"
PASS=$(( PASS + 1 ))
else
printf ' FAIL [%-7s] %s — %s\n' "$kind" "$desc" "$why"
printf '%s\n' "$out" | sed 's/^/ | /'
FAIL=$(( FAIL + 1 ))
fi
}
excl() { printf '%s\n' "$2" >> "$1/packages/mosaic/framework/tools/quality/test-enumeration-exclusions.txt"; }
echo "=== c1: a fully consistent fixture passes ==="
R="$(fixture c1)"
expect CONTROL 0 "consistent tree: both surfaces enumerated, nothing unlisted" \
--out "enumeration guard: OK" -- "$R"
echo "=== n1: an on-disk suite reachable from no surface must fail ==="
R="$(fixture n1)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/test-rogue.sh"
expect NEEDLE 1 "unlisted suite is named in the failure" \
--out "UNENUMERATED: 'packages/mosaic/framework/tools/git/test-rogue.sh'" -- "$R"
echo "=== n6: the 20124 boundary file — a suite the strict prefix cannot name ==="
R="$(fixture n6)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/rogue.test.sh"
expect NEEDLE 1 "naming-outlier suite (*.test.sh) is a population member, not invisible" \
--out "UNENUMERATED: 'packages/mosaic/framework/tools/git/rogue.test.sh'" -- "$R"
echo "=== c3: a non-suite script outside the pattern is outside it on BOTH sides ==="
R="$(fixture c3)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/check-unrelated.sh"
expect CONTROL 0 "check-script on disk, unlisted, outside population: not the guard's business" \
--out "enumeration guard: OK" -- "$R"
echo "=== n2/n2b: a surface naming a path absent from disk must fail — both surfaces ==="
R="$(fixture n2)"
rm "$R/packages/mosaic/framework/tools/git/test-a.sh"
expect NEEDLE 1 "S1 (package.json) stale entry" \
--out "STALE ENUMERATION: surfaces name 'packages/mosaic/framework/tools/git/test-a.sh'" -- "$R"
R="$(fixture n2b)"
rm "$R/packages/mosaic/framework/tools/quality/scripts/test-ci.sh"
expect NEEDLE 1 "S2 (ci.yml) stale entry — proves ci.yml is parsed, not line-ranged" \
--out "STALE ENUMERATION: surfaces name 'packages/mosaic/framework/tools/quality/scripts/test-ci.sh'" -- "$R"
echo "=== c2: a rogue suite with a SIGNED exclusion passes, and is counted ==="
R="$(fixture c2)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/test-rogue.sh"
excl "$R" "packages/mosaic/framework/tools/git/test-rogue.sh | non-hermetic pending fixture work (needle-suite specimen)"
expect CONTROL 0 "signed exclusion is honoured and visible in the summary" \
--out "excluded (signed) 1" -- "$R"
echo "=== n3: an exclusion with no reason is not a decision ==="
R="$(fixture n3)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/test-rogue.sh"
excl "$R" "packages/mosaic/framework/tools/git/test-rogue.sh | "
expect NEEDLE 1 "empty reason rejected" --out "EXCLUSION MISSING REASON" -- "$R"
R="$(fixture n3b)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/test-rogue.sh"
excl "$R" "packages/mosaic/framework/tools/git/test-rogue.sh"
expect NEEDLE 1 "missing separator rejected (the path alone is not a signature)" \
--out "EXCLUSION MISSING REASON" -- "$R"
echo "=== n4: an exclusion whose path is gone is stale, not satisfied ==="
R="$(fixture n4)"
excl "$R" "packages/mosaic/framework/tools/git/test-vanished.sh | was excluded once, then deleted"
expect NEEDLE 1 "stale exclusion rejected" --out "STALE EXCLUSION" -- "$R"
echo "=== n5: excluding an enumerated suite is a contradiction, not belt-and-braces ==="
R="$(fixture n5)"
excl "$R" "packages/mosaic/framework/tools/git/test-a.sh | already in CI but excluded anyway"
expect NEEDLE 1 "contradictory exclusion rejected" --out "CONTRADICTORY EXCLUSION" -- "$R"
echo "=== n8/c4: a commented-out ci.yml line is not enumeration (F1, 20155) ==="
R="$(fixture n8)"
printf '#!/usr/bin/env bash\nexit 0\n' > "$R/packages/mosaic/framework/tools/git/test-disabled.sh"
printf ' # - bash packages/mosaic/framework/tools/git/test-disabled.sh\n' >> "$R/.woodpecker/ci.yml"
expect NEEDLE 1 "suite named only in a commented-out invocation is UNENUMERATED" \
--out "UNENUMERATED: 'packages/mosaic/framework/tools/git/test-disabled.sh'" -- "$R"
R="$(fixture c4)"
printf ' # - bash packages/mosaic/framework/tools/git/test-vanished.sh\n' >> "$R/.woodpecker/ci.yml"
expect CONTROL 0 "comment naming an absent path raises no false stale-enumeration" \
--out "enumeration guard: OK" -- "$R"
echo "=== n7: excluding a file outside the population is dead weight, not coverage ==="
R="$(fixture n7)"
excl "$R" "packages/mosaic/framework/tools/quality/scripts/verify-thing.sh | not a suite but signing it anyway"
expect NEEDLE 1 "out-of-population exclusion rejected" --out "EXCLUSION OUTSIDE POPULATION" -- "$R"
echo
printf 'enumeration-guard needles: %d passed, %d failed\n' "$PASS" "$FAIL"
(( FAIL == 0 ))
@@ -1,45 +0,0 @@
# test-enumeration-exclusions.txt — signed exclusions for check-test-enumeration.sh (#1017).
#
# Every entry is a recorded decision: a suite-shaped file that exists on disk,
# is NOT reachable from any CI surface, and carries the reason someone signed
# for that. The guard FAILS on an entry with no reason, a stale path, or a path
# the surfaces already enumerate. Burning an entry down = making it CI-reachable
# (package.json test:framework-shell or a ci.yml step) and deleting its line.
#
# Format: <repo-relative path> | <reason>
# All entries below were signed at #1017's filing base (main 826a8b3b, 2026-07-31)
# by pepper (sb-it-1-dt); measurements cited are one-run assertions from that seat.
# --- tools/git: the #1007 five — non-hermetic, resolve real credentials ---
packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh | resolves real credentials (#1007 census); joins CI after the wrapper-half hermeticity fix (git -C scoping)
packages/mosaic/framework/tools/git/test-issue-create-interactive-auth.sh | resolves real credentials (#1007 census); joins CI after the wrapper-half hermeticity fix
packages/mosaic/framework/tools/git/test-gitea-login-resolution.sh | resolves real credentials (#1007 census); joins CI after the wrapper-half hermeticity fix
packages/mosaic/framework/tools/git/test-pr-metadata-gitea.sh | resolves real credentials (#1007 census, fourth entry via family-grep); joins CI after the wrapper-half hermeticity fix
packages/mosaic/framework/tools/git/test-issue-comment-readback.sh | resolves real credentials (#1007 census, fifth entry); joins CI after the wrapper-half hermeticity fix
# --- tools/git: push guards — measured green locally, CI-image fitness unverified ---
packages/mosaic/framework/tools/git/test-push-guard.sh | measured green at 826a8b3b (46 passed / 0 failed, one run, 2026-07-31); CI-image fitness unverified; #1017 burndown
packages/mosaic/framework/tools/git/test-mutate-push-guard.sh | measured green at 826a8b3b (8/0, 13 mutants killed 0 survived, one run, 2026-07-31); requires setsid (util-linux), absent from the alpine base image; #1017 burndown
packages/mosaic/framework/tools/git/test-issue-create-body-safety.sh | hermeticity unaudited — the unprotected suite in #1007's protected/unprotected split; audit before CI; #1017 burndown
# --- tools/git: unmeasured ---
packages/mosaic/framework/tools/git/test-verify-clean-clone.sh | unmeasured in CI image; asserts git file-mode (100644/755) semantics that need verification on the CI filesystem first; #1017 burndown
packages/mosaic/framework/tools/git/test-help-exit-code.sh | unmeasured in CI image; stub-based (#701 regression harness), likely CI-fit; #1017 burndown
packages/mosaic/framework/tools/git/test-lane-brief-pr-linkage.sh | unmeasured in CI image; fixture-based (#546/#547 regression harness), likely CI-fit; #1017 burndown
# --- tools/tmux: require a live tmux server ---
packages/mosaic/framework/tools/tmux/test-send-message-socket.sh | requires a real tmux server on a throwaway socket; CI image ships no tmux; #1017 burndown (needs tmux in image or a signed permanent exclusion)
packages/mosaic/framework/tools/tmux/test-send-message-verdict.sh | requires real tmux-pane fixtures on a throwaway socket; CI image ships no tmux; #1017 burndown (same condition as its sibling)
# --- single-suite directories: unmeasured in CI ---
packages/mosaic/framework/tools/fleet/test-start-agent-session.sh | unmeasured in CI image; stubs tmux via a fake bin dir, likely CI-fit; #1017 burndown
packages/mosaic/framework/tools/glpi/test-list-http-status.sh | unmeasured in CI image; stub-based (#807 regression harness), likely CI-fit; #1017 burndown
packages/mosaic/framework/tools/orchestrator/test-board-roll.sh | unmeasured in CI image; file-fixture based, likely CI-fit; #1017 burndown
packages/mosaic/framework/tools/woodpecker/test-ci-wait-exit-matrix.sh | unmeasured in CI image; drives ci-wait.sh against a stub pipeline-status.sh, likely CI-fit; #1017 burndown
# --- naming-boundary files the strict test-*.sh prefix cannot even name ---
# (#1017: three independent censuses handled the microtest file three different
# ways — editorial drop, structural exclusion, accidental inclusion — with no
# recorded judgement. These lines ARE that judgement, signed.)
packages/mosaic/framework/tools/orchestrator/smoke-test.sh | behavior smoke checks for coord continue/run workflows, run manually by orchestrator seats; unmeasured in CI; #1017 burndown
packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh | #973 instrument self-test, run as a precondition of the validate-973 evidence procedure rather than as a standing CI suite; #1017 burndown candidate
@@ -529,19 +529,7 @@ cmd_run() {
echo "detector.sh: WARN — off-host liveness beacon emit failed (see beacon.sh); the off-host absence check remains the authoritative dead-man." >&2
fi
[ "$once" -eq 1 ] && break
# Close the detector lock fd in the sleep child; otherwise an orphaned sleep
# keeps the single-instance flock (fd 9, taken at exec 9> above) alive after
# the detector parent dies. The lock is non-blocking (`flock -n`, above), so
# for as long as that sleep survives a replacement instance is REFUSED and
# exits rather than queueing. This particular hold is BOUNDED by one poll
# interval (WAKE_DETECTOR_INTERVAL, default 30s): when the orphaned sleep
# exits its copy of fd 9 closes, ending this bounded sleep-child hold. It
# does NOT follow that the next start succeeds — other inheritors of fd 9
# (the M1 adapter, M2 sink grandchildren) are outside this patch's scope and
# can keep holding the flock. The cost this removes is a restart window in
# which every supervisor retry fails on the sleep child's account.
# `9>&-` closes ONLY the child's copy — the parent's lock is unaffected.
sleep "$interval" 9>&-
sleep "$interval"
done
}
@@ -33,11 +33,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
BEACON="$SCRIPT_DIR/beacon.sh"
command -v jq >/dev/null 2>&1 || {
@@ -31,11 +31,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
DET="$SCRIPT_DIR/detector.sh"
STORE="$SCRIPT_DIR/store.sh"
@@ -37,11 +37,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
STORE="$SCRIPT_DIR/store.sh"
DIGEST="$SCRIPT_DIR/digest.sh"
SIGN="$SCRIPT_DIR/sign.sh"
@@ -119,11 +119,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
DIGEST="$SCRIPT_DIR/digest.sh"
command -v jq >/dev/null 2>&1 || {
@@ -27,11 +27,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
ORACLE="$SCRIPT_DIR/fn-oracle.sh"
DET="$SCRIPT_DIR/detector.sh"
@@ -36,11 +36,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
WI="$SCRIPT_DIR/wake-install.sh"
BEACON="$SCRIPT_DIR/beacon.sh"
FRAMEWORK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
@@ -48,11 +48,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
PRE="$SCRIPT_DIR/preimage.sh"
STORE="$SCRIPT_DIR/store.sh"
DET="$SCRIPT_DIR/detector.sh"
@@ -31,11 +31,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
RECON="$SCRIPT_DIR/reconcile.sh"
STORE="$SCRIPT_DIR/store.sh"
DET="$SCRIPT_DIR/detector.sh"
@@ -44,11 +44,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
STORE="$SCRIPT_DIR/store.sh"
ACK="$SCRIPT_DIR/ack.sh"
@@ -34,11 +34,7 @@ set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness.
# shellcheck disable=SC1091
if ! . "$SCRIPT_DIR/_wake-common.sh"; then
echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2
exit 97
fi
wake_assert_init
. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init
STORE="$SCRIPT_DIR/store.sh"
command -v jq >/dev/null 2>&1 || {
@@ -10,9 +10,8 @@ comparison come from independent code paths.
Subcommands (all print sorted, stable output; non-zero exit on any failure):
expected The expected coordinate set from the ARTIFACT: one
"<helper> <file>:<line+7>" row per denominator row (+7 = 3
converter header lines + 4 lines from the #984 source guard,
uniform across all ten suites).
"<helper> <file>:<line+3>" row per denominator row (+3 = the
uniform header shift the converter applied; converter-verified).
Multi-grep lines stay ONE coordinate.
static The converted-site inventory from the SOURCE TEXT at the current
@@ -24,9 +23,9 @@ Subcommands (all print sorted, stable output; non-zero exit on any failure):
from the text.)
arms The forced-error arm list: the 19 denominator canaries plus one
E-form arm (store-ack:733→740, a $(count_lines) capture compared
afterward — the A6 shape) plus one F-form arm (quarantine:560→567,
the multi-grep pipeline capture), as "<helper> <file>:<line+7>
E-form arm (store-ack:733→736, a $(count_lines) capture compared
afterward — the A6 shape) plus one F-form arm (quarantine:560→563,
the multi-grep pipeline capture), as "<helper> <file>:<line+3>
<form>". Both extras are asserted to exist in the artifact with
the expected form — a renumber that moved them fails here, not
silently downstream.
@@ -34,8 +33,7 @@ Subcommands (all print sorted, stable output; non-zero exit on any failure):
sweep Residual sweep: the denominator's own classifier (ported from the
frozen derivation) over the ten suites at the current tree must
find ZERO unconverted verdict-form grep sites; and, IN THE SAME
RUN, eight specimens (six per-form + two absorb-branch probes, #985)
planted into a temp copy of a real
RUN, six per-form specimens planted into a temp copy of a real
suite must ALL be found with their correct forms — an instrument
that reports zero must first be seen finding what it claims to
find (A5).
@@ -52,9 +50,7 @@ HERE = Path(__file__).resolve().parent
WAKE = HERE.parent
ART = HERE / "denominator-089615f.json"
HEADER_SHIFT = 7 # 3 converter header lines after SCRIPT_DIR + 4 lines from the
# #984 source guard (1-line `. _wake-common.sh && wake_assert_init` became a 5-line
# guarded block) — both uniform across all ten suites, both above every site.
HEADER_SHIFT = 3 # converter inserted 3 header lines after SCRIPT_DIR in every suite
# The two hand-picked extra arms (base coordinates; forms asserted at load).
EXTRA_ARMS = [
@@ -72,14 +68,10 @@ RX_ASSIGN_SUB = re.compile(r'=\s*"?\$\(.*grep')
RX_IF = re.compile(r"^\s*(el)?if\s+.*grep")
RX_GREP = re.compile(r"(^|[^A-Za-z0-9_.-])grep([^A-Za-z0-9_.-]|$)")
# grep in COMMAND position: at line start or after a command separator / subshell
# opener / shell keyword / `!`. Quote-unaware by design — a quoted "grep" after a
# separator reads as a command and lands the line in residual, which fails LOUD;
# the absorb direction (note) is the one that must never fire on a real verdict.
RX_GREP_CMD = re.compile(
r"(?:^|[;|&(`]|\$\(|\bif\b|\belif\b|\bthen\b|\belse\b|\bdo\b|\bwhile\b|\buntil\b|!)"
r"\s*grep(?:\s|$)"
)
def polarity(line):
m = RX_FAIL_SAME.search(line)
return "OR" if m.group(1) == "||" else "AND"
def classify(lines):
@@ -145,28 +137,6 @@ def classify(lines):
return sites, dispo
def residual_sites(lines):
"""classify() plus the absorb decision — the ONE path both sweep legs share.
A classified site is absorbed as a note only when its line carries a wake
helper token AND the line shows no grep in command position: a converted
line whose PATTERN argument merely contains the word grep. A helper line
that also runs a real grep verdict (has_match ... && grep -q SECRET ... &&
fail) stays residual (#985). Multi-line forms anchor the site at the line
containing grep, so a command-position grep on a continuation line never
shares its line with the helper token and stays residual by construction.
"""
sites, dispo = classify(lines)
residual, notes = [], []
for ln, form, text in sites:
line = lines[ln - 1]
if RX_HELPER.search(line) and not RX_GREP_CMD.search(line):
notes.append((ln, form, text))
else:
residual.append((ln, form, text))
return residual, notes, dispo
def load_art():
art = json.loads(ART.read_text())
assert art["total"] == 261 == len(art["rows"]), "artifact self-consistency"
@@ -229,20 +199,13 @@ def cmd_arms():
return 0
# (expected classify form, expected disposition through residual_sites, snippet)
PLANTS = [
("A-same-line", "residual", ['grep -q needle haystack || fail "plant-A"']),
("B-cont-operator", "residual", ["grep -q needle haystack ||", ' fail "plant-B"']),
("C-cont-backslash", "residual", ["grep -q needle \\", ' haystack || fail "plant-C"']),
("D-if-form", "residual", ["if ! grep -q needle haystack; then", ' fail "plant-D"', "fi"]),
("E-count-capture", "residual", ['[ "$(grep -c needle haystack)" = "1" ] || fail "plant-E"']),
("F-extract-capture", "residual", ['val="$(grep needle haystack)"']),
# G: a converted line that ALSO runs a raw grep verdict — the helper token
# must not absorb it (#985)
("A-same-line", "residual", ['has_match -q needle "$F" && grep -q SECRET "$F" && fail "plant-G"']),
# H: negative control — helper whose PATTERN argument is the word grep;
# must be absorbed as a note, never residual
("A-same-line", "note", ['has_match -q "grep" haystack || fail "plant-H"']),
("A-same-line", ['grep -q needle haystack || fail "plant-A"']),
("B-cont-operator", ["grep -q needle haystack ||", ' fail "plant-B"']),
("C-cont-backslash", ["grep -q needle \\", ' haystack || fail "plant-C"']),
("D-if-form", ["if ! grep -q needle haystack; then", ' fail "plant-D"', "fi"]),
("E-count-capture", ['[ "$(grep -c needle haystack)" = "1" ] || fail "plant-E"']),
("F-extract-capture", ['val="$(grep needle haystack)"']),
]
@@ -252,20 +215,22 @@ def cmd_sweep():
# leg 1: real suites at the current tree must be residual-free
for f in suite_files(art):
residual, notes, _dispo = residual_sites((WAKE / f).read_text().split("\n"))
for ln, form, text in notes:
# converted line whose PATTERN argument contains the word grep:
# not an unconverted site, but never silently absorbed either
print(f"SWEEP-NOTE {f}:{ln} converted line matches grep-token ({form}): {text[:80]}")
lines = (WAKE / f).read_text().split("\n")
sites, _dispo = classify(lines)
residual = []
for ln, form, text in sites:
if RX_HELPER.search(lines[ln - 1]):
# converted line whose PATTERN argument contains the word grep:
# not an unconverted site, but never silently absorbed either
print(f"SWEEP-NOTE {f}:{ln} converted line matches grep-token ({form}): {text[:80]}")
continue
residual.append((ln, form, text))
for ln, form, text in residual:
print(f"SWEEP-RESIDUAL {f}:{ln} {form}: {text[:100]}")
bad += 1
print(f"SWEEP {f}: {len(residual)} residual verdict site(s)")
# leg 2, SAME RUN, SAME PATH as leg 1: the instrument must find every plant
# with the right form AND the right absorb disposition — plants G/H exercise
# the absorb branch itself, so this leg must go through residual_sites(),
# not raw classify()
# leg 2, SAME RUN: the instrument must find six per-form plants
donor = suite_files(art)[0]
with tempfile.TemporaryDirectory() as td:
planted = Path(td) / donor
@@ -273,28 +238,25 @@ def cmd_sweep():
base_lines = planted.read_text().split("\n")
offset = len(base_lines)
expect = {}
for form, dispo, snippet in PLANTS:
expect[offset + 1] = (form, dispo) # first physical line of each plant
for form, snippet in PLANTS:
expect[offset + 1] = form # first physical line of each plant
base_lines.extend(snippet)
offset = len(base_lines)
planted.write_text("\n".join(base_lines))
residual, notes, _ = residual_sites(planted.read_text().split("\n"))
found = {ln: (form, "residual") for ln, form, _t in residual}
found.update({ln: (form, "note") for ln, form, _t in notes})
unexpected = [(ln, form) for ln, form, _t in residual if ln not in expect]
hits = sum(1 for ln, want in expect.items() if found.get(ln) == want)
n_plants = len(PLANTS)
print(f"SWEEP-PLANTS found={hits}/{n_plants} in planted copy of {donor}")
if hits != n_plants:
for ln, want in sorted(expect.items()):
got = found.get(ln, ("<missed>", "<missed>"))
if got != want:
print(f"SWEEP-PLANT-MISS line {ln}: expected {want}, got {got}")
sites, _ = classify(planted.read_text().split("\n"))
found = {ln: form for ln, form, _t in sites if ln in expect}
unexpected = [(ln, form) for ln, form, _t in sites if ln not in expect]
hits = sum(1 for ln, form in expect.items() if found.get(ln) == form)
print(f"SWEEP-PLANTS found={hits}/6 in planted copy of {donor}")
if hits != 6:
for ln, form in sorted(expect.items()):
got = found.get(ln, "<missed>")
if got != form:
print(f"SWEEP-PLANT-MISS line {ln}: expected {form}, got {got}")
bad += 1
if unexpected:
# the donor is a converted suite: any non-plant RESIDUAL site in the
# copy contradicts the zero leg 1 just reported on the original
# (non-plant notes mirror leg 1's treatment: printed there, not bad)
# the donor is a converted suite: any non-plant site the sweep finds
# in the copy contradicts the zero it just reported on the original
for ln, form in unexpected:
print(f"SWEEP-PLANT-UNEXPECTED {donor}(copy):{ln} {form}")
bad += 1
@@ -26,12 +26,12 @@
#
# Verified guard per site (line numbers at branch tip, +3 header shift):
count_lines test-wake-beacon.sh:354 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 353; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-detector.sh:706 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 705; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-digest-hmac.sh:438 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 437; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-digest-quarantine.sh:588 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 587; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-fn-oracle.sh:136 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 135; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-install.sh:438 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 437; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-reconcile.sh:393 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 392; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-store-ack.sh:745 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 744; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-store-enqueue-race.sh:212 — red-path summary (with "#927 TOCTOU reproduced (RED)" tail); guard `[ -s "$FAILFILE" ]` at line 211; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-beacon.sh:350 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 349; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-detector.sh:702 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 701; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-digest-hmac.sh:434 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 433; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-digest-quarantine.sh:584 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 583; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-fn-oracle.sh:132 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 131; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-install.sh:434 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 433; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-reconcile.sh:389 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 388; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-store-ack.sh:741 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 740; template execution measured by microtest C11; text verified by static inventory
count_lines test-wake-store-enqueue-race.sh:208 — red-path summary (with "#927 TOCTOU reproduced (RED)" tail); guard `[ -s "$FAILFILE" ]` at line 207; template execution measured by microtest C11; text verified by static inventory
@@ -4,8 +4,8 @@
#
# 0. instrument self-test (microtest) — no validate evidence is trusted
# before the instrument itself has been proven, including its abort arms.
# 1. expected set: 261 coordinates from the FROZEN artifact (+7 header
# shift: 3 converter lines + 4 #984 guard lines), count asserted against the number declared below BEFORE any
# 1. expected set: 261 coordinates from the FROZEN artifact (+3 header
# shift), count asserted against the number declared below BEFORE any
# suite runs.
# 2. static inventory: converted call sites re-derived from SOURCE TEXT,
# must equal the expected set exactly (amendment ONE, leg 1 — the
@@ -33,8 +33,7 @@
# site's ledger row must already be present (the append lands before the
# grep).
# 6. residual sweep: the denominator's own classifier finds zero unconverted
# verdict greps in the suites — and eight plants (six per-form + two
# absorb-branch probes, #985) in the same run.
# verdict greps in the suites — and six per-form plants in the same run.
#
# Output discipline (A10): every line that reports on a suite names the file
# under test; exit codes are reported before failure counts.
@@ -181,15 +180,8 @@ while read -r helper site form; do
bad="$bad no-ARMED-line"
printf '%s\n' "$out" | grep -q "WAKE-ASSERT ABORT: ${helper} at ${site}: grep exit" ||
bad="$bad no-ABORT-line"
# AND-polarity check (a match is the defect): a grep error (rc>=2) must be
# its own loud arm — it cannot fall through as "no sentinel = pass".
rc_sent=0
printf '%s\n' "$out" | grep -Eq "$(sentinel_for "$f")" || rc_sent=$?
case "$rc_sent" in
0) bad="$bad sentinel-emitted" ;;
1) : ;;
*) bad="$bad sentinel-grep-error-rc=$rc_sent" ;;
esac
printf '%s\n' "$out" | grep -Eq "$(sentinel_for "$f")" &&
bad="$bad sentinel-emitted"
grep -q "^${helper} ${site}\$" "$aled" ||
bad="$bad no-ledger-row"
if [ -z "$bad" ]; then
+1 -1
View File
@@ -25,7 +25,7 @@
"lint": "eslint src",
"typecheck": "tsc --noEmit",
"test": "vitest run --passWithNoTests && pnpm run test:framework-shell",
"test:framework-shell": "bash framework/tools/quality/scripts/check-test-enumeration.sh && bash framework/tools/quality/scripts/test-check-test-enumeration.sh && python3 src/lease-broker/daemon_deadline_unittest.py && python3 src/lease-broker/normative_fragments_unittest.py && python3 src/lease-broker/receipt_challenge_unittest.py && python3 src/lease-broker/context_recovery_unittest.py && python3 src/lease-broker/recovery_runtime_unittest.py && python3 src/lease-broker/recovery_b1_adversarial_unittest.py && python3 src/lease-broker/framework_skill_portability_unittest.py && python3 src/mutator-gate/runtime_tools_unittest.py && python3 src/mutator-gate/runtime_launch_guard_unittest.py && python3 src/mutator-gate/version_coupling_unittest.py && python3 framework/tools/lease-broker/check-runtime-launches.py --root ../.. && bash framework/tools/codex/test-pr-diff-context.sh && bash framework/tools/qa/test-deps-preflight.sh && bash framework/tools/git/test-pr-review-gitea-comment.sh && bash framework/tools/git/test-pr-review-repo-host-override.sh && bash framework/tools/git/test-ci-queue-wait-branch-absent.sh && bash framework/tools/git/test-ci-queue-wait-parse.sh && bash framework/tools/git/test-git-credential-mosaic.sh && bash framework/tools/git/test-gitea-token-identity.sh && bash framework/tools/_scripts/test-install-ordering-guard.sh && bash framework/tools/tmux/agent-send.test.sh && bash framework/tools/wake/test-wake-store-ack.sh && bash framework/tools/wake/test-wake-store-enqueue-race.sh && bash framework/tools/wake/test-wake-digest-hmac.sh && bash framework/tools/wake/test-wake-digest-quarantine.sh && bash framework/tools/wake/test-wake-detector.sh && bash framework/tools/wake/test-wake-fn-oracle.sh && bash framework/tools/wake/test-wake-reconcile.sh && bash framework/tools/wake/test-wake-beacon.sh && bash framework/tools/wake/test-wake-preimage.sh && bash framework/tools/wake/test-wake-install.sh"
"test:framework-shell": "python3 src/lease-broker/daemon_deadline_unittest.py && python3 src/lease-broker/normative_fragments_unittest.py && python3 src/lease-broker/receipt_challenge_unittest.py && python3 src/lease-broker/context_recovery_unittest.py && python3 src/lease-broker/recovery_runtime_unittest.py && python3 src/lease-broker/recovery_b1_adversarial_unittest.py && python3 src/lease-broker/framework_skill_portability_unittest.py && python3 src/mutator-gate/runtime_tools_unittest.py && python3 src/mutator-gate/runtime_launch_guard_unittest.py && python3 src/mutator-gate/version_coupling_unittest.py && python3 framework/tools/lease-broker/check-runtime-launches.py --root ../.. && bash framework/tools/codex/test-pr-diff-context.sh && bash framework/tools/qa/test-deps-preflight.sh && bash framework/tools/git/test-pr-review-gitea-comment.sh && bash framework/tools/git/test-pr-review-repo-host-override.sh && bash framework/tools/git/test-ci-queue-wait-branch-absent.sh && bash framework/tools/git/test-git-credential-mosaic.sh && bash framework/tools/git/test-gitea-token-identity.sh && bash framework/tools/_scripts/test-install-ordering-guard.sh && bash framework/tools/tmux/agent-send.test.sh && bash framework/tools/wake/test-wake-store-ack.sh && bash framework/tools/wake/test-wake-store-enqueue-race.sh && bash framework/tools/wake/test-wake-digest-hmac.sh && bash framework/tools/wake/test-wake-digest-quarantine.sh && bash framework/tools/wake/test-wake-detector.sh && bash framework/tools/wake/test-wake-fn-oracle.sh && bash framework/tools/wake/test-wake-reconcile.sh && bash framework/tools/wake/test-wake-beacon.sh && bash framework/tools/wake/test-wake-preimage.sh && bash framework/tools/wake/test-wake-install.sh"
},
"dependencies": {
"@mosaicstack/brain": "workspace:*",