Skip to content

Publish groundwork: docs, package metadata, decoder fuzzing - #16

Merged
eliahilse merged 1 commit into
mainfrom
groundwork
Aug 20, 2026
Merged

Publish groundwork: docs, package metadata, decoder fuzzing#16
eliahilse merged 1 commit into
mainfrom
groundwork

Conversation

@eliahilse

Copy link
Copy Markdown
Owner

Everything needed before npm publish except the publish itself — that's yours.

Docs

packages/hyperfly had no README, so the npm page would have shipped blank. It now covers two-line usage, plans and profiles, serving over the negotiation protocol, and the benchmark table with its caveats intact. Python and Rust get equivalent front doors, the root README stops claiming nothing is benchmarked, and the site's dead docs — soon button now points somewhere.

Packaging, verified rather than assumed

Built the tarball and installed it into a scratch project as a real consumer:

encode/decode: true
profiled: true
http: application/vnd.hyperfly | discovery: 200

All three entry points (hyperfly, /zod, /http) resolve — the check that usually catches a broken exports map. Tarball is 37 kB and contains README, LICENSE, NOTICE, dist. prepublishOnly now runs lint + types + tests + a fresh build, so a stale or failing build can't be published. Added keywords, homepage, bugs, provenance.

Name status: npm hyperfly is yours at 0.1.0 (the old load balancer — worth a npm deprecate pointing at the new major), PyPI hyperfly is available.

Decoder fuzzing

The decoder eats bytes from the network and had property tests for valid input only. The new suite throws ~34,000 hostile inputs at it across both plans — random bytes, bit-mutations of valid output, truncation at every offset, arbitrary dictionary codes, hostile envelopes — requiring each to either raise a typed HyperflyError or normalize to a stable fixed point. No TypeError, no RangeError, no hang.

Its first run failed, and the implementation was right. A mutated input decoded to values where delta and raw modes tie on size, so the encoder correctly picked the lower mode byte and re-encoded differently. Plan §4 makes canonicality an encoder obligation and explicitly lets decoders accept any valid mode — so byte identity only holds for output a conforming encoder produced. The assertion is now the invariant that actually holds, and still catches a decoder that loses or invents information.

TS 200 tests / 10.6k assertions, Python 138, Rust 9.

🤖 Generated with Claude Code

Everything needed before `npm publish` except the publish itself.

Docs. packages/hyperfly had no README, so the npm page would have shipped
blank; it now covers the two-line usage, plans and profiles, serving over the
negotiation protocol, and the benchmark table with its caveats. Python and Rust
get equivalent front doors, the root README stops claiming nothing is
benchmarked, and the site's dead "docs — soon" button points at the README.

Packaging. Verified by building the tarball and installing it into a scratch
project as a consumer: all three entry points resolve, encode and decode round
trip, training works, and the HTTP layer negotiates — the check that usually
catches a broken exports map. prepublishOnly now runs lint, types, tests and a
fresh build, so a stale or failing build cannot be published. Added keywords,
homepage, bugs, and provenance.

Fuzzing. The decoder is the one component that eats bytes from the network, and
it had property tests for valid input but nothing for hostile input. The new
suite throws roughly thirty-four thousand inputs at it across both plans —
random bytes, bit-mutations of valid output, truncation at every offset,
arbitrary dictionary codes, hostile envelopes — and requires that every one
either raises a typed HyperflyError or normalizes to a stable fixed point.

Its first run failed, and the implementation was right: a mutated input decoded
to values where delta and raw modes tie on size, so the encoder correctly chose
the lower mode byte and re-encoded to different bytes. Plan section 4 makes
canonicality an encoder obligation and explicitly lets decoders accept any
valid mode, so byte identity only holds for output a conforming encoder
produced. The assertion is now the invariant that actually holds — decode,
re-encode, and require a fixed point — which still catches a decoder that loses
or invents information.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_hf1
@eliahilse
eliahilse merged commit 1bbcfc7 into main Aug 20, 2026
7 checks passed
@eliahilse
eliahilse deleted the groundwork branch August 20, 2026 17:42
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.

1 participant