fix(coding-agent): use embedded Bun for xz-dev standalone packages - #5
Conversation
upstream/main 9661762 origin/ci fc2836b origin/patch/contributor-approval e005a34 origin/patch/model-startup-refresh-barrier 96d88ae origin/patch/model-refresh-session-rebind 95b910d origin/patch/model-catalog-extension-refresh 4656712 origin/patch/bun-bytecode-entrypoint 72f9732 origin/patch/startup-benchmark-exit 97a37c7 origin/patch/native-wrapper-release 405ccb7 origin/patch/update-clean 2c14802 origin/patch/agent-run-failure-seam 6aa4c49 origin/patch/managed-tool-executions 25a08dd origin/patch/esc-abort 0a7e3e6 origin/patch/manual-retry f1c72f1 origin/patch/changelog-prerelease 3ea1afe origin/patch/skill-overrides cd0314e origin/patch/retry-non-retryable-patterns ae23e14 origin/patch/slow-hook-tui-only b6c3008 origin/patch/session-tree-splice 2eaab4d
|
@JohnsonRan — additional verification results and required acceptance before merge. Please keep this PR unmerged until a standalone bundle built from the final corrected head passes actual installation, loading, and functional smoke tests for BOTH 1. What was verified on this headVerified Pi head:
Environment: rootless Podman, Debian bookworm, Git 2.39.5, public Tested bundle version:
These results belong to that head/bundle, not a future revision. Earlier missing-model-data/unbuilt-dist failures and the excluded Bun 1.3.14 build were retained separately. They were not fixed by editing tracked source. The full cross-platform suite was not run; this comment does not waive other required checks. 2. Blocking real-plugin failureRequired reproduction plugin:
Observed sequence: The original Please trace the actual Bun/install/migration behavior and fix the owning layer. Relevant integration points: 3. Linux metadata/cwd issue also needs resolutionThe compiled Bun 1.4.0 command below fails without a cwd manifest and succeeds with one: This is not only the Windows limitation described in the PR body:
Make metadata lookup work without requiring the user's project to be a Node project, while preserving registry/configuration and cwd semantics. Add a real standalone case with an installed version greater than the registry target and prove no downgrade. An actual downgrade was not reproduced here; exact-pin retention and ordinary range selection do not prove that adversarial case. 4. Required real plugins and functional testsA. pi-notifyKeep the failing pin above as the regression input. Required evidence:
The diagnostic load recipe below uses empty actions intentionally. That proves loading, not notification functionality; item 4 is additionally required. B. xz-dev/pi-subagents — this exact repository, not another projectThe required repository is exactly https://github.com/xz-dev/pi-subagents. Do not substitute
Required behavior is actual native subagent execution, not registration or a successful
The pinned extension already documents a deterministic 18-mode real standalone lifecycle matrix: standalone-background.md, with entrypoints Important: that harness currently pins an official Pi release. Passing it with the stock official executable does not validate this PR. Provide an isolated candidate-bound invocation/input manifest for the exact newly built bundle, retaining hash checks, sandbox checks, real execution/positive controls, and observed-exit checks. Do not weaken those checks or relabel an official-binary receipt. If the matrix stages a source package, report that separately and also run the public-install → installed-tree → real-child smoke above. A local/faux provider is acceptable; a fake child result, fake SDK, fake If an extension itself genuinely needs a coordinated fix, identify the owner/root cause, link the fix, and report old/new pins explicitly. Do not silently switch to another revision to avoid the failing case. Reproducible Linux build and pi-notify load recipeSave the following Bash block as a script and run it from a clean isolated checkout of the exact Pi head under review, not the operator's installed Pi. Host provisioning may use Node/npm, curl/unzip and rootless Podman; the execution container must not supply external Node/npm/Bun managers. Below is a consolidated rerun recipe based on the recorded commands, not a claim that this newly assembled script or the newly requested pi-subagents functional gate has already passed. set -euo pipefail
REPO="$PWD"
HEAD="$(git rev-parse HEAD)"
RUN="$(mktemp -d /tmp/pi-pr5-smoke.XXXXXX)"
mkdir -p "$RUN/logs" "$RUN/bun"
: > "$RUN/npmrc"
# Retain exact argv, both output streams, and the real exit status.
run_logged() {
local name="$1" rc=0
shift
printf '%q ' "$@" > "$RUN/logs/$name.command"
printf '\n' >> "$RUN/logs/$name.command"
"$@" > "$RUN/logs/$name.stdout" 2> "$RUN/logs/$name.stderr" || rc=$?
printf '%s\n' "$rc" > "$RUN/logs/$name.exit"
return "$rc"
}
git diff --exit-code
git diff --cached --exit-code
git ls-files -z | sort -z | xargs -0 sha256sum > "$RUN/source-before.sha256"
printf '%s\n' "$HEAD" > "$RUN/head.txt"
# Current candidate requires Bun 1.4.0. Do not accidentally use host Bun 1.3.x.
curl -fL https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-x64.zip -o "$RUN/bun/bun-linux-x64.zip"
curl -fL https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/SHASUMS256.txt -o "$RUN/bun/SHASUMS256.txt"
(cd "$RUN/bun"; awk '$2 == "bun-linux-x64.zip"' SHASUMS256.txt | sha256sum --check -)
unzip -q "$RUN/bun/bun-linux-x64.zip" -d "$RUN/bun"
BUN_BIN="$RUN/bun/bun-linux-x64"
test "$("$BUN_BIN/bun" --version)" = 1.4.0
run_logged deps env NPM_CONFIG_USERCONFIG="$RUN/npmrc" npm ci --ignore-scripts
# On this revision this invokes generate-models.ts --strict --data-only.
# Only ignored JSON may change; no tracked model-code repair.
run_logged hydrate env NPM_CONFIG_USERCONFIG="$RUN/npmrc" npm run hydrate:model-data
VERSION="$(node -p 'require("./packages/coding-agent/package.json").version')"
run_logged build env PATH="$BUN_BIN:$PATH" NPM_CONFIG_USERCONFIG="$RUN/npmrc" \
bash scripts/build-binaries.sh --skip-install --offline-model-data \
--platform linux-x64-gnu-modern --out "$RUN/release" \
--distribution-version "${VERSION}-xz.pr5.g${HEAD:0:8}"
run_logged check env NPM_CONFIG_USERCONFIG="$RUN/npmrc" npm run check
(cd "$REPO/packages/coding-agent"; run_logged focused \
node "$REPO/node_modules/vitest/dist/cli.js" --run \
test/package-manager.test.ts test/package-manager-ssh.test.ts test/package-command-paths.test.ts)
git diff --check
git ls-files -z | sort -z | xargs -0 sha256sum > "$RUN/source-after.sha256"
cmp "$RUN/source-before.sha256" "$RUN/source-after.sha256"
BUNDLE="$RUN/release/linux-x64-gnu-modern"
sha256sum "$BUNDLE/pi" "$BUNDLE/pi-native" "$RUN/release/pi-linux-x64-gnu-modern.zip" > "$RUN/bundle.sha256"
IMAGE="docker.io/library/debian@sha256:5ae3c39ebd15e229dcedd5cee596b2497182493d41ff162e824ba13fc1b2b867"
NAME="pi-pr5-smoke-${HEAD:0:8}-$$"
run_logged container-create podman run -d --name "$NAME" \
--security-opt=no-new-privileges "$IMAGE" sleep infinity
run_logged container-setup podman exec "$NAME" /bin/sh -ec \
'apt-get update; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git ca-certificates; mkdir -p /opt/pi /work/project /work/home/.pi/agent'
run_logged bundle-copy podman cp "$BUNDLE/." "$NAME:/opt/pi"
CENV=(env -i HOME=/work/home PI_CODING_AGENT_DIR=/work/home/.pi/agent \
PATH=/opt/pi:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
run_logged environment podman exec -w /work/project "$NAME" "${CENV[@]}" /bin/sh -ec '
command -v pi
pi --version
BUN_BE_BUN=1 pi --version
git --version
for tool in node nodejs npm npx bun pnpm yarn; do
if command -v "$tool"; then echo "Unexpected external manager: $tool" >&2; exit 1; fi
printf "%s=ABSENT\n" "$tool"
done
'
PIN=2d69229acd3037c31d4e9d566d02f6c0b92f24b9
SOURCE="git:github.com/xz-dev/pi-notify@$PIN"
EXT=/work/home/.pi/agent/git/github.com/xz-dev/pi-notify
printf '%s\n' '{"events":{"agent_settled":{"actions":[]},"tool_execution_start:ask_user_question":{"actions":[]}},"hooks":{"agent-notify":{"actions":[]},"user-ready":{"actions":[]}}}' > "$RUN/pi-notify.json"
run_logged inert-config podman cp "$RUN/pi-notify.json" "$NAME:/work/home/.pi/agent/pi-notify.json"
# Keep failed stages as failures; still collect the independent load evidence.
run_logged install podman exec -w /work/project "$NAME" "${CENV[@]}" pi install "$SOURCE" || :
run_logged list podman exec -w /work/project "$NAME" "${CENV[@]}" pi list || :
run_logged revision podman exec "$NAME" git -C "$EXT" rev-parse HEAD || :
run_logged dependency podman exec -w "$EXT" "$NAME" "${CENV[@]}" BUN_BE_BUN=1 pi -e \
'import("pi-extension-utils/semantic-hook").then(()=>console.log("dependency-import-ok")).catch(e=>{console.error(e);process.exit(1)})' || :
# Normal autoload from installed registration; no --no-extensions workaround.
printf '%s\n' '{"id":"smoke","type":"get_state"}' > "$RUN/request.jsonl"
run_logged rpc timeout 30s podman exec -i -w /work/project "$NAME" \
"${CENV[@]}" PI_OFFLINE=1 pi --mode rpc --no-session --no-skills \
--no-prompt-templates --no-themes --offline < "$RUN/request.jsonl" || :
run_logged settings-copy podman cp "$NAME:/work/home/.pi/agent/settings.json" "$RUN/settings.json" || :
# Host-side assertions; Node is not installed in the execution container.
run_logged load-verdict node --input-type=module - "$RUN" "$PIN" "$SOURCE" <<'JS' || :
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
const [root, pin, source] = process.argv.slice(2);
const read = (name) => readFileSync(`${root}/logs/${name}`, "utf8");
for (const stage of ["install", "list", "revision", "dependency", "rpc", "settings-copy"]) {
assert.equal(read(`${stage}.exit`).trim(), "0", `${stage} failed; inspect its logs`);
}
assert.equal(read("revision.stdout").trim(), pin);
assert.match(read("dependency.stdout"), /dependency-import-ok/);
const settings = JSON.parse(readFileSync(`${root}/settings.json`, "utf8"));
assert.deepEqual(settings.packages, [source]);
const replies = read("rpc.stdout").split("\n").filter(Boolean).map((line) => JSON.parse(line));
assert(replies.some((r) => r.id === "smoke" && r.type === "response" &&
r.command === "get_state" && r.success === true && r.data.messageCount === 0));
assert.doesNotMatch(read("rpc.stderr"), /Failed to load extension|Cannot find module/);
console.log("real-plugin-load-ok");
JS
printf 'Retained evidence: %s\nContainer: %s\n' "$RUN" "$NAME"
printf 'Load verdict exit: '; cat "$RUN/logs/load-verdict.exit"
exit "$(cat "$RUN/logs/load-verdict.exit")"Expected on the presently reviewed head: install 0, dependency/RPC/load-verdict nonzero. Expected after a valid fix: all those stages 0, dependency import marker, exact registration/revision, and a real RPC response. A timeout is a failure, even if some earlier output looked successful. Preserve the original and migrated lockfiles, installed dependency inventory, and failing checkout before cleanup. Keep the container until all selected independent cases and evidence exports are finished; then remove only that named container and verify it and its children are gone. Do not leave it running or recreate failed environments without accounting for them. For pi-subagents, repeat public install/load in a separate fresh home with its exact source above, then run the real functional/lifecycle harness. For the final combined case use a third fresh home, both registrations, and only the controlled test-local notification action. These additional functional cases require their own runnable scripts and receipts; the load-only recipe is not a claim that they passed. 5. Required reproducible handoff with the fixPlease attach or link artifacts accessible to reviewers, not only local
6. Ownership and scopePlease own the technical investigation end to end: read the Pi/Bun/extension source and existing tests, choose the appropriate runner and test seams, find the root cause, implement the smallest fix, and keep rerunning the failing checks until both real plugins meet the acceptance criteria. The maintainer should not have to choose package-manager flags, debug fixture URLs, design the SDK bootstrap, or supply implementation details. If local infrastructure is unsuitable, use an appropriate existing runner within your access instead of returning the technical problem to the user. Only escalate a genuine authorization/credential/cost/privilege or scope decision. State the exact blocker and minimal permission required; do not bypass authentication or safety boundaries. A technical failure by itself is a task to investigate, not a reason to stop and ask a non-specialist what implementation to try. Keep the separate runtime-distribution-gate removal out of this patch. Persistent This comment is AI-generated by Pi at the maintainer's request. |
Record local functional acceptance and the unresolved GLIBC_2.43 dependency. This candidate is not a portable release runtime.
|
Follow-up to the verification above: pushed d0c7f841 and 68730f34. This update adds only the Bun patch, regressions, and local-runtime metadata under
Not merge/release-ready: the locally built runtime requires GLIBC 2.43, versus official Bun's 2.17 baseline. A compatible runtime/final candidate still needs acceptance, and release integration is not included here. Full Windows suite and remaining platform/release gates remain outstanding. Local functional results do not close those blockers. This comment is AI-generated. |
upstream/main 6160683 origin/ci 3ca68a6 origin/patch/contributor-approval e005a34 origin/patch/model-startup-refresh-barrier 96d88ae origin/patch/model-refresh-session-rebind 95b910d origin/patch/model-catalog-extension-refresh 4656712 origin/patch/bun-bytecode-entrypoint 72f9732 origin/patch/startup-benchmark-exit 97a37c7 origin/patch/native-wrapper-release 405ccb7 origin/patch/update-clean 2c14802 origin/patch/agent-run-failure-seam 6aa4c49 origin/patch/managed-tool-executions 701ee7b origin/patch/esc-abort 0a7e3e6 origin/patch/manual-retry f1c72f1 origin/patch/changelog-prerelease 3ea1afe origin/patch/skill-overrides cd0314e origin/patch/retry-non-retryable-patterns ae23e14 origin/patch/slow-hook-tui-only b6c3008 origin/patch/session-tree-splice 2eaab4d
Merge current downstream main without rewriting PR history. Preserve current main's managed-tool schema and packaging fixes, normalize macOS test paths, and distinguish official-Bun core acceptance from the historical metadata experiment.
|
Updated to Exact-head Linux acceptance passed with official Bun 1.4.2, including 230 focused tests and real package install/update/repair/removal, installed-plugin actions, and native child completion/observed exit without external Node/npm/Bun. Projectless metadata queries still fail, and release workflows still pin Bun 1.4.0. This is core package-management acceptance, not release readiness. The updated PR description contains artifact hashes, evidence, and remaining limitations. This comment is AI-generated. |
16ab9e2 to
53f2fd8
Compare
|
Implemented and released through the independently maintainable downstream patch, preserving the core implementation from this PR:
Two fixes were required beyond the initial implementation:
The downloaded public Linux x64 GNU archive (SHA-256 All 12 platform build/archive/self-update jobs passed. The 18 lifecycle scenario categories were additionally exercised on Linux using an installed-tree adaptation of the pinned subagents tests, not the unmodified official-binary-hash/bubblewrap driver; do not interpret this as identical upstream harness certification or cross-platform plugin coverage. Native packages needing unavailable build tooling remain a documented compatibility limit. Closing as superseded by the shipped clean patch rather than merging the PR's inherited generated-main and unrelated overlay history. The runtime and packaging changes remain on their respective persistent branches. This comment is AI-generated by the Pi coding assistant. |
|
Final verification update: Release 147 now also passed all 18 lifecycle modes using the unmodified OpenSpec is synchronized and archived on This comment is AI-generated by the Pi coding assistant. |
Summary
Remove the external npm requirement for package management in Bun-compiled xz-dev standalone installations.
piresolved through inheritedPATH, withBUN_BE_BUN=1applied only to package-manager children.npmCommandtakes precedence. Other distributions and source/npm installations retain npm.infometadata queries. Keep existing lookup-error policy, Git dependency repair, failure cleanup, and command-specific root-cache behavior./varsymlinks and document the actual compatibility limits.A compatible public
pimust remain onPATH. This is a standalone default, not “probe npm and fall back.” It does not change Pi self-update or enable blanket lifecycle-script trust.Current review scope
Head:
eb918d4e0561bda99e1b5aee6bb252f22eb018ea.Current target main
2b3a99b8564523b820a5791624b4ce6cbd23bf4dwas merged normally, without rewriting PR history. The comparison is back to 7 files, not the previous 7,000-file rebuilt-main drift: four package-manager/test/doc files plus the three retained historical Bun experiment files underpatches/.CI remains separate. No release workflow, dependency, lockfile, launcher, or unrelated runtime change is added relative to target main by this PR.
Fresh acceptance of this exact PR head
Passed: non-publishing Linux run 34343698889.
The CI companion at
eaa188f339checks out the PR source separately and verifies its exact SHA before building. The receipt records PR source and CI source independently. This is not reuse of an earlier validation branch's green result.Target: Ubuntu 24.04, Linux x64 GNU, official Bun
1.4.2+744846f84.npm run checkpassed.piinstalled a bounded npm version and pinned real pi-notify/pi-subagents packages, repaired a deliberately removed runtime dependency throughpi update --extensions, preserved configured versions/refs, and removed the packages.package.jsonwas created as a workaround.Plugin pins:
2d69229acd3037c31d4e9d566d02f6c0b92f24b988639462aae9ba97465b203a305f3abf66bd195cCandidate, build log, receipts, and installed-input hashes are retained until 2026-09-16. The downloaded artifact and its candidate/installed binary hashes were independently checked against the receipt.
pibc975833465c21e0a44d8a2d2adc1dd54f1602d25b71de60d9b1bfd7faed92c4pi-natived51edca30db368aab4d96463c71207e4a3ea0ac2d368fb05ba42fa395da6efcbpi-linux-x64-gnu-modern.zip0acdc375c3d140c98a4fd831de6144adcf00e7847ab28263fc217429c2c72151Limits and separate compatibility work
failed, separately fromcoreComplete: true. Pi preserves lookup-error behavior rather than changing cwd, creating a caller manifest, or silently switching managers. Core package-management success is not npm metadata equivalence.patches/preserves the earlier optional metadata patch and its historical runtime record. That local patched runtime required GLIBC 2.43, versus official Bun's 2.17 baseline, and is not the candidate above. No custom-runtime preflight or provisioning is enabled by this PR.Historical evidence — not acceptance of the current head
The earlier local patched-runtime experiment reported 23 Bun query tests, an 18-mode subagent matrix, and additional coexistence/update/version-preservation checks. Its local CI companion and frozen archives were not submitted. Reproduction details and limitations remain in
patches/README.md.The earlier Windows full-suite run reported 4,284 passed, 127 failed, and 904 skipped Vitest tests, plus TUI failures. Only two package-command failures were reproduced on the unmodified baseline. The other failures have not been established as baseline-only; this Linux run does not claim they are fixed.
This PR description update is AI-generated.