Decision: Tag-triggered npm release workflow replaces the release-event publish workflow
Status: implemented
Problem
.github/workflows/publish.yml published to npm when a GitHub Release was published. Releases are cut by hand
after the tag, so the npm publish depended on a second manual step and could not verify that the tag and
package.json agree. The layout review (2026-10-12-cli-repository-layout) asks for a tag-driven release.
Decision
- Add
.github/workflows/release.yml: on avX.Y.Z[-pre]tag it checks that the tag equals thepackage.jsonversion, runsnpm ci, typecheck, build and unit tests,npm pack --dry-run, thennpm publish --provenance --access public(job permissionid-token: write, protectednpmenvironment,NPM_API_TOKENuntil a trusted publisher can be configured after the first release). - Remove
.github/workflows/publish.yml: its steps are a strict subset ofrelease.yml; keeping both would publish the same version twice.release-binary.ymlis unchanged and still runs when the GitHub Release is published. - Add
docs-links.yml(lychee: offline relative-link check on pull requests, full check weekly),.nvmrc(20),eslint.config.jswithnpm run lint(also run bymake ciand thelintjob inci.yml). - Removed Python leftovers: none remained to delete.
benchmarks/bench_cli_startup.pywas already replaced bybenchmarks/bench_cli_startup.mjs;scripts/build_hermes.sh,deploy_all_templates.shanddeploy_remaining.shwere already rewritten to call theabxexecutable (see2026-10-12-open-source-hygiene) and are kept because they have no replacement.
API Design
N/A — this decision does not involve API changes.
Alternatives considered
- Keep
publish.ymland addrelease.yml— publishes twice for one release. - Trusted publishing (OIDC) only — requires the package to exist on npm first; revisit after 0.3.0.
Dependencies
GitHub environment npm; repository secret NPM_API_TOKEN; npm organisation agent-sandbox.
Test Strategy
Dry run with npm pack --dry-run in CI; the first tagged release exercises the publish step.
Acceptance criteria
- Pushing
vX.Y.Zpublishes@agent-sandbox/cli@X.Y.Zwith provenance, and fails when the versions differ. scripts/check-repo-health.shpasses itsrelease.ymlchecks.