Measured by the os-dev merge round on #17080 (PR #18889) and handed to the seat to file — devs do not POST /issues. ⭐ The round measured this as pre-existing rather than assuming it was its own, and then found the one thing about it that is new.
The defect
At publish time spec-changes.json's aggregate.added / aggregate.removed carry a ONE-RELEASE slice — every entry attributed since: PROTOCOL_MAJOR / removedIn: PROTOCOL_MAJOR — under the from: 10, to: 17 aggregate record, while perMajor[16→17].added/removed stay 0 / 0.
⇒ a consumer reading aggregate.added reads 386 exports labelled at major resolution that really arrived in one minor.
Measured on real artifacts at PR #18889's head: the aggregate and the per-release section carry identical numbers (386 / 302) under from: 10, to: 17, while perMajor[16→17] stays 0/0.
⛔ NOT PR #18889's to fix — measured in two legs, not argued
| leg |
what ran |
result |
| A |
HEAD generator, --previous-package |
aggregate.added = 1 (.: ALL_CONVERSIONS (const), since: 17), aggregate.removed = 1 (removedIn: 17), perMajor[16→17] 0/0 |
| B |
merge-base generator (verified on disk to contain 0 occurrences of --previous-package), invoked the way the release lane already invoked it, --previous-surface |
aggregate.added and aggregate.removed BYTE-IDENTICAL to leg A; perMajor identical; the aggregate record identical on from/to/added/removed |
The only difference between the two outputs is the presence of the new release section. ⇒ the computation is pre-existing; #18889 inherits it.
Root cause is one line that PR does not change: PREV_SURFACE is set whenever --previous-package is, so surfaceDiff = PREV_SURFACE ? diffSurfaces(PREV_SURFACE) : {} and composeSpecChanges(MIGRATION_SUPPORT_FLOOR, PROTOCOL_MAJOR, surfaceDiff) run exactly as before — attributing a one-release slice since: PROTOCOL_MAJOR under the 10 → 17 record, while perMajor gets no surfaceDiff at all.
⭐ But the REACH is new, and that is why this is filed now rather than whenever
The computation is pre-existing. The DISTRIBUTION changed.
⇒ content and labelling unchanged and pre-existing; reach is new. ⚠️ The seat's position, recorded so it can be overturned: this does not block #18889, because the content is unchanged and the honest per-release section it adds is gated by a correctness gate that the aggregate is not. But it does move this from 「a wart on a Release-page asset」 to 「a machine-readable surface in node_modules that does not say what it means」, which is class (b): 「Machine-readable surfaces must not lie」.
What this card does NOT claim
- ⛔ No remedy prescribed. Several shapes exist — gate the aggregate arrays the way
release.* is gated; stop filling them when --previous-package is the input; or relabel them at the resolution they actually carry. They trade differently against what already consumes the Release-page asset, which was ⛔ not surveyed.
- ⛔ Not measured: who reads
aggregate.added today. If the answer is nobody, the cheapest honest fix may be to stop emitting it rather than to gate it.
- ⛔ Not measured: whether the same mislabelling reaches any other field of the aggregate record.
Dedupe words: aggregate.added major resolution, previous-surface one-release slice, spec-changes.json aggregate mislabelled, perMajor added removed zero, release asset vs npm tarball reach.
Generated by Claude Code
Measured by the
os-devmerge round on #17080 (PR #18889) and handed to the seat to file — devs do notPOST /issues. ⭐ The round measured this as pre-existing rather than assuming it was its own, and then found the one thing about it that is new.The defect
At publish time
spec-changes.json'saggregate.added/aggregate.removedcarry a ONE-RELEASE slice — every entry attributedsince: PROTOCOL_MAJOR/removedIn: PROTOCOL_MAJOR— under thefrom: 10, to: 17aggregate record, whileperMajor[16→17].added/removedstay 0 / 0.⇒ a consumer reading
aggregate.addedreads 386 exports labelled at major resolution that really arrived in one minor.Measured on real artifacts at PR #18889's head: the aggregate and the per-release section carry identical numbers (386 / 302) under
from: 10, to: 17, whileperMajor[16→17]stays 0/0.⛔ NOT PR #18889's to fix — measured in two legs, not argued
--previous-packageaggregate.added= 1 (.: ALL_CONVERSIONS (const),since: 17),aggregate.removed= 1 (removedIn: 17),perMajor[16→17]0/0--previous-package), invoked the way the release lane already invoked it,--previous-surfaceaggregate.addedandaggregate.removedBYTE-IDENTICAL to leg A;perMajoridentical; the aggregate record identical on from/to/added/removedThe only difference between the two outputs is the presence of the new
releasesection. ⇒ the computation is pre-existing; #18889 inherits it.Root cause is one line that PR does not change:
PREV_SURFACEis set whenever--previous-packageis, sosurfaceDiff = PREV_SURFACE ? diffSurfaces(PREV_SURFACE) : {}andcomposeSpecChanges(MIGRATION_SUPPORT_FLOOR, PROTOCOL_MAJOR, surfaceDiff)run exactly as before — attributing a one-release slicesince: PROTOCOL_MAJORunder the 10 → 17 record, whileperMajorgets nosurfaceDiffat all.⭐ But the REACH is new, and that is why this is filed now rather than whenever
The computation is pre-existing. The DISTRIBUTION changed.
release-spec-changes.shran post-publish (attach only), so the mislabelled aggregate reached only the GitHub Release asset.--prepareruns beforechangeset publish, so the same already-mislabelled arrays now also ship inside the npm tarball — wherenode_modulestooling reads them.⇒ content and labelling unchanged and pre-existing; reach is new.⚠️ The seat's position, recorded so it can be overturned: this does not block #18889, because the content is unchanged and the honest per-release section it adds is gated by a correctness gate that the aggregate is not. But it does move this from 「a wart on a Release-page asset」 to 「a machine-readable surface in
node_modulesthat does not say what it means」, which is class (b): 「Machine-readable surfaces must not lie」.What this card does NOT claim
release.*is gated; stop filling them when--previous-packageis the input; or relabel them at the resolution they actually carry. They trade differently against what already consumes the Release-page asset, which was ⛔ not surveyed.aggregate.addedtoday. If the answer is nobody, the cheapest honest fix may be to stop emitting it rather than to gate it.Dedupe words:
aggregate.added major resolution,previous-surface one-release slice,spec-changes.json aggregate mislabelled,perMajor added removed zero,release asset vs npm tarball reach.Generated by Claude Code