Goal
Evolve the RE-02.01 HermeticBuild control beyond the v0.1 grep-based heuristic toward verifiable hermeticity. Track scope, roadmap, and what we will and won't support out of the gate.
Originating discussion: PR #138 review.
What v0.1 does
repro_hermetic_build_handler (in darnit-reproducibility) reads .github/workflows/*.{yml,yaml} line-by-line and flags lines containing suspicious substrings (curl , wget , pip install , npm install, yarn install, apt-get install, brew install) unless the same line contains a known-safe pattern (uv sync, uv pip install, pip install --no-index, npm ci, yarn --frozen-lockfile).
Result: PASS / FAIL / INCONCLUSIVE based on whether any suspicious line is found.
What v0.1 misses
The grep heuristic only sees workflow YAML. Real builds frequently fetch deps from places it can't see:
Makefile — make build looks hermetic at the workflow level even if the Makefile does curl ... | bash.
setup.py / pyproject.toml build hooks — setup.py can run arbitrary network code at build time.
- Build scripts —
build.sh, scripts/setup, scripts/install-deps, etc.
- Composite GitHub Actions —
action.yml files in .github/actions/*/ can run any commands.
- Reusable workflows —
uses: org/repo/.github/workflows/foo.yml@ref is opaque.
- Containerfile / Dockerfile —
RUN apt-get install inside the build container is invisible to workflow scanning.
- Pre-commit / lefthook / similar — hooks that fetch tools mid-build.
- Other CI systems — GitLab CI, CircleCI, Jenkinsfile, Buildkite, Drone are not scanned.
Even within workflows, the heuristic has known false-positive and false-negative shapes:
- FN:
apt-get install -y curl on one line + curl ... | bash further down: caught by the per-line fix, but make install-deps invoking the same curl from a Makefile is not.
- FP: legitimate post-build uses (
curl to upload artifacts, pip install of a release tool unrelated to the build itself).
- FP: comments referencing the suspicious patterns.
What "true" hermeticity verification needs
Grep on CI files is a smell test, not a verification. Real hermeticity comes from one of:
- Runtime attestation — observe what the build actually does at runtime and attest to it. Witness collects in-toto attestations (network calls, file reads, subprocess invocations) during the build and produces signed evidence. We could (a) detect Witness in CI as a strong PASS signal, or (b) require Witness output as evidence for the control.
- Build-system-enforced sandboxing:
- Bazel with
--sandbox_network=false and --remote_cache — network is structurally unavailable to actions.
- Nix flakes with
--pure-eval — builds run in a network-isolated sandbox by default.
- Buck2, Pants — similar sandbox guarantees.
Detecting these (presence of BUILD.bazel, flake.nix with pure = true, etc.) is a much stronger signal than grepping shell commands.
- Reproducible-builds-style verification — running the build twice in different environments and diffing artifacts (
reprotest, diffoscope). Already partially covered by RE-03.01 BitForBitReproducible — worth thinking about how the two controls compose.
Proposed roadmap
v0.2 — broaden the grep, lower false-positive rate
v0.3 — strong PASS signals
v1.0 — verifiable hermeticity
Open questions
- Should v0.1 keep PASS/FAIL semantics on grep-only evidence, or downgrade to INCONCLUSIVE/WARN until v0.3 ships strong signals? Argument for downgrading: avoids falsely declaring a build hermetic on weak evidence (matches the project's conservative-by-default principle in
CLAUDE.md).
- Where does this control sit relative to RE-03.01 BitForBitReproducible? They overlap — bit-for-bit is the ground truth, hermeticity is one prerequisite. Consider whether they should compose (RE-02.01 evidence feeds RE-03.01 signal) or remain independent.
- For non-GitHub CI, is it worth shipping in v0.2, or should that wait until at least one user requests it?
Acceptance for closing this issue
cc @Marc-cn
Goal
Evolve the
RE-02.01 HermeticBuildcontrol beyond the v0.1 grep-based heuristic toward verifiable hermeticity. Track scope, roadmap, and what we will and won't support out of the gate.Originating discussion: PR #138 review.
What v0.1 does
repro_hermetic_build_handler(indarnit-reproducibility) reads.github/workflows/*.{yml,yaml}line-by-line and flags lines containing suspicious substrings (curl,wget,pip install,npm install,yarn install,apt-get install,brew install) unless the same line contains a known-safe pattern (uv sync,uv pip install,pip install --no-index,npm ci,yarn --frozen-lockfile).Result: PASS / FAIL / INCONCLUSIVE based on whether any suspicious line is found.
What v0.1 misses
The grep heuristic only sees workflow YAML. Real builds frequently fetch deps from places it can't see:
Makefile—make buildlooks hermetic at the workflow level even if the Makefile doescurl ... | bash.setup.py/pyproject.tomlbuild hooks —setup.pycan run arbitrary network code at build time.build.sh,scripts/setup,scripts/install-deps, etc.action.ymlfiles in.github/actions/*/can run any commands.uses: org/repo/.github/workflows/foo.yml@refis opaque.RUN apt-get installinside the build container is invisible to workflow scanning.Even within workflows, the heuristic has known false-positive and false-negative shapes:
apt-get install -y curlon one line +curl ... | bashfurther down: caught by the per-line fix, butmake install-depsinvoking the samecurlfrom a Makefile is not.curlto upload artifacts,pip installof a release tool unrelated to the build itself).What "true" hermeticity verification needs
Grep on CI files is a smell test, not a verification. Real hermeticity comes from one of:
--sandbox_network=falseand--remote_cache— network is structurally unavailable to actions.--pure-eval— builds run in a network-isolated sandbox by default.Detecting these (presence of
BUILD.bazel,flake.nixwithpure = true, etc.) is a much stronger signal than grepping shell commands.reprotest,diffoscope). Already partially covered by RE-03.01 BitForBitReproducible — worth thinking about how the two controls compose.Proposed roadmap
v0.2 — broaden the grep, lower false-positive rate
Makefile,**/Makefile,**/build.sh,setup.py,**/Containerfile,**/Dockerfile..gitlab-ci.yml,.circleci/config.yml,Jenkinsfile,azure-pipelines.yml.apt-get install -y --no-install-recommendsinsideRUNof aContainerfile/Dockerfileas DEFERRED (image-build network is acceptable; build-step network in the resulting container is not).v0.3 — strong PASS signals
--sandbox_network=false(or no override).flake.nixis present and used for the build (gated on RE-01.02 BuildEnvDeclared evidence).v1.0 — verifiable hermeticity
Open questions
CLAUDE.md).Acceptance for closing this issue
cc @Marc-cn