Bump uuid, gate publishes per-registry, and stop Go caching the corpus - #194
Merged
Conversation
Three unrelated-but-small fixes from a cross-repo sweep. uuid 9.0.1 -> 11.1.1. The advisory (missing buffer bounds check in v3/v5/v6 when `buf` is provided) is NOT reachable: logger calls `v4()` with no arguments and never v3/v5/v6. But every consumer inherits the advisory and has to carry its own pnpm.overrides pin — config already did — so fixing it at the source is cheaper than N overrides. @types/uuid removed; uuid 11 ships its own types. Publish steps no longer gate on `steps.changesets.outputs.published`. That output is true only when the publish command shipped something IN THAT RUN, so a run that died after npm left the other four registries behind — and the next run, with no changesets left, reported published=false, skipped all four, and went GREEN having published nothing. Not theoretical: 4.5.1 and 4.5.2 stranded crates.io, NuGet and the Go tag at 4.5.0 exactly this way today, across runs that looked fine. Each step now asks its own registry whether the version is already there, so a partial release heals on re-run instead of being reported as a success. The lookup fails TOWARD publishing: a garbled or failed response counts as "behind". Every path below it is duplicate-tolerant (NuGet `--skip-duplicate`) or version-guarded (the Go tag), so a redundant attempt is cheap while a skipped one loses a release. Verified against the live registries at 4.5.3 (pypi/crates/ go-tag correctly not-behind), at a fake 9.9.9 (all behind), and on an empty response (behind). go:test gains -count=1. Go currently declines to cache parity_corpus_test.go because it reads ../parity-corpus.json from outside the package dir — confirmed with a positive control: an in-package test reports "(cached)" on re-run while the corpus test never does. So the #183 corpus positive control was valid. But a five-language parity guarantee should not rest on that behaviour. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
🦋 Changeset detectedLatest commit: 40b3a97 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Caught by the format:check this PR's sibling added — my local run predated writing the file. Working as intended. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
Caught before merge: the changesets action leaves the workspace checked out on the version branch, so in a run that only OPENS the version PR, package.json is already bumped to a version nothing has published. The lag check would have read that bumped version, found every registry "behind", and shipped PyPI/crates.io/ NuGet/Go-tag ahead of npm from an unmerged branch. The old `published == 'true'` gate happened to prevent that; my replacement did not. npm is now the explicit source of truth: if npm does not have this version, there is nothing to backfill and all four steps skip. If npm does have it — either because ci:publish just shipped it, or because an earlier run did — each registry is asked individually. That keeps the original fix (a partial release heals on re-run) without ever publishing ahead of npm. Verified both directions: 4.5.3 -> npm has it, proceed; 9.9.9 -> npm lacks it, skip all four. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
brentrager
added a commit
that referenced
this pull request
Aug 20, 2026
) #194 made each registry publish gate on "does npm already serve this version", to stop a mid-run failure silently stranding four registries. It reintroduced the same failure through a different door: npm registry READS are eventually consistent, so `npm view @smooai/logger@4.5.4` moments after a successful publish still 404s. The gate concluded "not released", skipped PyPI, crates.io, the Go tag and NuGet, and the run went green — leaving 4.5.4 on npm alone. Two independent signals now count as released, because neither alone is enough: - changesets published it in THIS run (steps.changesets.outputs.published). Authoritative the instant it happens, no registry read involved. This is the normal path and the one the race broke. - npm already serves it. The backfill path, which is what lets a re-run catch up registries an earlier run left behind — the whole point of #194. Only when neither holds do the four steps skip, which is correct: that is a run that merely opened the version PR, where package.json is bumped to something nothing has published and the workspace sits on an unmerged branch. Deliberately NO changeset. With package.json staying at 4.5.4, merging this takes the backfill path and ships 4.5.4 to the four registries it is missing from. A changeset would bump to 4.5.5 and strand 4.5.4 permanently. Verified all three states by hand: published-this-run -> proceed even while npm 404s; npm-serves-it -> proceed; unreleased 9.9.9 -> skip all four. Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Three small fixes from a cross-repo sweep, plus a verified negative on the stream question (below).
1.
uuid9.0.1 → 11.1.1Advisory: moderate, missing buffer bounds check in v3/v5/v6 when
bufis provided, patched in>=11.1.1.Not reachable here. Logger's only call sites are
uuidv4()with no arguments (src/Logger.ts:189,:573); v3/v5/v6 are never imported and nobufis ever passed. But the advisory propagates to every consumer —@smooai/configtraced it through three separate paths into its tree and had to add apnpm.overridespin. Fixing it at the source is cheaper than N overrides.@types/uuiddropped; uuid 11 ships its own types.2. Publish steps gate on the registry, not on npm's success
That output is true only when the publish command shipped something in that run. So a run that dies after npm leaves the other four behind — and the next run, with no changesets left, reports
published=false, skips all four, and goes green having published nothing.This happened here today. 4.5.1 and 4.5.2 reached npm and PyPI while crates.io, NuGet and the Go tag sat at 4.5.0, across runs that reported success. It only got caught because I compared the live registries by hand.
Each step now asks its own registry whether the version is already there:
Side benefit: a re-run now heals a partial release instead of skipping it.
The lookup fails toward publishing — a garbled or failed response counts as "behind". Every path below is duplicate-tolerant (
--skip-duplicateon NuGet) or version-guarded (the Go tag), so a redundant attempt is cheap while a skipped one loses a release.Verified against the live registries:
¹ NuGet accepted the 4.5.3 push (HTTP 201, both
.nupkgand.snupkg) but its flat-container index still 404s ~50 min later — nuget.org validation latency, not a failure. This is precisely the case--skip-duplicateplus fail-toward-publish handles gracefully.3.
go:testgains-count=1Go's test cache does not invalidate on fixtures read from outside the package dir, and
go/parity_corpus_test.goreads../parity-corpus.json.I checked before changing anything, and Go is currently safe — it refuses to cache that test at all. Positive control:
I also re-ran the #183 corpus positive control: corrupting the placeholder still fails Go. So the Go half of that corpus proved what it claimed.
-count=1costs nothing and means a five-language parity guarantee no longer rests on that behaviour.Verified negative: no single-
read()and no hand-rolled stream mocksChecked all five languages for the
@smooai/filedefect class. Logger is clean, and structurally so — it is a log producer; it never consumes a stream. There is noread(),ReadAll,read_to_end, or.Read(anywhere in any port (the.read()grep hits are iterator.next()andRwLock::read()).Every write path uses a loop-until-done primitive:
process.stdout.write+ therotating-file-streamlibrary — Node buffers, never truncatesRotatingFileHandler/TimedRotatingFileHandler,sys.stdout.writewrite_allin both places (logger.rs:449,rotation.rs:87) — never barewriteio.WriteString;rotation.go:100usesos.File.Write, whose contract returns a non-nil error whenn != len(b), and the code checks itFileStream.Write(bytes, 0, bytes.Length)— writes all or throwsAnd no hand-rolled stream mocks. Every test writer is the real runtime type: Go
bytes.Buffer(io.Writer), .NETStringWriter(TextWriter), Pythonio.StringIO, Rusttempfile::tempdir(real files). There is novi.mockin the TS suite at all —CapturingLoggeroverrides the logger's own declaredlogFunchook, which is not a stream. The onlyMagicMockis a Lambda context object.🤖 Generated with Claude Code
https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC