Repository navigation
Enforce fresh-checkout host gates on pull requests - #198
Conversation
The arm runner runs make -j4, make test-native-artifact, make zero-cuda-gate, build/hello_gpu --sim, and read-only make doctor. make test stays in the existing host-tests job. The figure check requires docs/img/stack.svg to match its generator. Refs #90 — Grokbot Co-authored-by: Drake Stapleton <[email protected]>
drakestapleton
left a comment
There was a problem hiding this comment.
Review at cbcbcab: needs changes (small). CI hasn't started yet: all 13 checks were queued at review time, so fresh-checkout has no AArch64 result yet.
Provenance. This is 1 commit from cloud agent bc-a927ce42, branched off main 522ee0d. The body says Refs #90, which matches the issue. It doesn't close #90, and that's correct, since the ruleset's required checks are left to an admin.
Scope. Existing workflows aren't touched (ci.yml and runtime-api.yml are unchanged). It adds a new file, .github/workflows/host-gates.yml, with two jobs:
figures(L21-37): runs onubuntu-latestwith a 5-minute limit.fresh-checkout(L38-56): runs onubuntu-24.04-armwith a 30-minute limit.
Triggers are pull_request plus pushes to main, and permissions are contents: read. checkout and upload-artifact are pinned to SHAs. concurrency cancels in-progress runs per ref.
Also changed: the new tools/ci/host-gates.sh (415 lines) and docs/CI_ACCEPTANCE.md, plus pointer lines in AGENTS.md L78, CONTRIBUTING.md L24-25 and docs/START_HERE.md L93-97. The check names figures and fresh-checkout are new, and none collides with host-tests, runtime-api or the others.
Fake-green check. This is mostly strict.
run_logcaptures rc.finishexits 1 on any FAIL (L250-259).- Each checker requires the exact exit code and its marker lines: artifact
0 failed, ZERO_CUDA self-test plus both binaries, sim pinned output sha with two identical runs, past-end exit 1 with no PASS, GPU bug path exit 2, doctor exit 2 withNOT READYand noREADY.line, and figures with nostale. --self-testcovers the reject cases.- The
|| trueat L46, L365 and L366 only guards greps whose result is then checked. - The
if: always()lines are on the artifact upload only.
One gap fails open:
- tools/ci/host-gates.sh L356 and L391-393. If
make -j4passes butbuild/hello_gpuisn't built, the three sim and bug gates are recordedNOT_RUN.recorddoesn't setfailfor NOT_RUN, so the job ends withCUDA++ HOST GATES PASSwith no sim run at all. The same pattern sits at L352-353, but there it's harmless, because themake -j4failure already sets fail. Please make a missingbuild/hello_gpuafter a successfulmake -j4a FAIL, and add a self-test case for it. - Minor:
doctor_okmatches make'sError 1text (L295). That's fine, just brittle across make versions.
GB10. There's no claim beyond NOT_RUN. make hello-gpu, chip tests and device opens are NOT_RUN in both the script (L321) and the doc. The local evidence is x86-64 portable only, so the arm runner result is still pending.
Fit with #197 and #196. There are no shared files: #197 only edits runtime-api.yml. #196 is still an issue, with no PR open. Its x86 job should take a name other than host-tests, fresh-checkout, figures and runtime-api. If it edits ci.yml, it won't conflict with this PR. Suggested merge order: #197, then #198, then #196. No textual rebase is expected. #196's PR should update the pointers here (host-gates.yml L15, the script's x86-64 make test NOT_RUN note at L320, and docs/CI_ACCEPTANCE.md L9).
Follow-ups. The body lists none to file. It notes these as NOT_RUN or admin-only: the Inkscape legend test, an outside-engineer run, required status checks on main-verified-promotion, and x86 make test (#196).
— Grokbot
The three simulator gates are FAIL, not NOT_RUN, when make -j4 exits 0 and build/hello_gpu is absent. The doctor check uses make's exit code and ignores the Error 1 text. The x86 pointer names the x86-host-tests job. — Grokbot Co-authored-by: Drake Stapleton <[email protected]>
drakestapleton
left a comment
There was a problem hiding this comment.
Re-review at b7bc8da: needs changes (doctor gate only).
The branch has 2 commits: cbcbcab, then b7bc8da on top of it. It wasn't force-pushed. The base is now 86b78f2, after #199 merged. CI is green on all 14 checks: host-gates run 41080804127 (figures, fresh-checkout), ci run 41080804265, and the rest.
Fixed
- hello_gpu missing.
tools/ci/host-gates.shL117-130 and L325-341: a successfulmake -j4with nobuild/hello_gpunow records 3 FAILs and setsfail=1. NOT_RUN is kept only when make itself failed. - Self-tests. L256-287 feed real cases: a nonexistent path, an empty executable file, and a make rc of 2. They assert both
failand the FAIL/NOT_RUN row counts, andsaved_failcarries any failure into the exit 1 at L295-299. CI runs--self-testin both jobs (host-gates.yml), and a self-test failure fails the job. The|| trueat L257, L277 and L278-279 only stopsset -efrom aborting before the asserts run. The return code and counts are still checked. - Error 1 text. It's gone from
doctor_ok(L100-115), and L246-247 tests that the text alone doesn't pass. - x86 pointer. L395 now says
ENFORCED_ELSEWHEREwithx86-host-testsinhost-x86.yml.
Doctor gate: doesn't meet the policy yet (L100-115). Exit codes are handled right: only rc 2 passes, and 0, 1, 3 and anything else fail at L102. The output check is loose, though:
- It only checks that the five expected
FAILlines are present, usinggrep -Fsubstring matches (L104-108). There's no check that they're the only ones, so an unexpected sixthFAIL ...line still passes. That's a fixed list of required lines, not an allowlist that rejects anything else. - The count isn't pinned. L109 accepts any
NOT READY:, soNOT READY: 9 problems abovepasses. - The self-tests have no case for an unexpected problem line, a wrong count, or rc 1 or rc 3. Only rc 0 and the READY line are covered (L244-249).
What's needed:
- Take every line matching
^ FAILand require it to equal one of the five allowlisted lines exactly. Those are the kernel module line (full text, including the/proc/...parenthesis), nvidiactl, nvidia0, nvidia-uvm, and no NVIDIA GPU. Any other FAIL line fails the gate. - Require exactly 5 FAIL lines and an exact
NOT READY: 5 problems above.prefix. - Add self-test rejects for an extra unexpected FAIL line, a count of 6, a missing allowlisted line, rc 1 and rc 3.
Fake-green re-scan. It's clean: no continue-on-error, and no if: skip except always() on the artifact uploads. Every || true sits on a grep or count that's checked afterwards. GB10 stays NOT_RUN (L396), and the PR makes no chip claim.
#199 is merged and #197 is still open. The pointers are correct now.
— Grokbot
The gate accepts make doctor only when those five lines are present exactly once, the summary starts with "NOT READY: 5 problems above.", and the exit code is 2. — Grokbot Co-authored-by: Drake Stapleton <[email protected]>
drakestapleton
left a comment
There was a problem hiding this comment.
Re-review at 16ff7c1: needs changes, one small gap left in how FAIL lines are found.
This head is a fast-forward from b7bc8da: it is 1 commit ahead and 0 behind, so nothing was force-pushed. The only file changed is tools/ci/host-gates.sh (+57/-8). The PR is mergeable and clean on base bac7330. All 15 checks are green at 16ff7c1: host-gates run 41084623303 (figures, fresh-checkout), x86-host-tests 41084623395, ci 41084623539, runtime-api 41084623271, hello-sim 41084623681, library 41084623293, drift 41084623479, and CodeQL 41084617093.
I ran the doctor_ok function from L103-153 against edge cases.
Works
- Exit code (L124). Only exit 2 is accepted. Exit 0, 1 and 3 are all rejected.
- Allowlist (L103-119). A
casestatement compares the whole line against the five allowlisted lines exactly.- Duplicates and missing lines. The total must be exactly 5 (L146) and each kind must appear once (L147), so a repeated line can't stand in for a missing one. I tested this: replacing uvm with a second nvidia0 is rejected.
- Whitespace and partial matches. A trailing space, a longer line, or
FAIL xwith three spaces is rejected.
- Summary line (L148-151). The pattern
^NOT READY: 5 problems above\.must match exactly once, and there must be exactly one^NOT READY:line.- Rejected:
6 problems,50 problems, bareNOT READY: 5, an indented summary, a duplicated summary, and a missing summary. 50can't match, because the literalproblemsmust come straight after the5.
- Rejected:
- Self-tests. These are real.
expect_reject(L190-198) setsfail=1whenever the checker accepts a case it should reject, and that leads to the exit 1 at L347-348.doctor-extra-fail(L291-293) adds a sixth FAIL line.doctor-count-6(L294-295) usessedto change the summary to 6.doctor-missing-allowlisted-line(L296-297) drops the uvm line withgrep -vxF.doctor-exit1anddoctor-exit3(L298-299) pass exit 1 and exit 3.
Gap (L132). FAIL lines are found with ' FAIL '*, which only catches lines starting with exactly two spaces, FAIL and two spaces. A FAIL line in any other form is never counted, so the gate still passes. I tested each of these appended to the good fixture, and each was ACCEPTED:
FAIL something(no leading spaces)FAIL something(one leading space)- a tab followed by
FAIL x
Fix. Treat any line matching ^[[:space:]]*FAIL([[:space:]]|:|$) as a problem line, so it must pass doctor_fail_line or the gate fails. Then add a self-test reject for one of these variant forms.
Fake-green scan. It's still clean. There's no continue-on-error, and no if: skip apart from always() on the uploads. The new || true on the grep -c calls (L148-149) feeds counts that are checked right after. GB10 stays NOT_RUN.
— Grokbot
A problem line is any line matching ^[[:space:]]*FAIL([[:space:]]|:|$), so a missing indent or a tab is still checked against the allowlist and counted toward the five. — Grokbot Co-authored-by: Drake Stapleton <[email protected]>
drakestapleton
left a comment
There was a problem hiding this comment.
Re-review at d558e5d: ready to merge.
Diff. This head is a fast-forward from 16ff7c1: 1 commit ahead, 0 behind, so nothing was force-pushed. The only file changed is tools/ci/host-gates.sh (+10/-5):
- the comment at L98-99;
- the FAIL-line check at L132, which is now
[[ "$line" =~ ^[[:space:]]*FAIL([[:space:]]|:|$) ]]instead of thecaseprefix; - two new self-tests at L297-304.
Nothing else changed.
Edge cases. I ran the new doctor_ok (L104-155) on these:
- The good five-line output with exit 2 PASSES.
- Each of these is REJECTED:
FAIL xwith no indent;FAIL xwith one space;- a tab followed by
FAIL x; FAIL: x;- a bare
FAIL, indented or not; - an allowlisted line with a trailing space;
FAIL xwith three spaces;- a duplicated line standing in for uvm;
- a missing uvm line;
- a summary count of 6 or 50;
- a missing summary;
- exit 0, 1 or 3.
- Lines starting
FAILED,FAILUREor a lowercasefailaren't treated as problem lines, as the regex intends, so the gate still passes. That's acceptable: the doctor prints problems asFAIL. Note it for later if the doctor's output format changes.
Self-tests. Both are real:
doctor-fail-noindent(L299-301) appendsFAIL x.doctor-fail-tab(L302-304) appends a tab followed byFAIL x.
If either is accepted, expect_reject (L189-197) sets fail=1, which ends in SELF-TEST FAIL and exit 1 (L352-353). --self-test runs in both host-gates jobs.
CI. All 15 checks at d558e5d are green: host-gates 41087598473 (figures, fresh-checkout), x86-host-tests 41087598346, ci 41087598565, runtime-api 41087598377, hello-sim 41087598416, library 41087598383, drift 41087598347, and CodeQL 41087589254. The PR is mergeable clean on base bac7330, and #197 merged at 10:53 AM CT.
Fake-green scan. Still clean: no continue-on-error, and no if: skip apart from always() on the uploads. Every || true is followed by a check. GB10 stays NOT_RUN.
— Grokbot
Purpose and scope
Pull requests now run the fresh-checkout host commands from
docs/START_HERE.md, with a written rule for what each result means. Refs #90.New files:
.github/workflows/host-gates.ymltools/ci/host-gates.shdocs/CI_ACCEPTANCE.mdSmall pointers in
docs/START_HERE.md,CONTRIBUTING.md, andAGENTS.md.This does not edit
ci.yml,runtime-api.yml, the Makefile, or any file from PR #170. It does not touch the frozen C stack,src/omega_cubin.*, orom/cubin/.How this composes with #189 and the x86 job
make teststays thehost-testsjob in.github/workflows/ci.yml. This pull request does not run that suite a second time. The arm job still installs pinnednvdisasm13.0.85 there, and still judges the exit code and the finalCUDA++ HOST TESTS PASSline. IntentionalFAILandERRORlines in that log stay visible.make test-runtime-apistays.github/workflows/runtime-api.yml. Issue CI: runmake test-runtime-apion PRs and main (ADR 0043 follow-up) #189 owns that job. This pull request does not add another copy.make testis thex86-host-testsjob in.github/workflows/host-x86.yml(PR CI: add an x86-64 host-tests job (portable suite + freestanding link) #199). This pull request does not add that job and does not change the AArch64host-testsjob. On x86-64 the portable suite is the contract indocs/OMEGA_HOST_TESTS.md. The device open returnsENOTSUPandrequires AArch64 Linux. That is not a supported GPU run.What each gate runs
make -j4host-gates/fresh-checkoutonubuntu-24.04-arm, 30 minute limitmake testci.yml/host-testsmake test-native-artifactfresh-checkouttest_gpu_artifact_export: <n> checks, 0 failed.make zero-cuda-gatefresh-checkoutZERO_CUDA FAILfor the stublibcudartprobe, thenZERO_CUDA SELF-TEST PASS, thenZERO_CUDA PASSfor the two binaries.build/hello_gpu --simfresh-checkoutmake -j4exits 0 andbuild/hello_gpuis missing, the three simulator rows areFAIL.build/hello_gpu --sim --bug=past-endfresh-checkoutFAULT,0 bytes past the end of buffer a, and noPASSline.build/hello_gpu --bug=past-endfresh-checkoutmake doctorfresh-checkoutpython3 tools/figures/make_figures.py --checkhost-gates/figuresonubuntu-latest, 5 minute limitfigures current: <n>.tools/ci/host-gates.sh --self-testFAILline, a summary count of 6, a missing allowlisted line, exit 1, exit 3, aFAILline with no indent, and a tab beforeFAIL.docs/img/stack.svgalready matched the generator on main522ee0d(figures current: 10). No SVG was rewritten.CI on this pull request
GitHub tested head
d558e5d06eb5f9c847dc8bd28c50c76d862c2acb.host-gates passed.
fresh-checkoutlast line:CUDA++ HOST GATES PASS. The self-test printedPASS doctor-fail-noindent,PASS doctor-fail-tab, andCUDA++ HOST GATES SELF-TEST PASS.make doctorexited 2 and was recorded PASS. Chip qualification staysNOT_RUN.CI host-tests passed in 15m3s. Last line:
CUDA++ HOST TESTS PASS (62 targets).x86-host-tests passed in 7m47s.
The other checks also passed:
runtime-api,hello-sim,library,drift,om-units,sbom,audit-scanner, and CodeQL.Known limitations
make hello-gpu, chip tests, and any open of/dev/nvidia*or/dev/aien-gpuare NOT_RUN. The runners have no GB10.docs/START_HERE.mdon a machine this repository does not control is NOT_RUN.main-verified-promotionstill has no required status checks. Marking a check required is an administrator change and was not done.make testand does not setCUDAPP_MEM_RESERVE_MIB. That suite is thex86-host-testsjob in.github/workflows/host-x86.yml.— Grokbot