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
fix(formal): make the local Coq assumptions gate capable of failing (#202)
fix(formal): make the local Coq assumptions gate capable of failing
`just -f formal/Justfile check-assumptions` returned 0 whether or not
anything compiled, so a green local proof gate was not evidence of a
proof. Demonstrated by putting a stub `coqc` that exits 127 on PATH:
$ PATH=/tmp/fakebin:$PATH just -f formal/Justfile check-planner
coqc: not found
OK(Planner): Q1-lite 3 theorems x 4 axioms whitelisted
exit=0
Cause: every compile recipe was `coqc -q X.v | tee X.out`. A pipeline's
exit status is its *last* command's, so `just` saw `tee`'s 0 and moved
on; `coqc`'s diagnostics go to stderr, which `tee` never captures. The
guard then ran awk over an empty `X.out`, found no axioms, and reported
OK.
Fixed by redirecting instead of piping: `coqc -q X.v > X.out`. The exit
status is now `coqc`'s and `just` aborts the recipe.
Note this is deliberately NOT fixed with `set shell := [... "pipefail"
...]`.
The guards are shaped `awk | sort -u | grep -vE '<whitelist>' | { ...
}`,
and `grep -v` exits 1 precisely when it filters everything out — i.e. on
the success path, where every axiom is whitelisted. Enabling pipefail
would turn every passing check into a failure.
`.github/workflows/coq-build.yml`
already handles this correctly (`set -euo pipefail` *and* `|| true` on
each
grep), so CI was never affected; this was a local-only divergence.
Also adds `Set Printing Width 400.` to all nine modules. Both the CI and
Justfile guards match axiom names with `awk '/^[A-Za-z_][A-Za-z0-9_]*
:/'`,
which only fires when the name and its colon share a line. Coq wraps at
~78 columns and `Planner.out`'s longest line was **77** — one character
from silently escaping the check. With the directive, statements print
in
full (Normalizer 75 -> 157, WAL 62 -> 127, Octad 62 -> 127,
PlannerSemantic
74 -> 113, Drift 72 -> 95).
To be precise about what this did and did not find: comparing the axiom
names visible to the guard with and without the directive shows **no
difference today**. Nothing was being hidden; this closes a latent
escape
before it opens, it does not fix an active one.
Verified: with a broken `coqc` the gate now exits 127 ("recipe `planner`
failed on line 29"); with the real coqc 8.20.1 all nine modules compile
and
`check-assumptions` exits 0 with 9/9 OK lines. `reuse lint` still
compliant.
0 commit comments