Files
ersatztv/scripts
timothyandClaude Opus 5 b53c3bab47 fix(887): close what a pin cannot see — meaning changed without changing the text
A pin rejects any command it does not equal, so the remaining attack is to change what
the pinned text MEANS. Four such vectors, found by attacking the new mechanism rather
than reading it; the first was MEASURED escaping and the rest are the same class:

  * A NEW stage taking the SPA source across with `COPY --from=web-build /source/web`
    and running the suite there. `copies_spa_source` excluded every `--from=` copy on the
    grounds that a stage copy is not a context copy — true, but it can still carry the
    SOURCE TREE from a stage that has it. The receiving stage was therefore unpinned and
    unchecked, which is exactly the false-NEGATIVE direction this file's own residual
    warns about. A stage copy now counts when its SOURCE has a whole `web` path segment,
    which keeps the built-artifact copy this repo actually makes
    (`/source/ErsatzTV/wwwroot/app/.`) correctly out.
  * `working-directory:` moved off `web` — `npm test` somewhere else runs a different
    package, or none, with the pinned command text unchanged. Now pinned.
  * `defaults.run.shell` changed from `bash` to `sh`. `bash` here is `bash -e`, which is
    what makes a failing command fail the step; changing it changes whether a red suite
    blocks the image without touching the step at all. Now pinned.
  * A `SHELL` instruction in a pinned stage, which redefines what every later `RUN`
    executes. Refused outright rather than modelled — there is none in this repo, so the
    honest move is to reject the construct, not to reason about a replacement
    interpreter.

Battery 41 -> 45, 0 missed; the stage-copy mutant reddens three assertions. The residual
list gains the two cases that remain in this class and are NOT covered: a stage copy that
RENAMES the tree on the way in (no `web` segment in its source), and an `ENV` altering
`PATH` so a pinned `RUN` resolves a different `npm`. Naming them is the point — the
previous rounds' residual lists read as exhaustive while omitting the largest holes.

Refs: #887
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019T79beF1Ufid3dXju4yqkF
2026-08-30 13:37:58 +02:00
..
2024-01-15 10:29:07 -06:00
2024-01-16 13:28:46 -06:00