A serverless AT Protocol lexicon authority

tests: cover every line, then delete the ones that could not be

Coverage went from 96.88% lines / 86.82% branches to 100% lines, 100% functions, 99.52% branches across src/ and bin/, with the suite growing from 194 tests to 401. The interesting half was not the tests. Chasing the last branches turned up code that could not be triggered at all, and untestable defensive code is not defensive — it is an assertion nobody checked. So: - sameOrigin's try/catch in verify: both URLs provably parse upstream (@atproto/common-web's validateUrl requires URL.canParse, and origin already parsed as a base in get()). Deleted. - str()'s ?? '' in serve: all 13 call sites sit behind a requireParams naming that same parameter, and q is never mutated. requireParams now returns the validated values, so the compiler proves what the ?? was guessing. str() is gone. - summarize's ?. and ?? 0 in the build CLI: report.files and report.nsids are built from the same sources array with the same path template, so the find cannot miss. Replaced with an index built once. Three real defects surfaced along the way: - --lexicons ./lexicons was broken. relativeTo compared a normalized join() against an unnormalized dir, so the prefix check failed and the path got joined onto dir twice: a raw ENOENT with a doubled path, no BuildError, no file named. Every non-canonical spelling failed -- ./x, x/., x//y, x/../x -- which is to say the form a shell completes to. Now resolved once at the entry point; a build from ./path is byte-identical to one from path. - serve() reported url 'http://127.0.0.1://run/x.sock' for a socket path, because listen() reads a non-numeric string as a pipe name and ServeResult has no shape for one. Now a RangeError using --port's own predicate, so the library and the flag agree on what a port is. - --against <not-a-url> throws a bare TypeError instead of a BuildError naming the flag. Pinned by test, not yet fixed. The err instanceof Error ? err.message : String(err) dance appeared inline ten times; verify/ had already extracted it. It now lives in src/message.js, a leaf that imports nothing -- not in build/errors.js, because verify's header states it does not import the build, and an invariant should not be edited to fit a refactor. Four branches remain uncovered, each deliberate: bin's ?? 0 on process.exit (insurance against a subcommand forgetting a return), repo.js's missing-block assertion (reachable only by mocking @atproto/repo), canonical's : 0 comparator arm (kept for the total-ordering contract), and short()'s short-CID arm (unreachable -- the CAR reader fixes CIDs at 36 bytes). Also carries the in-progress list -> order bundle refactor, which was already in the working tree and is entangled with these serve/ changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>


Author evan.jarrett.net
Co-author Claude Opus 5 (1M context) Date Commit Parent 6e32009f