Conversation
jacderida
force-pushed
the
chrisoneil/v2-1152-distribute-the-ant-cli-via-npm
branch
from
September 8, 2026 16:11
e458702 to
0d1b820
Compare
Agent sandboxes and locked-down CI allow package-manager traffic by default while blocking direct binary downloads — Claude Code cloud sessions return 403 for release assets of repos not attached to the session, and skill-directory scanners flag piped installers while passing package managers. This makes getting `ant` onto such a machine a one-liner. Packaging only: nothing is rebuilt. The npm tarballs carry the same binaries the release workflow has already built and signed, verified against SHA256SUMS.txt and their ML-DSA-65 signatures before packaging, so they are byte-identical to the GitHub release assets. install.sh, install.ps1 and the release page are untouched. Six packages, following the mechanism esbuild established: a meta package plus one per platform, guarded by os/cpu and declared as optionalDependencies, so npm skips the four that do not match and a user downloads exactly one binary. A JS launcher resolves and execs it rather than a postinstall copying it into place, because install scripts cannot be relied on (below). Published from ant-cli-release.yml after the GitHub release, with provenance via OIDC and a dist-tag derived from the version: latest, beta, or rc. A pre-release may not be the package's first publish. npm sets `latest` from a package's very first publish even when --tag names something else, and later pre-release publishes move only their own tag, so a beta debut would pin `latest` to that beta until a stable release moved it — and the plain `npm install -g @withautonomi/ant` would serve it. Both behaviours were verified against a local registry. The publish job asks the registry whether the package exists and skips a pre-release publish when it does not; the condition clears itself once a stable release has gone out. `ant update` now recognises a package-manager-owned install and defers to it. Self-replacing an npm-managed binary left npm's metadata describing a file that was no longer there, so the next `npm update` silently rolled the user back. The check still reports whether a newer version exists, then prints `npm update -g @withautonomi/ant`; a second guard in ant-core refuses self-replacement for any other consumer of the crate. Detection is by resolved-path inspection rather than a build flag, since a build flag would produce a binary that is not byte-identical to the release asset. Finally, `config::resolve_bootstrap_multiaddrs` falls back to the seeds already bundled into the binary by `network_defaults` when no bootstrap_peers.toml is present, instead of returning NoBootstrapPeers. npm 12 blocks package install scripts by default, so the postinstall that copies that file into the config directory frequently does not run, which would otherwise leave a CLI that installs and reports its version but fails every network command — in exactly the sandboxes this change targets. Priority is unchanged (explicit -b peers, then a devnet manifest, then the config file, then the bundled seeds), and an explicitly selected devnet manifest still errors rather than reaching for mainnet peers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012H3LsaffUstGkhHQdZeQD3
jacderida
force-pushed
the
chrisoneil/v2-1152-distribute-the-ant-cli-via-npm
branch
from
September 22, 2026 21:38
05157f1 to
b70d808
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linear issue
Closes V2-1152
https://linear.app/autonominetwork/issue/V2-1152/distribute-the-ant-cli-via-npm
(mirrors #190)
Risk tier
Mostly packaging and CI, which alone would be T0. Proposed as T1 because two
client-side behaviours do change:
ant updaterefuses to self-replace on apackage-manager-owned install, and
antnow falls back to a bootstrap peer listcompiled into the binary when no config file is present. Neither touches node
behaviour, the wire protocol, stored-data format, or payments. The upgrade
mechanism is narrowed rather than altered — self-replacement is unchanged for
every install that exists today, and is only declined where it would corrupt a
package manager's view of its own files.
Compatibility
ant_core::install(InstallMethod,detect,classify_path) andant_core::update::DeferredUpdate. No existing signaturechanged.
ant_core::update::perform_updategains an early error return forpackage-manager-owned installs — a new failure mode on a path that previously
always attempted replacement.
config::resolve_bootstrap_multiaddrsgains afallback tier: where it previously returned
Error::NoBootstrapPeerswith noconfig file, it now returns the seeds already bundled by
network_defaults.Semver impact
Test evidence
Rebased and reworked onto current
main(2026-09-22)The branch was 118 commits behind and conflicting.
mainhad independently movedbootstrap_peers.tomltoant-core/resources/, changed its format toquic/webrtcmultiaddresses, and added
ant-core/src/network_defaults.rs, which already embeds thatfile with
include_str!and exposesbundled_bootstrap_seeds()for the WASM build.Rather than resolve four conflicts, the branch was rebuilt on top of
mainand only thestill-wanted parts re-applied. That removed work rather than adding it: the file move,
the three workflow
cppath edits, a bespokeEMBEDDED_BOOTSTRAP_PEERSconstant with itsown parser and tests, an
ant-core/examples/bench-quoting.rsedit, and a rustdoc fix for alink on the constant that no longer exists. The remaining fallback is a handful of lines
reusing
bundled_bootstrap_seeds().Gates run locally on the reworked tree:
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo doc --all-features --no-depswithRUSTDOCFLAGS="-D warnings"cargo test --lib --allcargo test -p ant-core --test unit_self_encryptcargo test -p ant-core --test merkle_unitcargo test -p ant-core --test daemon_integration --test node_add_integration -- --test-threads=1The devnet-backed e2e suites are left to CI, which runs them in their own jobs.
Tests covering this change: 11 in
ant-core/src/install.rs(npm global, npm local, nestednode_modules, Windows paths,install.sh/cargo/local-build locations, and a directorywhose name merely contains the substring). The fallback's own invariants are already
covered on
main—network_defaultsasserts the bundled seeds parse and are non-empty,and three
configtests assert that an explicitly selected devnet manifest never fallsback.
npm behaviour, verified against a local registry
Done before the rework, against a verdaccio registry with a scratch
npm_config_prefixand
XDG_CONFIG_HOME. The npm packaging is unchanged by the rework.npm install -g @withautonomi/antgives a workingant --versionant 0.3.6)cmpclean, sha2567d7847f1…)npm uninstall -gremoves everything except the config directoryBeyond the ACs:
allow-scriptsis empty out of the box),so a plain install does not write
bootstrap_peers.toml. With postinstall blocked,antstill resolved peers and connected. This is the reason the fallback exists.--allow-scripts, the postinstall wrote the file, and a reinstall over auser-edited copy left it untouched.
ant update --jsonon the npm-installed binary returned"install_method": "npm"with"update_command": "npm update -g @withautonomi/ant";--forceexplained the refusalrather than silently doing nothing.
dist-tag behaviour on a pre-release debut
npm sets
latestfrom a package's first publish even when--tagnames something else,and later pre-release publishes move only their own tag:
A bare install against that registry resolved to the beta. Publishing a stable
0.3.7with--tag latestafterwards reclaimed the tag cleanly. Hence the debut guard. Its dist-tagmapping was replayed offline across
0.3.7,-beta.N,-rc.N,-alpha.Nand-betamax.Nagainst both 200 and 404 registry responses, and the registry probe checkedagainst the real registry (
@withautonomi/ant→ 404,@stripe/cli→ 200).Not verified locally: cross-platform binaries (only the host target was built; the other
four packages carried a stand-in binary), the real npm registry, OIDC provenance, and the
publish job itself.
install-test.ymlgains fourworkflow_dispatchjobs — npm install onLinux/macOS/Windows plus an
--ignore-scriptsjob — to cover those against a real publishedversion.
New dependency
None — no new Rust crates. The npm packages declare no runtime dependencies;
the launcher and postinstall use only Node's standard library. Node ≥18 becomes a
requirement for the npm install path only, and the release workflow gains
actions/setup-node.ADR
n/a — Tier 1.
Mitigation / rollback
The publish job is the last job in the release workflow and runs only after the
GitHub release has been created, so a failure there cannot affect the release. It
also skips itself with a warning when
NPM_TOKENis absent, so merging this beforethe token is configured cannot turn a release red. Backing the distribution out
means deprecating the npm packages and deleting the job; no released artifact
changes.
The two client-side behaviours are independently reversible. The
ant updatedeferral only triggers on a
node_modulespath — no existing install can reach it.The embedded peer fallback only runs where the previous code returned
Error::NoBootstrapPeers, so it can turn a hard failure into a success but neverchange the outcome of a currently-working configuration.
🤖 Generated with Claude Code
https://claude.ai/code/session_012H3LsaffUstGkhHQdZeQD3