diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml
index 1cc2979..32bbd7f 100644
--- a/.github/workflows/publish-crates.yml
+++ b/.github/workflows/publish-crates.yml
@@ -48,7 +48,7 @@ jobs:
- name: Mint a short-lived crates.io token
id: crates
- uses: rust-lang/crates-io-auth-action@82864bf380abd3e242c564a5ba58dd29d6265b00
+ uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
- name: Publish pi-setup-system
env:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1bccbc3..0770682 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,17 @@ cut and that this clone does not carry.
## [Unreleased]
+## [0.0.67] - 2026-09-07
+
+nddev-builder creates complete native tool collections: select and author
+components, compose exact setups across declared roots, document capabilities,
+and verify installation, native invocation and recovery. Provider maintenance
+checks are separate from ordinary setup authoring. The toolkit includes the
+consumer's exact digest-approval steps and preserves the active environment.
+Product artifacts are refreshed from verified vendor bytes, with previous
+pins retained for rollback. Release authentication uses the tagged upstream
+action release.
+
## [0.0.66] - 2026-09-07
Reset is an optional protocol operation: it empties declared native
diff --git a/Cargo.lock b/Cargo.lock
index f1d699c..398f6d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -66,7 +66,7 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "harness-runtime"
-version = "0.0.66"
+version = "0.0.67"
dependencies = [
"provider-v3",
"serde",
@@ -128,7 +128,7 @@ dependencies = [
[[package]]
name = "pi-setup-system"
-version = "0.0.66"
+version = "0.0.67"
dependencies = [
"harness-runtime",
"provider-v3",
@@ -147,7 +147,7 @@ dependencies = [
[[package]]
name = "provider-v3"
-version = "0.0.66"
+version = "0.0.67"
dependencies = [
"serde",
"serde_json",
@@ -209,7 +209,7 @@ dependencies = [
[[package]]
name = "setup-core"
-version = "0.0.66"
+version = "0.0.67"
dependencies = [
"miniz_oxide",
"serde",
diff --git a/Cargo.toml b/Cargo.toml
index 51ede40..d8eb5e3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,7 +8,7 @@ members = [
]
[workspace.package]
-version = "0.0.66"
+version = "0.0.67"
edition = "2024"
rust-version = "1.89"
license = "AGPL-3.0-or-later"
@@ -23,9 +23,9 @@ sha2 = "0.11"
# `setup-core::archive`); an inflate loop is not, because its bugs are
# memory-safety bugs and it is not improved by being hand-written here.
miniz_oxide = "0.9"
-setup-core = { path = "crates/setup-core", version = "0.0.66" }
-provider-v3 = { path = "crates/provider-v3", version = "0.0.66" }
-harness-runtime = { path = "crates/harness-runtime", version = "0.0.66" }
+setup-core = { path = "crates/setup-core", version = "0.0.67" }
+provider-v3 = { path = "crates/provider-v3", version = "0.0.67" }
+harness-runtime = { path = "crates/harness-runtime", version = "0.0.67" }
[workspace.lints.rust]
unsafe_code = "forbid"
diff --git a/README.md b/README.md
index e664420..05bec15 100644
--- a/README.md
+++ b/README.md
@@ -179,7 +179,7 @@ release is a convenience, not the authorised copy.
```bash
docker run --rm -v "$HOME/.config:/config" \
- ghcr.io/nddev-opennetwork/pi-setup-system:0.0.66 \
+ ghcr.io/nddev-opennetwork/pi-setup-system:0.0.67 \
status --target /config/
--json
```
diff --git a/crates/pi-setup-system/src/software.rs b/crates/pi-setup-system/src/software.rs
index 8d53cdf..851be38 100644
--- a/crates/pi-setup-system/src/software.rs
+++ b/crates/pi-setup-system/src/software.rs
@@ -20,103 +20,103 @@ use harness_runtime::{Artifact, Delivery, Previous, Shape, Software};
pub(crate) const ARTIFACTS: &[Artifact] = &[
Artifact {
platform: "linux/arm64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-arm64.tar.gz",
- bytes: 42_774_976,
- sha256: "sha256:821750e0ac6bf6e10c35b93ddab88a44f2d0ef8411af9ea4e8ffe620f62130df",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-linux-arm64.tar.gz",
+ bytes: 42_628_180,
+ sha256: "sha256:042d20ae885ee4f3b102815f3280b962c377b2e9fb44de4037908cc530eae4d4",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "linux/x86_64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-x64.tar.gz",
- bytes: 42_708_859,
- sha256: "sha256:a7e7c65f1dc528d2e17e7d946ad2b61df0e2b0f9952faee77807c2484b464d6e",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-linux-x64.tar.gz",
+ bytes: 42_560_927,
+ sha256: "sha256:494e498f47d74d21f40b3386f6a5e921a3d49531a169cab55bbdaca0ea1fe25a",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "macos/arm64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-arm64.tar.gz",
- bytes: 31_183_100,
- sha256: "sha256:b0a1a3ab9708047e31b76a27911e8b445b3e4a38e2f46a08b6635df75f3499c0",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-darwin-arm64.tar.gz",
+ bytes: 31_035_676,
+ sha256: "sha256:d5f70e3c0cf7398eac239fd0261ee074d98b7ba7f6b43fe3617f052ed5b79d06",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "macos/x86_64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-x64.tar.gz",
- bytes: 33_687_389,
- sha256: "sha256:611290e032a47f1546bd30e12c14a59a600a24662d5239c0c159ef3c7a0ca3b0",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-darwin-x64.tar.gz",
+ bytes: 33_544_584,
+ sha256: "sha256:adb918b845625f184d8bea408d55eacaf21aa87238793c0f5b4f3b9737bce62b",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "windows/arm64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-arm64.zip",
- bytes: 43_703_991,
- sha256: "sha256:c10fb6f30f188b1eba61608e0d33453456ee9805ff543fdd99bcaf85f2d949df",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-windows-arm64.zip",
+ bytes: 43_556_369,
+ sha256: "sha256:b25e96fe64c9f41f75a924c0d36f395abb98d6c6fec0b78aaa0b86926f938bb4",
shape: Shape::Zip,
member: "pi.exe",
},
Artifact {
platform: "windows/x86_64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-x64.zip",
- bytes: 45_158_082,
- sha256: "sha256:526085e0206acb8e8f9997efcd4e3654fb8a47a04318e09e7324ed5abe549586",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-windows-x64.zip",
+ bytes: 45_009_021,
+ sha256: "sha256:002fa95b90d521245b9985d8f168caebc237ad56e7e30b319807dee1b2e17e1c",
shape: Shape::Zip,
member: "pi.exe",
},
];
-/// The artifacts 0.84.4 was published as, kept so
+/// The artifacts 0.85.0 was published as, kept so
/// `software_update` has a version to move from and `rollback` a tree to
/// return to. Measured from bytes when it was the current pin.
pub(crate) const PREVIOUS_ARTIFACTS: &[Artifact] = &[
Artifact {
platform: "linux/arm64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-linux-arm64.tar.gz",
- bytes: 42_529_658,
- sha256: "sha256:135580f6b942151646e67b8b866d987d28ce3cff5a497030775ddd29659f943d",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-arm64.tar.gz",
+ bytes: 42_774_976,
+ sha256: "sha256:821750e0ac6bf6e10c35b93ddab88a44f2d0ef8411af9ea4e8ffe620f62130df",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "linux/x86_64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-linux-x64.tar.gz",
- bytes: 42_464_648,
- sha256: "sha256:c2f3c3e6a1850bd87654cc3ca8811013272397c3d042a4e2a64c43ee1b423972",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-x64.tar.gz",
+ bytes: 42_708_859,
+ sha256: "sha256:a7e7c65f1dc528d2e17e7d946ad2b61df0e2b0f9952faee77807c2484b464d6e",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "macos/arm64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-darwin-arm64.tar.gz",
- bytes: 30_928_407,
- sha256: "sha256:c68e3ac4d05b4e282aaab2e6c76f161d3e9e68f19a22e38913cbfaadb6c800f0",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-arm64.tar.gz",
+ bytes: 31_183_100,
+ sha256: "sha256:b0a1a3ab9708047e31b76a27911e8b445b3e4a38e2f46a08b6635df75f3499c0",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "macos/x86_64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-darwin-x64.tar.gz",
- bytes: 33_440_191,
- sha256: "sha256:7a042d6413065421387001a4986190a1a03186c95a695f4dee0bdc76e60de8f7",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-x64.tar.gz",
+ bytes: 33_687_389,
+ sha256: "sha256:611290e032a47f1546bd30e12c14a59a600a24662d5239c0c159ef3c7a0ca3b0",
shape: Shape::GzipTar,
member: "pi/pi",
},
Artifact {
platform: "windows/arm64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-windows-arm64.zip",
- bytes: 43_455_125,
- sha256: "sha256:6b2726efc34a9158ab06bf7b981f7bcccf15de9ea236a3f4ef7a894a78aa386e",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-arm64.zip",
+ bytes: 43_703_991,
+ sha256: "sha256:c10fb6f30f188b1eba61608e0d33453456ee9805ff543fdd99bcaf85f2d949df",
shape: Shape::Zip,
member: "pi.exe",
},
Artifact {
platform: "windows/x86_64",
- url: "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-windows-x64.zip",
- bytes: 44_907_374,
- sha256: "sha256:03b2318774f18721e959d9f8f3340a9f942e7aa516fb7030d3007a12a40a4a97",
+ url: "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-x64.zip",
+ bytes: 45_158_082,
+ sha256: "sha256:526085e0206acb8e8f9997efcd4e3654fb8a47a04318e09e7324ed5abe549586",
shape: Shape::Zip,
member: "pi.exe",
},
@@ -124,12 +124,12 @@ pub(crate) const PREVIOUS_ARTIFACTS: &[Artifact] = &[
/// Pi Coding Agent's program, and where its bytes come from.
pub(crate) const SOFTWARE: Software = Software {
- version: "0.85.0",
+ version: "0.85.1",
command: "pi",
delivery: Delivery::Artifacts(ARTIFACTS),
unsupported: &[],
previous: Some(Previous {
- version: "0.84.4",
+ version: "0.85.0",
artifacts: PREVIOUS_ARTIFACTS,
}),
};
diff --git a/install.ps1 b/install.ps1
index 5d948ea..b141b91 100644
--- a/install.ps1
+++ b/install.ps1
@@ -7,7 +7,7 @@
# powershell -ExecutionPolicy Bypass -File install.ps1 -Version 0.1.0
[CmdletBinding()]
param(
- [string]$Version = "0.0.66",
+ [string]$Version = "0.0.67",
[string]$InstallDir = "$env:LOCALAPPDATA\Programs\pi-setup-system"
)
$ErrorActionPreference = "Stop"
diff --git a/install.sh b/install.sh
index 8238f18..e5d15e3 100644
--- a/install.sh
+++ b/install.sh
@@ -14,7 +14,7 @@ set -eu
REPO="NDDev-OpenNetwork/pi-setup-system"
BINARY="pi-setup-system"
-VERSION="${1:-0.0.66}"
+VERSION="${1:-0.0.67}"
PREFIX="${PI_INSTALL_DIR:-$HOME/.local/bin}"
case "$(uname -s)" in
diff --git a/references/pi-baseline.json b/references/pi-baseline.json
index 0c34490..37c965b 100644
--- a/references/pi-baseline.json
+++ b/references/pi-baseline.json
@@ -9,11 +9,11 @@
},
"package": {
"name": "@earendil-works/pi-coding-agent",
- "version": "0.85.0",
+ "version": "0.85.1",
"registry": "https://registry.npmjs.org/@earendil-works%2fpi-coding-agent",
- "tarball": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.85.0.tgz",
- "integrity": "sha512-INxVkLAVfAMju5MojJpmyu/0bMP+r+ffZuS7UqVv32E2JwHBRbcHfELDfmFNvapEbgYfKN2r9OYO1p3TqDBR+g==",
- "shasum": "063fab0fe6d5f6654e09b479e95dd5e2359824c4",
+ "tarball": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.85.1.tgz",
+ "integrity": "sha512-FGRN+OHbWaefBPGaTggAdLjrIHW+s2PzLyglz/5dfLzb9of7uuXMXYC0fJIeZTw+shS32o2cuQ9jF7YSDuL/oQ==",
+ "shasum": "4cd00f653c3dabeb193b46f511044e7fbfe0f947",
"node": ">=22.19.0",
"repository_directory": "packages/coding-agent",
"note": "**This block describes the npm distribution, which this provider no longer installs.** It is kept because it is a true and useful record of the product -- `bin.pi`, `engines.node`, the registry tarball and its integrity -- and because the version it names is the one the standalone release carries. `node: >=22.19.0` is a requirement of *that* distribution: the artifacts installed here carry their own runtime, and the whole lifecycle was measured 2026-08-31 with `node` absent from `PATH`."
@@ -25,7 +25,7 @@
"pi",
"--version"
],
- "expected_stdout": "0.85.0",
+ "expected_stdout": "0.85.1",
"package_version_source": "package.version",
"independent_package_identity_required": true
},
@@ -189,7 +189,7 @@
"plugin_marketplace": null,
"mcp_projection": null
},
- "verified_at": "2026-09-04T13:31:46+00:00",
+ "verified_at": "2026-09-07T03:14:53+00:00",
"native_surfaces": {
"verified_at": "2026-08-31",
"config_home": "~/.pi/agent",
@@ -402,95 +402,95 @@
"shape": "gzip-tar",
"platforms": {
"linux/arm64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-arm64.tar.gz",
- "bytes": 42774976,
- "sha256": "sha256:821750e0ac6bf6e10c35b93ddab88a44f2d0ef8411af9ea4e8ffe620f62130df",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-linux-arm64.tar.gz",
+ "bytes": 42628180,
+ "sha256": "sha256:042d20ae885ee4f3b102815f3280b962c377b2e9fb44de4037908cc530eae4d4",
"member": "pi/pi"
},
"linux/x86_64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-x64.tar.gz",
- "bytes": 42708859,
- "sha256": "sha256:a7e7c65f1dc528d2e17e7d946ad2b61df0e2b0f9952faee77807c2484b464d6e",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-linux-x64.tar.gz",
+ "bytes": 42560927,
+ "sha256": "sha256:494e498f47d74d21f40b3386f6a5e921a3d49531a169cab55bbdaca0ea1fe25a",
"member": "pi/pi"
},
"macos/arm64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-arm64.tar.gz",
- "bytes": 31183100,
- "sha256": "sha256:b0a1a3ab9708047e31b76a27911e8b445b3e4a38e2f46a08b6635df75f3499c0",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-darwin-arm64.tar.gz",
+ "bytes": 31035676,
+ "sha256": "sha256:d5f70e3c0cf7398eac239fd0261ee074d98b7ba7f6b43fe3617f052ed5b79d06",
"member": "pi/pi"
},
"macos/x86_64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-x64.tar.gz",
- "bytes": 33687389,
- "sha256": "sha256:611290e032a47f1546bd30e12c14a59a600a24662d5239c0c159ef3c7a0ca3b0",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-darwin-x64.tar.gz",
+ "bytes": 33544584,
+ "sha256": "sha256:adb918b845625f184d8bea408d55eacaf21aa87238793c0f5b4f3b9737bce62b",
"member": "pi/pi"
},
"windows/arm64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-arm64.zip",
- "bytes": 43703991,
- "sha256": "sha256:c10fb6f30f188b1eba61608e0d33453456ee9805ff543fdd99bcaf85f2d949df",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-windows-arm64.zip",
+ "bytes": 43556369,
+ "sha256": "sha256:b25e96fe64c9f41f75a924c0d36f395abb98d6c6fec0b78aaa0b86926f938bb4",
"shape": "zip",
"member": "pi.exe"
},
"windows/x86_64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-x64.zip",
- "bytes": 45158082,
- "sha256": "sha256:526085e0206acb8e8f9997efcd4e3654fb8a47a04318e09e7324ed5abe549586",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.1/pi-windows-x64.zip",
+ "bytes": 45009021,
+ "sha256": "sha256:002fa95b90d521245b9985d8f168caebc237ad56e7e30b319807dee1b2e17e1c",
"shape": "zip",
"member": "pi.exe"
}
},
"note": "**The vendor's standalone release, not its npm package, since 2026-08-31.** The npm tarball is 6.8MB of JavaScript whose entry point is `dist/bundle/cli.js` with a `#!/usr/bin/env node` shebang. Installing it left a host without Node >= 22.19 with a program that installed and could not start -- an install that succeeds and a launch that fails, with nothing between them saying so.\n\nThe release publishes one standalone archive per platform for all six declared hosts, and each was fetched, checked against the vendor's own `SHA256SUMS`, and recorded from the bytes. **Two layouts in one release:** the four gzip-tars carry the executable at `pi/pi`, and the two Windows ZIPs carry `pi.exe` at the root. A rule built from the platform name would have been right four times -- the same lesson cursor and antigravity each taught once, on the container rather than the path.\n\n**Measured, with the absence controlled:** the whole lifecycle -- install, launch, update from 0.84.3, rollback, roll forward, inactive removal, removal -- runs with `node` unreachable on `PATH`, and the run checked that it was unreachable. The product answers `0.84.4` from the exposed command.\n\nthe pin refresher reads the release rather than the registry now, and refuses an artifact whose bytes disagree with the vendor's published digest. The twelve records here were produced twice -- once by hand and once by the tool -- and compared.",
- "version": "0.85.0",
- "verified_at": "2026-09-04T13:31:46+00:00"
+ "version": "0.85.1",
+ "verified_at": "2026-09-07T03:14:53+00:00"
},
- "setup_catalogue_digest": "sha256:b48ddee99bccc2520b333e202e87d2ecfc4347a9d57378e1c2ff51740403ea79",
+ "setup_catalogue_digest": "sha256:de5f86bef10a8b99b6049fe6d72069fbff4a9391fa29575690d66091a9e1a66d",
"previous_software_artifacts": {
"command": "pi",
"shape": "gzip-tar",
"platforms": {
"linux/arm64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-linux-arm64.tar.gz",
- "bytes": 42529658,
- "sha256": "sha256:135580f6b942151646e67b8b866d987d28ce3cff5a497030775ddd29659f943d",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-arm64.tar.gz",
+ "bytes": 42774976,
+ "sha256": "sha256:821750e0ac6bf6e10c35b93ddab88a44f2d0ef8411af9ea4e8ffe620f62130df",
"member": "pi/pi"
},
"linux/x86_64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-linux-x64.tar.gz",
- "bytes": 42464648,
- "sha256": "sha256:c2f3c3e6a1850bd87654cc3ca8811013272397c3d042a4e2a64c43ee1b423972",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-linux-x64.tar.gz",
+ "bytes": 42708859,
+ "sha256": "sha256:a7e7c65f1dc528d2e17e7d946ad2b61df0e2b0f9952faee77807c2484b464d6e",
"member": "pi/pi"
},
"macos/arm64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-darwin-arm64.tar.gz",
- "bytes": 30928407,
- "sha256": "sha256:c68e3ac4d05b4e282aaab2e6c76f161d3e9e68f19a22e38913cbfaadb6c800f0",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-arm64.tar.gz",
+ "bytes": 31183100,
+ "sha256": "sha256:b0a1a3ab9708047e31b76a27911e8b445b3e4a38e2f46a08b6635df75f3499c0",
"member": "pi/pi"
},
"macos/x86_64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-darwin-x64.tar.gz",
- "bytes": 33440191,
- "sha256": "sha256:7a042d6413065421387001a4986190a1a03186c95a695f4dee0bdc76e60de8f7",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-darwin-x64.tar.gz",
+ "bytes": 33687389,
+ "sha256": "sha256:611290e032a47f1546bd30e12c14a59a600a24662d5239c0c159ef3c7a0ca3b0",
"member": "pi/pi"
},
"windows/arm64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-windows-arm64.zip",
- "bytes": 43455125,
- "sha256": "sha256:6b2726efc34a9158ab06bf7b981f7bcccf15de9ea236a3f4ef7a894a78aa386e",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-arm64.zip",
+ "bytes": 43703991,
+ "sha256": "sha256:c10fb6f30f188b1eba61608e0d33453456ee9805ff543fdd99bcaf85f2d949df",
"shape": "zip",
"member": "pi.exe"
},
"windows/x86_64": {
- "url": "https://github.com/earendil-works/pi/releases/download/v0.84.4/pi-windows-x64.zip",
- "bytes": 44907374,
- "sha256": "sha256:03b2318774f18721e959d9f8f3340a9f942e7aa516fb7030d3007a12a40a4a97",
+ "url": "https://github.com/earendil-works/pi/releases/download/v0.85.0/pi-windows-x64.zip",
+ "bytes": 45158082,
+ "sha256": "sha256:526085e0206acb8e8f9997efcd4e3654fb8a47a04318e09e7324ed5abe549586",
"shape": "zip",
"member": "pi.exe"
}
},
"note": "**The vendor's standalone release, not its npm package, since 2026-08-31.** The npm tarball is 6.8MB of JavaScript whose entry point is `dist/bundle/cli.js` with a `#!/usr/bin/env node` shebang. Installing it left a host without Node >= 22.19 with a program that installed and could not start -- an install that succeeds and a launch that fails, with nothing between them saying so.\n\nThe release publishes one standalone archive per platform for all six declared hosts, and each was fetched, checked against the vendor's own `SHA256SUMS`, and recorded from the bytes. **Two layouts in one release:** the four gzip-tars carry the executable at `pi/pi`, and the two Windows ZIPs carry `pi.exe` at the root. A rule built from the platform name would have been right four times -- the same lesson cursor and antigravity each taught once, on the container rather than the path.\n\n**Measured, with the absence controlled:** the whole lifecycle -- install, launch, update from 0.84.3, rollback, roll forward, inactive removal, removal -- runs with `node` unreachable on `PATH`, and the run checked that it was unreachable. The product answers `0.84.4` from the exposed command.\n\nthe pin refresher reads the release rather than the registry now, and refuses an artifact whose bytes disagree with the vendor's published digest. The twelve records here were produced twice -- once by hand and once by the tool -- and compared.",
- "version": "0.84.4",
- "verified_at": "2026-09-03T14:08:27+00:00"
+ "version": "0.85.0",
+ "verified_at": "2026-09-04T13:31:46+00:00"
},
"surface_presence": {
"measured_at": "2026-09-02",
diff --git a/setups/nddev-builder/home/prompts/nddev-setup.md b/setups/nddev-builder/home/prompts/nddev-setup.md
index dacc7ec..b7b296b 100644
--- a/setups/nddev-builder/home/prompts/nddev-setup.md
+++ b/setups/nddev-builder/home/prompts/nddev-setup.md
@@ -1,13 +1,14 @@
# Setup
-Add or revise a setup in this system.
+Create or improve a complete native tool collection for the user's tasks.
+Start from the builder's ai-stp lifecycle guidance: define acceptance scenarios,
+inventory existing components, select exact versions, fill missing capabilities,
+compose the graph, validate it, and deliver invocation and recovery instructions.
-Every harness offers the same three postures, and the names are the estate's
-rather than each product's so that learning them once is enough:
-
-- `baseline` — a working floor
-- `minimal` — the product's own defaults
-- `full-auto` — nothing asked, nothing sandboxed
+Ask `pi-setup-system list` for the shipped presets. Their names describe
+payload composition, not different authority levels. Read the selected payload
+and its documented policy; do not assume `minimal` means product defaults or
+that only a preset named `full-auto` supports autonomous work.
Rules a setup must satisfy, each held by a guard:
@@ -22,7 +23,8 @@ Rules a setup must satisfy, each held by a guard:
- **No two files may differ only in case.** They are one file on macOS and
Windows and two on Linux.
-Say which of these the change touches, then run this tree's checks:
+Exercise the setup's intended tasks and backup/restore in disposable targets.
+If changing provider implementation, also run this tree's checks:
```bash
cargo fmt --all --check
diff --git a/setups/nddev-builder/home/prompts/nddev-validate.md b/setups/nddev-builder/home/prompts/nddev-validate.md
index ff3ce2e..9968b37 100644
--- a/setups/nddev-builder/home/prompts/nddev-validate.md
+++ b/setups/nddev-builder/home/prompts/nddev-validate.md
@@ -1,7 +1,10 @@
# Validate
-Run everything that must pass before handing off, in order, and report what each
-one said rather than that it passed.
+For a setup, follow the builder's ai-stp lifecycle validation: native component
+checks, exact composition, evaluation, disposable install/readback/restore and
+the intended product tasks. Document capabilities and evidence gaps.
+
+For provider implementation changes, also run this checkout's checks:
```bash
cargo fmt --all --check
diff --git a/setups/nddev-builder/home/skills/nddev-builder/SKILL.md b/setups/nddev-builder/home/skills/nddev-builder/SKILL.md
index 1c88f3d..8d6b538 100644
--- a/setups/nddev-builder/home/skills/nddev-builder/SKILL.md
+++ b/setups/nddev-builder/home/skills/nddev-builder/SKILL.md
@@ -1,30 +1,36 @@
---
name: nddev-builder
-description: Build, review or validate a Pi Coding Agent setup for pi-setup-system -- its owned surfaces, the components it carries, the lifecycle it performs, and the checks it must pass. Use when changing pi-setup-system or the native artifacts a setup writes.
+description: Create, improve or review a complete Pi Coding Agent setup -- a native collection of tools for the user's tasks. Use for selecting and authoring components, composing setups, explaining their capabilities, adapting them to this harness, and validating installation and recovery through pi-setup-system.
---
# NDDev Builder
-The entry point for work on `pi-setup-system`. Keep changes
-target-explicit, reversible, and backed by this tree's checks.
+Build a complete native tool collection for the user's tasks. Start with
+`references/ai-stp-lifecycle.md` for outcome, component selection, composition,
+evaluation, installation and delivery. Keep changes target-explicit and
+reversible. The provider's implementation is changed only when that is the task.
## Workflow
-1. **Name the surface being changed**, and check this harness actually owns it:
+1. **Name the user outcome and required capabilities.** Inventory and reuse
+ existing components, then compose one setup for this harness through
+ `references/ai-stp-lifecycle.md`.
+2. **Name the surface being changed**, and check this harness actually owns it:
`references/surfaces.md`, which is generated from the baseline rather than
written beside it.
-2. **Prefer what the program answers over a copy of it.** Ask the binary:
+3. **Prefer what the program answers over a copy of it.** Ask the binary:
`list`, `status --target `, `provider-info`. In a checkout, read
`crates/pi-setup-system/src/main.rs` and the baseline a test binds it to.
-3. **Declare against the vendor, never against a routing table.** A path with no
+4. **Declare against the vendor, never against a routing table.** A path with no
page behind it is a false statement in `provider-info`, and the consumer
plans postconditions and target identity from that statement.
-4. **A declaration can refute a route and cannot confirm one.** Reading finds a
+5. **A declaration can refute a route and cannot confirm one.** Reading finds a
directory; only running the product says what it is read *as*. Where a run is
impossible, confirm at the line in the product's own code -- a path literal
alone is not evidence that the path is used.
-5. **Run the checks in `references/validation.md`**, and report what each one
- said rather than that it passed.
+6. **Exercise the setup's acceptance scenarios and recovery.** For provider
+ implementation changes also run `references/validation.md`. Report observed
+ results, exact versions and unmeasured cases.
## Routing
diff --git a/setups/nddev-builder/home/skills/nddev-builder/references/ai-stp-lifecycle.md b/setups/nddev-builder/home/skills/nddev-builder/references/ai-stp-lifecycle.md
index e658e0e..b5e235a 100644
--- a/setups/nddev-builder/home/skills/nddev-builder/references/ai-stp-lifecycle.md
+++ b/setups/nddev-builder/home/skills/nddev-builder/references/ai-stp-lifecycle.md
@@ -1,34 +1,104 @@
-# The ai-stp CLI lifecycle
-
-Native install, select and restore of this provider are the lifecycle section
-of this toolkit. This page is the consumer path: author a component, compose a
-setup, install it, read it back, release an immutable version, and request
-publication.
-
-Resolve every flag from `ai-stp help --agent --json`. Do not invent options.
-Start with `ai-stp doctor --json`.
-
-## Exercise from a blank authoring directory
-
-1. **Scaffold** a real skill with `ai-stp component scaffold plan` then
- `ai-stp component scaffold apply`. Replace every draft marker before
- compose or release.
-2. **Passport.** `ai-stp component passport validate` and
- `ai-stp component skill validate` on the package directory (the directory
- with `SKILL.md` at its root), not the whole tree.
-3. **Harness semantics.** This harness's surfaces table says where the kind
- lands. Do not invent a path the declaration does not carry. Adaptations are
- those native files, not a second copy of the passport.
-4. **Compose a setup.** `ai-stp select propose` then `ai-stp select confirm`,
- or `ai-stp setup compose plan`. Confirm only the proposal just returned.
-5. **Install and read back.** `ai-stp install plan`, then `ai-stp install apply`
- with that plan's digest, then `ai-stp target status` with the same provider.
- Trust `pending_authorization`, not the apply exit code.
-6. **Immutable release.** `ai-stp component version release`.
-7. **Requested publication.** `ai-stp component publish` or
- `ai-stp setup publish plan`. Publicity is a separate user decision.
-
-## What this page does not name
-
-- Private authoring gates, repository coordinates, or unpublished tools.
-- Flags other than `ai-stp doctor --json` and `ai-stp help --agent --json`.
+# Build a complete setup with ai-stp
+
+A setup is a complete configuration of one chosen harness: a working collection
+of tools for a user outcome. It is more than one plugin or a set of unrelated
+files. Use this workflow to create a new setup, improve an existing collection,
+or recast it for another harness. Provider development is a separate task.
+
+Start with `ai-stp doctor --json` and resolve command arguments from
+`ai-stp help --agent --json` in the installed consumer. Do not invent options or
+assume a newer development command is available in a released CLI.
+
+## 1. Define the outcome and inspect existing tools
+
+Record the intended tasks, chosen harness, operating systems, installation
+scopes and the user's existing authority. Name concrete acceptance scenarios,
+such as building a tested application, reviewing a change, or maintaining an
+MCP integration. Inspect the explicitly named authoring directories with
+`ai-stp component inventory`; use `ai-stp component discover` for native
+configuration. Discovery does not adopt files or establish ownership.
+
+Build a capability inventory: the outcome each component enables, its source,
+exact version, native entry point, scope, dependencies, external accounts,
+activation needs and evidence. Reuse a suitable existing component before
+creating another. Explain overlap and omitted capabilities. Choose only the
+tools the intended tasks need; a large file count is not completeness.
+
+## 2. Author native components
+
+Use `ai-stp setup scaffold plan` / `ai-stp setup scaffold apply` for a complete
+authoring tree, or `ai-stp component scaffold plan` / `ai-stp component scaffold apply` for a missing member. Replace every draft marker with useful content.
+Keep authored sources and generated harness projections distinct.
+
+Read this harness's surfaces and per-kind references before choosing paths or
+keys. Put durable context in instructions, repeatable procedures in skills,
+external tool connections in MCP, lifecycle callbacks in hooks, and narrowly
+scoped delegation in native agents where supported. A plugin packages the
+capabilities its own harness supports; it is not itself the whole setup.
+Shared executables use the consumer's `cli` component lifecycle and are not
+slash commands. Do not create a new component kind for a descriptive category.
+
+Use `ai-stp component passport validate` for metadata and
+`ai-stp component skill validate` for a skill package. Validate the native file
+format and demonstrate discovery in the actual product separately. Passing a
+parser does not prove the harness discovers, trusts or executes the component.
+Keep credential values out of the artifact; document only required variable
+names or the product's account connection procedure.
+
+## 3. Compose one exact graph
+
+Freeze authored components with `ai-stp component version release`. Compose
+exact sources through `ai-stp setup compose plan` / `ai-stp setup compose apply`,
+or select registered components through `ai-stp select propose` /
+`ai-stp select confirm`. Apply the exact returned plan, after revalidating its
+preconditions. Inspect dependency closure, path and key conflicts, scope
+compatibility, executable prerequisites and conversion losses with the
+consumer's graph and report commands. Resolve conflicts before installation.
+
+A setup stays bound to one harness. To derive another, use `ai-stp setup recast plan` / `ai-stp setup recast apply`; inspect the destination's native files,
+semantic losses and provenance. Do not relabel the original or copy one
+harness's config into another. A shared instruction or skill format does not
+make permissions, hooks, agents or plugin manifests interchangeable.
+
+## 4. Prove the collection works
+
+Use `ai-stp eval plan` / `ai-stp eval run` for the setup's own adaptations, and
+`ai-stp eval component plan` / `ai-stp eval component run` when evaluating all
+adaptations of a component. Local static evaluation is not a security scan or
+an authenticated product run; retain those evidence distinctions.
+
+Build and review the exact bundle. For a single scope use `ai-stp install plan`,
+`ai-stp install approve` with the returned digest, then `ai-stp install apply`.
+For a setup spanning roots use `ai-stp install transaction plan`,
+`ai-stp install transaction approve`, and its matching apply/recovery commands.
+These approval commands record the exact effect already authorized by the
+task; they do not require another user question for that same effect.
+Exercise this first
+in disposable homes, targets and prefixes. Read `ai-stp target status`, diff
+and backups; an exit code alone is not a verified effect. Preserve any pending
+authorization, refusal or unknown outcome as such and follow its recovery
+path. Demonstrate restore and verify that pre-existing files survive.
+
+Run each acceptance scenario through the real harness, including one implicit
+and one explicit invocation where supported. Check missing dependencies and
+conflicting components as well as the happy path. Record the exact harness,
+provider and consumer versions, OS/architecture, artifact digests and results.
+An unavailable credential or platform is unmeasured, never a passing cell.
+
+## 5. Deliver a usable setup
+
+Write a concise setup guide with its purpose, supported tasks, component and
+capability inventory, native activation/invocation examples, required accounts,
+scope, compatibility, evidence limits, update path and backup/restore path.
+Separate built-in harness features from features supplied by this setup.
+Use current vendor documentation and the measured product version; cite the
+source for a feature claim instead of promising parity across harnesses.
+
+Use `ai-stp setup export` for a reviewable tree. For a requested publication,
+use `ai-stp component publish` or `ai-stp setup publish plan` followed by
+`ai-stp setup publish confirm` on the reviewed exact set. Preserve immutable
+versions. Task authority is separate from verification; changing an existing
+object's visibility or access rights needs the user's decision. Report what
+was created, where it is, how to invoke it, what passed and what remains
+unmeasured. Deliver authoring artifacts without modifying the running agent's
+own active configuration.
diff --git a/setups/nddev-builder/home/skills/nddev-builder/references/second-target.md b/setups/nddev-builder/home/skills/nddev-builder/references/second-target.md
index c0733f5..41ad1cd 100644
--- a/setups/nddev-builder/home/skills/nddev-builder/references/second-target.md
+++ b/setups/nddev-builder/home/skills/nddev-builder/references/second-target.md
@@ -24,12 +24,13 @@ The one root in this estate that belongs to a convention rather than to a produc
Relative to this scope's own root the path is `skills`, not `.agents/skills`: the root is what the scope names, and writing it into the path again would put the skills at `~/.agents/.agents/skills`.
-**A setup cannot carry one of these.** A setup is installed into one
-target and its payload is relative to that target, so a component
-for this scope is installed by the consumer against that root -- not
-by a setup aimed at the configuration home. If you are looking for
-where to put one by hand, it is the path above joined to the root
-above, and nowhere under the home.
+**A complete setup may include these scoped components.** Each
+provider request still reaches one root. The consumer coordinates
+the roots with `ai-stp install transaction plan`, exact digest
+approval, apply and recovery. A shipped configuration-home preset
+cannot reach this root by nesting a path inside its home payload.
+Declare the component's actual scope and bind the matching root
+explicitly in the transaction.
**The root is shared, and that changes what removal means.** Several
products read it. Under this scope `remove`, the backup and a
diff --git a/setups/nddev-builder/home/skills/nddev-builder/references/validation.md b/setups/nddev-builder/home/skills/nddev-builder/references/validation.md
index c8114b0..d5d3d88 100644
--- a/setups/nddev-builder/home/skills/nddev-builder/references/validation.md
+++ b/setups/nddev-builder/home/skills/nddev-builder/references/validation.md
@@ -1,7 +1,10 @@
# Before Handing Off
-Run the checks this tree's CI runs, in order, and report what each one said
-rather than that it passed.
+For setup authoring, run the component validators, composition/evaluation and
+disposable product scenarios described in the ai-stp lifecycle guidance. A
+setup containing Python tools does not require a Rust provider checkout.
+
+When changing provider implementation, run that checkout's CI checks:
```bash
cargo fmt --all --check
@@ -9,7 +12,8 @@ cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```
-If a command here is not present, say so rather than working around it.
+Report each result and any unavailable check. The cargo commands apply only
+to the provider implementation workspace.
## A lifecycle smoke test against a disposable target
@@ -34,13 +38,14 @@ before anyone types it.
## Conformance against the consumer
+Use this additional check when changing or qualifying the provider itself.
The wire surface is checked by the consumer's own runner, not by anything here.
Ask `pi-setup-system provider-info` for `harness_id`; that is the value
`--harness` takes, and it is not always the directory name.
```bash
ai-stp provider conformance --harness \
- --executable target/release/pi-setup-system \
+ --executable \
--target --protocol-version 3 --json
```
@@ -66,8 +71,11 @@ code until a checker goes quiet is not. The difference is whether the change
stands on its own merits: if the code was worse for a reason that has nothing to
do with the checker, fix it; if it was not, dismiss the finding and say why.
-## What this toolkit does not do
+## Task scope and disposable verification
-- It does not push, tag, or release.
-- It does not write a live configuration home.
-- It does not install software or start a product.
+Authoring includes creating files and running the required checks in disposable
+homes, targets and prefixes. Installing verified prerequisites and launching a
+product there are valid validation steps. Keep credentials and live state out
+of those copies. Publishing or applying to a user's live target happens only
+when the task includes that effect, through the exact reviewed lifecycle.
+Never change the running agent's active configuration in place.
diff --git a/setups/nddev-builder/setup.json b/setups/nddev-builder/setup.json
index c2eb48e..4b370f3 100644
--- a/setups/nddev-builder/setup.json
+++ b/setups/nddev-builder/setup.json
@@ -1,7 +1,7 @@
{
"schema_version": 1,
"id": "nddev-builder",
- "description": "The harness-native full-auto posture plus the NDDev builder toolkit: autonomous implementation, exact product formats, lifecycle, verification and release handoff.",
+ "description": "Build complete native tool collections: select and author components, compose exact setups, document capabilities, and verify installation and recovery with ai-stp.",
"sources": [
"https://github.com/earendil-works/pi/releases/tag/v0.84.4",
"https://pi.dev/docs/latest/extensions",