You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: RELEASING.md
+42-3Lines changed: 42 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,15 +29,54 @@ pnpm strips `scripts` from the packed manifest, so the published package carries
29
29
30
30
| Registry | Job | Packages | Credential |
31
31
| --- | --- | --- | --- |
32
-
| GitHub Packages |`publish`| all five|`secrets.GITHUB_TOKEN`, `packages: write`|
33
-
| public npm |`publish-npm`| the closure of the wrapper + the two harness roots — all five today |`secrets.NPM_TOKEN`, `id-token: write` for provenance |
32
+
| GitHub Packages |`publish`| all six|`secrets.GITHUB_TOKEN`, `packages: write`|
33
+
| public npm |`publish-npm`| the closure of the wrapper + the two harness roots + the wrapper's `optionalDependency`— all six today |`secrets.NPM_TOKEN`, `id-token: write` for provenance |
34
34
35
35
Neither registry is chosen on a command line. `--registry` sets only `registries.default`, and both
36
36
pnpm and npm consult the **scope** binding first — a committed `@yanlinglabs:registry` line would
37
37
therefore beat it, which is why the project `.npmrc` pins nothing. Each job binds its own scope *and*
38
38
credential with `actions/setup-node` (`registry-url` + `scope`), and
39
39
`scripts/publish-routing.test.ts` proves the routing with real `npm publish --dry-run` runs.
40
40
41
+
## The darwin-arm64 platform package (P9a-3/P9a-4)
42
+
43
+
`@yanlinglabs/winter-agent-sdk-darwin-arm64` ships the compiled `winter` runtime binary — the
44
+
artifact the wrapper spawns — as an `optionalDependency` of `@yanlinglabs/winter-agent-sdk`. It is
45
+
bin-only: no `main`, no `types`, no `exports` at all, just `bin: { winter: "bin/winter" }`, gated on
46
+
`os: ["darwin"]` / `cpu: ["arm64"]` so a package manager that honours those fields (npm; `bun install`
47
+
partially — see below) simply does not fetch it on any other platform.
48
+
49
+
**Built ONLY on a macOS `arm64` runner.**`bun build --compile` targets the CURRENT host — it does not
50
+
cross-compile — so a `build-platform` job (`runs-on: macos-15`) exists in BOTH workflows: `ci.yml`
51
+
runs it on every push (no tag pin, and it runs the smoke's real EXECUTE path —
52
+
`smoke-installed.ts --runtime=bun` actually spawns the just-built binary, since `os`/`cpu` match on
53
+
that runner) so a broken darwin build fails long before a tag exists; `release.yml` runs the same
54
+
build, additionally checks the binary's own `--version` against the pushed tag, tars it (GitHub
55
+
Actions artifact uploads drop the executable bit, which is exactly why this matters), and uploads it
56
+
as one artifact. Both jobs assert `uname -s`/`uname -m` themselves rather than trusting the `macos-15`
57
+
label.
58
+
59
+
**Both publish jobs `needs: build-platform`, download that ONE artifact, and restore + verify it —
60
+
`chmod +x`, `test -x`, `file` reports `Mach-O 64-bit executable arm64`, `shasum -a 256 -c` against the
61
+
recorded checksum — BEFORE their own version-tag gate and BEFORE the publish step.** Neither job
62
+
rebuilds the binary itself: they ship exactly what `build-platform` produced.
63
+
64
+
**Locally**, `bun run build:runtime --platform-package` (or `bun run scripts/build-runtime.ts
65
+
--platform-package`) stages `packages/platform/darwin-arm64/bin/winter` — git-ignored, built on
66
+
demand, never committed. `scripts/release-pack.ts` HARD-FAILS a pack attempted on a matching host
67
+
(`darwin`/`arm64`) with that file missing, naming the exact command to run first; on a non-matching
68
+
host (e.g. this repo's own `ubuntu-latest``pack-smoke` jobs) the same absence is expected and
69
+
tolerated — a package manager on Linux was never going to fetch this binary either.
70
+
71
+
**The smoke (`scripts/smoke-installed.ts`) treats a bin-only package differently from an importable
72
+
one**: it executes `<bin> --version` and compares it to the package's own `version` when `os`/`cpu`
73
+
match the current host, and prints an explicit `SKIP … (bin-only; os/cpu mismatch on …)` line
74
+
otherwise — never a silent no-op, and never an import attempt that would fail for the wrong reason.
75
+
76
+
A Norma consumer (`packages/core`) resolves this package via `createRequire(...).resolve` and never
77
+
needs `dist/winter` built from an SDK checkout once it installs from a real release —
78
+
see that repo's `runtime-sdk/executable.ts` and P9a-8/P9a-9.
79
+
41
80
The npm set is **data** (`winter.publish.npm` per manifest), asserted to equal the transitive
42
81
workspace `dependencies` closure of the ROOTS: the wrapper, plus every package flagged
43
82
`winter.publish.harness` (R-7b-5 — the two conformance harnesses, which the out-of-repo router
@@ -101,7 +140,7 @@ English, and a regex over English is a heuristic:
101
140
Round 4 narrowed the negation skip to the matched clause and accepts unbackticked `src/`, which closes
102
141
the two evasions the review demonstrated. The class remains: these gates catch the mistakes people
103
142
actually make (a stale sentence surviving a rewrite) and cannot prove a README is true. **When you
104
-
change what ships, re-read the five package READMEs** — the gate is a net, not a proof.
143
+
change what ships, re-read the six package READMEs** — the gate is a net, not a proof.
0 commit comments