From b4637fd1402cd5aab3fa04d74675171632637304 Mon Sep 17 00:00:00 2001 From: Danil Silantyev Date: Mon, 14 Sep 2026 15:38:19 +0500 Subject: [PATCH] feat(setup): refresh pi harness --- .gds/bundle.lock.yaml | 16 + .gds/compiled-policy.json | 412 ++++++++++++++++++++++ CHANGELOG.md | 25 ++ Cargo.lock | 8 +- Cargo.toml | 8 +- README.md | 2 +- crates/pi-setup-system/tests/lifecycle.rs | 17 +- install.ps1 | 2 +- install.sh | 2 +- references/pi-baseline.json | 4 +- 10 files changed, 477 insertions(+), 19 deletions(-) create mode 100644 .gds/bundle.lock.yaml create mode 100644 .gds/compiled-policy.json diff --git a/.gds/bundle.lock.yaml b/.gds/bundle.lock.yaml new file mode 100644 index 0000000..08fb1a5 --- /dev/null +++ b/.gds/bundle.lock.yaml @@ -0,0 +1,16 @@ +# GENERATED FILE - DO NOT EDIT DIRECTLY +schema_version: 1 + +bundle: + version: "0.9.4-dev" + release_sequence: 0 + channel: "development" + source_tree_digest: "sha256:b1c334df899c661304dc45ef29898df24ff4a6ddffd2a6ca4d6f1f795d585189" + digest: "sha256:469ac74bf934333ee1fde843ad04a26e002e5b5ec9c782fbe68ec6fe313bfac0" + +projection: + input_digest: "sha256:2dd0dffeddab126112790a9eeee1e9afbb182b96abf84434dcfb6a6925b35303" + output_digest: "sha256:1f35d25857f6220a514c2f71d0de656c9bf6de270fab5d0cb15c5eb628caec60" + files: + - path: ".gds/compiled-policy.json" + digest: "sha256:8cdeb569cde4badfe3ba739992b7f1fea4ff326ca9ad58b8aa475f4c46c44bce" diff --git a/.gds/compiled-policy.json b/.gds/compiled-policy.json new file mode 100644 index 0000000..72999aa --- /dev/null +++ b/.gds/compiled-policy.json @@ -0,0 +1,412 @@ +{ + "schema_version": 1, + "compiled_policy": { + "repository_id": "repo_01M0QEF36PQQRHG5CNF1FGEH3J", + "bundle_version": "0.9.4-dev", + "digest": "sha256:d4eee4e4f6cce0f8de6d37bae9d6fc92b54e23ff407b31f4bf5f0fb2601a3322" + }, + "sources": [ + { + "id": "repository-default", + "tier": "base", + "priority": 100, + "distribution": "public", + "path": "policies/base/repository-default.yaml", + "digest": "sha256:0ea560cc2653184e07c6f744455f745a34f764a5c0dcda55f2dc76fa5296f2f0" + }, + { + "id": "opennetwork-default", + "tier": "owner", + "priority": 110, + "distribution": "public", + "path": "policies/owners/opennetwork-default.yaml", + "digest": "sha256:096b9781b05c37fd5b440a171a6e5599cda3ef77983db72bf9c68d3d40b34ab4" + } + ], + "effective": { + "agent": { + "generated_projection_edit": "forbidden", + "profiles": [ + "core", + "drakkars" + ] + }, + "context": { + "private_parent_persistence": "forbidden" + }, + "git": { + "branch_cleanup": "merged-only", + "default_branch": "main", + "integration": "pull-request" + }, + "github": { + "actions": { + "allowed_actions": { + "management": "observed" + }, + "enabled": { + "management": "managed", + "value": true + }, + "selected_actions": { + "management": "observed" + }, + "sha_pinning_required": { + "management": "observed" + } + }, + "merge": { + "allow_auto_merge": { + "management": "observed" + }, + "allow_merge_commit": { + "management": "managed", + "value": true + }, + "allow_rebase_merge": { + "management": "observed" + }, + "allow_squash_merge": { + "management": "managed", + "value": false + }, + "allow_update_branch": { + "management": "managed", + "value": true + }, + "delete_branch_on_merge": { + "management": "managed", + "value": true + }, + "merge_commit_message": { + "management": "observed" + }, + "merge_commit_title": { + "management": "observed" + }, + "squash_merge_commit_message": { + "management": "observed" + }, + "squash_merge_commit_title": { + "management": "observed" + } + }, + "releases": { + "immutable": { + "management": "observed" + } + }, + "rulesets": { + "management": "observed" + }, + "security": { + "management": "observed" + }, + "workflow": { + "can_approve_pull_request_reviews": { + "management": "managed", + "value": false + }, + "default_workflow_permissions": { + "management": "managed", + "value": "read" + } + } + }, + "package_management": { + "mutable_version_resolution": "forbidden", + "npm_family_on_managed_path": "allowed", + "remote_stream_to_shell": "forbidden" + }, + "rollout": { + "mode": "pull-request" + }, + "security": { + "external_write_requires_approval": true, + "public_projection_scan": "required", + "secrets_in_repository": "forbidden" + } + }, + "provenance": { + "/effective/agent/generated_projection_edit": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/agent/profiles/0": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "append" + }, + "/effective/agent/profiles/1": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "append" + }, + "/effective/context/private_parent_persistence": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/git/branch_cleanup": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/git/default_branch": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/git/integration": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/actions/allowed_actions/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/actions/enabled/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/actions/enabled/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/actions/selected_actions/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/actions/sha_pinning_required/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_auto_merge/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_merge_commit/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_merge_commit/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_rebase_merge/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_squash_merge/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_squash_merge/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_update_branch/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/allow_update_branch/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/delete_branch_on_merge/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/delete_branch_on_merge/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/merge_commit_message/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/merge_commit_title/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/squash_merge_commit_message/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/merge/squash_merge_commit_title/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/releases/immutable/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/rulesets/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/security/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/workflow/can_approve_pull_request_reviews/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/workflow/can_approve_pull_request_reviews/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/workflow/default_workflow_permissions/management": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/github/workflow/default_workflow_permissions/value": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/package_management/mutable_version_resolution": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/package_management/npm_family_on_managed_path": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/package_management/remote_stream_to_shell": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/rollout/mode": { + "source": "opennetwork-default", + "tier": "owner", + "priority": 110, + "file": "policies/owners/opennetwork-default.yaml", + "operation": "set" + }, + "/effective/security/external_write_requires_approval": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/security/public_projection_scan": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + }, + "/effective/security/secrets_in_repository": { + "source": "repository-default", + "tier": "base", + "priority": 100, + "file": "policies/base/repository-default.yaml", + "operation": "set" + } + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5beb2fe..343a38e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,31 @@ cut and that this clone does not carry. ## [Unreleased] +## [0.0.71] - 2026-09-13 + +nddev-builder guidance is refreshed against each harness's current native +extension model. Codex custom agents now cover inherited session settings and +project scope; its hook guide includes Interrupt and the limits of asynchronous +hooks as enforcement. Antigravity plugin and subagent guidance records the +current manifest minimum, bundled agents, workspace isolation, inherited safety +boundaries and validation behavior observed in CLI 1.2.2. + +Every builder manifest now cites all vendor pages used by its generated +component guides, including sources beyond the base permission posture. The +provider protocol, setup ownership and software artifact pins are unchanged. + +## [0.0.70] - 2026-09-13 + +Software artifacts are refreshed from verified vendor bytes: Claude Code +2.1.270, Codex 0.154.0, Grok Build 1.0.31, OpenCode 1.18.30, Cursor +2026.09.10-fd3934a and Antigravity CLI 1.2.2. Pi remains at 0.85.1. +Every published platform digest and rollback pin is transcribed from the same +verified ledger. + +Lifecycle integration tests remain compatible with the pinned Rust 1.98.0 +toolchain by reading Cargo's executable path at runtime. Provider behavior, +protocol-v3 declarations and setup ownership are unchanged. + ## [0.0.69] - 2026-09-08 Native lifecycle evidence runs every provider command in the same isolated diff --git a/Cargo.lock b/Cargo.lock index 182d503..7ec6727 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,7 +66,7 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "harness-runtime" -version = "0.0.69" +version = "0.0.71" dependencies = [ "provider-v3", "serde", @@ -128,7 +128,7 @@ dependencies = [ [[package]] name = "pi-setup-system" -version = "0.0.69" +version = "0.0.71" dependencies = [ "harness-runtime", "provider-v3", @@ -147,7 +147,7 @@ dependencies = [ [[package]] name = "provider-v3" -version = "0.0.69" +version = "0.0.71" dependencies = [ "serde", "serde_json", @@ -209,7 +209,7 @@ dependencies = [ [[package]] name = "setup-core" -version = "0.0.69" +version = "0.0.71" dependencies = [ "miniz_oxide", "serde", diff --git a/Cargo.toml b/Cargo.toml index b782014..5c69725 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -version = "0.0.69" +version = "0.0.71" 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.69" } -provider-v3 = { path = "crates/provider-v3", version = "0.0.69" } -harness-runtime = { path = "crates/harness-runtime", version = "0.0.69" } +setup-core = { path = "crates/setup-core", version = "0.0.71" } +provider-v3 = { path = "crates/provider-v3", version = "0.0.71" } +harness-runtime = { path = "crates/harness-runtime", version = "0.0.71" } [workspace.lints.rust] unsafe_code = "forbid" diff --git a/README.md b/README.md index ad64bec..2ab54cb 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.69 \ + ghcr.io/nddev-opennetwork/pi-setup-system:0.0.71 \ status --target /config/ --json ``` diff --git a/crates/pi-setup-system/tests/lifecycle.rs b/crates/pi-setup-system/tests/lifecycle.rs index bb15921..2e999cb 100644 --- a/crates/pi-setup-system/tests/lifecycle.rs +++ b/crates/pi-setup-system/tests/lifecycle.rs @@ -10,12 +10,15 @@ //! runs for all seven systems on all three platforms, and a crate carries only //! the one fact that is its own: which binary to run. +#![allow(clippy::expect_used, reason = "tests require Cargo's binary path")] + /// Install, select, back up, hold, restore, restore to a named slot, release, /// remove -- and a file this provider does not own, present throughout. #[test] fn the_documented_round_trip_works_on_this_system() { - let exe = std::path::Path::new(env!("CARGO_BIN_EXE_pi-setup-system")); - let problems = harness_runtime::probe::round_trip(exe); + let exe = std::env::var("CARGO_BIN_EXE_pi-setup-system") + .expect("Cargo must expose the pi setup-system binary to integration tests"); + let problems = harness_runtime::probe::round_trip(std::path::Path::new(&exe)); assert!( problems.is_empty(), "the round trip disagreed with what this build documents:\n {}", @@ -26,8 +29,9 @@ fn the_documented_round_trip_works_on_this_system() { /// A target this provider was never pointed at is refused, never guessed at. #[test] fn a_target_that_is_not_one_is_refused_on_this_system() { - let exe = std::path::Path::new(env!("CARGO_BIN_EXE_pi-setup-system")); - let problems = harness_runtime::probe::refuses_a_target_it_should(exe); + let exe = std::env::var("CARGO_BIN_EXE_pi-setup-system") + .expect("Cargo must expose the pi setup-system binary to integration tests"); + let problems = harness_runtime::probe::refuses_a_target_it_should(std::path::Path::new(&exe)); assert!(problems.is_empty(), "{}", problems.join("\n ")); } @@ -38,7 +42,8 @@ fn a_target_that_is_not_one_is_refused_on_this_system() { /// test in one process cannot reach it, so this drives real ones. #[test] fn one_process_writes_this_target_at_a_time() { - let exe = std::path::Path::new(env!("CARGO_BIN_EXE_pi-setup-system")); - let problems = harness_runtime::probe::one_writer_at_a_time(exe); + let exe = std::env::var("CARGO_BIN_EXE_pi-setup-system") + .expect("Cargo must expose the pi setup-system binary to integration tests"); + let problems = harness_runtime::probe::one_writer_at_a_time(std::path::Path::new(&exe)); assert!(problems.is_empty(), "{}", problems.join("\n ")); } diff --git a/install.ps1 b/install.ps1 index efce786..e9e09a0 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.69", + [string]$Version = "0.0.71", [string]$InstallDir = "$env:LOCALAPPDATA\Programs\pi-setup-system" ) $ErrorActionPreference = "Stop" diff --git a/install.sh b/install.sh index 938cded..6582f29 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.69}" +VERSION="${1:-0.0.71}" PREFIX="${PI_INSTALL_DIR:-$HOME/.local/bin}" case "$(uname -s)" in diff --git a/references/pi-baseline.json b/references/pi-baseline.json index 37c965b..f887ec9 100644 --- a/references/pi-baseline.json +++ b/references/pi-baseline.json @@ -189,7 +189,7 @@ "plugin_marketplace": null, "mcp_projection": null }, - "verified_at": "2026-09-07T03:14:53+00:00", + "verified_at": "2026-09-13T15:18:02+00:00", "native_surfaces": { "verified_at": "2026-08-31", "config_home": "~/.pi/agent", @@ -442,7 +442,7 @@ }, "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.1", - "verified_at": "2026-09-07T03:14:53+00:00" + "verified_at": "2026-09-13T15:18:02+00:00" }, "setup_catalogue_digest": "sha256:de5f86bef10a8b99b6049fe6d72069fbff4a9391fa29575690d66091a9e1a66d", "previous_software_artifacts": {