From d73cbd6b0aea20a0e99d29e6c775f26d27f59eb5 Mon Sep 17 00:00:00 2001 From: chopratejas Date: Thu, 14 May 2026 19:31:23 -0700 Subject: [PATCH] =?UTF-8?q?fix(build):=20shrink=20Rust=20extension=20wheel?= =?UTF-8?q?s=20=E2=80=94=20strip=20+=20thin-LTO=20+=20single=20codegen=20u?= =?UTF-8?q?nit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PyPI rejected the v0.21.37 release publish with: HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/ Project size too large. Limit for project 'headroom-ai' total size is 10 GB. PyPI inventory check confirmed: **191 versions × ~213 MB/release = 10.00 GB exactly** — at the cumulative project storage ceiling. Each recent release ships 12 wheels × ~16-18 MB each. Post-mortem inspection of a production wheel (``headroom_ai-0.21.36-cp311-cp311-manylinux_2_28_x86_64.whl``) showed the binary was ``not stripped``: .text 18.3 MB (code) .rodata 11.4 MB (Magika model + ONNX runtime data) .strtab 4.9 MB (debug strings — strippable) .eh_frame 1.9 MB (unwind tables) .symtab 1.5 MB (debug symbols — strippable) .gcc_except_table 1.2 MB This commit adds a release profile: [profile.release] strip = "symbols" lto = "thin" codegen-units = 1 That: * Strips ``.symtab`` + ``.strtab`` (~6.4 MB direct savings per wheel) * Enables thin link-time optimization for cross-crate dead-code elimination (~5-10% ``.text`` savings) * Single codegen unit for better inlining + DCE at the cost of ~30-50% slower release builds (acceptable for CI) Deliberately NOT setting ``panic = "abort"``: * The proxy is a long-lived async process. A panic on one bad request triggering process abort would disconnect every concurrent client. Accept the smaller savings; keep unwind behaviour. Estimated impact * Per wheel: ~16-18 MB → ~10-11 MB (40% smaller) * Per release (12 wheels): ~213 MB → ~130 MB * PyPI capacity: ~30+ more releases before hitting 10 GB again Verification * Local build of ``headroom._core`` with new profile: ``.so`` size 29 MB on macOS arm64 (was ~45 MB pre-fix; final wheel compressed will be smaller on Linux which also benefits from the ``strip`` directive). * 77 Rust-parity tests pass — extension still functional. * Single-codegen-unit slows build by ~30-50% but maturin/cibuildwheel build time was never the bottleneck. Forward strategy (separate work) * Submit a PyPI project-size-limit-increase request to unblock the immediate release. * Adopt a release-deprecation policy: yank versions older than N patches per minor; consider dropping Python 3.10 wheels (EOL'd October 2026) and manylinux_2_28_aarch64 wheels (niche audience, largest at 18.75 MB). * Investigate runtime-download for Magika model (~10 MB further savings) — same pattern Kompress already uses. --- .claude-plugin/marketplace.json | 4 +-- .github/plugin/marketplace.json | 4 +-- Cargo.toml | 31 +++++++++++++++++++ .../.claude-plugin/plugin.json | 2 +- .../.github/plugin/plugin.json | 2 +- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 2794ffa4e..d22330cb7 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,14 +5,14 @@ }, "metadata": { "description": "Headroom marketplace for Claude Code and GitHub Copilot CLI plugins.", - "version": "0.21.33" + "version": "0.21.37" }, "plugins": [ { "name": "headroom", "source": "./plugins/headroom-agent-hooks", "description": "Headroom startup hooks for Claude Code and GitHub Copilot CLI.", - "version": "0.21.33", + "version": "0.21.37", "author": { "name": "Headroom Contributors", "url": "https://github.com/chopratejas/headroom" diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 2794ffa4e..d22330cb7 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -5,14 +5,14 @@ }, "metadata": { "description": "Headroom marketplace for Claude Code and GitHub Copilot CLI plugins.", - "version": "0.21.33" + "version": "0.21.37" }, "plugins": [ { "name": "headroom", "source": "./plugins/headroom-agent-hooks", "description": "Headroom startup hooks for Claude Code and GitHub Copilot CLI.", - "version": "0.21.33", + "version": "0.21.37", "author": { "name": "Headroom Contributors", "url": "https://github.com/chopratejas/headroom" diff --git a/Cargo.toml b/Cargo.toml index 412561c5f..c2c14f83a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,3 +75,34 @@ aws-smithy-runtime-api = { version = "1", default-features = false, features = [ # us baking provider-specific knowledge in. The token source is wrapped # in a `TokenSource` trait so tests inject a static-token mock. gcp_auth = "0.12" + + +# ── Release profile — wheel size optimization ─────────────────────── +# +# PyPI imposes a 10 GB cumulative storage limit per project. We hit it +# at version 0.21.36 (191 versions × ~213 MB/release = 10.00 GB +# exactly). Recent wheels were ~16-18 MB each, of which ~6.4 MB was +# pure debug metadata (`.strtab` + `.symtab` ELF sections; uncovered +# by post-mortem inspection of an actual production wheel). +# +# This profile shrinks each Linux wheel from ~18 MB → ~10-11 MB by: +# * Stripping symbol/string tables (~6.4 MB direct savings) +# * Link-time optimization across crate boundaries (~5-10% .text +# savings via dead-code elim across the workspace) +# * Single codegen unit (better inlining + dead-code elim, at the +# cost of slightly slower release builds) +# +# We deliberately do NOT set ``panic = "abort"``. The proxy is a +# long-lived async process — a single misbehaving request triggering +# panic-abort would terminate the whole proxy and disconnect every +# concurrent client. Accept the smaller savings; keep unwind behaviour. +# +# Estimated impact: 213 MB/release → ~130 MB/release. Buys ~30+ more +# release slots within the 10 GB ceiling at the current release +# cadence. Per-PyPI-version savings AND faster downloads for end +# users. Tradeoff: release builds take ~30-50% longer due to +# `codegen-units = 1` + LTO; acceptable for the size win. +[profile.release] +strip = "symbols" +lto = "thin" +codegen-units = 1 diff --git a/plugins/headroom-agent-hooks/.claude-plugin/plugin.json b/plugins/headroom-agent-hooks/.claude-plugin/plugin.json index 4186feb0b..c7c5241d2 100644 --- a/plugins/headroom-agent-hooks/.claude-plugin/plugin.json +++ b/plugins/headroom-agent-hooks/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "headroom", - "version": "0.21.33", + "version": "0.21.37", "description": "Headroom startup hooks for Claude Code and GitHub Copilot CLI.", "author": { "name": "Headroom Contributors", diff --git a/plugins/headroom-agent-hooks/.github/plugin/plugin.json b/plugins/headroom-agent-hooks/.github/plugin/plugin.json index a8be4c901..5f0fbb8fc 100644 --- a/plugins/headroom-agent-hooks/.github/plugin/plugin.json +++ b/plugins/headroom-agent-hooks/.github/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "headroom", - "version": "0.21.33", + "version": "0.21.37", "description": "Headroom startup hooks for Claude Code and GitHub Copilot CLI.", "author": { "name": "Headroom Contributors",