cmux-next: a pull request carries only the generated files it caused

Merged
TE
17d ago
+322-6

The PR autofix now pushes only what a pull request owns, and a new generated drift check fails a PR that carries a generated file it didn't cause. Part of #21946.

Leo's question was why we keep hitting reds and conflicts in generated files. Most of them come from the bots: the PR autofix formatted base files and regenerated exports against a newer base, then committed all of it into whichever PR it was repairing. Those copies conflicted with every other PR, and a later merge could silently drop the base's newer rows. The click-through lane saw both on #21729 and #21272: CmuxNextChromiumWarmup vanished from ci-target-graph.json, and vp fmt rewrote replyHref.ts and links.ts.

Change

scripts/cmux-next/generated_outputs.py is a table that maps each committed generated output to the inputs it's made from.

  • Autofix push. pr-autofix-apply.sh --changed FILE keeps the PR's own files and the outputs whose inputs the PR changed. Everything else is left out with a dropped: line. The push job reads the PR's changed files from the files API, not from the artifact.
  • generated drift job. A Linux job in cmux-next-pr-autofix.yml runs the base's copy of the table on the files API's list. It fails with an ::error:: per file, naming the generator and the fix: git checkout origin/feat-cmux-next -- PATH. The base autofix regenerates every output after each merge. The generated-drift-ok label skips the check.

Measured on all 259 open PRs (diff against merge base)

  • The first version of the table flagged 10 PRs. Checking them found two false positives:
    • Settings declared in CmuxNextDesign (#20175, #20430) do change the settings exports, so every CmuxNext source now counts as an input.
    • ci-target-graph.json records the repo paths that test sources name, so test sources count as inputs to the graph.
  • With those fixes the check flags 2 PRs: #21160 (schemas/defaults/cmux-next.json with no Swift change) and #22004 (ci-target-graph.json with no Package.swift or test change).
  • Limit: a PR that touches any CmuxNext test file still gets its graph copy treated as its own. The next PR makes the graph CI output, which removes this case.

Verification

  • scripts/cmux-next/tests/generated-ownership.test.sh was committed red first: the module and the --changed option didn't exist. It passes at the head. It's registered in cmux-next.yml next to pr-autofix.test.sh.
  • pr-autofix.test.sh passes, and actionlint is clean on both workflows.

Workflow files change here. Leo waived Lawrence's code-owner sign-off for the deconflict work, and Lawrence's coordinator was told.

Changelog

none

šŸ¤– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Pull requests now carry only the generated files their own changes caused: the PR autofix push leaves out repairs of files the PR did not change or outputs whose inputs it did not change, and a new generated drift job fails a PR that changes a generated output without its inputs.

Ownership

  • scripts/cmux-next/generated_outputs.py maps each committed generated output to the inputs it is made from, covering every output kind the autofix may push, including Java SDK sources and the namespace ratchet.
  • The push reports each left-out path with a dropped: line, and the autofix commit lists the files it actually pushes.
  • generated drift runs the base's copy of the table on the files API's list and fails per file with the fix (git checkout origin/feat-cmux-next -- PATH); the generated-drift-ok label skips the check from the next push.
  • A PR that touches any CmuxNext test file still counts as causing the graph; the next PR makes the graph CI output, which removes this case.

Measured

  • On all 259 open PRs the check flags 2 (#21160, #22004); two false positives were fixed first: a setting declared in CmuxNextDesign changes the settings exports, and test sources name the graph's paths.