Skip to content

fix(ci): run the Kernel Admitted gate under bash, not the container dash - #3397

Merged
gHashTag merged 1 commit into
masterfrom
fix/coq-admitted-gate-shell-3396
Sep 7, 2026
Merged

fix(ci): run the Kernel Admitted gate under bash, not the container dash#3397
gHashTag merged 1 commit into
masterfrom
fix/coq-admitted-gate-shell-3396

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Closes #3396

The Kernel PHI Admitted gate could not fail for the reason it exists, and could not pass for that reason either: under the container shell it died on syntax before reading a single file.

The defect

The step declares no shell: key and neither does the job, so it inherits the coqorg/coq container default sh -e — dash. Its body uses four bash-only constructs:

VFILES=()                                    # the first one dash rejects
VFILES+=("coq/$f")
"${#VFILES[@]}"
done < <(grep -E "\.v$" coq/_CoqProject)     # process substitution

The step comment already stated the constraint — "the step shell is sh -e -- dash" — and the code below it violated it.

Measured

Body extracted verbatim from the workflow (89 lines; the extractor refuses if the result does not contain VFILES, so a silent empty extract cannot masquerade as a passing probe — it did exactly that on the first attempt and was caught). Run against a tree holding the 9 .v files coq/_CoqProject names, materialised from master.

shell tree exit first line
dash clean 2 Syntax error: "(" unexpected
dash one Admitted. planted in coq/Kernel/Trit.v 2 Syntax error: "(" unexpected
bash clean 0 reading 9 file(s) named by coq/_CoqProject
bash one Admitted. planted 1 reading 9 file(s) named by coq/_CoqProject

Under the CI shell the gate returned the same thing in both states — it carried no information. The bash rows are the positive control: they show the probe can separate the two states, so the dash rows are a finding rather than a broken probe.

macOS /bin/sh is bash 3.2 and accepts arrays, so it passes this body and proves nothing. /bin/dash was used. That trap is now recorded in the workflow comment.

Class enumerated, not assumed

Of 50 workflow files, 4 use a container (coq-kernel, coq-proofs, rings-rust, vivado-synth). This is the only step in any of them that combines a container with a bash-only construct. The <<< in rings-rust.yml is in the discover job, which runs on ubuntu-latest with no container and already gets bash.

Scope

One shell: bash key. The gate body is unchanged, and the other 7 steps in the job keep no shell key. set -eu is kept — Actions invokes a bash step as bash --noprofile --norc -eo pipefail {0}, so pipefail is already on; the dash rationale that originally chose set -eu is gone with the shell, and the comment saying so is corrected in place rather than left to mislead.

Not fixed here

The meta-gate written to protect this gate extracts the body correctly and then runs it through subprocess.run(["bash", "-c", body]) — a different shell from CI. It passes 13/13 on the body dash refuses. That is the larger half and is left in #3396 as context; a guard that does not use the shell it guards will keep certifying bodies CI cannot run.

… dash

Refs #3396

The step declares no shell key and neither does the job, so it inherits
the coqorg/coq container default of `sh -e` -- dash -- while its body uses
four bash-only constructs: VFILES=(), VFILES+=(...), ${#VFILES[@]} and
`done < <(...)`. Dash rejects the first of them with a syntax error before
opening any file.

Measured on the body extracted verbatim from this workflow, against the
nine .v files coq/_CoqProject names, materialised from master:

  dash  clean    exit 2  Syntax error: "(" unexpected
  dash  planted  exit 2  Syntax error: "(" unexpected
  bash  clean    exit 0  reading 9 file(s) named by coq/_CoqProject
  bash  planted  exit 1  reading 9 file(s) named by coq/_CoqProject

Identical under dash in both states: the gate carried no information. The
bash rows are the positive control -- they show the probe can separate the
two states, so the dash rows are a finding and not a broken probe. Note
that macOS /bin/sh is bash 3.2 and accepts arrays, so it cannot serve as
the control here; /bin/dash was used.

The class was enumerated rather than assumed: of 50 workflow files, 4 use
a container, and this is the only step in any of them that combines a
container with a bash-only construct. The `<<<` in rings-rust.yml sits in
the `discover` job, which runs on ubuntu-latest with no container and so
already gets bash.

The body is unchanged. `set -eu` is kept -- Actions invokes a bash step
with -eo pipefail already, and the dash rationale that originally chose it
no longer applies, so the comment saying so is corrected in place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gHashTag
gHashTag enabled auto-merge (squash) September 7, 2026 16:21
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-07 16:21:29 UTC

Summary

Status Count
Total Open PRs 16
PRs with Failing Checks 14
PRs with All Checks Green 2
READY 2
FAILING 14
PENDING 0
NO CHECKS YET 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=745cf51f9c7e != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit ad5ddc1 into master Sep 7, 2026
32 of 34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

coq-kernel: the "no Admitted" gate exits 2 before it reads a file (bash array under dash)

1 participant