fix: real SHA-pinning check, real Justfile targets, and docs that match the code - #144
Conversation
PROOF-NEEDS.md claimed "1 `Admitted` in proofs/coq/lambda/LambdaCNO.v". Measured against absolute-zero @87902bb7: there are ZERO `Admitted` anywhere. `y_not_cno` is a KEPT AXIOM with a written rationale (LambdaCNO.v:388-399). The old wording was wrong in both directions — it overstated the incompleteness and understated the trusted base by a factor of 23. There are 23 `Axiom` declarations across 6 .v files, already classified by an in-source AXIOM AUDIT (end of physics/LandauerDerivation.v), which this file now points at as the authoritative record instead of duplicating it. Operationally the distinction matters: an `Axiom` PASSES a "no sorry / no Admitted" gate silently, so counting only `Admitted` measures the wrong thing. Promoted to the top of "What Needs Proving": the audit's own SOUNDNESS WARNINGS — `prob_nonneg`, `prob_normalized` (false over unconstrained function-type distributions) and `shannon_entropy_maximum` (stated inequality is backwards). All three are currently unused, which makes them cheap to fix now and expensive to discover later. Removed `y_not_cno` from that list: the in-source rationale explains it needs an invariant closed under the full reduction congruence, or a coinductive argument — out of scope, not "concrete and closable". aletheia/CLAUDE.md said all logic lives in src/main.rs (~950 lines) and "don't split into modules unless >1000 lines". It has been 5 modules / 995 lines for a while, with main.rs at 121. That instruction would have told the next agent to undo the existing structure. Also corrected: 23 workflows -> 16, flake.nix listed but absent, 18 integration tests -> 32. Added to aletheia/CLAUDE.md a prominent warning that those 16 nested workflows have NEVER run (Actions reads .github/workflows/ at the repo root only) — the fault that let this crate stay uncompilable for a month — and a note on the #124/#125 gap explaining why the integration suite is a UI contract, not a spec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`check_workflow_pins` decided a line was unpinned with:
if line.contains("@v") && !line.contains("@") {
`contains("@v")` implies `contains("@")`, so the second clause is always false
and `has_unpinned` could never be set. Every repository passed the check
unconditionally, including ones with `@v4` or `@master` refs. Verified with a
standalone binary before changing anything:
uses: actions/checkout@v4 old_detects_unpinned=false
This is aletheia's Silver-level "GitHub Actions SHA pinning" check — a gate
that has never been able to fail. It is also, pointedly, the exact check that
would have caught `SonarSource/sonarqube-scan-action@master`, the unpinned
action that broke this repo's Governance and CodeQL in #139.
Replaced with `uses_line_is_pinned`, which requires the ref after the final `@`
to be 40 hex characters, and:
- accepts both `uses:` and list form `- uses:` (the estate's existing
workflow linter anchors to line-start and misses the inline form)
- ignores a trailing `# v7.0.1` provenance comment, so a correctly pinned
line with a stale version comment is not a false positive
- exempts `./…` local actions/reusable workflows and `docker://` refs, which
cannot carry a Git SHA
Also replaced `assert!(true)` in test_file_exists with a real assertion. It had
given up on CWD-dependence; anchoring on `env!("CARGO_MANIFEST_DIR")` makes it
deterministic, and it now covers the negative case and the is_file()-not-
exists() distinction.
Verified: 29 unit tests pass (was 26), `cargo fmt --check` clean, clippy 25 -> 23
findings. End-to-end `cargo run -- .` against this repo now reports
`[FAIL] GitHub Actions SHA pinning`, correctly identifying the one genuinely
unpinned action, where before the fix it reported a pass.
Refs #125.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every build-ish recipe was a fake gate:
build:
@echo "Build not configured yet"
`just build`, `test`, `fmt`, `lint` and `clean` all printed a string and exited
0, so any caller — human or CI — got a pass for doing nothing.
Wired to the same commands the root rust-ci.yml gate runs, in the same order, so
`just check` locally means what CI means:
build -> cargo build --locked --all-targets, then --release
test -> cargo test --locked --bins
fmt -> cargo fmt --check (fmt-fix applies)
lint -> cargo clippy --locked --all-targets
deps-check -> the zero-dependency assertion, copied from rust-ci.yml
check -> build test fmt deps-check
self-verify -> run aletheia against this repository
Two deliberate limits, documented in the recipes so nobody "fixes" them:
- `test` is `--bins` only. The integration suite is a specification for a CLI
that does not exist yet; 27 of 29 fail by design (#124). Adding `--tests`
here would make the bar green by breaking it.
- `lint` is not yet `-D warnings`; 23 findings remain (#125). When that
closes, `-D warnings` must be added HERE AND to rust-ci.yml in the same
change, so local and CI never disagree about what "lint passes" means.
Verified by running them, not by reading them:
just --list parses; just deps-check -> "OK: zero dependencies";
just test -> 29 passed; just check -> exit 0.
And verified the gate can actually FAIL, which is the whole point: appending
badly-formatted Rust makes `just fmt` exit 1 while `just build` still exits 0,
and reverting restores exit 0.
Closes #99.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Note Automatic reviews are paused because your trial's included automatic processing has been used for this period. Upgrade now, or comment "Gitar review" to run a review anytime. Code Review ✅ Approved 1 resolved / 1 findingsFixes GitHub Actions SHA-pinning validation, wires the root Justfile targets to real cargo commands, and corrects inaccurate documentation. Consider handling dynamic action references in the SHA-pinning check to prevent false positives on expression-driven uses lines.
✅ 1 resolved✅ Edge Case: Dynamic action refs flagged as unpinned
OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
|
|
Three independent commits, each droppable on its own. Two fix gates that could never fail; one fixes documentation that actively misdirects.
1.
docs:— two files misstate the code they describePROOF-NEEDS.mdClaimed "1
Admittedinproofs/coq/lambda/LambdaCNO.v(y_not_cno)". Measured againstabsolute-zero @87902bb7:Zero
Admitted. Twenty-threeAxioms across 6 files. The old wording was wrong in both directions — it overstated the incompleteness and understated the trusted base 23×.y_not_cnois a KEPT AXIOM with a written rationale (LambdaCNO.v:388-399), not an unproven hole — and it is not the "concrete, closable proof obligation" the old text claimed. The in-source note explains it needs an invariant closed under the full reduction congruence, or a coinductive/step-indexed argument.The doc now defers to the AXIOM AUDIT already in
physics/LandauerDerivation.v, which is notably self-critical — it records thatcno_zero_energy_dissipation_derivedis an axiom despite its_derivedname, and that the triage docs' "DISCHARGE" marks are inaccurate.Promoted to the top of "What Needs Proving" — the audit's own SOUNDNESS WARNINGS:
prob_nonnegandprob_normalizedare false over unconstrained function-type distributions, andshannon_entropy_maximum's inequality is backwards (asserts uniform minimises entropy). All three are currently unused — cheap now, expensive later.aletheia/CLAUDE.mdSaid "all core logic lives in
src/main.rs(~950 lines)" and "don't split into modules unless >1000 lines". It has been 5 modules / 995 lines for a while,main.rsat 121. That instruction would tell the next agent to undo the existing structure.Also corrected: 23 workflows → 16;
flake.nixlisted but absent; 18 integration tests → 32. Added a prominent warning that those 16 nested workflows have never run (root-only discovery) — the fault that let this crate stay uncompilable for a month.2.
fix(aletheia):— the SHA-pinning check could never failcontains("@v")impliescontains("@"), so the second clause is always false andhas_unpinnedcould never be set. Proven before changing anything:This is aletheia's Silver-level "GitHub Actions SHA pinning" check — and pointedly, the exact check that would have caught
SonarSource/sonarqube-scan-action@master, the unpinned action that broke this repo's Governance and CodeQL in #139.Replaced with
uses_line_is_pinned, requiring 40 hex chars after the final@, which also:- uses:form (the estate's existing linter anchors to line-start and misses it)# v7.0.1provenance comment, so a correct pin with a stale comment isn't a false positive./…local actions/reusables anddocker://refsAlso replaced
assert!(true)intest_file_existswith a real assertion, anchored onenv!("CARGO_MANIFEST_DIR")so it is deterministic regardless of CWD.Verified: 29 unit tests (was 26) ·
cargo fmt --checkclean · clippy 25 → 23. End-to-endcargo run -- .now reports[FAIL] GitHub Actions SHA pinning, correctly finding the one genuinely unpinned action — where before the fix it reported a pass.Refs #125.
3.
fix(#99):— rootJustfilewas a fake gatebuild: @echo "Build not configured yet"build,test,fmt,lint,cleanall printed a string and exited 0. Wired to the same commands rootrust-ci.ymlruns, in the same order, sojust checkmeans what CI means.Two deliberate limits, documented in the recipes so nobody "fixes" them:
testis--binsonly — the integration suite is a spec for a CLI that doesn't exist; 27/29 fail by design (aletheia: 27/29 integration tests fail — main.rs never wires up the CLI surface #124). Adding--testswould make the bar green by breaking it.lintis not yet-D warnings(aletheia: clippy -D warnings has 25 findings — add as blocking gate once clean #125). When that closes it must be added here and torust-ci.ymltogether, so local and CI never disagree.Verified by running them, not reading them:
just deps-check→OK: zero dependencies;just test→ 29 passed;just check→ exit 0.And verified the gate can actually fail — appending badly-formatted Rust makes
just fmtexit 1 whilejust buildstill exits 0; reverting restores 0. A gate nobody has watched fail is not a gate.Closes #99.
Not in this PR
guix.scmidentity/licence clobber — separate, more urgent: fix: restore guix.scm identity and licence (squisher-corpus clobber is live on main) #143🤖 Generated with Claude Code