Harness-mem Release Process
May 27, 2026 · View on GitHub
This document is the maintainer-facing release contract for this repository.
The goal is simple: a release should land in the same shape whether you use the harness-release skill or run the steps manually.
1. What is the source of truth?
For normal day-to-day changes:
- add user-visible release notes to
CHANGELOG.mdunder## [Unreleased] - keep
CHANGELOG_ja.mdas a Japanese summary, not an independent contract
For a shipped release:
CHANGELOG.mdcontains the versioned entrypackage.jsoncontains the same version- the git tag matches that version (
vX.Y.Z) - GitHub Release uses that same tag/version
- npm publish exposes that same version
If any of those disagree, the release is not reproducible enough.
2. Skill path vs manual path
If your local workflow uses the harness-release skill, treat it as an automation wrapper around this checklist.
- The skill is allowed to save time.
- The skill is not allowed to change the release contract.
- If the skill output disagrees with this document, this document wins and the skill should be fixed.
In other words:
- skill path = convenience
- repo docs + workflow contract = policy
3. Pre-flight checks
Before starting a release, make sure all of these are true.
Working tree
git diff --quiet && git diff --cached --quiet
Why this matters:
- a dirty tree makes it unclear what was actually released
- it becomes hard to reproduce the exact shipped state later
Version planning
Choose the next version according to semantic versioning:
patch: bug fix, no breaking changeminor: new feature, backward compatiblemajor: breaking change
Changelog discipline
Check that user-visible changes are already written under ## [Unreleased] in CHANGELOG.md.
Why this matters:
- release notes should be accumulated during normal work
- the release step should mostly reorganize and ship, not rediscover what changed
npm auth preflight
If you have rotated NPM_TOKEN, changed npm ownership, or just recovered from a failed publish, run the manual auth check workflow before tagging the next release.
Workflow:
- GitHub Actions:
npm Auth Check - file:
.github/workflows/npm-auth-check.yml
What it verifies:
NPM_TOKENexists in GitHub Actions secrets- GitHub Actions can authenticate with
npm whoami - the token can read collaborator access for
@chachamaru127/harness-mem - the package is still marked
public - the current repo state can still produce the publish tarball with
npm pack --dry-run
What it intentionally does not do:
- it does not run
npm publish - it does not create or modify tags
- it does not replace the real release workflow
Why this matters:
- it lets maintainers verify "the key still opens the door" before a real release
- it separates credential failures from code / package failures
- it prevents the frustrating case where the tag and all tests are green, but publish fails at the last step because the secret was stale or belonged to the wrong npm identity
4. Local quality gate
Run the quality checks that protect the published package.
Minimum expected checks:
bash scripts/harness-mem model pull multilingual-e5 --yes
npm test
npm pack --dry-run
Why the extra model bootstrap matters:
- the release workflow runs semantic benchmark suites such as
tests/benchmarks/memory-durability.test.ts - those suites assume the local ONNX embedding model
multilingual-e5is available - without that model, the runtime falls back to a lightweight hash embedding and the benchmark no longer measures the intended quality bar
- GitHub Actions now restores/downloads this model before
npm test, so local maintainers should use the same precondition when validating a clean machine npm testitself also relies on the repo's Bun panic mitigation path, so maintainers should run the scripted command instead of replacing it with rawbun test ...one-liners
What npm test means in this repository:
- it is the maintainer-facing behavior gate
- it already includes the panic-mitigated root test path described in
docs/TESTING.md - it is intentionally different from "one huge
bun testover everything", because that path can report0 failand then die in Bun teardown
If you need the deeper background or want to report the Bun crash upstream, see docs/bun-test-panic-repro.md.
Recommended additional checks when the touched area justifies them:
bash scripts/harness-mem doctor --json --platform codex --skip-version-check
bun test tests/session-start-parity-contract.test.ts tests/benchmarks/first-turn-continuity.test.ts
Why this matters:
npm testprotects behaviornpm pack --dry-runprotects package contents- targeted contracts protect release-sensitive wiring claims
Developer-domain ranking gate (S108-005/S108-005b)
S108-004 selected the code_token tokenizer (camelCase / kebab-case / path / issue / PR / command) as the default ranking policy. The release gate is wired through:
docs/benchmarks/developer-domain-thresholds.json— Layer 1 floors (recall@10 ≥ 0.70, bilingual recall@10 ≥ 0.88, search p95 ≤ 50ms)npm run benchmark:developer-domain— reconciles S108 dev-workflow and S108 temporal planner metrics into the CI manifestscripts/check-developer-domain-gate.sh— readsmodeand the env overrideHARNESS_MEM_DEVDOMAIN_GATE=warn|enforce.github/workflows/release.yml— invokes the script before publish
Default mode is now enforce: developer-domain metric failures block release after S108-005b reconciliation writes the manifest fields. Maintainers can verify locally with npm run benchmark:developer-domain && bash scripts/check-developer-domain-gate.sh and roll back with HARNESS_MEM_DEVDOMAIN_GATE=warn. CHANGELOG entry is required only when the gate contract changes; not on tokenizer-internal tweaks.
5. Versioning and release notes
When you are ready to ship:
- move or rewrite
CHANGELOG.md [Unreleased]into## [X.Y.Z] - YYYY-MM-DD - add a matching summary entry to
CHANGELOG_ja.md - update
package.jsonversion toX.Y.Z - update
package-lock.jsonto the same version when it exists - update
.claude-plugin/plugin.jsonversiontoX.Y.Z - update
.claude-plugin/marketplace.jsonpluginversionandmetadata.versiontoX.Y.Z
The repository behavior gate (tests/marketplace-schema.test.ts) asserts that the
plugin.json and marketplace.json versions match package.json. Bumping
package.json alone makes npm test fail inside the release workflow and blocks
publish, so all four version surfaces must move together.
The important part is not the exact editing style. The important part is that all release surfaces agree on the same version and the same user-facing story.
6. Tag and publish contract
This repository's GitHub workflow publishes on v*.*.* tags and checks two important things:
- the tag commit is contained in
main - the tag version matches
package.json
That means the preferred path is:
git add CHANGELOG.md CHANGELOG_ja.md package.json package-lock.json
git commit -m "chore: release vX.Y.Z"
git tag -a "vX.Y.Z" -m "Release vX.Y.Z"
git push origin main --tags
After that, .github/workflows/release.yml is expected to:
- install the CLI prerequisites used by
harness-mem setup/doctoron a fresh Linux runner (jq,ripgrep) - build the MCP server runtime before the repository behavior gate, so setup/doctor contract tests do not spend their timeout budget bootstrapping
mcp-server/dist/index.js - restore or download the
multilingual-e5local embedding model before the repository behavior gate - run the same repository behavior gate as local maintainers (
npm test) - run quality gates
- run
npm pack --dry-run - publish to npm
- create a GitHub Release
When npm credentials were recently changed, run .github/workflows/npm-auth-check.yml manually first. Treat it as a preflight for registry identity, not as a substitute for the release workflow itself.
In practice today, the release workflow also keeps two extra checks separate:
harness-mem-uitest / typecheckmemory-servertypecheck
That split is intentional. It keeps the local contract easy to explain while still protecting the UI and the strict TypeScript gate in CI.
7. Post-release verification
After the workflow or manual publish finishes, verify the public surfaces.
npm view @chachamaru127/harness-mem version
gh release view vX.Y.Z
What you are checking:
- npm version is the version you intended to ship
- GitHub Release exists for the same tag
- the release notes correspond to the same change set
8. If automation fails
Sometimes the release workflow can fail for reasons unrelated to product quality, such as billing issues or temporary registry problems.
When that happens:
- keep the release contract intact
- do not silently skip verification
- if you must do a manual recovery, record that in
CHANGELOG.mdor the release notes
Examples of acceptable manual recovery:
- manually creating the GitHub Release after the tag already exists
- manually publishing to npm after confirming the package and version are correct
Examples of good pre-release diagnostics:
- running the manual
npm Auth Checkworkflow after updatingNPM_TOKEN - confirming
npm whoamiand package collaborator access on the GitHub runner before tagging
Examples of unacceptable shortcuts:
- publishing a version that does not match
package.json - creating notes that do not match the shipped code
- skipping changelog updates because the skill or workflow failed
9. Short checklist
Use this when you want the shortest possible release checklist.
CHANGELOG.md [Unreleased]is up to dateCHANGELOG_ja.mdsummary will match the releasepackage.json,package-lock.json,.claude-plugin/plugin.json, and.claude-plugin/marketplace.jsonversions all matchnpm testpassesnpm pack --dry-runpasses- tag =
package.jsonversion - tag commit is on
main - npm and GitHub Release both show the same version