Files
ersatztv/scripts
timothy f420649fa2 fix(786,789): harden the step-text predicate and sharpen the guard/none rule
Self-review findings on the previous commit, all measured before fixing.

THE PREDICATE HAD BOTH FAILURE DIRECTIONS. Measured against constructed inputs:

  full-line comment       -> ['dotnet']      false POSITIVE
  echo string / heredoc   -> ['dotnet']      false POSITIVE
  dotnet-ef migrations    -> []              false NEGATIVE
  playwright install      -> []              false NEGATIVE

The false positive is the dangerous one: a bare-runner job whose COMMENT merely mentions dotnet
would redden the suite on a correct tree, and a correct guard going red on a correct tree is the
fastest route to that guard being deleted. Full-line comments are now stripped before matching.
`dotnet-ef` and `playwright` join the tool list, and the alternation is sorted longest-first so the
match does not depend on backtracking out of the `dotnet` prefix.

The residue is stated in the code rather than papered over: a TRAILING `# ...` comment, an
`echo "run dotnet build"` and a heredoc body all still match. Parsing those means parsing shell,
which `testing.fixing-a-parser-bug-introduces-the-next-one` prices at three or more rounds. It is
tolerable only because of its DIRECTION — a loud red naming the job and the token, with an obvious
remedy — never a silent pass.

Verified the real workflow's classification is unchanged and exact after the change:
needs-toolchain derives to {test, migrations, functional-e2e, api-docs, format}, equal to the
declared set, zero violations.

THE GUARD/NONE RULE WAS UNDER-SPECIFIED. "Purpose, not whether a step can fail" does not decide
`docker-build.yml::test`, which blocks the merge as a required context. Sharpened everywhere it is
stated: a `guard` job enforces an invariant about the REPOSITORY or its ARTIFACTS; a job that builds
or exercises the PRODUCT is `none` even when it is a required check. No marker value changed — the
rule now explains the classifications that were already there.

Also: a row for test_workflow_job_guards.py in the file-populations table, and the scope-limit
preamble de-narrated (it recounted an earlier draft; the operative warning — an unlisted class reads
as covered — is kept, the autobiography dropped).

Refs #786
Refs #789
2026-08-28 22:14:44 +02:00
..
2024-01-15 10:29:07 -06:00
2024-01-16 13:28:46 -06:00