chrismdp / ci-a-commit

A commit is checked

Public · Version 1 of 1
Fork

GitHub Actions, ci.yml

GitHub: commits, pull requests and checksActions jobs test (1.22) and test (stable): run the commit's code, with no secret and a token that only readsActions jobs Bug review, Security review and Classify, one session each, with a token that only reads, running nothing from the changeClaude Code, claude-opus-5-5, on the maintainer's subscription, a fresh session in each jobthe committhe committhe commit's code[pass or fail][its own people's]the patch and the pull request'stextits findingsits findings[both reviews passed, on theapp's pull request from afactory branch]both reviews' findingsship, show or ask, with itsreasonsTriggerA pull request from any branchbut main is opened or pushedto, or a commit is pushed tomainDecided in #160's follow-up: CI runs on pull_request for every branch but main, and on push only for main, so each commit has one run. The build pushes, then opens its pull request, so CI first runs when it opensLinked to chrismdp/issue-to-pull-request#tokenConnectionThe repository, through itsown Actions tokenData · untrustedThe commit as pushed, and itspull request's title anddescription, if it has oneCode · checkRun the tests, vet, theexamples and wasm parity, onGo 1.22 and on the newest GoA fork's pull request, or one a stranger opened between two branches here, gets no review: its author could steer the sessions, which hold the maintainer's login token. Its review jobs still run, and fail at the gate before any secret is given, since GitHub counts a skipped required check as passed. The test jobs hold no secret and a token that only reads. Keeping the check on who opened it was agreed in #160's follow-upCode · doRecord each test job's resultas its check on the commitCode · sortSort by rule, in a gate thatholds no secret: is this apull_request run from a branchof this repository, opened byits own people or the app? Ifnot, the review fails here. Apush to main runs the testsonlyCode · bring-inBring in the pull request'spatch against main as data,and list the binary files itchanges in a file of the job'sownThe list of binary files is written by this step to a file of its own, which the prompts point at, so text in the patch or the description can't forge it (#153)DataThe patch applied to thecommit of main the branchstarts from, made read-only,with the list of binary filesDataMain's review prompts,AGENTS.md and REVIEW.md,copied out before any sessionstartsMain's prompts, AGENTS.md and REVIEW.md are copied out before a session starts, so the patch can't rewrite what it's held to. GitHub runs the pull request's own ci.yml, so a person with write access could change how their pull request is reviewed: they're trusted, and the app never pushes .github/ (#160)AI · checkReview the patch for bugs,with fresh context, keepingonly the findings that survive asecond lookThe sessions read the patch as data and run none of the change's code. No job that holds the Claude token runs tests, make or go run, since the runner has sudo and its memory holds the job's secrets (#160) Each session has its own empty home folder and output folder, reads inputs made read-only, runs in --permission-mode default with one Edit(//dir/file.json) rule for its own findings, and has no Bash (#153, #160) Read is limited to the workspace and the session's own input folder, with Read(//proc/**) denied, and Edit, which covers writing a file, is denied on .git/**. Each session keeps the login token from its commands (awml #121)3AI · checkReview the patch for security,in a session of its ownEach session has its own empty home folder and output folder, reads inputs made read-only, runs in --permission-mode default with one Edit(//dir/file.json) rule for its own findings, and has no Bash (#153, #160) Read is limited to the workspace and the session's own input folder, with Read(//proc/**) denied, and Edit, which covers writing a file, is denied on .git/**. Each session keeps the login token from its commands (awml #121)2Code · doOnce a review is done, makeits findings the job's owncheck on the commit, failed onan Important findingA session's text is escaped before it's posted: < escaped, mentions broken, length capped. It carries no marker for a workflow to parse, and is refused if it holds anything like a token (#160 rule 5) Each job's own check carries its result and its summary, so no job needs a token that writes checks, and nothing passes between jobs: no artifact here (#160 rule 6)2AI · sortSort by risk, reading the patchand both reviews' findings:ship, show or ask?Classify moved here from the build, so land reads its verdict from a check on the commit rather than from the build's artifact. Its check always passes, so the verdict never wakes the fixer. Only the app's pull request from a factory branch is classified, and only once both gated reviews have passed, so it has no gate of its own (#160) Each session has its own empty home folder and output folder, reads inputs made read-only, runs in --permission-mode default with one Edit(//dir/file.json) rule for its own findings, and has no Bash (#153, #160) Read is limited to the workspace and the session's own input folder, with Read(//proc/**) denied, and Edit, which covers writing a file, is denied on .git/**. Each session keeps the login token from its commands (awml #121)3Code · doMake Classify's verdict and itsreasons the job's own check,which always passesEach job's own check carries its result and its summary, so no job needs a token that writes checks, and nothing passes between jobs: no artifact here (#160 rule 6)Used by chrismdp/fix-review-findings and chrismdp/land-a-pull-requestData · untrustedThe head commit's checks:test (1.22), test (stable), Bugreview, Security review andClassifyOne judge: these checks on the commit as pushed. Nothing merges without the tests and both reviews passing on the head commit, and land and fix read only these, never a record a workflow passed on (#160 rules 1 and 2) The checks carry text from sessions that read a stranger's patch, so every workflow that reads them treats them as untrusted. Nothing here reaches an outside action: the checks are GitHub's record of this run2