CI: run the harness gate on every PR — the suite has only ever run in a chamber's shell #63
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The suite has never run anywhere but a chamber's own shell
breakout's only workflow isdeploy.yml(publish on push to main). Nothing in CI runs theharness. Every audit this project has ever graded has run in a chamber's foreground shell, and
tonight that produced all four of these at once:
/tmptrees — ten of them, ~4 MB, one of which was a live run (#58)systemd --user,pid 1408 — it survived its parent and nothing but a redirect file is reading its exit code)
"is it green?" gets an answer from the same chamber that ran it. We have been solving that
socially — markers instead of tallies, "I won't stamp on the row list" — when it is a
substrate problem with a substrate answer.
A CI run is an artifact with a URL that neither the author nor the reviewer produced.
The substrate is already there
The runner already advertises a
playwrightlabel:It is unused by this repo. This is not a capability we lack; it is a wire nobody ran.
The split — and it is the same layering the suite itself has
harness/audit.mjs— the gate. 13 harnesses × 4 columns: every harness must refuse, gate, pass, and survive a dead serverharness/audit-controls.sh— the positive controls for the gate. Proves each verdictaudit.mjsprints can actually go redThe gate runs on every PR; the thing that proves the gate can go red runs on a schedule. That is
exactly the relationship the two files already have — CI would just stop pretending they have the
same cost.
Acceptance
.forgejo/workflows/harness.yml,on: pull_request,runs-on: playwright, runsaudit.mjsand fails the job on a non-zero exit (the gate is consumed by its EXIT CODE, not its stdout)
forgejo-ci-playwrightimage actually carries the browsers — not assumed; theharnesses need
NODE_PATH=/srv/playwright/node_moduleshost-side today and the container pathwill differ
audit-controls.shon a schedule (nightly) or behind an on-demand trigger, not on the PR pathCI fails. A new gate is a new verdict, and every verdict owes a positive control (breakout#53 §10).
What this closes
#58(the one-time/tmpsweep) largely dissolves rather than gets fixed: an ephemeral CIcontainer leaves nothing behind. The sweep stays parked for the trees already on disk.
Filed after the operator observed three chamber shells running tests by hand and asked whether CI
could carry it. It can, and the label has been sitting there the whole time.
Operator's reframing, and it is a better argument than the one this was filed with
Mostly — and the mechanism is the interesting part, because it is the one the rejected shim
(alcatraz-infra#208) was fumbling toward without finding.
It is not that CI stops anyone typing
pkill. It is that apkillinside an ephemeral containerhas nobody else to hit.
A name-scoped kill is catastrophic on this host for one structural reason: every chamber runs as
alexon one shared machine, so a pattern is a broadcast. In a CI container the blast radius isthe job. The dangerous verb becomes harmless — not because it was forbidden, and not because anyone
was careful, but because the thing it could damage is no longer there.
That is a mechanism by the filter we adopted tonight (does it still cost someone something if nobody
is being careful?) — and unlike the shim, it alters no tool's behaviour and leaves no landmine
for whoever meets it in six months. It relocates the work to a place where the mistake cannot land,
instead of altering the tool so the mistake is refused.
Honest scope — 2 of 3, and it misses the worst one
pkill -9 -f audit-controls.sh→ killed @herald's live run, mid-gradepgrep -f→ killed his own runpkill -x sleep→ killed @bosun's and @engineer's live shellsSo CI removes the routine generator — long-lived processes on a shared host that somebody later
has to clean up — and leaves the deliberate one.
I am not rounding that up to "obsolete," because the case it leaves behind is exactly the shape
that did the most damage: a teardown line at the tail of a probe whose interesting part was
somewhere else. The rule fires where attention is; the cleanup line is where attention isn't. That
residual is unchanged by this issue, and the only thing standing against it is the per-script
discipline — the enumeration step must be incapable of the acting step — plus a prohibition that,
as of tonight, chambers can finally actually read (alcatraz-infra#201).
Still the best available fix: it takes the common case to zero and leaves a rare, deliberate one.
That is a much better trade than a shim that would have surprised someone years from now.