Repository navigation
tamarin-prover: use the packaged alex/happy instead of cabal's own (intermittent amd64 failure) #609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tamarin-prover: use the packaged alex/happy instead of cabal's own (intermittent amd64 failure) #609
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -102,12 +102,57 @@ if grep -q 'getCurrentTime' "$stamp_file"; then | |
| exit 1 | ||
| fi | ||
|
|
||
| # ── amd64: use the PACKAGED alex/happy, not cabal's own ────────────────────── | ||
| # | ||
| # tamarin fails INTERMITTENTLY on amd64 (pkgs#606's run, 2026-08-14) with: | ||
| # | ||
| # Error: [Cabal-1008] | ||
| # The program 'alex' version >=3.1.4 is required but the version of | ||
| # /build/.cabal-home/store/ghc-9.10.3-inplace/alex-3.5.4.2-.../bin/alex | ||
| # could not be determined. | ||
| # | ||
| # NOT a compile error: cabal BUILT alex fine ("Completed alex-3.5.4.2 (exe:alex)") | ||
| # and then could not get a version out of it when `language-javascript` | ||
| # configured. So the binary exists and will not answer — which is what you get | ||
| # from a partially-installed store entry under `--jobs=$(nproc)`, or from an | ||
| # invocation killed for memory. Either way it is cabal provisioning its own copy | ||
| # that fails, and both alex and happy are already packaged for both arches. | ||
| # | ||
| # INTERMITTENT is established, not assumed: pkgs#607 and #608 built the same | ||
| # tamarin source on the same amd64 builder and PASSED (merged 20:28 and 20:30 | ||
| # the same day) hours after #606 failed at 12:33. So this is not a miscompile | ||
| # and not a missing dependency — it is a race, and #606 drew the short straw. | ||
| # | ||
| # That is the worse shape for a queue: the natural response to a flake is to | ||
| # re-run it, which usually works, which is how one survives for weeks without | ||
| # anyone fixing it. | ||
| # | ||
| # Point cabal at those instead. `--with-PROG` is Cabal's documented override for | ||
| # a known program, and alex/happy are known programs. | ||
| # | ||
| # The assertions below are deliberate: if the packaged tools are the problem | ||
| # rather than the fix, this fails HERE with the version printed, instead of 40 | ||
| # minutes later inside a dependency's configure step with no way to tell which | ||
| # alex cabal used. Amd64 could not be reproduced locally (this fleet develops on | ||
| # arm64), so the next run's log is the experiment. | ||
| ALEX_BIN="$(command -v alex)" | ||
| HAPPY_BIN="$(command -v happy)" | ||
| echo "tamarin: packaged alex = ${ALEX_BIN:-<not on PATH>}" | ||
| echo "tamarin: packaged happy = ${HAPPY_BIN:-<not on PATH>}" | ||
| [ -n "$ALEX_BIN" ] || { echo "ERROR: alex not on PATH — build_deps regression" >&2; exit 1; } | ||
| [ -n "$HAPPY_BIN" ] || { echo "ERROR: happy not on PATH — build_deps regression" >&2; exit 1; } | ||
| # Prove they RUN and report a version — the exact thing cabal could not do. | ||
| "$ALEX_BIN" --version || { echo "ERROR: packaged alex cannot report a version" >&2; exit 1; } | ||
| "$HAPPY_BIN" --version || { echo "ERROR: packaged happy cannot report a version" >&2; exit 1; } | ||
|
Comment on lines
+138
to
+146
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/sh
set -eu
rg -n -C 4 \
'LD_LIBRARY_PATH|ghc --print-libdir|ALEX_BIN|HAPPY_BIN|--with-alex|--with-happy' \
packages/tamarin-prover/build.sh packages/haskell-language-server/build.shRepository: gominimal/pkgs Length of output: 4512 🏁 Script executed: #!/bin/sh
set -eu
printf '%s\n' '--- tamarin build script header and relevant setup ---'
sed -n '1,180p' packages/tamarin-prover/build.sh
printf '%s\n' '--- all tamarin library-path and shell-mode references ---'
rg -n -C 3 'LD_LIBRARY_PATH|ghc --print-libdir|#!/|set \+[euo]|PIPESTATUS|cabal build|command -v alex|command -v happy' packages/tamarin-prover/build.sh
printf '%s\n' '--- package metadata ---'
fd -i -t f 'build.ncl' packages/tamarin-prover packages/haskell-language-server -x sh -c 'echo "--- $1"; sed -n "1,180p" "$1"' sh {}Repository: gominimal/pkgs Length of output: 16533 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- packaged generator build scripts ---'
for d in packages/alex packages/happy packages/ghc packages/base; do
if [ -f "$d/build.sh" ]; then
echo "--- $d/build.sh"
sed -n '1,180p' "$d/build.sh"
fi
done
printf '%s\n' '--- library-path setup in related Haskell packages ---'
rg -n -C 3 'LD_LIBRARY_PATH|ghc --print-libdir|GHC_LIBDIR|command -v alex|command -v happy' packages --glob 'build.sh' --glob 'build.ncl' | head -250
printf '%s\n' '--- generator package metadata ---'
for f in packages/alex/build.ncl packages/happy/build.ncl packages/ghc/build.ncl; do
if [ -f "$f" ]; then
echo "--- $f"
sed -n '1,180p' "$f"
fi
doneRepository: gominimal/pkgs Length of output: 28686 🏁 Script executed: python3 - <<'PY'
<
8000
span class="pl-s">from pathlib import Path
tamarin = Path("packages/tamarin-prover/build.sh").read_text()
alex = Path("packages/alex/build.sh").read_text()
happy = Path("packages/happy/build.sh").read_text()
alex_ncl = Path("packages/alex/build.ncl").read_text()
happy_ncl = Path("packages/happy/build.ncl").read_text()
hls = Path("packages/haskell-language-server/build.sh").read_text()
cut = tamarin.index('ALEX_BIN=')
setup = tamarin[:cut]
checks = {
"tamarin uses bash strict mode": tamarin.startswith("#!/bin/bash\nset -euo pipefail"),
"tamarin sets GHC library path before generators": (
"ghc --print-libdir" in setup and "LD_LIBRARY_PATH" in setup
),
"alex is built with GHC": "ghc --make" in alex,
"happy is built with GHC": "ghc --make" in happy,
"alex declares GHC runtime libraries": all(x in alex_ncl for x in ("base,", "gmp,")),
"happy declares GHC runtime libraries": all(x in happy_ncl for x in ("base,", "gmp,")),
"analogous HLS setup exports GHC library path": (
"GHC_LIBDIR=\"$(ghc --print-libdir)\"" in hls
and 'export LD_LIBRARY_PATH="${GHC_LIBDIR}:${LD_LIBRARY_PATH:-}"' in hls
),
}
for name, result in checks.items():
print(f"{name}: {'PASS' if result else 'FAIL'}")
PYRepository: gominimal/pkgs Length of output: 437 Export GHC’s library path before running These GHC-built generators require GHC shared libraries. 🤖 Prompt for AI Agents |
||
|
|
||
| # Build + install the executable (STATIC — a normal Haskell static link; the link | ||
| # was never the problem). The sandbox hides build detail, so on failure dump the | ||
| # real error (compile OR link) rather than a silent "Failed to build". | ||
| set +e | ||
| cabal build exe:tamarin-prover \ | ||
| --with-compiler="$(command -v ghc)" \ | ||
| --with-alex="$ALEX_BIN" \ | ||
| --with-happy="$HAPPY_BIN" \ | ||
|
Comment on lines
151
to
+155
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/sh
set -eu
rg -n -C 3 '/tmp/tam-build\.log|mktemp|trap' packages/tamarin-prover/build.shRepository: gominimal/pkgs Length of output: 719 🏁 Script executed: #!/bin/sh
set -eu
printf '%s\n' '--- build script header and relevant block ---'
sed -n '1,18p;120,165p' packages/tamarin-prover/build.sh
printf '%s\n' '--- related temporary-path conventions ---'
rg -n -C 2 '(/tmp/|mktemp|TMPDIR|trap)' packages/*/build.sh | head -200
printf '%s\n' '--- repository build isolation references ---'
rg -n -i -C 2 'sandbox|private /tmp|TMPDIR|concurrent builds|parallel builds' AGENTS.md README.md packages 2>/dev/null | head -200Repository: gominimal/pkgs Length of output: 29135 🏁 Script executed: #!/bin/sh
set -eu
printf '%s\n' '--- sandbox and build-runner semantics ---'
rg -n -i -C 4 'build sandbox|sandbox.*(/tmp|tmp)|/tmp.*sandbox|private.*tmp|tmp.*private|mount.*tmp|temporary directory' AGENTS.md docs cmd internal pkg packages 2>/dev/null | head -300
printf '%s\n' '--- build execution entry points ---'
rg -n 'build\.sh|OUTPUT_DIR|sandbox' --glob '*.go' --glob '*.ncl' --glob '*.md' --glob '*.sh' . | head -300Repository: gominimal/pkgs Length of output: 28521 Use a unique Cabal log path If builds share 🧰 Tools🪛 ast-grep (0.45.1)[warning] 146-146: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing else
61DF
where) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. (predictable-tmp-file-bash) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| --jobs="$(nproc)" -v1 2>&1 | tee /tmp/tam-build.log | ||
| rc=${PIPESTATUS[0]} | ||
| set -e | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: gominimal/pkgs
Length of output: 3812
🏁 Script executed:
Repository: gominimal/pkgs
Length of output: 3071
Keep the missing-tool diagnostic reachable under strict mode.
With
set -e, a failedcommand -vexits the script before the custom error checks run. Handle lookup failures explicitly:Proposed lookup handling
📝 Committable suggestion
🤖 Prompt for AI Agents
Source: Coding guidelines