From 09e1ade157edbf9b1ef9ecd4e799b529881a8878 Mon Sep 17 00:00:00 2001 From: Julian Matschinske Date: Sun, 11 Oct 2026 21:40:50 +0200 Subject: [PATCH 1/2] ci: the mirror readback unwraps npm 12.2's one-element dist array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit npm 12.2 prints `view dist --json` as [{integrity,…}], so run 38168865821 read dist.integrity as undefined and failed after a correct publish (its retained readback shows the exact bytes and integrity). Unwrap exactly one entry; any other shape fails. Tested on that run's real artifacts. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/mirror-private-scope.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mirror-private-scope.yml b/.github/workflows/mirror-private-scope.yml index 14f7e0f..aea89f3 100644 --- a/.github/workflows/mirror-private-scope.yml +++ b/.github/workflows/mirror-private-scope.yml @@ -127,7 +127,10 @@ jobs: const { EXPECTED_SHA512, MIRROR_SHA256, RUNNER_TEMP, PACKAGE, VERSION } = process.env; const fail = message => { console.error(message); process.exit(1); }; const directory = `${RUNNER_TEMP}/mirror/readback`; - const dist = JSON.parse(readFileSync(`${directory}/packument-dist.json`, 'utf8')); + // npm 12.2 prints `view dist --json` as a one-element array. + const viewed = JSON.parse(readFileSync(`${directory}/packument-dist.json`, 'utf8')); + if (Array.isArray(viewed) && viewed.length !== 1) fail('Expected one packument dist entry'); + const dist = Array.isArray(viewed) ? viewed[0] : viewed; const files = readdirSync(directory).filter(name => name.endsWith('.tgz')); if (files.length !== 1) fail('Expected exactly one tarball read back'); const bytes = readFileSync(`${directory}/${files[0]}`); From f1fa84f2eb8408754c648f27f9bbd60caab1bf99 Mon Sep 17 00:00:00 2001 From: Julian Matschinske Date: Sun, 11 Oct 2026 21:49:40 +0200 Subject: [PATCH 2/2] docs: a mirror package's first publication is public; it was set private before any grant GitHub Packages gave both new mirror packages their public source repository's visibility despite --access=restricted; the service desk set them private before any consumer Read grant (Chief 14b66f77). Later versions keep the settings. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/mirror-private-scope.yml | 2 ++ RELEASING.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mirror-private-scope.yml b/.github/workflows/mirror-private-scope.yml index aea89f3..d3f5311 100644 --- a/.github/workflows/mirror-private-scope.yml +++ b/.github/workflows/mirror-private-scope.yml @@ -6,6 +6,8 @@ name: Mirror released bytes into the private scope # exactly the released tarball, verified against the integrity every lock pins, and nothing else. # Written while this repository's owner was offline, under the operator's service-matrix alignment # instruction (platform Chief decision 08858c6a); the owner may keep, change or remove it. +# A package's first publication from this public repository is public on GitHub Packages whatever +# --access says: make it private before granting consumers Read. Later versions keep its settings. on: workflow_dispatch: diff --git a/RELEASING.md b/RELEASING.md index 5d69b40..9abd513 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -5,7 +5,7 @@ One root `vX.Y.Z` tag versions the Go module and TypeScript package together. bi - Go module: `github.com/Bitspark/bitruntime`, packages `core/go`, `websocket/go` and `hydrated/go`. - TypeScript package: `@bitspark/bitruntime`, subpaths `/core`, `/websocket` and `/hydrated`. - TypeScript distribution: GitHub release asset `bitspark-bitruntime-.tgz`, covered by `SHA256SUMS`. This is an npm-compatible tarball, not a registry publication. URL installs with npm 12 require `--allow-remote=root`. -- Private-scope mirror: the released asset is also mirrored, byte for byte, into the private `@bitspark` scope on GitHub Packages, for Bitspark's private consumers whose `@bitspark` scope resolves there (`.github/workflows/mirror-private-scope.yml`). The public distribution above is unchanged. +- Private-scope mirror: the released asset is also mirrored, byte for byte, into the private `@bitspark` scope on GitHub Packages, for Bitspark's private consumers whose `@bitspark` scope resolves there (`.github/workflows/mirror-private-scope.yml`). The public distribution above is unchanged. The mirror package is private: its first publication from this public repository was public on GitHub Packages despite `--access=restricted`, and was set private before any consumer was granted Read. Later versions keep the package's settings. Before tagging, land a reviewed green PR on main. CI requires Go formatting/vet/race tests, TypeScript checking/build/tests, bitwire conformance observations, a fresh installed package consumer, and Go/TypeScript WebSocket and hydrated interoperability. Run the same checks locally where supported. Confirm bitwire's exact dependency release is publicly installable, with no file dependencies, module replacements or private registries. Run `node scripts/go-smoke.mjs ` before tagging.