Releases and changes
Wraptool does not currently maintain a separate changelog file. The authoritative history is the repository:
Tags named wraptool-v* publish precompiled binaries for Linux, macOS, and Windows on AMD64 and ARM64. Each Forgejo release also includes a checksums.txt file containing SHA-256 checksums and build-info.txt recording the source commit, Go version, and hashes of the pinned Guix inputs.
Compatibility
Starting with 1.0, wraptool makes one promise: the surfaces listed as frozen below do not break under any 1.x release. This is not a claim that everything in the repository is stable, or that wraptool is finished — only that the enumerated list holds.
| Bump | Promise |
|---|---|
1.0.x → 1.0.y |
Bug fixes only. No new keys, flags, or tools. |
1.x → 1.y |
New capability. Everything frozen below still works with no edit to your configuration, your generated harness configuration, or your devcontainer.json. |
1 → 2 |
The frozen list may change. |
Frozen
- The configuration schema, as documented in Configuration. A
1.xrelease may add keys and may add members to a value enum. It does not remove a key, rename one, or change a documented default such that an existingconfig.yamlbehaves differently. - CLI command names and their documented flags, per CLI reference. New commands and new flags may appear. Documented ones keep their name, meaning, and default.
- MCP tool naming. A wrapped capability is named
<tool>_<subcommand tokens joined by _>. The three fixed toolswraptool_discover,wraptool_info, andwraptool_request_capabilitykeep their names and their input schemas — these are wire identifiers an agent has already learned, and renaming one is a break. - Generated harness configuration: the file path and JSON shape wraptool writes for each harness.
- The
wraptool:1Dev Container feature: its option set, itscontainerEnv(HOME=/home/wraptool-harness, appended poolPATH), and the two pool mount targets it depends on. - Release artifacts: the tag format
wraptool-vX.Y.Z, the six binary asset names,checksums.txt,build-info.txt, and the release signing keyC8ABC91CAB2DC195B9763877DFABC43C55F2E63A. wraptool doctorexit codes 0/1/2 and the--jsonschema version.- The
/api/v1admin JSON API. It stabilizes through its path version: a field rename or a semantic change requires/api/v2; adding a field is fine.
Excluded
Some surfaces are deliberately left out of the promise. Excluding them now, in writing, is what keeps them free to change in a minor release instead of forcing a major version later:
mcp_servers.*— experimental. Its shape may change in a1.xrelease.- The experimental
harnesssubcommands —sync,rollback,gc,policy set, and their--backend,--platform, and--legacyflags. The stable pair-plus-two areharness list,install,refresh, andupdate. - wraptool’s own
stdioserver transport. It exists for tests only, is unsupported for real use, and may be removed in any1.xrelease. Usesseorunix. - The legacy harness pool
bin/+lib/trees. Already carries a deprecation notice; not a supported surface. - The
wraptool:0feature major and thewraptool-connectfeature. Deprecated and sunset respectively. Already-published artifacts keep working indefinitely; nothing new ships for either. serve’s override flags (--listen,--auth-token-file,--admin-listen,--admin-auth-token-file) — internal plumbing betweenwraptool upandserveon an already-hidden command.- The review UI’s HTML, URLs, and form fields. Operator-facing, not an API.
- Console output text, including
wraptool server status’s prose. - The scaffolded starter configuration.
EnsureConfigFilenever overwrites an existing file, so its content is a starting point, not a contract. - Internal formats: the introspection cache, pool generation IDs, receipts, and
recipe_revision. All self-heal by design. - Go packages and the module path. Everything real lives under
internal/and is unimportable;cmdis not a supported API and the module path may move. design/notes. See the callout below.
One reserved exception
A security fix may narrow what policy permits in a minor release. wraptool’s policy engine has four known permissive behaviours that a future release may tighten: exact-length deny matching, unbounded positionals when arg_constraints is absent, default-open ?cwd= containment, and unenforced valuelessness on boolean flags. See Security’s “Known limitations” for the currently documented ones. Without this exception, tightening any of them would be a breaking change; with it, they are a roadmap instead.
Homebrew tap
The same workflow generates wraptool.rb from the checksums of the build it just produced, attaches it to the release, and commits it to the Homebrew tap repository — so the tap can never reference bytes that were not released together. The tap is a separate repository because brew tap clones a whole repository named homebrew-<tap>:
- Repository:
pti/homebrew-wraptool, with the formula atFormula/wraptool.rbon the default branch. Override the name with the repository variableHOMEBREW_TAP_REPOSITORY. - Secret:
HOMEBREW_TAP_TOKEN, a Forgejo token with write access to that repository only.github.tokenis scoped to this repository and cannot push to the tap.
Without the secret the tap step logs a skip and the release still succeeds; the generated wraptool.rb is attached to the release and can be committed to the tap by hand. Nothing about the tap affects the binaries themselves.
Create a release from a clean main branch that exactly matches origin/main:
./release-version patchThe argument can be patch, minor, major, or an explicit stable SemVer such as 0.2.0. The script fetches release tags, calculates and validates the next version, verifies that the release signing key is available, runs the test suite, asks for confirmation, and pushes a signed wraptool-v* tag. Run it on the trusted host where the GPG agent and private key are available, not inside the isolated harness container. Use --dry-run to verify a release without creating a tag or --yes for a non-interactive release.
Confirm the signing-capable secret key is available on the host before running the release command:
gpg --list-secret-keys C8ABC91CAB2DC195B9763877DFABC43C55F2E63ARelease tags are signed by C8ABC91CAB2DC195B9763877DFABC43C55F2E63A. The public key is committed as release-signing-key.asc, making CI verification reproducible and independent of keyserver availability. The same key may be obtained from a public keyserver for independent verification, but always check the complete fingerprint above. CI imports the committed key into a temporary keyring and rejects an invalid, unsigned, wrong-key, or wrong-commit tag before building release artifacts.
If release infrastructure fails after the signed tag is published, do not move or recreate the tag. Run Publish release binaries manually from Forgejo Actions and supply the existing tag name; the workflow restores and verifies the original annotated tag before retrying publication.
The tag is the only source of the release version. The Forgejo workflow derives the artifact names and linker-injected binary version from an exact-match git describe; no version number is maintained in Go source.
The in-binary version is derived from the release tag and Go build VCS information:
wraptool versionIt reports the project version, revision when available, whether the checkout was dirty at build time, and the Go version. The MCP wraptool_info tool reports the running server’s build identity and introspection freshness, which is useful when a long-lived server may not match the binary currently on PATH.
Design files under design/ can contain roadmaps and audit findings. They are not a release ledger and are excluded from the compatibility promise; verify shipped behavior in source, tests, CLI help, and the documentation pages marked as current reference.