The 0.33.0 release PR (#2339) has been blocked since 2026-07-17 in
changes-requested, because release-please only rewrites `pyproject.toml` and its
configured `extra-files`. `server.json` is asserted byte-for-byte against
`render_server_json()`, which reads the version from `pyproject.toml`, so the
bump alone fails `test_root_server_json_matches_builder` on the release PR —
the `test (2)` shard. Nothing in the repo regenerated `server.json` at all.
`release.yml` already runs `version-sync.py` before its own `verify-versions.py`
gate (lines 145/278), which is why `build` and `build-wheels` pass on the release
PR despite the drift — it syncs in the workspace, uncommitted. The regular CI test
job does not sync, so the fix has to be committed to the branch.
- `scripts/version-sync.py`: also write `server.json`. It was the one
version-carrying file with no writer anywhere, so it fell behind every release.
Values are rewritten in place so key order and formatting keep matching the
builder's byte-for-byte output.
- `.github/workflows/release-metadata-sync.yml` (new): on a push to
`release-please--branches--**`, run version-sync, gate on verify-versions, and
commit if anything changed. Keyed off the branch push because release-please
force-regenerates that branch on every merge to main — that is what repeatedly
wiped the hand-pushed metadata fixes on #2339. Uses the same PAT as
release-please.yml, since a GITHUB_TOKEN push would not re-trigger the release
PR's checks. Idempotent, so the self-triggered rerun no-ops instead of looping.
- Corrected the pre-existing drift on main: the agent-hooks plugin manifests,
both marketplace manifests, and `.releasemetadata` were stranded at 0.31.0 and
were never bumped for 0.32.0 either. `verify-versions.py` now passes on main.
Chose running the script over adding ~13 `extra-files` jsonpath entries: the
script is the single place that knows these locations, and a jsonpath that fails
to match is silent — the same class of failure this removes. There is also no
precedent for nested jsonpath in the config today.
Tests: `test_server_json_version_is_synchronized`,
`test_release_metadata_sync_runs_on_release_please_branch`, and
`test_version_sync_covers_every_file_the_verifier_gates` (guards the two scripts
against drifting apart again).
Not addressed: PyPI is at 9.69GB of its 10GB project cap; the 0.21.x series alone
holds 6.58GB across 31 releases. Roughly 4 more releases fit before that blocks.
## Description
Harden the release artifact workflow so maintainers can reproduce npm
and Python release checks locally and so OpenClaw packaging does not
depend on a not-yet-published SDK version. This follow-up also keeps the
OpenClaw loader export contract explicit and updates the PR after the
branch was merged with current `headroomlabs/main`.
## Type of Change
- [x] Bug fix (non-breaking change that fixes an issue)
- [x] New feature (non-breaking change that adds functionality)
- [x] Documentation update
## Changes Made
- Added reusable local release smoke scripts for npm assets, Python
wheel/sdist artifacts, and the combined release gate.
- Switched the release workflow npm asset build to the reusable npm
builder.
- Made OpenClaw release asset building install against the just-built
local SDK tarball before rewriting packed metadata to the release
dependency range.
- Kept the OpenClaw source dependency registry-installable at
`headroom-ai@^0.22.3` while the packed artifact still ships
`^<release-version>`.
- Added `registerHeadroomPlugin` as a named export while preserving the
default `{ register }` OpenClaw loader contract.
- Added Windows development bootstrap docs/script and regression tests
for version sync, npm asset ordering, OpenClaw source installability,
and Python wheel smoke import isolation.
## Testing
- [x] Unit tests pass (`pytest`)
- [x] New tests added for new functionality
- [x] Manual testing performed
### Test Output
```text
uv run --with pytest python -m pytest tests/test_release_workflows.py scripts/tests/test_version_sync.py -q
44 passed, 1 warning
node --check scripts/build_npm_release_assets.mjs
node --check scripts/verify_npm_release_assets.mjs
python -m py_compile scripts/build_python_release_smoke.py scripts/release_smoke_all.py scripts/version-sync.py
python scripts/verify-versions.py
All versions aligned at 0.31.0
npm ci (plugins/openclaw)
added 88 packages, audited 89 packages, found 0 vulnerabilities
python scripts/release_smoke_all.py --out release-assets-local/all-pr1824-postmerge-fixed-20260710-104739
Verified npm release assets for 0.31.0
wheel metadata OK: headroom_ai-0.31.0-cp310-abi3-win_amd64.whl contains headroom/_core.pyd
sdist License-File metadata OK: ['LICENSE', 'NOTICE']
smoke-import OK: version=0.31.0 hello=headroom-core
```
## Real Behavior Proof
- Environment: Windows 11, Python 3.14.3, Node v24.14.0, npm 11.9.0, uv
0.11.15, Rust/Cargo already installed in the local development
environment.
- Exact command / steps: Ran `python scripts/release_smoke_all.py --out
release-assets-local/all-pr1824-postmerge-fixed-20260710-104739` after
syncing this branch with current `headroomlabs/main`.
- Observed result: The command built `headroom-ai-0.31.0.tgz`,
`headroom-openclaw-0.31.0.tgz`,
`headroom_ai-0.31.0-cp310-abi3-win_amd64.whl`, and
`headroom_ai-0.31.0.tar.gz`; npm verifier passed; the wheel installed
into a fresh venv and imported `headroom._core`.
- Not tested: Full GitHub Actions release matrix and publish jobs with
real PyPI/npm/GitHub Packages credentials.
## Review Readiness
- [x] I have performed a self-review
- [x] This PR is ready for human review
## Checklist
- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable
## Screenshots (if applicable)
N/A.
## Additional Notes
The post-merge full smoke initially failed because the OpenClaw source
package depended on `headroom-ai@^0.31.0`, which is not available on
public npm yet. The builder now installs OpenClaw against the just-built
local SDK tarball before build/pack, and then rewrites packed metadata
to `^0.31.0`.
---------
Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
Co-authored-by: Tejas Chopra <chopratejas@gmail.com>
## Description
Fixes a typo in the release metadata filename written by
`scripts/version-sync.py`.
The file was being created as `.releaseetadata` (double `e`) instead of
`.releasemetadata`.
Any downstream tooling or developer looking for the artifact by its
correct name would not find it.
Closes #
## Type of Change
- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)
## Changes Made
- `scripts/version-sync.py`: corrected the filename in
`write_release_metadata()` — both the docstring and the `metadata_path`
assignment.
- `scripts/tests/test_version_sync.py`: updated 3 test assertions to
reference `.releasemetadata`.
## Testing
- [x] Unit tests pass (`pytest`)
- [ ] Linting passes (`ruff check .`)
- [ ] Type checking passes (`mypy headroom`)
- [ ] New tests added for new functionality
- [ ] Manual testing performed
### Test Output
```text
$ uv run python -m pytest scripts/tests/test_version_sync.py -q
============================= test session starts
==============================
platform linux -- Python 3.14.0, pytest-9.1.1, pluggy-1.6.0
rootdir: /home/sepurisaikrishna/Documents/calude-here/headroom
configfile: pyproject.toml
collected 6 items
scripts/tests/test_version_sync.py ...... [100%]
=============================== warnings summary
===============================
PytestConfigWarning: Unknown config option: asyncio_mode
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
========================= 6 passed, 1 warning in 1.00s
=========================
$ git diff --check origin/main..HEAD
# no output; command exited 0
```
## Real Behavior Proof
- Environment: Linux, Python 3.14.0, uv-managed .venv, branch based on
current origin/main.
- Exact command / steps: grep -r "releaseetadata" scripts/ before the
fix returns hits; after the fix returns nothing. Confirmed
.releasemetadata is written correctly by
test_release_metadata_written.
- Observed result: all 6 test_version_sync.py tests pass with the
corrected filename.
- Not tested: full repository pytest, ruff, and mypy — this is a
one-line spelling fix with no logic changes.
## Review Readiness
- [x] I have performed a self-review
- [x] This PR is ready for human review
## Checklist
- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable
## Screenshots (if applicable)
N/A.
## Additional Notes
- The typo was consistent across implementation and tests, so all tests
passed before this fix with the wrong name. The fix corrects both the
code and the test expectations together.
- No production behaviour changes the file is written but not yet
consumed by any workflow step.
Derive source-tree versions from release history so headroom --version no longer reports stale project metadata.
Restart stale idle proxies after an upgrade, but leave active sessions running to avoid interrupting ongoing conversations.
Remove _version.py from version-sync ownership and make version verification catch package/plugin manifest drift.
- publish-pypi: add permissions: id-token: write for OIDC trusted publishing
- publish-npm: add npm run build before npm publish for both packages
- publish-github-packages: add npm run build, use --registry for GPR
- version-sync: add update_openclaw_package_json to sync headroom-ai dep range
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>