fix(sync): keep a real per-tuple floor when canonical gains a clause - #4
Merged
Merged
Conversation
targetRange() returned canonical as soon as the clause counts differed, which was safe only while canonical never changed length. Adding the 0.1.6-0 clause changed exactly that: a repo declaring '>=0.1.2-rc.1 <0.2.0 || >=0.1.5-rc.1 <0.2.0' (a genuinely higher 0.1.5 floor) was silently rewritten down to canonical's >=0.1.5-alpha.1, and a single-clause '>=0.1.5-rc.1 <0.2.0' lost its floor the same way. Clauses now pair by [major, minor, patch] tuple when the counts differ, so the higher floor survives while the new clause is added. Tests cover both shapes and the end-to-end fixture exercises the merge instead of the raised-floor bypass. data/peer-range.json documents why the third clause uses a -0 floor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
targetRange()returned the canonical range as soon as the clause counts differed:That was harmless only while canonical never changed length — and #2 added the
0.1.6-0clause, which is exactly a length change. From that commit on, the sync tool silently downgrades any repository whose declared range has a different clause count while carrying a genuinely higher floor:>=0.1.2-rc.1 <0.2.0 || >=0.1.5-rc.1 <0.2.0>=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0 || >=0.1.6-0 <0.2.0— the0.1.5-rc.1floor is lost0.1.5-rc.1>=0.1.5-rc.1 <0.2.00.1.5-rc.1This matters more than a normal edge case because
--writeis the tool the whole ecosystem is re-pinned with: running it would quietly walk real per-package floors backwards.Fix. When the counts match, keep the pairwise merge as before. When they differ, pair clauses by
[major, minor, patch]tuple instead, so a higher floor in a shared tuple survives while the new clause is added; a current clause whose tuple canonical does not carry is preserved only when its floor is above every canonical floor (a real requirement), and anything below is still raised to canonical (drift-low).Tests.
test/sync-peer-range.test.mjsgains the two-clause and single-clause merge cases, and the end-to-end fixture now exercises the merge (it previously used a floor raised above canonical so the old bypass never ran).test/check-peer-range-latest.test.mjs'sCANONICALconstant is updated to the three-clause shape and the "future tuple" assertion moves to0.1.7-rc.1, so the tripwire test still tests what it says.Data note.
data/peer-range.jsonnow records why the third clause uses a-0floor (it admits every0.1.6prerelease, including0.1.6-alpha.2) rather than the bare>=0.1.6form the tripwire warns about.Not in this PR — the
compat.ymlre-anchor. The workflow change (weekly0 4 * * 1+pull_requestinstead of monthly; pin@deepseek-ai/dsh@0.1.6-alpha.2,dsh-base/dsh-headless@0.1.6-alpha.2;minimumReleaseAge: 0in the scratch profile; keeping #1's 25-minute cap) cannot be pushed with the token this branch was prepared with — GitHub rejects any push touching.github/workflows/*without theworkflowscope. The ready-to-apply patch is kept outside the repository and will be applied separately.Gate on this branch:
pnpm run build✓ ·pnpm run typecheck✓ ·pnpm test66 passed / 9 files ✓ ·verify-self-contained✓ ·verify-artifacts✓.