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
{{ message }}
Repository navigation
gpu-q does not pin the binary it runs — the GPU has two entrances and only one is guarded #3879
The decision surface is "what runs on the GPU". There are two paths to it and only one is guarded.
scripts/apr_bin.sh is a hard gate for anything that goes through it: it proves a binary was built from THIS commit in THIS tree, and CLAUDE.md Step 0 makes it mandatory (. scripts/apr_bin.sh || exit 1). gpu-q is the other entrance, and it is unpinned by construction — it takes whatever path it is handed and queues it for the GPU.
The proof, measured on gx10 2026-09-22
An orphaned job had been sitting in gpu-q's poll loop for 23 hours:
pid 1936324 ppid 1 started Sep 21 19:08
bash gpu-q --prio 8 -- /tmp/tmp.8vclFRPCe1/.receipt-work/root/bin/apr run …
that binary: apr 0.68.2 (v0.68.2+no-git)
v0.68.2+no-git — the previous release, carrying no git sha at all. apr_bin.sh would have refused it on sight. It was queued for the GPU precisely because it never met apr_bin.sh. Had it won the lock mid-ladder it would have taken the GPU from a rung and produced an answer attributable to no commit in history — #3784's defect ("the receipt's identity is the binary that ran") in its purest form, with nobody watching for it.
It also demonstrates the failure is not hypothetical and not loud: it sat there for a day, contending for /tmp/apr-gpu.lock against a release measurement, and was found only because someone read ps output while checking whether a ladder was hung.
Why this is the CLAUDE.md rule 5 shape
a guard that does not scan the surface where the DECISION is made is theater
The enumerated surface was "things that call apr_bin.sh". The actual surface is "things that reach the GPU", and nobody enumerated it, so the second entrance was never in scope. Pinning was strengthened repeatedly (#2360, the Makefile scope extension) without anyone asking which paths bypass it entirely.
Suggested fix, in order of strength
Minimum:gpu-q refuses a binary whose --version carries no git sha. Cheap, catches the measured case, and cannot pass vacuously.
Better:gpu-q pins the same way apr_bin.sh does — one rail rather than two — so "what runs on the GPU" has a single guarded entrance.
Either way it wants a case table (a no-sha binary, a sha from another tree, a correctly pinned one), per CLAUDE.md rule 7.
Related: #3784, #3876 (evidence that misreports its own subject), and the enumeration question generally — the same audit that asks what else do the receipts carry that nobody checks should ask what else reaches the GPU without meeting the pin.
milestone → 0.70.0 per docs/roadmaps/milestone-triage-2026-09-23.md (#4024), operator approval 2026-09-23 (relayed by aprender-cf). Reason: release/CI/gate speed and reliability: Fast Train (#3998)
Parked by APR-EPIC-001: over S1 budget (rank 136/163). Reopen = pull. Applied by aprender-d1: claude+agy both said close, apr shadow row recorded (handoff/close-quorum-2026-09-25.json).
Activity
noahgift commentedon Sep 23, 2026
milestone → 0.70.0 per docs/roadmaps/milestone-triage-2026-09-23.md (#4024), operator approval 2026-09-23 (relayed by aprender-cf). Reason: release/CI/gate speed and reliability: Fast Train (#3998)
noahgift commentedon Sep 25, 2026
Parked by APR-EPIC-001: over S1 budget (rank 136/163). Reopen = pull. Applied by aprender-d1: claude+agy both said close, apr shadow row recorded (handoff/close-quorum-2026-09-25.json).