Skip to content

update io.pilot.aegis 0.1.5: darwin/amd64, prod natives, no leaked children - #118

Draft
TeoSlayer wants to merge 2 commits into
mainfrom
update/aegis-0.1.5
Draft

TeoSlayer wants to merge 2 commits into
mainfrom
update/aegis-0.1.5

Conversation

@TeoSlayer

@TeoSlayer TeoSlayer commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Draft. Do not merge yet. Merging this runs publish-rich-from-r2.sh, which builds the catalogue entry from whatever is already on R2 under bundles/io.pilot.aegis/0.1.5/. Merge only after all of these:

  1. Stop the judge server and model download when aegis exits aegis#4 is merged. It carries the native fixes this version ships.
  2. The four native tarballs listed in artifacts[] are on the prod bucket at io.pilot.aegis/0.1.5/<os>-<arch>/, and each one serves bytes that match its sha256.
  3. The template lifecycle fixes are merged: fix(scaffold): generated adapters exit with their daemon and drop abandoned calls #111 and fix(scaffold): a cli app is ready before its binary is, and a failed download is retried #116. fix(scaffold): a cli app is ready before its binary is, and a failed download is retried #116's head a0d7665 already contains fix(scaffold): a cli adapter's in-flight children never outlive it (io.pilot.otto) #114's commits and the SIGTERM-first cancel, so fix(scaffold): a timed-out cli call gets SIGTERM before SIGKILL #117 is not needed.
  4. The four 0.1.5 adapter bundles are built from that main with publish.BuildBundle, signed with the aegis publisher key (ed25519:+nt58BA0gpPYuyaeG2GwfTI79j8IHP+zra5GvRQv0N0=), uploaded to R2, and checked over their public URLs (docs/UPDATING-BUNDLES.md).

What changes

0.1.3 (live) 0.1.5 (this PR)
Platforms darwin/arm64, linux/amd64, linux/arm64 the same, plus darwin/amd64
Native aegis upstream v0.1.3 v0.1.5, built from aegis#4 (8ceabce): nothing aegis starts outlives it
Native host dev bucket pub-2328865f… prod bucket pub-f09f9a4e…
aegis.help listed twice. The submission's aegis --help method was shadowed by the generated discovery handler, so it could never be reached. once: the generated discovery method

darwin/amd64

  • 0.1.3 behavior. There was no darwin/amd64 native, and upstream v0.1.3 has no macos-x86_64 release asset.
    • pilotctl v1.12+ refuses to install: io.pilot.aegis has no bundle for this platform (darwin/amd64).
    • Older pilotctl installs the top-level linux/amd64 ELF, which fails with exec format error.
  • 0.1.5. The native is cargo build --release --target x86_64-apple-darwin (Mach-O x86_64, minos 10.12), run under Rosetta below.

Natives (artifacts[])

Built from aegis 8ceabce (tree-identical to ce5be55):

  • cargo build for the two macOS targets;
  • cargo zigbuild for x86_64-unknown-linux-musl and aarch64-unknown-linux-musl, static, like the 0.1.3 natives;
  • --remap-path-prefix, so no local paths are embedded.

They are packaged as aegis-0.1.5-<os>-<arch>/bin/aegis, the same layout and exec_path scheme as 0.1.3. The tarballs are deterministic: fixed mtime 1790244350, uid/gid 0, no owner names, gzip mtime 0. Repackaging the same binaries gives the same sha256.

Platform Tarball sha256 Size bin/aegis sha256
darwin/arm64 d3541bf9…be9975 470891 079fd32d…6b211
darwin/amd64 bb46a068…c3077b 531001 78223796…71a57
linux/amd64 700e70fd…44273d 599685 76c2fb44…1f873
linux/arm64 38df7c1a…473a06 538309 74aa3f17…ed254

To ship CI-built binaries from a v0.1.5 tag instead, repackage them the same way and update sha256/size here.

Verified (TEST-ONLY key, nothing uploaded or signed with a real key)

Checks on the submission:

  • pilot-app verify-submission: VERIFY OK, 4 platforms, native-delivery (install.json) … 4 asset(s).
  • pilot-app verify-update: UPDATE GATE OK, 0.1.5 ≥ 0.1.3.
  • pilot-app verify on the four built bundles: VERIFY OK.

I built the bundles from this submission with publish.BuildBundle, from a scratch template: #111, then #116, then #117. The adapter binaries are byte-identical to the ones exercised below. For the runs, the adapter staged the natives over HTTP from a local mirror of the exact tarballs above; that is the only difference from a real install. The lifecycle harness drove the app: darwin/amd64 under Rosetta, Linux in docker --init.

darwin/arm64 darwin/amd64 linux/arm64 linux/amd64
aegis.help ×200 200/200, fd 7→7 200/200, fd 7→7 200/200 200/200
aegis.version ×200, which execs the staged native 200/200 200/200 200/200 200/200
aegis.status ×200 p50 (0.1.3 on darwin/arm64: 226 ms) 6.2 ms 23 ms 5.5 ms 42 ms
judge after a flagged scan ×5, then app SIGTERM / SIGKILL 0 left 0 left 0 left 0 left
install-models past the 60 s timeout IPC error at 60.0 s, 0 left same same same
app SIGTERMed with install-models in flight 0 left, 3/3 0 left, 3/3 0 left, 3/3 0 left, 3/3
orphan, no Pdeathsig (0.1.3: ORPHAN) SELF-EXIT 304 ms SELF-EXIT 306 ms SELF-EXIT 314 ms SELF-EXIT 207 ms
orphan, Pdeathsig n/a n/a PASS 2 ms PASS 1 ms
offline first spawn, help ×20 (0.1.3: exit 1) 20/20 20/20 20/20 20/20

Which template

The same aegis checks, built from #114's head (808243f), show:

#116 alone, without the SIGTERM-first line from #117/#114, leaves the download running (ppid=1) on macOS when the app is stopped mid-call. Details are in the comments on #114 and #116.

Catalogue follow-up (not in this PR)

The per-platform entries, the proposed metadata.json and the upload steps are prepared outside the repo. The bundle sha/size values there come from the TEST-ONLY build, so they are placeholders. Things the catalogue PR will need:

  • catalogue-lint approval for a stateful app. The aegis manifest grants fs.write $APP, so the lint marks the app stateful and refuses the bump without it (checked locally). Approve with {"id":"io.pilot.aegis","version":"0.1.5",…} in catalogue/stateful-apps.json, or with the PR label. $APP holds only the staged native; aegis keeps its own state in the daemon user's ~/.aegis. With that approval, the lint's bundle checks pass on the four bundles.
  • A hand edit to metadata.json. publish-rich-from-r2.sh reuses the existing catalogue/apps/io.pilot.aegis/metadata.json and refreshes only publisher, size.bundle_bytes, the demo and next_steps. The duplicate aegis.help, the changelog and installed_bytes have to be fixed by hand, and metadata_sha256 updated.

Update 2026-09-24: darwin pins rebuilt, re-verified

Why the darwin pins changed (commit 9d4f860). The darwin tarballs the first commit pinned were local build outputs. They were never uploaded, and they no longer exist, so no server could ever have served those bytes. I rebuilt all four natives from aegis 8ceabce with the same flags (--remap-path-prefix, --locked, rustc 1.96.0) and the same packaging.

  • The two Linux tarballs reproduce byte-identical: 700e70fd…, 38df7c1a….
  • The Mach-O binaries differ only in their 16-byte LC_UUID plus the 32-byte ad-hoc signature page hash that covers it. cmp -l shows 48 bytes, and no path strings. ld64 ties that UUID to the build location.
  • To upload: natives/<os>-<arch>/aegis-0.1.5-<os>-<arch>.tar.gz from the prepared publish dir, or CI-built natives repackaged the same way (then update artifacts[] again).

Re-verified. The template is #116's head a0d7665 (it includes #111 and #114). The bundles were built from this submission with publish.BuildBundle and a TEST-ONLY key.

  • pilot-app verify passes on all 4 bundles.
  • verify-submission: VERIFY OK, 4 assets.

The adapter staged the exact native tarballs above from a local HTTP mirror; install.json URLs are the only difference from a real install. A rewritten lifecycle harness drove the app: sandbox-exec on macOS (darwin/amd64 under Rosetta), docker --init on Linux.

  • Positive control first: published 0.1.3 on darwin/arm64 left 5/5 judge servers with ppid=1 after a flagged scan (both SIGTERM and SIGKILL of the app), and left the curl with ppid=1 in 2/2 in-flight rounds.
darwin/arm64 darwin/amd64 linux/arm64 linux/amd64
help / version / status / exec scan-cmd ×200 200/200 each 200/200 each 200/200 each 200/200 each
status p50 10.3 ms 36.4 ms 9.2 ms 29.2 ms
flagged scan ×5: judge started / left (app running, then SIGTERM; SIGKILL) 5 / 0, 0; 0 5 / 0, 0; 0 5 / 0, 0; 0 5 / 0, 0; 0
install-models past 60 s IPC error at 60,001 ms, 0 left 60,024 ms, 0 left 60,001 ms, 0 left 60,022 ms, 0 left
SIGTERM with install-models in flight 3/3 clean 3/3 clean 3/3 clean 3/3 clean
orphan, no Pdeathsig SELF-EXIT 275 ms SELF-EXIT 241 ms SELF-EXIT 245 ms SELF-EXIT 225 ms
orphan, Pdeathsig n/a n/a PASS 2 ms PASS 9 ms
offline first spawn, help ×20 20/20 20/20 20/20 20/20
SIGTERM exit / socket removed 0, 4 ms / yes 0, 16 ms / yes 0, 7 ms / yes 0, 8 ms / yes

Offline, aegis.version returns a clean IPC error (install assets: stage: fetch …) until the native can be downloaded.

🤖 Generated with Claude Code

teovl and others added 2 commits September 24, 2026 13:11
…ildren

- version 0.1.3 -> 0.1.5. The native aegis is v0.1.5
  (pilot-protocol/aegis fix/aegis-lifecycle, ce5be55): nothing it starts
  (the L2 judge server, the model download) outlives it any more.
- artifacts: all four platforms. darwin/amd64 is new: 0.1.3 had no
  darwin/amd64 native, so v1.12+ pilotctl refused to install the app on
  Intel Macs and older pilotctl installed the linux/amd64 ELF, which fails
  with "exec format error".
- artifacts move from the dev R2 bucket (pub-2328865f…) to the prod bucket
  (pub-f09f9a4e…), under io.pilot.aegis/0.1.5/<os>-<arch>/.
- drop the submission's own aegis.help. The generated <ns>.help handler is
  registered under the same name and replaced it, so `aegis --help` was
  unreachable and the manifest listed aegis.help twice.

The four native tarballs (sha256 + size in artifacts[]) must be on the prod
bucket, and the four adapter bundles built from a template that has the
cli lifecycle fixes, before this merges. See the PR for the order.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The darwin tarballs the first commit pinned (b9fb3077…, a2351b01…) were
local build outputs that are gone; they were never uploaded, so nothing
could ever serve those bytes. Rebuilt from aegis 8ceabce with the same
flags and packaging. The Linux natives reproduce byte for byte (same
sha256 as before); the Mach-O ones differ only in LC_UUID and the
ad-hoc signature page hash, which ld64 derives from the build location.

darwin/arm64 d3541bf9…be9975 470891 B (bin 079fd32d…)
darwin/amd64 bb46a068…c3077b 531001 B (bin 78223796…)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants