You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
✅ test(ci): correct the env bounding claim and close its three side routes
The round-6 comments claimed the bound was on declared bindings in general -- "so
there is no declared binding the harness fails to model". It is not. It is a bound on
three `env:` maps, and three declared routes reach a `run:` body without touching any
of them, each producing a live fail-open while the gate exits 0:
* `jobs.<id>.container.env` -- a container on the `test` reporter plus one guard
line makes the required context unconditionally green. The injection is at job
level and appears in neither `.env` nor `.jobs[job].env`, and `steps | length`
cannot see it either.
* a prior step writing `$GITHUB_ENV` -- an extra step in BOTH classifiers, so the
byte-identity check still passes, exporting a glob a one-line guard then reads. A
`Taskfile.yml`-only PR classifies docs-only. The reporters were safe only because
check_reporter pins them to one step; the classifier had no counterpart.
* the step's `shell:` -- never asserted anywhere while the harness hardcodes bash.
`shell: bash -n {0}` makes GitHub syntax-check the body and exit 0 forever.
None is present in the shipped files, so this is latent. What is not latent is the
claim: this lane's whole history is the distance between a claimed bound and an
actual one, and putting a false bounding claim into the file that IS the record of
what is bounded is that failure once more -- it is what the next reviewer would trust
instead of re-deriving. So the three sentences now say the bound is on the three
`env:` maps, and say plainly what it does not establish.
The three routes are blocked too, since they are cheap: `container` must be null, the
classifier must have exactly two steps (mirroring the reporters' one), and the
executed step must declare `shell: bash` -- asserted at all three harness sites, one
mutant each, killed by message. And the residual list gains (d), the class those
three belong to and which remains open, and (e), that the classifier step's env
VALUES are unasserted where the reporters' are pinned byte-exact -- no fail-open was
constructible through them, but an asymmetry recorded is better than one assumed away.
90 assertions, 64 message-anchored mutants, 4 tautology guard rails.
fail "job '${job}' in ${workflow} declares a 'container:' -- its own env: reaches every step without appearing in any map this harness models, so a binding could be live in the job and absent here"
163
+
# An extra step can write \$GITHUB_ENV for a later step in the same job -- a declared binding
164
+
# that appears in no env: map at all. check_reporter already pins the reporters to one step;
165
+
# this pins every job whose body is executed here, the classifier included.
fail "job '${job}' in ${workflow} has $(yq eval".jobs[\"${job}\"].steps | length""${workflow}") steps, expected exactly ${steps} -- an extra step can export a binding into the environment of the ${label} step by writing \$GITHUB_ENV, which no env: map declares and this harness would not export"
168
+
# The harness runs the body under bash. `shell: bash -n {0}` would make GitHub syntax-check it
169
+
# and exit 0 forever, so the required context would be permanently green.
fail "the ${label} step of job '${job}' in ${workflow} declares 'shell: $(yq eval".jobs[\"${job}\"].steps[${idx}].shell""${workflow}")', expected 'bash' -- this harness executes the body with bash, and any other shell (or a directive like 'bash -n {0}', which only syntax-checks) means the job runs something different from what is tested here"
fail "the ${label} step of job '${job}' in ${workflow} declares env keys [${actual:-none}], expected exactly [${expected}] -- this harness exports precisely those and nothing else, so any other declared binding is present when the job runs and ABSENT when the body is tested here. That is how a fail-open hides: the body reads a variable no assertion knows about."
@@ -341,7 +364,7 @@ check_reporter() {
341
364
342
365
# The truth table below exports CODE and RESULT. Anything else the step declares would be
343
366
# live in the job and missing here -- see assert_step_env_exactly.
fail "${workflow}'s push paths-ignore list is empty -- the reference matcher would call every path code and this check would pass for the wrong reason"
0 commit comments