Compare commits

..
Author SHA1 Message Date
Jason Woltje cd373b4b10 fix(docs): fit Pi runtime resident budget
ci/woodpecker/pr/ci Pipeline was successful
2026-08-10 17:40:21 -05:00
Jason Woltje 873e7a9fed feat(pi): add persistent Mosaic goal controller
ci/woodpecker/pr/ci Pipeline failed
2026-08-10 17:33:34 -05:00
16 changed files with 53 additions and 408 deletions
+1 -12
View File
@@ -69,15 +69,4 @@ All 22 baseline sites below are `FIXED`; the checked-in tranche fixture is passe
| `tmux/test-send-message-socket.sh:37,38,44-46,68,72` | FIXED | capture commands complete before redirected grep assertions | | `tmux/test-send-message-socket.sh:37,38,44-46,68,72` | FIXED | capture commands complete before redirected grep assertions |
| `tmux/test-send-message-verdict.sh:34` | FIXED | grep reads from a here-string | | `tmux/test-send-message-verdict.sh:34` | FIXED | grep reads from a here-string |
## Tranche 3 — wake validation harnesses Remaining wake-validation sites are intentionally deferred to the final review-sized tranche and are not yet assigned a safety verdict here.
All 26 baseline occurrences (25 normalized identities; one preimage selector occurs twice) are `FIXED` and mechanically bound through the wake fixture and shared scanner.
| Baseline site(s) | Verdict | Construction |
| --- | --- | --- |
| `wake/test-wake-digest-quarantine.sh:567` | FIXED | complete match populations are captured, then first line selected by parameter expansion |
| `wake/test-wake-preimage.sh:182-183,346-347` | FIXED | jq `first(...)` reads each JSONL file directly |
| `wake/validate-973/microtest-wake-assert.sh:153,170-171,176,204-209,233-234,251-252,286-287` | FIXED | scalar assertions use here-strings; diagnostics use non-early sed ranges; source line captured before matching |
| `wake/validate-973/validate-973.sh:110,119,180,182,187` | FIXED | scalar assertions use here-strings; diagnostic truncation uses consuming sed ranges |
The scoped inventory is complete: 26 runtime/general + 22 non-wake tests + 26 wake tests fixed; 11 explicitly withdrawn or non-load-bearing sites retain their documented verdicts.
+1 -5
View File
@@ -25,10 +25,6 @@ Site-by-site verdicts: `docs/reports/quality/1099-pipefail-sweep.md`.
Expanded the unconditional scanner over 11 non-wake test harnesses. RED named exactly 22 source lines; a second immutable-baseline fixture now asserts those 22 entries through the same scanner. Rewrites preserve command status by capturing producers before redirected assertions, use parameter expansion for line selection, and use complete `mapfile` populations where ordering matters. Current-tree finding count is zero for tranches 1 and 2. Expanded the unconditional scanner over 11 non-wake test harnesses. RED named exactly 22 source lines; a second immutable-baseline fixture now asserts those 22 entries through the same scanner. Rewrites preserve command status by capturing producers before redirected assertions, use parameter expansion for line selection, and use complete `mapfile` populations where ordering matters. Current-tree finding count is zero for tranches 1 and 2.
## Tranche 3 TDD
Expanded the shared scanner over four wake validation harnesses. RED named 26 occurrences. The wake fixture asserts 26 occurrences / 25 normalized identities through the same scanner; all scalar assertions now use redirection, direct jq selection, complete capture, or consuming diagnostic ranges. Current-tree finding count is zero across the full scoped population.
## Verification so far ## Verification so far
- `bash -n` on every changed shell script: pass. - `bash -n` on every changed shell script: pass.
@@ -37,5 +33,5 @@ Expanded the shared scanner over four wake validation harnesses. RED named 26 oc
- `test-send-message-verdict.sh`: 3/3 pass. - `test-send-message-verdict.sh`: 3/3 pass.
- `test-send-message-socket.sh`: pass. - `test-send-message-socket.sh`: pass.
- Independent review 143 found two semantic regressions: a help-probe `|| true` changed the failure truth table, and an unguarded Git capture changed non-Git data-dir behavior from rc 0 + JSON to silent rc 128. Both received RED-first regressions before correction; help status is now separate and required, and Git status remains condition-guarded. - Independent review 143 found two semantic regressions: a help-probe `|| true` changed the failure truth table, and an unguarded Git capture changed non-Git data-dir behavior from rc 0 + JSON to silent rc 128. Both received RED-first regressions before correction; help status is now separate and required, and Git status remains condition-guarded.
- Wake static inventory remains aligned at 261/261 after line-neutral rewrites; no static-set mismatch. Wake detector/reconcile/digest/preimage suites terminate at their existing fail-closed #973 `BASH_LINENO` environment probe (exit 97, observed `[3 5]`, expected `[3 4]`) before subject tests. No bypass or skip was used; canonical CI remains required. - Wake detector/reconcile/digest/preimage suites terminate at their existing fail-closed #973 `BASH_LINENO` environment probe (exit 97, observed `[3 5]`, expected `[3 4]`) before subject tests. No bypass or skip was used; canonical CI remains required.
- ShellCheck reports only pre-existing source-following, unused-variable, and untouched `ls | head` findings; no new diagnostic was introduced. - ShellCheck reports only pre-existing source-following, unused-variable, and untouched `ls | head` findings; no new diagnostic was introduced.
@@ -254,32 +254,15 @@ from urllib.parse import urlparse
def _origin_and_path(url): def _origin_and_path(url):
# Normalize a URL to (scheme-class, host, distinguishing-port) + comment path. # Normalize a URL to (scheme, host, effective-port) + comment path. The port
# # defaults to the scheme's default (80 http / 443 otherwise) so an implicit
# #991: http and https collapse into ONE scheme class ("web"). A Gitea whose # port and its explicit default form compare equal.
# ROOT_URL is configured http:// returns http:// object URLs even when every
# client reaches it over https://, so a scheme-strict comparison rejects the
# provider's own correct answer about a write that landed — a deterministic
# false negative on every comment posted against such a deployment. The
# scheme is also not what this check defends: the forgeries it exists to
# catch (look-alike host, decoy path prefix, wrong owner/repo/number) all
# vary the HOST or the PATH, both of which stay strict below. Any OTHER
# scheme (file:, ftp:, javascript:) remains distinguishing and is rejected.
#
# Port: an implicit port and its own scheme's default compare equal, so
# http://h == https://h. An EXPLICIT non-default port still distinguishes,
# because a different port is a different service on the same host.
parsed = urlparse(url or "") parsed = urlparse(url or "")
scheme = (parsed.scheme or "").lower() scheme = (parsed.scheme or "").lower()
host = (parsed.hostname or "").lower() host = (parsed.hostname or "").lower()
if scheme in ("http", "https"): default_port = 80 if scheme == "http" else 443
scheme_class = "web" port = parsed.port if parsed.port is not None else default_port
default_port = 80 if scheme == "http" else 443 return (scheme, host, port), parsed.path.rstrip("/")
port = None if parsed.port in (None, default_port) else parsed.port
else:
scheme_class = scheme
port = parsed.port
return (scheme_class, host, port), parsed.path.rstrip("/")
try: try:
@@ -243,35 +243,15 @@ from urllib.parse import urlparse
def _origin_and_path(url): def _origin_and_path(url):
# Normalize a URL to (scheme-class, host, distinguishing-port) + comment path. # Normalize a URL to (scheme, host, effective-port) + comment path. The port
# # defaults to the scheme's default (80 http / 443 otherwise) so an implicit
# #991: http and https collapse into ONE scheme class ("web"). A Gitea whose # port and its explicit default form compare equal.
# ROOT_URL is configured http:// returns http:// object URLs even when every
# client reaches it over https://, so a scheme-strict comparison rejects the
# provider's own correct answer about a comment that landed — a deterministic
# false negative on EVERY review comment posted against such a deployment.
# That matters more here than anywhere else: on a host where no seat can
# create a review OBJECT, the comment-form review record this path produces
# is the only gate-16 evidence available, and this check refuses all of it.
# The scheme is also not what the check defends: the forgeries it exists to
# catch (look-alike host, decoy path prefix, wrong owner/repo/kind/number)
# all vary the HOST or the PATH, both of which stay strict below. Any OTHER
# scheme (file:, ftp:, javascript:) remains distinguishing and is rejected.
#
# Port: an implicit port and its own scheme's default compare equal, so
# http://h == https://h. An EXPLICIT non-default port still distinguishes,
# because a different port is a different service on the same host.
parsed = urlparse(url or "") parsed = urlparse(url or "")
scheme = (parsed.scheme or "").lower() scheme = (parsed.scheme or "").lower()
host = (parsed.hostname or "").lower() host = (parsed.hostname or "").lower()
if scheme in ("http", "https"): default_port = 80 if scheme == "http" else 443
scheme_class = "web" port = parsed.port if parsed.port is not None else default_port
default_port = 80 if scheme == "http" else 443 return (scheme, host, port), parsed.path.rstrip("/")
port = None if parsed.port in (None, default_port) else parsed.port
else:
scheme_class = scheme
port = parsed.port
return (scheme_class, host, port), parsed.path.rstrip("/")
try: try:
@@ -7,40 +7,14 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/gitea-login-resolution}" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/gitea-login-resolution}"
REPO_DIR="$WORK_DIR/repo" REPO_DIR="$WORK_DIR/repo"
BIN_DIR="$WORK_DIR/bin" BIN_DIR="$WORK_DIR/bin"
HOME_DIR="$WORK_DIR/home"
LOG_FILE="$WORK_DIR/calls.log" LOG_FILE="$WORK_DIR/calls.log"
CREDENTIALS_FILE="$WORK_DIR/credentials.json" CREDENTIALS_FILE="$WORK_DIR/credentials.json"
rm -rf "$WORK_DIR" rm -rf "$WORK_DIR"
mkdir -p "$REPO_DIR" "$BIN_DIR" "$HOME_DIR" mkdir -p "$REPO_DIR" "$BIN_DIR"
git -C "$REPO_DIR" init -q git -C "$REPO_DIR" init -q
git -C "$REPO_DIR" remote add origin https://git.uscllc.com/USC/uconnect.git git -C "$REPO_DIR" remote add origin https://git.uscllc.com/USC/uconnect.git
# HERMETICITY (#1007) — TWO mechanisms with DIFFERENT jobs; do not conflate them.
#
# OPERATIVE: the empty repo-local `mosaic.gitIdentity` below. 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 so 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. This suite is the one where the consequence is not subtle: it FAILS
# outright on a provisioned seat (rc=1 bare, rc=0 with $HOME sandboxed, one
# variable changed) and passes everywhere else, including CI, which has no
# per-agent token to leak.
#
# CONTAINMENT: the sandboxed HOME in the four run helpers below. It only has to
# bound a failure that the pin should already have prevented.
#
# NOTE FOR ANYONE AUDITING THIS SUITE: the sandboxed HOME is containment, NOT an
# assay. Running a suite under a decoy HOME to test for this defect REMOVES the
# trigger — ~/.gitconfig is where the global identity lives, so step 0 is skipped
# by construction and every suite reads clean however vulnerable it is. To measure,
# REPLICATE a seat (a decoy HOME whose .gitconfig sets mosaic.gitIdentity, with no
# per-slot token) so step 0 reaches its fail-loud branch.
#
# Note the env-var route does NOT work: detect-platform.sh reads
# "${MOSAIC_GIT_IDENTITY:-}", and `:-` treats set-but-empty identically to unset.
git -C "$REPO_DIR" config mosaic.gitIdentity ""
cat > "$CREDENTIALS_FILE" <<'JSON' cat > "$CREDENTIALS_FILE" <<'JSON'
{ {
@@ -112,7 +86,6 @@ run_in_repo() {
( (
cd "$REPO_DIR" cd "$REPO_DIR"
PATH="$BIN_DIR:$PATH" \ PATH="$BIN_DIR:$PATH" \
HOME="$HOME_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \ MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
MOSAIC_TEST_LOG="$LOG_FILE" \ MOSAIC_TEST_LOG="$LOG_FILE" \
"$@" "$@"
@@ -310,7 +283,6 @@ run_in_repo2() {
( (
cd "$REPO_DIR" cd "$REPO_DIR"
PATH="$BIN_DIR2:$PATH" \ PATH="$BIN_DIR2:$PATH" \
HOME="$HOME_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \ MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
MOSAIC_TEST_LOG="$LOG_FILE" \ MOSAIC_TEST_LOG="$LOG_FILE" \
"$@" "$@"
@@ -371,7 +343,7 @@ write_fixture() { printf '%s' "$1" > "$FIXTURE_XDG/tea/config.yml"; }
token_fallback() { token_fallback() {
( (
cd "$REPO_DIR" cd "$REPO_DIR"
HOME="$HOME_DIR" XDG_CONFIG_HOME="$FIXTURE_XDG" PYTHONPATH="$NOYAML_DIR" bash -c ' XDG_CONFIG_HOME="$FIXTURE_XDG" PYTHONPATH="$NOYAML_DIR" bash -c '
source "'"$SCRIPT_DIR"'/detect-platform.sh" source "'"$SCRIPT_DIR"'/detect-platform.sh"
get_gitea_token_for_login "$1" "$2" get_gitea_token_for_login "$1" "$2"
' _ "$1" "$2" ' _ "$1" "$2"
@@ -382,7 +354,7 @@ token_fallback() {
token_pyyaml() { token_pyyaml() {
( (
cd "$REPO_DIR" cd "$REPO_DIR"
HOME="$HOME_DIR" XDG_CONFIG_HOME="$FIXTURE_XDG" bash -c ' XDG_CONFIG_HOME="$FIXTURE_XDG" bash -c '
source "'"$SCRIPT_DIR"'/detect-platform.sh" source "'"$SCRIPT_DIR"'/detect-platform.sh"
get_gitea_token_for_login "$1" "$2" get_gitea_token_for_login "$1" "$2"
' _ "$1" "$2" ' _ "$1" "$2"
@@ -61,54 +61,15 @@ STATE_FILE="$WORK_DIR/comments.json"
# A dedicated scratch dir the wrapper is pointed at via TMPDIR, so the leak # 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. # check can assert every POST/GET body + metadata temp file is cleaned up.
TMP_SCRATCH="$WORK_DIR/scratch" TMP_SCRATCH="$WORK_DIR/scratch"
HOME_DIR="$WORK_DIR/home"
cleanup() { cleanup() {
rm -rf "$WORK_DIR" rm -rf "$WORK_DIR"
} }
trap cleanup EXIT trap cleanup EXIT
mkdir -p "$REPO_DIR" "$BIN_DIR" "$XDG_DIR" "$TMP_SCRATCH" "$HOME_DIR" mkdir -p "$REPO_DIR" "$BIN_DIR" "$XDG_DIR" "$TMP_SCRATCH"
git -C "$REPO_DIR" init -q git -C "$REPO_DIR" init -q
git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git
# HERMETICITY (#1007) — TWO mechanisms with DIFFERENT jobs; do not conflate them.
#
# OPERATIVE: the empty repo-local `mosaic.gitIdentity` below. 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 so 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 credential below is silently
# ignored. The stub curl then rejects the unrecognised bearer, and this suite
# fails at its FIRST case with `Gitea authenticated-identity read failed with
# HTTP 401`. An empty repo-local value shadows the global one and reads back
# empty at rc=0. Measured: without this pin the suite is RED on every seat.
#
# CONTAINMENT: the sandboxed HOME in run_comment(). It only has to bound a
# failure that the pin should already have prevented.
#
# THIS SUITE WAS THE HARDEST OF THE FIVE TO SEE, and the reason is worth stating
# because it generalises: run_comment() sends the wrapper's stdout AND stderr to
# $OUTPUT_FILE, and the EXIT trap above deletes $WORK_DIR. So the 401 — the only
# thing that says what went wrong — exists only inside a directory that is gone
# by the time anyone looks. The suite exits 1 with ZERO bytes on stdout and
# stderr. A suite that discards or deletes its own evidence turns any post-hoc
# assay into a non-measurement: "nothing found" there means "no surviving
# trace", never "clean". It was found by intercepting the identity read at its
# SOURCE (a PATH shim over `git` logging every `mosaic.gitIdentity` read to a
# file outside $WORK_DIR), which is deletion-proof by construction, rather than
# by grepping for the symptom.
#
# NOTE FOR ANYONE AUDITING THIS SUITE: the sandboxed HOME is containment, NOT an
# assay. Running a suite under a decoy HOME to test for this defect REMOVES the
# trigger — ~/.gitconfig is where the global identity lives, so step 0 is skipped
# by construction and every suite reads clean however vulnerable it is. To
# measure, REPLICATE a seat (a decoy HOME whose .gitconfig sets
# mosaic.gitIdentity, with no per-slot token) so step 0 reaches its fail-loud
# branch — or intercept the read as described above.
#
# Note the env-var route does NOT work: detect-platform.sh reads
# "${MOSAIC_GIT_IDENTITY:-}", and `:-` treats set-but-empty identically to unset.
git -C "$REPO_DIR" config mosaic.gitIdentity ""
ISSUE_NUMBER=7 ISSUE_NUMBER=7
REPO_SLUG="mosaicstack/stack" REPO_SLUG="mosaicstack/stack"
@@ -411,7 +372,6 @@ run_comment() {
cd "$REPO_DIR" cd "$REPO_DIR"
PATH="$BIN_DIR:$PATH" \ PATH="$BIN_DIR:$PATH" \
TMPDIR="$TMP_SCRATCH" \ TMPDIR="$TMP_SCRATCH" \
HOME="$HOME_DIR" \
XDG_CONFIG_HOME="$XDG_DIR" \ XDG_CONFIG_HOME="$XDG_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \ MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
ISSUE_COMMENT_TEA_LOG="$TEA_LOG" \ ISSUE_COMMENT_TEA_LOG="$TEA_LOG" \
@@ -7,38 +7,13 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/issue-create-interactive-auth}" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/issue-create-interactive-auth}"
REPO_DIR="$WORK_DIR/repo" REPO_DIR="$WORK_DIR/repo"
BIN_DIR="$WORK_DIR/bin" BIN_DIR="$WORK_DIR/bin"
HOME_DIR="$WORK_DIR/home"
LOG_FILE="$WORK_DIR/calls.log" LOG_FILE="$WORK_DIR/calls.log"
CREDENTIALS_FILE="$WORK_DIR/credentials.json" CREDENTIALS_FILE="$WORK_DIR/credentials.json"
rm -rf "$WORK_DIR" rm -rf "$WORK_DIR"
mkdir -p "$REPO_DIR" "$BIN_DIR" "$HOME_DIR" mkdir -p "$REPO_DIR" "$BIN_DIR"
git -C "$REPO_DIR" init -q git -C "$REPO_DIR" init -q
git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git
# HERMETICITY (#1007) — TWO mechanisms with DIFFERENT jobs; do not conflate them.
#
# OPERATIVE: the empty repo-local `mosaic.gitIdentity` below. 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 so 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 credential below is silently
# ignored and the suite runs against a production credential. An empty repo-local
# value shadows the global one and reads back empty at rc=0. Measured: this suite
# resolves a per-slot token without it.
#
# CONTAINMENT: the sandboxed HOME in run_wrapper(). It only has to bound a failure
# that the pin should already have prevented.
#
# NOTE FOR ANYONE AUDITING THIS SUITE: the sandboxed HOME is containment, NOT an
# assay. Running a suite under a decoy HOME to test for this defect REMOVES the
# trigger — ~/.gitconfig is where the global identity lives, so step 0 is skipped
# by construction and every suite reads clean however vulnerable it is. To measure,
# REPLICATE a seat (a decoy HOME whose .gitconfig sets mosaic.gitIdentity, with no
# per-slot token) so step 0 reaches its fail-loud branch.
#
# Note the env-var route does NOT work: detect-platform.sh reads
# "${MOSAIC_GIT_IDENTITY:-}", and `:-` treats set-but-empty identically to unset.
git -C "$REPO_DIR" config mosaic.gitIdentity ""
cat > "$CREDENTIALS_FILE" <<'JSON' cat > "$CREDENTIALS_FILE" <<'JSON'
{"gitea":{"mosaicstack":{"url":"https://git.mosaicstack.dev","token":"test-token"}}} {"gitea":{"mosaicstack":{"url":"https://git.mosaicstack.dev","token":"test-token"}}}
@@ -75,7 +50,6 @@ run_wrapper() {
( (
cd "$REPO_DIR" cd "$REPO_DIR"
PATH="$BIN_DIR:$PATH" \ PATH="$BIN_DIR:$PATH" \
HOME="$HOME_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \ MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
MOSAIC_TEST_LOG="$LOG_FILE" \ MOSAIC_TEST_LOG="$LOG_FILE" \
"$@" "$@"
@@ -8,7 +8,6 @@ WORK_ROOT="${AGENT_WORK_ROOT:-${HOME:-/tmp}/mosaic/agent-work}"
SANDBOX="$WORK_ROOT/pr-merge-empty-uid-test-$$" SANDBOX="$WORK_ROOT/pr-merge-empty-uid-test-$$"
MOCK_BIN="$SANDBOX/bin" MOCK_BIN="$SANDBOX/bin"
REPO_DIR="$SANDBOX/repo" REPO_DIR="$SANDBOX/repo"
HOME_DIR="$SANDBOX/home"
LOG_FILE="$SANDBOX/mock.log" LOG_FILE="$SANDBOX/mock.log"
cleanup() { cleanup() {
@@ -16,7 +15,7 @@ cleanup() {
} }
trap cleanup EXIT trap cleanup EXIT
mkdir -p "$MOCK_BIN" "$REPO_DIR" "$HOME_DIR" mkdir -p "$MOCK_BIN" "$REPO_DIR"
: > "$LOG_FILE" : > "$LOG_FILE"
cat > "$MOCK_BIN/tea" <<'EOF' cat > "$MOCK_BIN/tea" <<'EOF'
@@ -110,48 +109,7 @@ chmod +x "$MOCK_BIN/curl"
cd "$REPO_DIR" cd "$REPO_DIR"
git init -q git init -q
git remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git git remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git
# HERMETICITY (#1007) — TWO mechanisms with DIFFERENT jobs; do not conflate them.
#
# OPERATIVE: the empty repo-local `mosaic.gitIdentity` below. 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 so leaks into this fresh
# repo. Step 0 runs BEFORE the credential loader AND before the GITEA_TOKEN env
# check, so the `GITEA_TOKEN=redacted-test-token` exported below is silently
# overridden and a REAL per-slot token from $HOME is what flows through the
# wrapper. Measured on a provisioned seat before this pin: all 5 mock-curl calls
# carried the real per-slot token in argv and the fixture token was never used at
# ALL. Three consequences specific to this suite:
# 1. pr-merge.sh passes the token as `-H "Authorization: token $token"` and the
# mock curl logs full argv, so the real credential is written to $LOG_FILE
# on disk — transiently: the suite truncates that file between phases and
# the EXIT trap removes $SANDBOX, so it leaves NO post-hoc trace. That is
# why this suite was the hardest of the three to detect; observing it needs
# an instrument that captures argv while the run is live.
# 2. Every failure path dumps $OUTPUT/$LOG_FILE to stderr through
# `sed 's/redacted-test-token/***REDACTED***/g'` — a redaction pattern that
# is the literal fixture string and therefore CANNOT match the token
# actually in use.
# 3. The leak assertion at "Token leaked to pr-merge.sh output" greps for that
# same fixture string, so on a provisioned seat it passes vacuously: it is
# searching for a value the run never used.
# An empty repo-local value shadows the global one and reads back empty at rc=0.
#
# CONTAINMENT: the sandboxed HOME exported below. It only has to bound a failure
# that the pin should already have prevented.
#
# NOTE FOR ANYONE AUDITING THIS SUITE: the sandboxed HOME is containment, NOT an
# assay. Running a suite under a decoy HOME to test for this defect REMOVES the
# trigger — ~/.gitconfig is where the global identity lives, so step 0 is skipped
# by construction and every suite reads clean however vulnerable it is. To measure,
# REPLICATE a seat (a decoy HOME whose .gitconfig sets mosaic.gitIdentity, with no
# per-slot token) so step 0 reaches its fail-loud branch.
#
# Note the env-var route does NOT work: detect-platform.sh reads
# "${MOSAIC_GIT_IDENTITY:-}", and `:-` treats set-but-empty identically to unset.
git -C "$REPO_DIR" config mosaic.gitIdentity ""
# $SANDBOX/$HOME_DIR were derived from the real $HOME above, before this export.
export HOME="$HOME_DIR"
export PATH="$MOCK_BIN:$PATH" export PATH="$MOCK_BIN:$PATH"
export PR_MERGE_TEST_LOG="$LOG_FILE" export PR_MERGE_TEST_LOG="$LOG_FILE"
export GITEA_LOGIN="git.mosaicstack.dev" export GITEA_LOGIN="git.mosaicstack.dev"
@@ -8,68 +8,12 @@ WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/pr-metadata-gitea}"
REPO_DIR="$WORK_DIR/repo" REPO_DIR="$WORK_DIR/repo"
FIXTURE_DIR="$WORK_DIR/fixtures" FIXTURE_DIR="$WORK_DIR/fixtures"
STUB_DIR="$WORK_DIR/stubs" STUB_DIR="$WORK_DIR/stubs"
HOME_DIR="$WORK_DIR/home"
CREDENTIALS_FILE="$WORK_DIR/credentials.json"
rm -rf "$WORK_DIR" rm -rf "$WORK_DIR"
mkdir -p "$REPO_DIR" "$FIXTURE_DIR" "$STUB_DIR" "$HOME_DIR" mkdir -p "$REPO_DIR" "$FIXTURE_DIR" "$STUB_DIR"
git -C "$REPO_DIR" init -q git -C "$REPO_DIR" init -q
git -C "$REPO_DIR" remote add origin https://git.uscllc.com/USC/uconnect.git git -C "$REPO_DIR" remote add origin https://git.uscllc.com/USC/uconnect.git
# HERMETICITY (#1007) — TWO mechanisms with DIFFERENT jobs; do not conflate them.
#
# OPERATIVE: the empty repo-local `mosaic.gitIdentity` below. 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 so leaks into this fresh
# repo. Step 0 runs BEFORE the credential loader AND before the GITEA_TOKEN env
# check, so the `GITEA_TOKEN="stub-token"` set in the run helpers below is
# silently overridden and a REAL per-slot token from $HOME is what reaches curl.
# Measured on a provisioned seat before this pin: both stub-curl calls carried
# the real token in argv. An empty repo-local value shadows the global one and
# reads back empty at rc=0.
#
# CONTAINMENT: the sandboxed HOME in the three run helpers below. It only has to
# bound a failure that the pin should already have prevented.
#
# NOTE FOR ANYONE AUDITING THIS SUITE: the sandboxed HOME is containment, NOT an
# assay. Running a suite under a decoy HOME to test for this defect REMOVES the
# trigger — ~/.gitconfig is where the global identity lives, so step 0 is skipped
# by construction and every suite reads clean however vulnerable it is. To measure,
# REPLICATE a seat (a decoy HOME whose .gitconfig sets mosaic.gitIdentity, with no
# per-slot token) so step 0 reaches its fail-loud branch. See
# test-gitea-token-identity.sh for the stronger `env -i HOME=…` form used where a
# suite's whole subject IS identity resolution.
#
# Note the env-var route does NOT work: detect-platform.sh reads
# "${MOSAIC_GIT_IDENTITY:-}", and `:-` treats set-but-empty identically to unset.
git -C "$REPO_DIR" config mosaic.gitIdentity ""
# The pin above removes step 0, but this suite has a SECOND, independent
# dependency on operator state, and closing only the first would leave the suite
# red on any hermetic environment. The `GITEA_TOKEN="stub-token"` /
# `GITEA_URL="https://git.example.test"` pair the run helpers set is INERT: step 2
# of get_gitea_token accepts GITEA_TOKEN only when GITEA_URL matches the remote
# host, and this repo's origin is git.uscllc.com, so that pair can never satisfy
# it. Before this fixture the only credential that could reach the authenticated
# curl branch was a REAL one — from step 0 on an agent seat, or from step 1
# reading the operator's own ~/.config/mosaic/credentials.json. That is why the
# "curl success path" case passed: not because the stub credential worked, but
# because a production credential was available.
#
# A fixture is used rather than relying on the sandboxed HOME making step 1 find
# nothing: a test that passes because production configuration is ABSENT fails
# the moment it is present. Step 1 now resolves deterministically to a value that
# is a fixture on every machine.
cat > "$CREDENTIALS_FILE" <<'JSON'
{
"gitea": {
"usc": {
"url": "https://git.uscllc.com",
"token": "stub-token"
}
}
}
JSON
cat > "$FIXTURE_DIR/gitea-standard.json" <<'JSON' cat > "$FIXTURE_DIR/gitea-standard.json" <<'JSON'
{ {
@@ -187,8 +131,6 @@ run_curl_success_case() {
set +e set +e
output=$(cd "$REPO_DIR" && \ output=$(cd "$REPO_DIR" && \
PATH="$STUB_DIR:$PATH" \ PATH="$STUB_DIR:$PATH" \
HOME="$HOME_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
TMPDIR="$tmpdir" \ TMPDIR="$tmpdir" \
GITEA_TOKEN="stub-token" \ GITEA_TOKEN="stub-token" \
GITEA_URL="https://git.example.test" \ GITEA_URL="https://git.example.test" \
@@ -228,8 +170,6 @@ run_curl_early_exit_cleanup_case() {
set +e set +e
output=$(cd "$REPO_DIR" && \ output=$(cd "$REPO_DIR" && \
PATH="$STUB_DIR:$PATH" \ PATH="$STUB_DIR:$PATH" \
HOME="$HOME_DIR" \
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
TMPDIR="$tmpdir" \ TMPDIR="$tmpdir" \
GITEA_TOKEN="stub-token" \ GITEA_TOKEN="stub-token" \
GITEA_URL="https://git.example.test" \ GITEA_URL="https://git.example.test" \
@@ -264,8 +204,7 @@ run_curl_early_exit_cleanup_case() {
run_case() { run_case() {
local fixture="$1" expected_number="$2" expected_head="$3" local fixture="$1" expected_number="$2" expected_head="$3"
local output local output
output=$(cd "$REPO_DIR" && HOME="$HOME_DIR" MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \ output=$(cd "$REPO_DIR" && MOSAIC_GITEA_PR_METADATA_RAW_FILE="$fixture" "$SCRIPT_DIR/pr-metadata.sh" -n "$expected_number")
MOSAIC_GITEA_PR_METADATA_RAW_FILE="$fixture" "$SCRIPT_DIR/pr-metadata.sh" -n "$expected_number")
PR_METADATA_OUTPUT="$output" python3 - "$expected_number" "$expected_head" <<'PY' PR_METADATA_OUTPUT="$output" python3 - "$expected_number" "$expected_head" <<'PY'
import json import json
import os import os
@@ -439,19 +439,6 @@ elif mode == "comment-url-wrong-repo":
elif mode == "comment-url-suffix-injection": elif mode == "comment-url-suffix-injection":
# Prefix-injected: a bare endswith("/<slug>/pulls/123") test would ACCEPT it. # Prefix-injected: a bare endswith("/<slug>/pulls/123") test would ACCEPT it.
pr_url = f"{_origin}/deceptive{_slug}/pulls/123" pr_url = f"{_origin}/deceptive{_slug}/pulls/123"
elif mode == "comment-url-wrong-port":
# #991 bound: an EXPLICIT non-default port is a different service on the same
# host. Relaxing http-vs-https must NOT relax this.
pr_url = f"{_p.scheme}://{_p.hostname}:8443{_slug}/pulls/123"
elif mode == "comment-url-non-web-scheme":
# #991 bound: ONLY http/https collapse; any other scheme stays distinguishing.
pr_url = f"ftp://{_p.netloc}{_slug}/pulls/123"
elif mode == "comment-url-scheme-downgrade":
# #991, and the only URL mode here that must be ACCEPTED. A Gitea whose
# ROOT_URL is http:// returns http:// object URLs for a repo reached over
# https://. Same host, same path, correct record — a truthful provider
# answer about a comment that landed, not a forgery.
pr_url = f"http://{_p.netloc}{_slug}/pulls/123"
elif mode == "comment-mixed-case-slug": elif mode == "comment-mixed-case-slug":
# #875: EXPECTED_REPO_SLUG is taken verbatim from GITEA_API_BASE and can be # #875: EXPECTED_REPO_SLUG is taken verbatim from GITEA_API_BASE and can be
# mixed-case (e.g. "USC/uconnect"), but Gitea canonicalizes the returned # mixed-case (e.g. "USC/uconnect"), but Gitea canonicalizes the returned
@@ -906,16 +893,11 @@ fi
assert_no_temp_leak "review-body-reuse" assert_no_temp_leak "review-body-reuse"
# Cases 12-15 (#865 Blocker 3): a PR comment whose id/author/body are all correct # Cases 12-15 (#865 Blocker 3): a PR comment whose id/author/body are all correct
# but whose provider-returned pull_request_url does not belong to this PR must # but whose provider-returned pull_request_url is forged must FAIL CLOSED.
# FAIL CLOSED. Verification pins the URL's ORIGIN (scheme-class + host + explicit # Verification pins the URL's ORIGIN (scheme+host+effective-port) and FULL path
# non-default port) and FULL path (deployment prefix + exact owner/repo + kind + # (deployment prefix + exact owner/repo + kind + number); a bare endswith/suffix
# number); a bare endswith/suffix test would wrongly accept the look-alike-host # test would wrongly accept the look-alike-host and prefix-injection variants.
# and prefix-injection variants. comment-url-wrong-port and for bad_mode in comment-url-wrong-host comment-url-wrong-owner comment-url-wrong-repo comment-url-suffix-injection; do
# comment-url-non-web-scheme (#991) bound the scheme relaxation from the other
# side: collapsing http/https must not also collapse a different port or a
# different scheme family.
for bad_mode in comment-url-wrong-host comment-url-wrong-owner comment-url-wrong-repo \
comment-url-suffix-injection comment-url-wrong-port comment-url-non-web-scheme; do
if run_review "$bad_mode" comment durable-body; then if run_review "$bad_mode" comment durable-body; then
echo "FAIL: forged comment URL ($bad_mode) was accepted" >&2 echo "FAIL: forged comment URL ($bad_mode) was accepted" >&2
cat "$OUTPUT_FILE" >&2 cat "$OUTPUT_FILE" >&2
@@ -941,19 +923,6 @@ run_review comment-mixed-case-slug comment durable-body https://git.mosaicstack.
grep -q 'Added and verified comment on Gitea PR #123' "$OUTPUT_FILE" grep -q 'Added and verified comment on Gitea PR #123' "$OUTPUT_FILE"
assert_no_temp_leak "comment-mixed-case-slug" assert_no_temp_leak "comment-mixed-case-slug"
# Case 15c (#991): the deployment's Gitea ROOT_URL is http:// while every client
# reaches it over https://, so the provider returns an http:// pull_request_url
# for a comment that is otherwise entirely correct. Same class as 15b — a
# legitimate provider response, not a spoof — and a scheme-strict compare
# rejects it on EVERY comment, deterministically. That is not a cosmetic false
# negative here: on a host where no seat can create a review OBJECT, this
# comment-form record is the only gate-16 evidence obtainable, and the wrapper
# refuses all of it while the comment sits durably on the PR. Host, path, owner,
# repo, kind and number stay strict; only http-vs-https is relaxed.
run_review comment-url-scheme-downgrade comment durable-body
grep -q 'Added and verified comment on Gitea PR #123' "$OUTPUT_FILE"
assert_no_temp_leak "comment-url-scheme-downgrade"
# Case 16 (#865 ITEM 1, current-head TOCTOU): the PR head advances between the # Case 16 (#865 ITEM 1, current-head TOCTOU): the PR head advances between the
# pre-submit head read (which pins the review) and the post-verify re-read. The # pre-submit head read (which pins the review) and the post-verify re-read. The
# review is genuinely created and verified as pinned to the OLD head, but the # review is genuinely created and verified as pinned to the OLD head, but the
@@ -564,7 +564,7 @@ echo "== Q16 (guard): Q2's ENUM-B fixture must STAY address-free — the reconci
# Token concatenated so THIS guard's own source lines never contain the # Token concatenated so THIS guard's own source lines never contain the
# literal fixture id and cannot self-match. # literal fixture id and cannot self-match.
enum_id='ENUM''-B' enum_id='ENUM''-B'
fixture_lines="$(has_match -F "\"id\":\"$enum_id\"" "$self")"; fixture_matches="$(has_match -F '"observed_seq":5' <<<"$fixture_lines")"; fixture_line="${fixture_matches%%$'\n'*}" fixture_line="$(has_match -F "\"id\":\"$enum_id\"" "$self" | has_match -F '"observed_seq":5' | head -n1)"
[ -n "$fixture_line" ] || fail_msg "Q16: could not locate Q2's $enum_id fixture line (renamed/renumbered? update this guard)" [ -n "$fixture_line" ] || fail_msg "Q16: could not locate Q2's $enum_id fixture line (renamed/renumbered? update this guard)"
fixture_json="$(printf '%s' "$fixture_line" | sed "s/.*'\({.*}\)'.*/\1/")" fixture_json="$(printf '%s' "$fixture_line" | sed "s/.*'\({.*}\)'.*/\1/")"
# Positive controls FIRST (blind-instrument rule): the extraction must yield # Positive controls FIRST (blind-instrument rule): the extraction must yield
@@ -179,8 +179,8 @@ echo "== P3: detector orders the cause line BEFORE the delta it explains =="
printf 'r1 state v2\n' >"$fx/repo_r1" printf 'r1 state v2\n' >"$fx/repo_r1"
"$DET" poll-once >/dev/null 2>&1 || fail_msg "P3: second poll failed" "$DET" poll-once >/dev/null 2>&1 || fail_msg "P3: second poll failed"
sd="$(state_dir)" sd="$(state_dir)"
pre_seq="$(jq -nr 'first(inputs | select(.locators.kind == "preimage") | .observed_seq) // empty' "$sd/pending.jsonl")" pre_seq="$(jq -r 'select(.locators.kind == "preimage") | .observed_seq' "$sd/pending.jsonl" | head -n1)"
src_seq="$(jq -nr 'first(inputs | select(.locators.kind == "repo") | .observed_seq) // empty' "$sd/pending.jsonl")" src_seq="$(jq -r 'select(.locators.kind == "repo") | .observed_seq' "$sd/pending.jsonl" | head -n1)"
[ -n "$pre_seq" ] || fail_msg "P3: no preimage cause entry enqueued" [ -n "$pre_seq" ] || fail_msg "P3: no preimage cause entry enqueued"
[ -n "$src_seq" ] || fail_msg "P3: no source delta entry enqueued" [ -n "$src_seq" ] || fail_msg "P3: no source delta entry enqueued"
if [ -n "$pre_seq" ] && [ -n "$src_seq" ]; then if [ -n "$pre_seq" ] && [ -n "$src_seq" ]; then
@@ -343,8 +343,8 @@ echo "== P11: reconcile surfaces the cause line before its enumerations =="
printf '# adapter changed while detector down\n' >>"$fx/adapter.sh" printf '# adapter changed while detector down\n' >>"$fx/adapter.sh"
"$RECON" reconcile >/dev/null 2>&1 # rc 1 expected (unaccounted enumerated) "$RECON" reconcile >/dev/null 2>&1 # rc 1 expected (unaccounted enumerated)
sd="$(state_dir)" sd="$(state_dir)"
pre_seq="$(jq -nr 'first(inputs | select(.locators.kind == "preimage") | .observed_seq) // empty' "$sd/pending.jsonl")" pre_seq="$(jq -r 'select(.locators.kind == "preimage") | .observed_seq' "$sd/pending.jsonl" | head -n1)"
enum_seq="$(jq -nr 'first(inputs | select(.locators.reconciled == true) | .observed_seq) // empty' "$sd/pending.jsonl")" enum_seq="$(jq -r 'select(.locators.reconciled == true) | .observed_seq' "$sd/pending.jsonl" | head -n1)"
[ -n "$pre_seq" ] || fail_msg "P11: reconcile must enqueue the preimage cause line" [ -n "$pre_seq" ] || fail_msg "P11: reconcile must enqueue the preimage cause line"
[ -n "$enum_seq" ] || fail_msg "P11: reconcile must still enumerate the unaccounted source" [ -n "$enum_seq" ] || fail_msg "P11: reconcile must still enumerate the unaccounted source"
if [ -n "$pre_seq" ] && [ -n "$enum_seq" ]; then if [ -n "$pre_seq" ] && [ -n "$enum_seq" ]; then
@@ -150,7 +150,7 @@ site_line() { # site_line FILE MARKER -> first physical line of that call
local f="$1" marker="$2" ln local f="$1" marker="$2" ln
ln="$(grep -n "# SITE:${marker}\$" "$f" | cut -d: -f1)" ln="$(grep -n "# SITE:${marker}\$" "$f" | cut -d: -f1)"
# continuation marker sits on the tail line; the call starts one line up # continuation marker sits on the tail line; the call starts one line up
source_line="$(sed -n "${ln}p" "$f")"; if ! grep -Eq 'has_match|count_lines' <<<"$source_line"; then if ! sed -n "${ln}p" "$f" | grep -Eq 'has_match|count_lines'; then
ln=$((ln - 1)) ln=$((ln - 1))
fi fi
printf '%s' "$ln" printf '%s' "$ln"
@@ -167,13 +167,13 @@ rcB=$?
sort "$LEDGER" >"$TMP/got-c1" sort "$LEDGER" >"$TMP/got-c1"
n_expected="$(grep -c . "$TMP/expected-c1")" n_expected="$(grep -c . "$TMP/expected-c1")"
if [ "$rcA" -eq 0 ] && [ "$rcB" -eq 0 ] && if [ "$rcA" -eq 0 ] && [ "$rcB" -eq 0 ] &&
grep -q 'mini-a: OK' <<<"$outA"&& printf '%s' "$outA" | grep -q 'mini-a: OK' &&
grep -q 'mini-b: OK' <<<"$outB"&& printf '%s' "$outB" | grep -q 'mini-b: OK' &&
[ "$n_expected" -gt 1 ] && [ "$n_expected" -gt 1 ] &&
cmp -s "$TMP/expected-c1" "$TMP/got-c1"; then cmp -s "$TMP/expected-c1" "$TMP/got-c1"; then
check C1 0 "" check C1 0 ""
else else
check C1 1 "rcA=$rcA rcB=$rcB expected($n_expected)/got diff: $(diff "$TMP/expected-c1" "$TMP/got-c1" 2>&1 | sed -n '1,10p' | tr '\n' ' ')" check C1 1 "rcA=$rcA rcB=$rcB expected($n_expected)/got diff: $(diff "$TMP/expected-c1" "$TMP/got-c1" 2>&1 | head -n 10 | tr '\n' ' ')"
fi fi
# --- C2: early exit -> short ledger, comparison catches it ----------------- # --- C2: early exit -> short ledger, comparison catches it -----------------
@@ -201,12 +201,12 @@ abort_case() { # abort_case NAME MARKER HELPER
bash "$TMP/mini-a.sh" "$TMP" 2>&1)" bash "$TMP/mini-a.sh" "$TMP" 2>&1)"
rc=$? rc=$?
if [ "$rc" -ne 0 ] && if [ "$rc" -ne 0 ] &&
! grep -q 'mini-a: OK' <<<"$out"&& ! printf '%s' "$out" | grep -q 'mini-a: OK' &&
! grep -q 'mini-a: FAILED' <<<"$out"&& ! printf '%s' "$out" | grep -q 'mini-a: FAILED' &&
grep -q "WAKE-ASSERT ARMED: forcing real grep error at $site" <<<"$out"&& printf '%s' "$out" | grep -q "WAKE-ASSERT ARMED: forcing real grep error at $site" &&
grep -q "WAKE-ASSERT ABORT" <<<"$out"&& printf '%s' "$out" | grep -q "WAKE-ASSERT ABORT" &&
grep -q "$site" <<<"$out"&& printf '%s' "$out" | grep -q "$site" &&
grep -q "grep exit 2" <<<"$out"&& printf '%s' "$out" | grep -q "grep exit 2" &&
grep -q "^${helper} ${site}\$" "$ledger"; then grep -q "^${helper} ${site}\$" "$ledger"; then
check "$name" 0 "" check "$name" 0 ""
else else
@@ -230,8 +230,8 @@ if [ "$got" = "1" ]; then check C8 0 ""; else check C8 1 "env-prefix did not rea
out="$(WAKE_ASSERT_FORCE_GREP_ERROR_AT="mini-a.sh:9999" bash "$TMP/mini-a.sh" "$TMP" 2>&1)" out="$(WAKE_ASSERT_FORCE_GREP_ERROR_AT="mini-a.sh:9999" bash "$TMP/mini-a.sh" "$TMP" 2>&1)"
rc=$? rc=$?
if [ "$rc" -eq 0 ] && if [ "$rc" -eq 0 ] &&
grep -q 'mini-a: OK' <<<"$out"&& printf '%s' "$out" | grep -q 'mini-a: OK' &&
! grep -q 'WAKE-ASSERT ARMED' <<<"$out"; then ! printf '%s' "$out" | grep -q 'WAKE-ASSERT ARMED'; then
check C9 0 "" check C9 0 ""
else else
check C9 1 "rc=$rc out=$(printf '%s' "$out" | tail -n 3 | tr '\n' ' ')" check C9 1 "rc=$rc out=$(printf '%s' "$out" | tail -n 3 | tr '\n' ' ')"
@@ -248,8 +248,8 @@ chmod +x "$TMP/fake-bash"
out="$(WAKE_ASSERT_PIN_BASH="$TMP/fake-bash" bash -c '. "$WAKE_COMMON" && wake_assert_init && echo REACHED-PAST-INIT' 2>&1)" out="$(WAKE_ASSERT_PIN_BASH="$TMP/fake-bash" bash -c '. "$WAKE_COMMON" && wake_assert_init && echo REACHED-PAST-INIT' 2>&1)"
rc=$? rc=$?
if [ "$rc" -ne 0 ] && if [ "$rc" -ne 0 ] &&
! grep -q 'REACHED-PAST-INIT' <<<"$out"&& ! printf '%s' "$out" | grep -q 'REACHED-PAST-INIT' &&
grep -q 'WAKE-ASSERT INIT ABORT: BASH_LINENO convention violated' <<<"$out"; then printf '%s' "$out" | grep -q 'WAKE-ASSERT INIT ABORT: BASH_LINENO convention violated'; then
check C10 0 "" check C10 0 ""
else else
check C10 1 "rc=$rc out=$(printf '%s' "$out" | tail -n 2 | tr '\n' ' ')" check C10 1 "rc=$rc out=$(printf '%s' "$out" | tail -n 2 | tr '\n' ' ')"
@@ -283,8 +283,8 @@ out="$(WAKE_ASSERT_LEDGER="$LEDGER" bash "$TMP/mini-c.sh" "$TMP" 2>&1)"
rc=$? rc=$?
summary_ln="$(site_line "$TMP/mini-c.sh" c-summary)" summary_ln="$(site_line "$TMP/mini-c.sh" c-summary)"
if [ "$rc" -eq 1 ] && if [ "$rc" -eq 1 ] &&
grep -q 'wake mini-c harness: FAILED (1 assertion(s))' <<<"$out"&& printf '%s' "$out" | grep -q 'wake mini-c harness: FAILED (1 assertion(s))' &&
! grep -q 'all invariants passed' <<<"$out"&& ! printf '%s' "$out" | grep -q 'all invariants passed' &&
grep -q "^count_lines mini-c.sh:${summary_ln}\$" "$LEDGER"; then grep -q "^count_lines mini-c.sh:${summary_ln}\$" "$LEDGER"; then
check C11 0 "" check C11 0 ""
else else
@@ -107,7 +107,7 @@ if cmp -s "$TMP/expected.txt" "$TMP/static.txt"; then
echo "STATIC-INVENTORY equals expected set ($(grep -c . "$TMP/static.txt") rows from source text)" echo "STATIC-INVENTORY equals expected set ($(grep -c . "$TMP/static.txt") rows from source text)"
else else
flag "static inventory (source text) differs from expected set (artifact):" flag "static inventory (source text) differs from expected set (artifact):"
diff "$TMP/expected.txt" "$TMP/static.txt" | sed -n '1,20p' | sed 's/^/ /' diff "$TMP/expected.txt" "$TMP/static.txt" | head -n 20 | sed 's/^/ /'
fi fi
# --- 3: green instrumented run ---------------------------------------------- # --- 3: green instrumented run ----------------------------------------------
@@ -116,7 +116,7 @@ LEDGER="$TMP/ledger"
for s in "${SUITES[@]}"; do for s in "${SUITES[@]}"; do
out="$(WAKE_ASSERT_LEDGER="$LEDGER" bash "$WAKE/$s" 2>&1)" out="$(WAKE_ASSERT_LEDGER="$LEDGER" bash "$WAKE/$s" 2>&1)"
rc=$? rc=$?
if grep -Eq "$(sentinel_for "$s")" <<<"$out"; then if printf '%s\n' "$out" | grep -Eq "$(sentinel_for "$s")"; then
sent="present" sent="present"
else else
sent="ABSENT" sent="ABSENT"
@@ -177,14 +177,14 @@ while read -r helper site form; do
rc=$? rc=$?
bad="" bad=""
[ "$rc" -ne 0 ] || bad="$bad exit=0" [ "$rc" -ne 0 ] || bad="$bad exit=0"
grep -q "WAKE-ASSERT ARMED: forcing real grep error at $site" <<<"$out"|| printf '%s\n' "$out" | grep -q "WAKE-ASSERT ARMED: forcing real grep error at $site" ||
bad="$bad no-ARMED-line" bad="$bad no-ARMED-line"
grep -q "WAKE-ASSERT ABORT: ${helper} at ${site}: grep exit" <<<"$out"|| printf '%s\n' "$out" | grep -q "WAKE-ASSERT ABORT: ${helper} at ${site}: grep exit" ||
bad="$bad no-ABORT-line" bad="$bad no-ABORT-line"
# AND-polarity check (a match is the defect): a grep error (rc>=2) must be # 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". # its own loud arm — it cannot fall through as "no sentinel = pass".
rc_sent=0 rc_sent=0
grep -Eq "$(sentinel_for "$f")" <<<"$out"|| rc_sent=$? printf '%s\n' "$out" | grep -Eq "$(sentinel_for "$f")" || rc_sent=$?
case "$rc_sent" in case "$rc_sent" in
0) bad="$bad sentinel-emitted" ;; 0) bad="$bad sentinel-emitted" ;;
1) : ;; 1) : ;;
@@ -1,28 +0,0 @@
[
"packages/mosaic/framework/tools/wake/test-wake-digest-quarantine.sh:fixture_line=\"$(has_match -F \"\\\"id\\\":\\\"$enum_id\\\"\" \"$self\" | has_match -F '\"observed_seq\":5' | head -n1)\"",
"packages/mosaic/framework/tools/wake/test-wake-preimage.sh:pre_seq=\"$(jq -r 'select(.locators.kind == \"preimage\") | .observed_seq' \"$sd/pending.jsonl\" | head -n1)\"",
"packages/mosaic/framework/tools/wake/test-wake-preimage.sh:src_seq=\"$(jq -r 'select(.locators.kind == \"repo\") | .observed_seq' \"$sd/pending.jsonl\" | head -n1)\"",
"packages/mosaic/framework/tools/wake/test-wake-preimage.sh:pre_seq=\"$(jq -r 'select(.locators.kind == \"preimage\") | .observed_seq' \"$sd/pending.jsonl\" | head -n1)\"",
"packages/mosaic/framework/tools/wake/test-wake-preimage.sh:enum_seq=\"$(jq -r 'select(.locators.reconciled == true) | .observed_seq' \"$sd/pending.jsonl\" | head -n1)\"",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:if ! sed -n \"${ln}p\" \"$f\" | grep -Eq 'has_match|count_lines'; then",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$outA\" | grep -q 'mini-a: OK' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$outB\" | grep -q 'mini-b: OK' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:check C1 1 \"rcA=$rcA rcB=$rcB expected($n_expected)/got diff: $(diff \"$TMP/expected-c1\" \"$TMP/got-c1\" 2>&1 | head -n 10 | tr '\\n' ' ')\"",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:! printf '%s' \"$out\" | grep -q 'mini-a: OK' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:! printf '%s' \"$out\" | grep -q 'mini-a: FAILED' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q \"WAKE-ASSERT ARMED: forcing real grep error at $site\" &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q \"WAKE-ASSERT ABORT\" &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q \"$site\" &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q \"grep exit 2\" &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q 'mini-a: OK' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:! printf '%s' \"$out\" | grep -q 'WAKE-ASSERT ARMED'; then",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:! printf '%s' \"$out\" | grep -q 'REACHED-PAST-INIT' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q 'WAKE-ASSERT INIT ABORT: BASH_LINENO convention violated'; then",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:printf '%s' \"$out\" | grep -q 'wake mini-c harness: FAILED (1 assertion(s))' &&",
"packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh:! printf '%s' \"$out\" | grep -q 'all invariants passed' &&",
"packages/mosaic/framework/tools/wake/validate-973/validate-973.sh:diff \"$TMP/expected.txt\" \"$TMP/static.txt\" | head -n 20 | sed 's/^/ /'",
"packages/mosaic/framework/tools/wake/validate-973/validate-973.sh:if printf '%s\\n' \"$out\" | grep -Eq \"$(sentinel_for \"$s\")\"; then",
"packages/mosaic/framework/tools/wake/validate-973/validate-973.sh:printf '%s\\n' \"$out\" | grep -q \"WAKE-ASSERT ARMED: forcing real grep error at $site\" ||",
"packages/mosaic/framework/tools/wake/validate-973/validate-973.sh:printf '%s\\n' \"$out\" | grep -q \"WAKE-ASSERT ABORT: ${helper} at ${site}: grep exit\" ||",
"packages/mosaic/framework/tools/wake/validate-973/validate-973.sh:printf '%s\\n' \"$out\" | grep -Eq \"$(sentinel_for \"$f\")\" || rc_sent=$?"
]
-47
View File
@@ -8,7 +8,6 @@ import test from 'node:test';
const ROOT = new URL('../', import.meta.url); const ROOT = new URL('../', import.meta.url);
const EXPECTED_BASELINE_SITES = 26; const EXPECTED_BASELINE_SITES = 26;
const EXPECTED_TEST_BASELINE_SITES = 22; const EXPECTED_TEST_BASELINE_SITES = 22;
const EXPECTED_WAKE_BASELINE_SITES = 26;
const TARGETS = [ const TARGETS = [
'tools/matrix-presence-harness/run.sh', 'tools/matrix-presence-harness/run.sh',
'tools/e2e-install-test.sh', 'tools/e2e-install-test.sh',
@@ -38,10 +37,6 @@ const TARGETS = [
'packages/mosaic/framework/tools/quality/scripts/test-upgrade-rollback.sh', 'packages/mosaic/framework/tools/quality/scripts/test-upgrade-rollback.sh',
'packages/mosaic/framework/tools/tmux/test-send-message-socket.sh', 'packages/mosaic/framework/tools/tmux/test-send-message-socket.sh',
'packages/mosaic/framework/tools/tmux/test-send-message-verdict.sh', 'packages/mosaic/framework/tools/tmux/test-send-message-verdict.sh',
'packages/mosaic/framework/tools/wake/test-wake-digest-quarantine.sh',
'packages/mosaic/framework/tools/wake/test-wake-preimage.sh',
'packages/mosaic/framework/tools/wake/validate-973/microtest-wake-assert.sh',
'packages/mosaic/framework/tools/wake/validate-973/validate-973.sh',
]; ];
// These statuses are explicitly non-load-bearing or unreachable at designed input. // These statuses are explicitly non-load-bearing or unreachable at designed input.
@@ -111,14 +106,6 @@ test('the registered test baseline denominator is exactly 22 unsafe sites', asyn
); );
}); });
test('the registered wake baseline denominator is exactly 26 unsafe sites', async () => {
await assertBaselineFixture(
'scripts/fixtures/pipefail-early-exit-wake-baseline.json',
EXPECTED_WAKE_BASELINE_SITES,
25,
);
});
test('load-bearing pipefail paths do not pipe into early-exiting consumers', async () => { test('load-bearing pipefail paths do not pipe into early-exiting consumers', async () => {
assert.deepEqual(scan(await currentSources()), []); assert.deepEqual(scan(await currentSources()), []);
}); });
@@ -151,40 +138,6 @@ test('gateway verify capability preserves the complete help-probe truth table',
} }
}); });
test('wake JSONL selectors take the first match across the complete input stream', async () => {
const source = await readFile(
new URL('packages/mosaic/framework/tools/wake/test-wake-preimage.sh', ROOT),
'utf8',
);
assert.equal((source.match(/jq -nr 'first\(inputs \| select\(/g) ?? []).length, 4);
const directory = await mkdtemp(path.join(tmpdir(), 'wake-jsonl-first-'));
const input = path.join(directory, 'pending.jsonl');
const filter = 'first(inputs | select(.locators.kind == "preimage") | .observed_seq) // empty';
try {
await writeFile(
input,
'{"locators":{"kind":"repo"},"observed_seq":1}\n' +
'{"locators":{"kind":"preimage"},"observed_seq":4}\n' +
'{"locators":{"kind":"preimage"},"observed_seq":9}\n',
);
let result = spawnSync('jq', ['-nr', filter, input], { encoding: 'utf8' });
assert.equal(result.status, 0, result.stderr);
assert.equal(result.stdout, '4\n');
await writeFile(input, '{"locators":{"kind":"repo"},"observed_seq":1}\n');
result = spawnSync('jq', ['-nr', filter, input], { encoding: 'utf8' });
assert.equal(result.status, 0, result.stderr);
assert.equal(result.stdout, '');
await writeFile(input, '{invalid json}\n');
result = spawnSync('jq', ['-nr', filter, input], { encoding: 'utf8' });
assert.notEqual(result.status, 0);
} finally {
await rm(directory, { recursive: true, force: true });
}
});
test('board-history preserves non-git data-dir as a non-detectable result', async () => { test('board-history preserves non-git data-dir as a non-detectable result', async () => {
const directory = await mkdtemp(path.join(tmpdir(), 'reflect-board-non-git-')); const directory = await mkdtemp(path.join(tmpdir(), 'reflect-board-non-git-'));
try { try {