Repository navigation
CI: run the checks a pull request's changed paths map to (jpdev.json mapping) - #177
Conversation
…mapping) jpdev.json gains a `changed` mapping from each dev.json step's inputs. On a pull request the Runner jobs run `check.sh --all --changed origin/<base>` less the four release steps; a push to main and the release call keep the whole list. Release contents is unchanged. Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review record: runner #177 (changed-path mapping, PR Runner jobs on
|
| Step | Input | Severity | Rule to add |
|---|---|---|---|
| none |
What the steps read: the Go tests read files outside their packages only at ../../openapi.json, ../../docs/MAPPING-V2.md, ../../docs/design/{manual-admission-wire,executor-ownership-boot}.json, ../../vectors/preparation/** and ../../internal/runner/testdata/**. No test reads any other doc, .github/, deploy/, tools/, go.mod or the repository through git. There is no //go:embed. manual-gate and chain-tests are fixed subsets of the same packages, and every test rule selects them together with build-pinned. local-paths, agent-docs and diff-check are in every rule, so a PR run is never empty. third-party-notices hard-codes its target list (it does not read .goreleaser.yml). The release steps are skipped in the Runner jobs, and Release contents runs them on every commit.
What was simulated (vendored runner, scratch clone, origin/main set to the PR head)
changed_checks.pygave the whole list for:jpdev.json,dev.json,scripts/dev/check.sh,changed_checks.py,ci.yml,release.yml,.gitattributes, and a file in a new directory.- Scoped selections: go.mod 13/15, go.sum 13/15, a core Go file 11/15, a cmd Go file 12/15, a testdata pack 9/15, an untracked new testdata file 9/15, openapi.json 8/15, docs/releasing.md 3/15.
- Each of these selects 7/15 (the three whole-tree steps,
build-pinnedand the three test steps): MAPPING-V2.md, a design wire json, a vector file, a vector deletion, a vector renamed intodocs/, a nested vector README, unit-tests.sh, build-pinned.sh. - tools/preparation-vectors selects 11/15. deploy/, README.md, AGENTS.md and a design
.mdselect 3/15. - The PR's selections I checked: core Go 11/15, testdata 9/15, openapi 8/15, releasing.md 3/15 and go.mod 13/15 all match.
check.sh --all --changed origin/main --skip <four release steps>was run on a stub manifest (each step runsecho, kept outside the clone) for 11 change kinds. In each, the steps that ran were exactly the selection minus the four release steps; nothing else was dropped. The push branch (--all --skip) ran all 11 non-release steps.- If changed_checks refuses,
check.shexits 2, so the job fails rather than passing silently.
ci.yml against templates/ci-check.yml
- Matches the template: the
env: EVENT/BASE_REFandif [ "$EVENT" = pull_request ]form, andfetch-depth: 0on the Runner checkout. workflow_callfrom release.yml carries the caller's push event, so it takes the--allbranch.- Unchanged: the "manifest parses" step, the
Release contentsjob andrelease.yml; there is no CI evidence file.
Public text
- No machine-local paths, personal names or organisations in
jpdev.json,ci.yml, AGENTS.md or the PR body. - AGENTS.md and CLAUDE.md are byte-identical. Commit is DCO-signed with the noreply author.
merge: yes
What
jpdev.json(new) holds achangedmapping. Each rule comes from what adev.jsonstep's command and the scripts it calls read. The reads were checked twice: by reading each command, script and test, and by recording every file opened under the clone's tracked directories during one fullcheck.sh --allrun, attributed to the step that was running..github/workflows/ci.yml, theRunner (<os>)jobs: the checkout takes the whole history (fetch-depth: 0). The Checks step runsscripts/dev/check.sh --all --changed "origin/$BASE_REF" --skip <the four release steps>onpull_request. Otherwise it runs the current--all --skip <the four release steps>, in the template'senv:/ifform. A push tomain, and the call fromrelease.ymlat a tag, still run the whole list. The job names, the "manifest parses" step, theRelease contentsjob (which always runs its four release steps), the triggers andrelease.ymlare unchanged. The repository has no.github/ci-evidence.json.AGENTS.md/CLAUDE.md("This repository"): a paragraph on the scoped pull-request run, the whole list onmain, the local command, thebuild-pinnedprerequisite and where the Go tests read outside their packages.--changedand--skipcombine as the vendored runner defines: the selection becomes the--onlyset, and--skipthen removes the release steps from it. Every rule names the three whole-tree steps, so a pull-request run is never empty.Inputs: step → paths read
git grep) except*.png,*.jpgand two files named inscripts/checks/local-paths.shAGENTS.md,CLAUDE.md,scripts/sync-agent-docs.shgit diff --checkagainst the empty tree).gofile (gofmt -lwalks each package directory, test data included);go.mod,go.sum(go list ./...);.gitignore(read during the go command's VCS lookup).gofile outside test data;go.mod,go.sumscripts/checks/build-pinned.sh(plus the pinned commits fetched over the network)scripts/checks/manual-gate.sh; the.gofiles ofinternal/runnerand its imports;go.mod,go.sum;internal/runner/testdata/**;docs/design/manual-admission-wire.json; the binariesbuild-pinnedwrites to.ci/binscripts/checks/unit-tests.sh; every.gofile (includinginternal/runner/testdata/async-mcp, which a test builds);go.mod,go.sum;internal/runner/testdata/**,internal/derivation/testdata/**,cmd/jpack-runner/testdata/**;vectors/**;openapi.json;docs/MAPPING-V2.md,docs/design/manual-admission-wire.json,docs/design/executor-ownership-boot.json;.gitignore; the.ci/binbinariesscripts/checks/chain-tests.sh; the.gofiles ofinternal/runner,cmd/jpack-runnerand their imports;go.mod,go.sum;internal/runner/testdata/**; the.ci/binbinariesopenapi.json.gofiles in the import graphs ofcmd/jpack-runnerandcmd/jpack-source-worker;go.mod,go.sum;.gitignorescripts/checks/release-toolchain.sh,.github/workflows/release.yml,go.mod(viago env GOVERSION)tools/third_party_notices.py,THIRD_PARTY_NOTICES; the.gofiles in./cmd/...'s import graph;go.mod,go.sum; the module cache and GOROOTtools/test_release_archives.py,tools/release_archives.py,go.mod(it builds a synthetic tree in a temporary directory)scripts/checks/release-programs.sh,.goreleaser.yml, the names undercmd/The trace found no file read that the mapping leaves uncovered. Its other events were directory listings: the go command's package walk over the module (
./,docs/,deploy/,scripts/,tools/,vectors/) and Python's import lookup intools/. A listing depends only on which files exist. A new.gofile selects every Go step through**/*.go, and a file in a new place is unmapped.The rules
local-paths,agent-docsanddiff-checkread the whole tree. They are in every rule rather than in one**rule, so an unmapped path still runs the whole list. Each rule below also selects those three.**/*.go,go.mod,go.sum→ go-fmt, go-vet, build-pinned, manual-gate, unit-tests, chain-tests, build, third-party-notices.go.mod,go.sum→ release-toolchain, release-archives (as well).cmd/**,internal/**,tools/preparation-vectors/**→ go-vet, build-pinned, manual-gate, unit-tests, chain-tests, build.cmd/**→ release-programs (as well).vectors/**,docs/MAPPING-V2.md,docs/design/*.json→ build-pinned, manual-gate, unit-tests, chain-tests.openapi.json→ openapi, build-pinned, manual-gate, unit-tests, chain-tests.scripts/checks/{build-pinned,manual-gate,unit-tests,chain-tests}.sh→ build-pinned, manual-gate, unit-tests, chain-tests.THIRD_PARTY_NOTICES,tools/third_party_notices.py→ third-party-notices.tools/release_archives.py,tools/test_release_archives.py→ release-archives..goreleaser.yml,scripts/checks/release-programs.sh→ release-programs.scripts/checks/release-toolchain.sh→ release-toolchain.*.md,docs/**,LICENSE,deploy/**,scripts/checks/local-paths.sh,scripts/sync-agent-docs.sh,scripts/dev/handover_check.sh→ the three whole-tree steps only.manual-gate,unit-testsandchain-testsrun against the binariesbuild-pinnedwrites to.ci/bin, which a fresh CI checkout does not have. So every rule that selects one of them selectsbuild-pinnedtoo.Mapped broad on purpose:
.gofile selects all the Go steps (andthird-party-notices), tests andtools/preparation-vectorsincluded.cmd/**andinternal/**, not onlytestdata/, selectsgo-vetandbuildas well as the test steps. That covers a future//go:embed.vectors/**,openapi.json,docs/MAPPING-V2.mdanddocs/design/*.jsonselectmanual-gateandchain-teststoo. The trace shows that the fixed test lists of those two steps read onlyinternal/runner/testdata/**,docs/design/manual-admission-wire.json(manual-gate) and Go files.go.modandgo.sumselectrelease-archives, although its test builds a synthetic module.Left unmapped on purpose (whole list):
.github/workflows/**:ci.ymlnames the toolchains, andrelease.ymlis read byrelease-toolchainand decides the release..gitattributesand.gitignore. The go command reads.gitignoreduring go-fmt, build and unit-tests.tools/*.pyor a nestedgo.modoutsidecmd/andinternal/.jpdev.json,dev.json,scripts/dev/check.shandscripts/dev/changed_checks.pyalways select the whole list. Every other tracked path matches a rule (checked againstgit ls-files), and everydev.jsonstep appears in at least one rule.Simulated pull requests (selection only, scratch copy)
Each case is one commit on top of this branch, run through
scripts/dev/changed_checks.py --base <branch head>. The count is out of 15 steps. In the CIRunnerjobs,--skipthen removes any of the four release steps, andRelease contentsruns those four on every pull request.internal/runner/workflow_read.go: 11 of 15. local-paths, agent-docs, diff-check, go-fmt, go-vet, build-pinned, manual-gate, unit-tests, chain-tests, build, third-party-notices. In the Runner jobs that is all 11 non-release steps.internal/runner/testdata/triage.pack.json: 9 of 15. local-paths, agent-docs, diff-check, go-vet, build-pinned, manual-gate, unit-tests, chain-tests, build.openapi.json: 8 of 15. local-paths, agent-docs, diff-check, openapi, build-pinned, manual-gate, unit-tests, chain-tests.docs/design/manual-admission-wire.jsonandvectors/preparation/README.mdeach select 7 (the same without openapi).docs/releasing.md: 3 of 15. local-paths, agent-docs, diff-check.README.mdselects the same three.go.mod: 13 of 15. Every step except openapi and release-programs.Other cases:
.goreleaser.ymlselects the whole-tree three plus release-programs;tools/test_release_archives.pyselects the three plus release-archives;.github/workflows/release.ymlselects the whole list.End to end, a docs-only commit run with the CI form (
check.sh --all --changed <base> --skip <release steps>) ran exactly local-paths, agent-docs and diff-check.Checks
scripts/dev/check.sh --all --changed origin/mainon this branch selected the whole list, becausejpdev.jsonchanged: 15 passed, 0 failed, 0 skipped, 0 not run (unit-tests 612 s). This is the run that was traced.🤖 Generated with Claude Code