Documentation
Release process
Published npm versions are immutable. A matching version-tag push can publish a new version, but it cannot replace the contents of an existing version.
- Update canonical content and run
npm run buildto refresh progressive skill references and the site. - Set the intended release version on the release branch with
npm version <version> --no-git-tag-version. This updatespackage.jsonandpackage-lock.jsonwithout creating a premature commit or tag. - Update the changelog, migration guidance, and any public examples that pin a reviewed version.
- Run
npm run release:check. This includes tests, validation, review dates, builds, a clean tarball installation, andnpm audit. - Confirm the package archive contains no credentials, local reports, nested repositories, or generated consumer data.
npm pack --dry-run --jsonmust show only the approved public files underdocs/listed inscripts/public-docs.mjs, and everymain,bin, andexportstarget must exist in the archive. - Commit and push the release branch, open a pull request, and require the configured CI matrix to pass before merge.
- After the reviewed release commit is on
main, create and push the matchingv<version>tag on that exact commit. A matchingv*tag onmainruns.github/workflows/publish-npm.yml, verifies the version and ancestry, and publishes through npm trusted publishing. - Let the workflow create the matching GitHub Release. npm may temporarily show the new version as
Validating; wait for automated review to finish rather than reusing the tag or publishing again. - After npm marks the version Published and moves
latest, verifynpx --yes @ghostbyte/agent-docs-kit@<version> --helpfrom a clean directory outside this package's source repository.
git switch -c release/v6.2.1
npm version 6.2.1 --no-git-tag-version
node scripts/sync-version.mjs # rewrites every pinned version from package.json
npm ci
npm run release:check
git add -A
git commit -m "release: prepare v6.2.1"
git push -u origin release/v6.2.1
# After the pull request is approved, CI passes, and the merge commit is on main:
git switch main
git pull --ff-only
git tag v6.2.1
git push origin v6.2.1
On Windows PowerShell, call npm.cmd and npx.cmd if the execution policy blocks npm.ps1.
One source for the version number
package.json version is the only place a release version is authored.
node scripts/sync-version.mjsrewrites the pinned version inREADME.mdand both release documents.site/index.htmlstores the placeholder__AGENT_DOCS_KIT_VERSION__;scripts/build-site.mjssubstitutes the real version at build time, so the page source cannot drift.node scripts/sync-version.mjs --checkfails when any pin, includingpackage-lock.json, disagrees.npm run release:checkruns it, and a test asserts the same agreement.
Run the sync immediately after npm version, before release:check. The version npm lifecycle script also invokes it, but verify the rewrite landed rather than assuming the hook fired.
Choose the dist-tag
The workflow derives the dist-tag from the version in package.json: a plain version publishes to latest, and a prerelease version such as <version>-beta.1 publishes to beta. workflow_dispatch accepts an explicit dist_tag input.
Publishing straight to latest is the owner's decision. It is the shorter path, and it means the first execution of the publish workflow lands on the tag every consumer installs. Before tagging a release that goes directly to latest, confirm all of the following:
- The full CI matrix passed on the release commit.
npm run release:checkpassed locally, including the packed-installation smoke test.- The rollback procedure below is understood, because a published version can never be replaced.
- The site and npm will agree: the built site pins the new version in its install commands, so a merge that deploys the site before the version exists on npm leaves visitors with install instructions that return a 404. Merge and tag close together.
The beta route below stays available and is worth using for a large or risky change, because it lets testers confirm a build before @latest moves.
Optional: publish to the beta tag first
- Publish under the
betadist-tag. The workflow derives the dist-tag from the version inpackage.json: a prerelease version such as<version>-beta.1publishes tobeta, and a plain<version>publishes tolatest.workflow_dispatchaccepts an explicitdist_taginput.
The publish workflow requires the pushed tag to equal the version in package.json, so a prerelease is a real version bump, not just a differently named tag:
git switch -c release/v<version>-beta.1
npm version <version>-beta.1 --no-git-tag-version # also runs sync-version
npm run release:check
git commit -am "release: prepare v<version>-beta.1"
# merge to main, then:
git tag v<version>-beta.1
git push origin v<version>-beta.1
- Testers install the beta explicitly:
npm install --save-dev @ghostbyte/agent-docs-kit@beta
- Promote after the agent-behavior checks and the post-publish smoke test pass:
npm dist-tag add @ghostbyte/agent-docs-kit@6.2.1 latest
npm dist-tag ls @ghostbyte/agent-docs-kit
Verify provenance after publishing
docs/SECURITY_MODEL.md states that provenance is used when configured. Confirm it on each release rather than assuming it:
# In a throwaway project that installed the published version:
npm audit signatures
The npm package page must also show the provenance badge for the exact version. Record the result as release evidence. Keep 2FA on the npm account, branch protection on main, and OIDC trusted publishing instead of a long-lived token.
Post-publish smoke test
The smoke job in .github/workflows/publish-npm.yml runs after publication on a clean runner: it installs the exact published version from the registry and runs --version, doctor, setup --dry-run, setup, and audit documentation in a temporary directory. It retries for several minutes because a freshly published version takes time to propagate and may sit in npm's automated validation.
Freeze rule for a prerelease window
While a release sits under the beta dist-tag and has not been promoted:
- Accept bug fixes only, for about two weeks. No new commands, no new options, and no changes to generated text.
- No major version during the window. A breaking change needs a deprecation cycle first, as
COMPATIBILITY.mddescribes. - Triage tester feedback into "fix now" (correctness, data loss, safety) and "after promotion" (everything else).
- Promote to
@latestonly when the agent-behavior scenarios inTESTING_GUIDE.mdand the post-publish smoke test both pass on the prerelease build. This applies to the prerelease route; a release published directly tolatesthas no promotion step, so its verification happens before the tag.
Generated text is part of the contract because it changes what AI agents do, so a wording change during the freeze is a release decision, not a cleanup.
If a release is bad
Published versions cannot be overwritten or re-uploaded.
- Deprecate the bad version with a reason users will see on install:
npm deprecate @ghostbyte/agent-docs-kit@6.2.1 "Superseded: <reason>. Install @latest."
- If the bad version holds
latest, move the tag back to the last good version immediately. This is the primary safety net for a release published directly tolatest:
npm dist-tag add @ghostbyte/agent-docs-kit@<last-good-version> latest
npm dist-tag ls @ghostbyte/agent-docs-kit
Moving latest does not unpublish the bad version; it stops new installs from resolving to it.
- Publish a corrective patch version. Never reuse the bad version number.
- Record what happened in the changelog and in a dated evidence record.
Use a patch version for a backward-compatible fix, a minor version for a backward-compatible feature, and a major version for a breaking change. The workflow enforces agreement between package.json and the pushed tag, then creates the corresponding GitHub Release after publication.
The first release was published manually because the package had to exist before its trusted publisher could be configured. If a pushed version already exists, the workflow validates the project and safely skips publication; increment the version before pushing package changes that should reach npm.
When validating local source from this repository, run node .\bin\agent-docs.mjs. An npx invocation from the package's own root can be affected by npm self-resolution because the root package does not link its own executable into node_modules/.bin; this does not represent consumer behavior.