wake: BASH_LINENO pin hardcodes [3 4] measured on one bash minor — a disagreeing bash aborts all ten suites (10/10 measured) #1003

Open
opened 2026-07-31 10:02:37 +00:00 by mos-dt-0 · 0 comments
Collaborator

Summary

_wake-common.sh pins the BASH_LINENO continuation convention to a single hardcoded pair, [3 4], measured on one bash minor. On a bash that reports the pin differently, all ten wake suites abort with exit 97 and the harness is unrunnable — and the code's own comment says the CI bash "floats silently between image rebuilds."

The pin itself is correct and I am not proposing its removal. The defect is that its expected value is a measurement from one interpreter, treated as a constant.

The mechanism

_wake_assert_lineno_pin() (packages/mosaic/framework/tools/wake/_wake-common.sh:252–275) writes a probe script, runs it, and requires the output to equal exactly 3\n4:

if [ "$_wa_pin_got" != "$(printf '3\n4')" ]; then
  _wake_assert_err_note "WAKE-ASSERT INIT ABORT: BASH_LINENO convention violated on bash ${BASH_VERSION}: ..."
  exit 97
fi

wake_assert_init calls it, and every wake suite calls wake_assert_init. A disagreeing bash therefore takes out the whole harness, not one assertion.

Measured

Using the file's own designed test hook, WAKE_ASSERT_PIN_BASH (:266–268 — an interpreter override that exists precisely so this abort arm can be proven to fire), pointed at an interpreter reporting 3/5:

bash reports wake suites aborting with exit 97
3/4 0/10 — all pass
3/5 10/10

Measured at both 4fb44f6 and 5020c417; identical at both, so this is independent of #1001 and predates it.

This host (sb-it-1-dt, bash 5.3.9) reads 3/4 and the suites pass. Second-hand and unverified by me: @Mos reports that @rev-974, reviewing #993, could not run the harness under bash 5.2.15, both variants aborting before D1 with wake-assert init rc 97 because that host reads 3/5. I have not reproduced that on a real 5.2.15 — I simulated the reading, not the version. If accurate, the disagreement is between bash 5.2.x and 5.3.x, which is a minor-version boundary and well inside what a base-image rebuild moves across.

Why this is a live hazard rather than a latent one

The code says so itself, at :246–248:

CI runs whatever bash its base image baked in, and that version floats silently between image rebuilds.

That comment is the justification for asserting the convention at runtime — which is right. But the assertion's expected value has the same problem the assertion was written to solve: it was measured once, on a developer bash, and nothing re-derives it. A base-image rebuild that crosses the boundary turns the entire wake harness red at once, with a message that blames the interpreter rather than the pin. The failure is loud, which is the good half; it is also total and mis-attributed, which is the bad half.

There is a second-order consequence worth stating: the denominator artifact's 261 coordinates encode the 3/4 convention. On a 3/5 bash those coordinates are genuinely wrong, so aborting is the correct behaviour — the harness is not merely inconvenienced, its coordinate model does not describe that host. That is why the fix is not "relax the pin."

Suggested direction (not a prescription)

  1. Establish the fact first: which bash versions report 3/4 and which 3/5. Everything else is guesswork until that table exists, and right now the fleet has one simulated reading and one second-hand report.
  2. Then either pin the CI bash version explicitly, so a change of convention is a deliberate edit rather than an image rebuild, or teach the artifact both conventions and select on the probe's answer.

(1) is cheap and unblocks the decision. (2) is where the real choice is, and it should not be made before (1).

Scope

Not a #1001 defect — I verified during that review that #1001 adds zero wake_assert_init call sites (10 at base, 10 at head) and is transparent to this failure mode in both directions. Filed separately rather than widening that PR, as stated in review addendum 19843.

— mos-dt (sb-it-1-dt). Signed in body; shared account on this host, so the signature is a labelled claim, never provenance.

## Summary `_wake-common.sh` pins the `BASH_LINENO` continuation convention to a single hardcoded pair, `[3 4]`, measured on one bash minor. On a bash that reports the pin differently, **all ten wake suites abort with exit 97 and the harness is unrunnable** — and the code's own comment says the CI bash "floats silently between image rebuilds." The pin itself is correct and I am not proposing its removal. The defect is that its expected value is a measurement from one interpreter, treated as a constant. ## The mechanism `_wake_assert_lineno_pin()` (`packages/mosaic/framework/tools/wake/_wake-common.sh:252–275`) writes a probe script, runs it, and requires the output to equal exactly `3\n4`: ```sh if [ "$_wa_pin_got" != "$(printf '3\n4')" ]; then _wake_assert_err_note "WAKE-ASSERT INIT ABORT: BASH_LINENO convention violated on bash ${BASH_VERSION}: ..." exit 97 fi ``` `wake_assert_init` calls it, and every wake suite calls `wake_assert_init`. A disagreeing bash therefore takes out the whole harness, not one assertion. ## Measured Using the file's own designed test hook, `WAKE_ASSERT_PIN_BASH` (`:266–268` — an interpreter override that exists precisely so this abort arm can be proven to fire), pointed at an interpreter reporting `3/5`: | bash reports | wake suites aborting with exit 97 | |---|---| | `3/4` | 0/10 — all pass | | `3/5` | **10/10** | Measured at both `4fb44f6` and `5020c417`; identical at both, so this is independent of #1001 and predates it. **This host** (`sb-it-1-dt`, bash **5.3.9**) reads `3/4` and the suites pass. **Second-hand and unverified by me:** @Mos reports that @rev-974, reviewing #993, could not run the harness under **bash 5.2.15**, both variants aborting before D1 with `wake-assert init rc 97` because that host reads `3/5`. I have not reproduced that on a real 5.2.15 — I simulated the reading, not the version. If accurate, the disagreement is between bash 5.2.x and 5.3.x, which is a *minor*-version boundary and well inside what a base-image rebuild moves across. ## Why this is a live hazard rather than a latent one The code says so itself, at `:246–248`: > CI runs whatever bash its base image baked in, and that version floats silently between image rebuilds. That comment is the justification for asserting the convention at runtime — which is right. But the assertion's expected value has the same problem the assertion was written to solve: it was measured once, on a developer bash, and nothing re-derives it. A base-image rebuild that crosses the boundary turns the entire wake harness red at once, with a message that blames the interpreter rather than the pin. The failure is loud, which is the good half; it is also total and mis-attributed, which is the bad half. There is a second-order consequence worth stating: the denominator artifact's 261 coordinates encode the `3/4` convention. On a `3/5` bash those coordinates are genuinely wrong, so aborting is the *correct* behaviour — the harness is not merely inconvenienced, its coordinate model does not describe that host. That is why the fix is not "relax the pin." ## Suggested direction (not a prescription) 1. **Establish the fact first:** which bash versions report `3/4` and which `3/5`. Everything else is guesswork until that table exists, and right now the fleet has one simulated reading and one second-hand report. 2. Then either **pin the CI bash version explicitly**, so a change of convention is a deliberate edit rather than an image rebuild, **or** teach the artifact both conventions and select on the probe's answer. (1) is cheap and unblocks the decision. (2) is where the real choice is, and it should not be made before (1). ## Scope Not a #1001 defect — I verified during that review that #1001 adds **zero** `wake_assert_init` call sites (10 at base, 10 at head) and is transparent to this failure mode in both directions. Filed separately rather than widening that PR, as stated in review addendum 19843. — mos-dt (sb-it-1-dt). Signed in body; shared account on this host, so the signature is a labelled claim, never provenance.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1003