Release Checklist
This page records the package publish order. It is intentionally conservative: publish lower-level packages first, then install and smoke the layers above them.
Server release boundary
The single-node remote SSOT Phase 1 engineering gate is complete on main. The server foundation remains workspace-only and unpublished; it is not part of the public v0.1.0 package contract and does not imply a production SaaS deployment. PostgreSQL canonical storage, high availability, managed hosted operations, and production backup/restore are Phase 2 or later release work.
1. Registry and repository setup
Create the repository environments and registry trusted-publisher entries before
the first live publish run. The configured PyPI and npm workflows use OIDC, so
do not add long-lived PYPI_API_TOKEN or NPM_TOKEN repository secrets for the
normal release path.
GitHub environments:
| Environment | Workflows | Purpose |
|---|---|---|
crates-publish | .github/workflows/crates-publish.yml | Approval gate for crates.io trusted publishing |
pypi-publish | .github/workflows/aidememo-python-publish.yml, .github/workflows/aidememo-agent-sdk-publish.yml, .github/workflows/hermes-aidememo-publish.yml | Approval gate for PyPI trusted publishing |
npm-publish | .github/workflows/aidememo-napi-publish.yml | Approval gate for npm trusted publishing |
github-pages | .github/workflows/pages.yml | OIDC-backed deployment of the validated Docusaurus build |
Publishing a canonical v<version> GitHub Release also triggers
.github/workflows/cli-release-assets.yml. It builds native CLI archives for
macOS and Linux on x64 and arm64, creates SHA256SUMS, and attaches all five
files to the existing GitHub Release. The publish job alone receives
contents: write; matrix build jobs remain read-only.
Recommended protection: require a reviewer for the registry environments and restrict deployment branches/tags to the release branches or tags that the project uses.
Before the first documentation deployment, open Settings → Pages, set the
publishing source to GitHub Actions, and restrict the generated
github-pages environment to main. The Pages workflow keeps repository
contents read-only during the build and grants pages: write plus
id-token: write only to the deployment job. GitHub Pages content is publicly
reachable independently of repository visibility; do not enable it until the
site is ready for public access.
PyPI trusted publishers:
| Project | GitHub owner/repo | Workflow | Environment | Status |
|---|---|---|---|---|
aidememo-python | taeyun16/aidememo | aidememo-python-publish.yml | pypi-publish | Workflow ready |
aidememo-agent-sdk | taeyun16/aidememo | aidememo-agent-sdk-publish.yml | pypi-publish | Workflow ready |
hermes-aidememo | taeyun16/aidememo | hermes-aidememo-publish.yml | pypi-publish | Workflow ready |
All three projects have public v0.1.0 packages. The status column records the trusted-publisher workflow configuration separately from package publication.
npm trusted publishers:
Register each npm package with GitHub owner/repo taeyun16/aidememo, workflow
aidememo-napi-publish.yml, and environment npm-publish:
aidememo-napiaidememo-napi-darwin-arm64aidememo-napi-darwin-x64aidememo-napi-linux-arm64-gnuaidememo-napi-linux-x64-gnuaidememo-napi-win32-x64-msvc
All six npm packages now have GitHub Actions trusted publishers. The workflow
builds the five platform packages on native GitHub-hosted runners and publishes
the root wrapper only after every platform job succeeds. It authenticates only
through OIDC; do not add an NPM_TOKEN or reintroduce a token bootstrap path.
Public-repository releases also receive npm provenance from trusted publishing.
Rust crates publish through .github/workflows/crates-publish.yml with the
crates-publish environment and crates.io OIDC trusted publishers. The first
release was bootstrapped from an operator machine; normal releases do not use a
repository CARGO_REGISTRY_TOKEN secret.
The Elixir NIF is currently documented as a local/path binding. There is no Hex
publish workflow or repository HEX_API_KEY requirement yet; add those only if
the project decides to publish aidememo_nif through Hex.
Optional runtime keys such as OPENAI_API_KEY are for local feature use
(aidememo extract --llm) and are not release secrets.
2. Local preflight
Run the local release gate from a clean checkout:
scripts/release-preflight.sh
The same gate is also available as the manual GitHub workflow
.github/workflows/release-preflight.yml. Use profile=local for the normal
release-candidate pass. Use profile=full only when you also want the Rust
package dry-run or Python/npm publish dry-runs, and turn those on explicitly
with the workflow inputs.
This includes the version pins, changelog release gate, registry readiness, public portability, workflow syntax lint, docs feature coverage, docs-site build, binding smoke, agent SDK/Hermes wheel smoke, workflow smoke, and SDK promotion check.
The changelog release gate is offline and should pass after cutting the current
release notes out of Unreleased:
mise run changelog-release-check
python3 scripts/changelog-release-check.py 0.1.0
It verifies that CHANGELOG.md has an empty [Unreleased] section, one dated
current-version section immediately below it, and non-empty release-note
content. Set AIDEMEMO_RELEASE_PREFLIGHT_CHANGELOG=0 only for focused
non-release debugging.
The registry readiness gate is offline and should pass before creating or editing registry entries:
python3 scripts/registry-readiness-check.py
It verifies that PyPI trusted-publisher project names, workflow names, GitHub environments, npm root/platform package names, and this release document stay aligned. It also rejects first-party publish workflows that drift back to long-lived publish-token assumptions.
The public onboarding gates should also pass before pushing the release tag:
python3 scripts/public-portability-check.py
scripts/fresh-checkout-smoke.sh
The portability gate rejects developer-specific home paths in first-party
tracked files. The fresh-checkout smoke is also available as
.github/workflows/fresh-checkout-smoke.yml; it rebuilds from a copy without
.git, target, or Node build output and runs the deterministic quickstart.
maturin is intentionally run through uvx using the pinned spec from
mise.toml, not from whichever maturin happens to be on PATH.
The Python binding uses PyO3 0.29. Release smoke scripts prefer the same Python 3.13 interpreter used by CI, while accepting PyO3-supported local interpreters. To force a specific interpreter, set it explicitly:
AIDEMEMO_PYO3_PYTHON=python3.13 scripts/release-preflight.sh
For a full registry dry-run:
AIDEMEMO_RELEASE_PREFLIGHT_PROFILE=full scripts/release-preflight.sh 0.1.0
The full profile also runs the Rust publish dry-run readiness gate. Standalone use is:
scripts/cargo-package-readiness.sh
CI also runs the same gate in the cargo-package-readiness job. That PR guard
enforces aidememo-core cargo publish --dry-run while keeping dependent Rust
crates as the documented publish-order skip until aidememo-core exists on
crates.io.
3. Release tag contract
The canonical source release tag is v<version>, so the first public release
uses v0.1.0. Create it only after remote CI and the full release preflight pass
on the exact commit that will be published:
git tag -a v0.1.0 -m "AideMemo 0.1.0"
git push origin v0.1.0
Package-specific tags such as aidememo-python-v0.1.0 and
aidememo-napi-v0.1.0 are optional artifact or dry-run triggers. They do not
replace the canonical v0.1.0 source tag. Real PyPI and npm publishes remain
manual workflow dispatches with an exact version input and approval environment.
To rebuild or backfill assets for an existing release, dispatch CLI release
assets with its exact tag, for example v0.1.0. Uploads use --clobber, so a
retry replaces assets with the same names only after every matrix build passes.
4. Rust crates
Publish in dependency order:
aidememo-coreaidememo-cliaidememo-ffi,aidememo-napi,aidememo-nif,aidememo-python
aidememo-cli and all native bindings depend on aidememo-core, so their
cargo publish --dry-run checks will fail against crates.io until
aidememo-core is published at the matching version.
The readiness script runs cargo publish --dry-run for aidememo-core by
default and records dependent Rust crates as a deliberate skip until that first
publish-order blocker is removed. After aidememo-core is visible on crates.io
at the matching version, run the full dependent check:
AIDEMEMO_CARGO_PACKAGE_CHECK_DEPENDENTS=1 scripts/cargo-package-readiness.sh
5. Python packages
Publish native bindings before composition packages:
aidememo-pythonaidememo-agent-sdkhermes-aidememo
Local Python payload checks:
mise run python-pack-smoke
mise run python-publish-dry-run
mise run agent-sdk-publish-dry-run
mise run hermes-publish-dry-run
Public v0.1.0 packages are installed from PyPI:
python -m pip install aidememo-agent-sdk
python -m pip install "aidememo-agent-sdk[binding]"
python -m pip install hermes-aidememo
Features added under the current
Unreleased
section must
continue to show checkout installs until the next version is published. This
currently includes handoff, agent profiles, and the worker lane:
python -m pip install -e packages/aidememo-agent-sdk
python -m pip install -e plugins/hermes
6. Node package
Publish the platform packages before the root wrapper:
aidememo-napi-*platform packagesaidememo-napi
Set the manual workflow inputs to the exact version and dry_run=false. The
workflow authenticates through the six npm trusted-publisher registrations and
is safe to rerun after a partial failure because it skips package versions
already visible on npm.
Use each trusted-publisher workflow with the exact version input. The default workflow mode is dry-run:
.github/workflows/aidememo-python-publish.yml.github/workflows/aidememo-agent-sdk-publish.yml.github/workflows/hermes-aidememo-publish.yml
7. Post-release checks
Before the registries are live, the post-release smoke can run in plan mode and print the exact install checks it will perform:
scripts/public-registry-smoke.sh
After each registry publish, run verify mode:
AIDEMEMO_PUBLIC_REGISTRY_SMOKE_MODE=verify scripts/public-registry-smoke.sh
The same check is available as the manual GitHub workflow
.github/workflows/public-registry-smoke.yml. Keep mode=plan before the
registries are live, then run the exact released version with mode=verify
after publishing. The workflow exposes per-registry toggles so a partial
publish can verify only the registry that changed.
This installs aidememo-cli, aidememo-agent-sdk,
aidememo-agent-sdk[binding], hermes-aidememo, and aidememo-napi from
public registries into temporary environments and imports / runs the installed
packages. Use AIDEMEMO_PUBLIC_REGISTRY_SMOKE_* toggles to narrow the check when
only one registry was published.
Then update README and docs to remove "from checkout until release" caveats for the packages that are actually available from public registries.