fix: restore the root bundle and enforce a budget (0.16.0) - #24
Merged
Conversation
The root bundle had grown from 9,643 to 22,497 bytes — undoing most of the 65% reduction in #21 — because payments, gateway, entitlement and firewall all exported from the package root. Every consumer paid for them whether or not they charged anyone, and the firewall recommender in particular is an offline analysis tool that will never execute in middleware. dist/index.js 22,497 -> 11,608 B (8,695 -> 4,546 gzipped) dist/pay.js 10,861 B opt-in dist/firewall.js 6,821 B opt-in Entry points now: @apideck/agent-analytics detection, classification, agentPolicy, trackVisit @apideck/agent-analytics/verify Web Bot Auth + published IP range tables @apideck/agent-analytics/payments 402 challenges, gateways, entitlements @apideck/agent-analytics/firewall WAF recommendations (offline) @apideck/agent-analytics/markdown Markdown-twin negotiation agentPolicy stays in the root: classification without a policy to apply it to is half a library, and it costs ~2 kB. That is why the root lands at 11.6 kB rather than back at 9.6 kB. README gains an entry-point table with the real numbers, and every import example in the README, the testing guide and the site now points at the right subpath. Verified from a clean install of the packed package that all five entry points resolve. Found while pulling accurate figures for the site's install section, which was still advertising "216 tests" and "CI on Node 18, 20 and 22" — Node 18 was dropped in 0.12 for lacking globalThis.crypto, so the site was claiming support for a runtime the library refuses to run on. Both corrected.
The root entry ships in every consumer's edge middleware and runs on every request, so its size is a feature rather than a vanity metric. It silently doubled anyway: #21 cut it from 27.7 kB to 9.6 kB, then payments, gateway, entitlement and firewall were each exported from the root by reflex and it climbed back to 22.5 kB. Nothing failed. Every test passed. It surfaced weeks later only because someone needed an accurate figure for a marketing page. Same shape as the unpublished-0.10.0 bug and the agentIntent divergence: the mechanism existed, nothing asserted the invariant, and it stayed broken until something unrelated exposed it. So assert it. scripts/check-size.mjs measures each entry gzipped against size-budget.json and fails the build over budget. Zero dependencies, in keeping with the package — node:zlib does the work. entry gzipped budget used dist/index.js 4.44 kB 4.88 kB 91% dist/verify.js 6.25 kB 7.42 kB 84% dist/pay.js 4.05 kB 4.49 kB 90% dist/firewall.js 2.80 kB 3.13 kB 90% dist/markdown.js 1.03 kB 1.27 kB 81% Verified by reintroducing the exact regression — re-exporting pay and firewall from the root put index.js at 174% of budget and exited 1, with a message naming the likely cause rather than just a number. Budgets sit ~10% above current. verify.js gets more headroom because the published IP range tables grow whenever the weekly refresh adds prefixes, and a routine range update should not fail CI. Raising a budget is deliberate: `npm run size -- --update`, and justify it in the commit. The table prints on every run, not only on failure, so the trend is visible in CI logs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
0.15.0shipped a bundle regression. This fixes it and adds a check so it cannot recur silently.The regression
#21 cut the root entry from 27.7 kB to 9.6 kB. Over the following commits
payments,gateway,entitlementandfirewallwere each exported from the package root, and it climbed back to 22.5 kB — which is what0.15.0published.The root entry ships in every consumer's edge middleware and runs on every request. Sites that never charge anyone are currently paying for a firewall recommender that can never execute there.
Entry points
@apideck/agent-analyticsagentPolicy,trackVisit…/verify…/payments…/firewall…/markdownagentPolicystays in the root deliberately — classification with no policy to apply it to is half a library, and it costs ~2 kB. That's why the root lands at 11.6 kB rather than back at 9.6 kB.Breaking for anyone importing
paymentGate,entitlementGateway,paymentRequiredorrecommendFirewallRulesfrom the root.0.15.0published hours ago, so realistically nobody. Every example in the README, the testing guide and the site has been updated.The check
npm run sizemeasures each entry gzipped againstsize-budget.jsonand fails the build over budget. Zero dependencies —node:zlibdoes the work.Verified by reintroducing the exact regression — re-exporting
payandfirewallfrom the root putindex.jsat 174% of budget and exited 1, with a message naming the likely cause rather than just a number.Budgets sit ~10% above current.
verify.jsgets more headroom because its IP range tables grow when the weekly refresh adds prefixes, and a routine range update shouldn't fail CI and train people to bump budgets reflexively.Why it needed a new PR
Both commits were originally pushed to
feat/pay-to-trainafter #23 had already merged, so they were stranded on a merged branch and never reachedmain. Cherry-picked here onto currentmain.That's the fourth time in this session I've pushed to an already-merged branch. The habit that causes it: checking out a local branch by name without re-checking whether its PR is still open.
🤖 Generated with Claude Code