Repository navigation
Stop stable releases from rewriting the community QR template - #8002
Conversation
Stable release prep now runs Changesets with bumpVersionsWithWorkspaceProtocolOnly, so a release no longer edits QR's plain npm range on @agent-native/core. That rewrite broke the lockfile and Dispatch's QR blob pins after every release, and the release-time pin rewrite would make the auto-merge guard refuse the next release PR. Snapshot releases keep the shared config, so their peer ranges still move to each snapshot. Remove the QR lock and pin sync script, resolve QR's Core from npm, and stop release prep with a frozen-lockfile check when a manifest and the lockfile disagree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Here's a visual recap of what changed: Open the full interactive recap |
[Medium impact] The PR appears safe to merge; no blocking issues were found. SummaryStable releases leave QR's plain Core range alone without changing snapshot release settings.
No actionable new issues were found in the changes since the previous review. No previous review threads were supplied.
|
Running the alias by hand still rewrote the QR template's Core range, so it now runs the stable wrapper and release prep reuses it. Snapshot jobs call `pnpm changeset version --snapshot` directly and keep the shared config. Regenerate the lockfile by re-resolving only QR's Core entry, so tsx keeps its existing esbuild resolution. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main gained two stable releases and #8046, whose QR pin verifier imported gitBlobSha from the sync script this branch deletes. The helper now lives in the verifier, and the release workflow tests import it from there. The lockfile starts from main's and re-resolves only the QR template's Core entry, as before, now at ^0.216.0. The consumed QR changeset stays deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep #8066's new list-release-pr-package-files import next to this branch's changeset-version-stable and check-changeset imports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: - scripts/package-release-workflow.test.ts: keep main's new release coordinator, version policy and required-check imports; drop the import from the removed sync-community-qr-core-lock.ts. - pnpm-lock.yaml: take main's lockfile, then re-resolve only QR's @agent-native/core (^0.219.0) from npm instead of the forced link: to packages/core, as this branch intends. pnpm pruned the published @agent-native/* versions nothing references. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Builder reviewed your changes — looks good ✅
Review Details
Incremental Code Review Summary
Reviewed the latest PR #8002 head. The lockfile now resolves the QR template’s Core dependency at 0.219.0, matching its declared ^0.219.0 range; the release wrapper and QR pin verifier otherwise remain unchanged. The stable-only Changesets override continues to separate the stable path from snapshot workflows.
One additional low-severity edge case was found in withStableChangesetConfig: the override write occurs before entering the try/finally, so a rejected or interrupted write is not covered by the restoration path and may leave the shared config truncated or modified. This is distinct from the previously noted SIGINT/SIGTERM-during-versioning and dropped-CLI-arguments concerns; those remain unchanged and are not resubmitted. No high- or medium-severity issues were identified. Standard-risk release tooling; browser testing is not applicable.
🧪 Browser testing: Skipped — PR only modifies release scripts/config/lockfile/tests, no UI impact.

Problem
Every stable release edits a file it shouldn't:
templates/community/qr/package.json, the QR app that Dispatch offers as a curated community install (#7924). Each edit broke something, and each fix added another step to release prep:@agent-native/corerange without updating the lockfile, sopnpm install --frozen-lockfilefailed on every PR. Sync community QR lock during release preparation #7967 fixed that by rewriting QR's lockfile entry during release prep.community-apps.spec.tsfailed, and Dispatch refused QR installs as an integrity failure. Refresh curated QR package hash #7975 repinned by hand and was overtaken by the next release; Fix stale QR template pin and refresh it on release #7978 now rewrites the pins during release prep.packages/dispatch/src/server/lib/community-apps.tsinto every release PR, andauto-merge-version-packages.ymlrefused those until ci: verify generated QR pin for release merges #8046 taught it to accept catalog changes that only repin QR to the release head's blobs. Stable releases are publishing again (chore: release packages (patch) [stable-release] [skip netlify] #8036, chore: release packages (patch) [stable-release] [skip netlify] #8045), but each one still edits QR's manifest, re-links its lockfile entry, and repins Dispatch, and the guard has to prove every repin.QR is the only workspace package with a regular dependency on an internal package through a plain npm range (
^0.219.0) instead ofworkspace:*, because its files get copied into other people's workspaces. Several packages declare plain peer ranges on Core, such as Dispatch's>=0.209.1; Safety and operations covers those. Changesets rewrites those ranges on every release, even for packages it otherwise skips: QR has noversionfield, yet Changesets still adds it to the release plan as anonerelease and updates its range. Addingqrtoignorewould not stop this, for the same reason.Approach
Stable releases stop rewriting plain ranges. With Changesets'
bumpVersionsWithWorkspaceProtocolOnlyon, a release only updatesworkspace:ranges and leaves QR's Core range alone. QR's range then moves only in a deliberate PR, and Dispatch's pin test already makes that PR refresh the pins too. Since releases no longer touch QR, the lockfile sync and the pin rewrite have nothing left to do, so this PR removes them. #8046's guards stay, and release PRs take their "catalog unchanged" path.The setting is on for stable release prep only. A small wrapper sets it in
.changeset/config.jsonfor thechangeset versionrun and restores the original file afterward, even when versioning fails. Turning it on repo-wide would break nightly and dev snapshots. Those rely on Changesets rewriting open peer ranges, such as Dispatch's>=0.209.1on Core, to the exact snapshot version, because a prerelease Core falls outside the open range. The published@agent-native/dispatch@nightlydeclares"@agent-native/core": "0.212.0-nightly-20261021093329".Release prep also fails closed now. After versioning, it runs
pnpm install --frozen-lockfile --lockfile-only --ignore-scripts. Release PRs are admin-merged without waiting for CI, so if a release ever leaves a manifest out of step with the lockfile again, release prep stops before it opens the PR instead of merging a lockfile that breaks every install.What changed
scripts/changeset-version-stable.ts(new): runschangeset versionwith the stable override and restores the config.package.json:changeset:versionnow runs the wrapper, so running it by hand can't rewrite QR either.changeset:release-versionruns it, compacts changelogs, then runs the frozen-lockfile check.scripts/sync-community-qr-core-lock.tsand its tests: removed.scripts/verify-community-qr-release-pin.ts:gitBlobSha, the one helper ci: verify generated QR pin for release merges #8046's verifier imported from the removed script, now lives here.pnpm-lock.yaml: QR now resolves@agent-native/core@0.219.0from npm instead of a forcedlink:to the in-repo package, which is how pnpm resolves a plain range here by default. Only QR's Core entry was re-resolved. pnpm also pruned old published@agent-native/*versions that nothing referenced (Core 0.210.2 and 0.212.0 with their agentkit, core-corpus, and recap-cli versions).scripts/package-release-workflow.test.ts: three new tests, listed under Verification, and an assertion thatchangeset:versionruns the wrapper.Safety and operations
>=0.209.1on Core, are all open>=ranges that the next patch, minor, or major bump still satisfies, so stable releases never rewrote them and nothing changes for them. A future closed peer range, such as^0.219.0, would stop moving with stable releases and would need a hand update.changeset version --snapshotdirectly with the shared config. Nightly publishes were failing onmainfor a related reason: snapshot versioning rewrites QR's range to the unpublished snapshot, and the lockfile refresh can't find it on npm. Unblock nightly publishes that fail on the community QR template #8006 fixed that separately and has merged; this branch includes it.^0.219.0stops matching at 0.220), so someone needs to bump it, together with the pins, from time to time. Installs already receive only the last reviewed files.pnpm changeset:versionrun by hand can leave the override in the working tree, wheregit statusshows it. If it were ever committed into a release PR, the auto-merge guard would refuse that PR, because.changeset/config.jsonisn't on its list.Verification
pnpm test:package-release-workflowplusscripts/ci-change-scope.test.ts, after mergingmainat 845e327 (which includes Unblock nightly publishes that fail on the community QR template #8006): 184 of 189 passed. The 5 failures are the tests that put an extensionlessghstub onPATH: Fix paginated release PR file verification #8066's "runs both release verifier CLIs through the shared file request" and four that arrived frommain(two required-check tests, a coordinator test, and the versionless-manifest CLI test). They fail only on Windows, wheregh.exewins over the stub and the test reaches the real API. CI runs them on Linux. The new tests show that:nonerelease without the override. With the override removed from the wrapper, this test fails.mainat 0de9529, with a real release changeset): exit 0. A pending Toolkit minor carries Core 0.216.0 → 0.217.0 through the fixed group, so this is the case where QR's^0.216.0stops matching Core. QR's manifest, Dispatch's pins, the Changesets config, and the lockfile were unchanged, the frozen-lockfile check passed, and ci: verify generated QR pin for release merges #8046'sassertReleaseOnlyPullRequestFilesaccepted all 46 changed paths. Because neither the catalog nor QR's manifest changed, the QR pin verifier would report the catalog unchanged. Not rerun after the later merges ofmain: they moved QR's lockfile entry from npm Core 0.216.0 to 0.219.0, resolved the same way, andpnpm install --frozen-lockfile --lockfile-onlypasses at the PR head.main): with QR's manifest out of step with the lockfile, release prep exits 1 withERR_PNPM_OUTDATED_LOCKFILEand restores the config.main,pnpm --filter qr typecheckpassed against npm Core 0.214.0, with QR's action spec (4) andcommunity-apps.spec.ts(17) passing. CI reruns QR's typecheck against 0.219.0, because the lockfile changed.mainafter Fix the reaped-run tracking spec's db mock on main #8120 fixed the reaped-run tracking spec that failed Fast tests onmain.Review focus
.changeset/config.jsonfor the length of one command, rather than a repo-wide setting: is restoring it infinallyenough, and is there a snapshot or release path that versions without going through the shared config?Follow-ups
main, so a deliberate QR change still invalidates the pins in Dispatch builds already deployed. Pinning the catalog to a commit would fix that; the loader accepts onlymaintoday.🤖 Generated with Claude Code