Metadata
| Status | open ‖ paused |
|---|---|
| Created | 2026-07-25T20:57:03.480428743+00:00 |
| Started | 2026-07-26T07:15:47.316250667+00:00 |
| Completed | 2026-07-26T07:16:15.731838049+00:00 |
| Tags | release, npm, distribution, ci |
| Tokens | 0 in / 0 out |
Description
Objective
Add npm as a third distribution channel onto the SAME attested GitHub-Release binaries (not a parallel build). The recommended shape is the industry-standard per-platform optionalDependencies driver pattern (Shape A): one small JS driver package + N platform subpackages, each holding one prebuilt binary. This reaches the no-Rust-toolchain majority (Node is ubiquitous) without weakening any property of the existing channels.
Context: docs/studies/wg-npm-distribution-design.md §5 (Shape A decision + the canonical driver shim), §6.5 (embed the manifest for offline SHA256), §8.3 (the CI npm-publish job), §10.1 (the minimum viable launch). docs/studies/roadmap-rate-limit-and-distribution.md §1/§4(T7). Depends on T6 for file-safety (both edit .github/workflows/release.yml); also means T7 repackages SIGNED binaries.
What to build
- New
npm-publishjob in.github/workflows/release.yml(needs: [plan, assemble], runs only whenpublish == 'true', i.e. on a realv*tag not a dry run), onubuntu-22.04(it only repackages + publishes, no compiling):gh release download <tag>each archive (or reuse theassemblejob uploaded artifacts).- Verify each archive Sigstore attestation:
gh attestation verify <archive> --repo graphwork/wg. - Verify each archive SHA256 against
release-manifest.json. - Extract
wg/nexfrom each archive into a platform package dir with theos/cpu/libcpackage.json, LICENSE, and a copy ofrelease-manifest.json. - For the driver package: set
version+ all fiveoptionalDependenciesversions to the release version; copy thebin/wg.js+bin/nex.jsshims; embedrelease-manifest.json. npm publish --provenance --access publicfor each of the 6 packages (5 platforms + driver). Usenpm dist-tagfor prerelease channels (rc/beta).- Anti-drift gate: assert the platform package embedded
release-manifest.jsonis byte-equal to the released one (mirrorsembed-worksgood-pi-check).
- The 6 packages (Shape A, study §5.1):
@wg/cli(driver):bin/wg.js+bin/nex.jsshims (the canonical ~30-line form from study §5.4 — resolve platform package, spawn binary, clear--omit=optionalerror + cargo-install fallback);optionalDependenciesmap of the 5 platform packages; embeddedrelease-manifest.json.@wg/cli-linux-x64(os: linux, cpu: x64, libc: glibc),@wg/cli-linux-arm64,@wg/cli-darwin-x64,@wg/cli-darwin-arm64,@wg/cli-win32-x64(each containswg+nex,.exeon win32).
- Driver shim runtime version-skew guard (study §10.3 open question — recommendation YES): assert
require("@wg/cli-<os>-<cpu>/package.json").version === require("@wg/cli/package.json").versionbefore spawn, error loudly (pi-plugin-compat-style handshake) if a monorepo hoist mismatched them. - Document the glibc floor (study §4.4 —
ubuntu-22.04builds pin glibc >= 2.35) and the 4 unsupported arches in the driver README; the shim prints a helpful error if the host is unsupported. - npm scope decision (study §10.3 open question):
@wgvs@graphworkmust be RESOLVED before the first publish (baked into package names, hard to change post-fact). If@wg403s on publish, fail loud and surface@graphwork/clias the alternative — do NOT silently rename.
Versioning (study §8.1)
npm package version = git tag (minus v) = Cargo version for stable releases. All 6 packages publish at the SAME version. Prereleases (v0.2.0-rc.1) map to npm prerelease versions under a rc dist-tag. The WG_*_COMPAT_VERSION consts NEVER appear in the npm version — they are runtime handshakes inside the binary, checked at runtime, not a delivery-channel concern.
File scope
.github/workflows/release.yml(newnpm-publishjob)- new
npm/package scaffolding:@wg/cli/bin/wg.js,@wg/cli/bin/nex.js,@wg/cli/package.json,@wg/cli/README.md, and the 5 platformpackage.jsontemplates + a publish script.
Implement directly. The job + scaffolding are one cohesive release-engineering unit.
Validation
-
The
npm-publishjob runs only on a realv*tag (publish == 'true'), downstream ofplan+assemble, and is skipped ondry-run-*/release-test-*. -
Each downloaded archive is verified (
gh attestation verify+ SHA256 vsrelease-manifest.json) before repackaging; a tampered/mismatched archive FAILS the job. -
The driver shim (
bin/wg.js) resolves the correct platform package for the host (process.platform+process.arch), spawns the binary withstdio: inherit, and exits with the binary exit code. -
The shim prints a CLEAR error under
--omit=optional(platform package missing) and surfaces thecargo install --locked worksgoodfallback. - The runtime version-skew guard errors loudly if the installed platform package version != the driver version.
-
The 5 platform packages carry the correct
os/cpu/libckeys so npm skips wrong platforms automatically. -
release-manifest.jsonis embedded in the driver and the anti-drift gate asserts it is byte-equal to the released one. -
npm publish --provenance --access publicis invoked for all 6 packages; prereleases go under arc/betadist-tag (NOTlatest). - The driver README documents the glibc 2.35 floor, the 5 supported (os,cpu) tuples, and the 4 unsupported arches.
-
The npm scope decision is recorded (resolve
@wgvs@graphworkbefore first publish; fail loud + surface the alternative on a 403). -
A dry-run/rehearsal of the publish job (against a test tag or
npm publish --dry-run) shows all 6 packages staged correctly. - No model pin; routes through the active zai profile.
Depends on
Required by
Log
- 2026-07-25T20:57:03.375800447+00:00 Task paused
- 2026-07-25T20:57:32.812675777+00:00 Task published
- 2026-07-26T07:15:53.537912954+00:00 Spawned by coordinator --executor pi --model zai:glm-5.2 --isolation required-worktree
- 2026-07-26T07:16:15.731843139+00:00 Task pending required evaluation gate (agent reported done; awaiting exact attempt-bound `.flip-*`/`.evaluate-*` verdicts)
- 2026-07-26T07:16:43.433937897+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:17:06.951237863+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:17:30.630184823+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:17:52.796401065+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:17:57.798083015+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:18:14.610344608+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:18:19.991513754+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:18:39.765678040+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:18:44.712200499+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:19:03.247416697+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:19:08.233965155+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:19:23.899492274+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:28:04.759753618+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T07:28:09.766742328+00:00 Repaired evaluation pipeline drift for authoritative source attempt 1 (evalp-92fb092cc46fabd07556a3be)
- 2026-07-26T07:57:06.580035995+00:00 Pinned historical PendingEval as a required gate at evaluator threshold 0.70
- 2026-07-26T08:14:35.631569036+00:00 Task reset for retry from pending-eval/failed-pending-eval (stuck evaluation gate) (attempt #1) — reason: Operator recovery: clear legacy pending-eval hold with the newly sanctioned CLI; keep paused until reliability review.
- 2026-07-26T08:14:35.631576946+00:00 Cleared stuck evaluation gate via `wg retry` — a fresh attempt will be minted; no graph.jsonl edit required.
- 2026-07-26T08:14:35.631601407+00:00 Minted evaluation pipeline evalp-afd6f3036f041701201e74ff for source attempt 2 (resume-in-place retry)
- 2026-07-26T08:14:35.691198762+00:00 Task paused