Skip to content

chore(util): adopt Bun.randomUUIDv7 — Bun-API audit - #93

Merged
Exelord merged 1 commit into
mainfrom
claude/bun-builtins
May 16, 2026
Merged

chore(util): adopt Bun.randomUUIDv7 — Bun-API audit#93
Exelord merged 1 commit into
mainfrom
claude/bun-builtins

Conversation

@Exelord

@Exelord Exelord commented May 16, 2026

Copy link
Copy Markdown
Member

Summary

Bun-API audit. One concrete replacement plus a record of the wider findings (so the next agent doesn't re-litigate).

Replaced

src/util/ulid.ts → thin Bun.randomUUIDv7() wrapper. Drops 50 LOC of hand-rolled Crockford-base32 encoding + custom random sampling. UUIDv7 (RFC 9562) gives us the same guarantees we need:

  • 48-bit ms-epoch timestamp prefix → lex-sortable for time-ordered run_id scans
  • Per-call randomness → unique under parallel calls
  • Standard format → DB clients / log indexers handle it natively

User-visible change: run_id strings switch from 26-char Crockford (01JC0K…) to 36-char hex (019e3255-9a99-7000-…). Pre-alpha, no migration concern.

Tests rewritten — old tests injected a custom timestamp arg the built-in doesn't expose. New tests cover the actual contract (format, uniqueness over 1000 rapid calls, lex ordering across a 5ms sleep).

NOT shipped (with reasons recorded in CLAUDE.md)

API Why not
Bun.Archive for extract Benchmarked 15-400× slower than our extractOutputs for typical artifacts (10-500 files, 1KB-64KB each). Fixed JS-bridge overhead dominates for small archives. Detailed numbers in tests/ulid.test.ts commit msg.
Bun.env Cosmetic alias for process.env; not worth the diff churn (13 sites)
Bun.semver, Bun.deepEquals, Bun.stripANSI, Bun.stringWidth, Bun.which, Bun.JSONC, Bun.TOML, Bun.password, Bun.markdown, Bun.serve No consumers in our code
Bun.stdout / Bun.stdin Bun.File-shaped, no advantage over process.stdout
Bun.write in tar.ts:200 Already use Bun.write everywhere it pays off (cache.ts/save, layered-cache, run-artifacts); the one writeFile in extractOutputs is fine and the bench shows the bottleneck is elsewhere

Already using

Bun.YAML.parse, Bun.Glob, bun:sqlite, Bun.hash.xxHash3, Bun.zstdCompress / zstdDecompress, Bun.spawn / spawnSync, Bun.color, Bun.file, Bun.write, Bun.nanoseconds, Bun.sleep.

Test plan

  • 478/478 tests pass
  • Lint + format clean
  • No CACHE_VERSION change — run_id format change doesn't affect cache key derivation
  • Decision log updated with the audit results

https://claude.ai/code/session_016HXj6HW6bxSn8EYuKcxTD9


Generated by Claude Code

`src/util/ulid.ts` shrinks from 50 LOC (Crockford-base32 encoder +
custom random sampler) to a 1-line wrapper over `Bun.randomUUIDv7()`.
UUIDv7 (RFC 9562) provides the same guarantees we relied on:

- 48-bit ms-epoch timestamp prefix → lex-sortable, so `runs` table
  range scans on `run_id` are time-ordered without an index.
- Per-call randomness → unique under heavy parallelism.
- Standard string format → tools that handle UUIDs (DB clients,
  log indexers) understand it for free.

User-visible: `run_id` column values switch from 26-char Crockford
base32 (`01JC0K…`) to 36-char hex with hyphens (`019e3255-9a99-…`).
Pre-alpha; no migration concerns.

Tests rewritten — old tests injected a custom timestamp arg, which
Bun.randomUUIDv7 doesn't expose. The new tests check the contract we
actually care about (format, uniqueness across N rapid calls, lex
ordering across a 5ms sleep).

Decision log entry in CLAUDE.md records this plus the wider Bun-API
audit results (notably: `Bun.Archive` benchmarked 15-400× slower
than our `extractOutputs` for typical KB-MB cache artifacts; not
adopting).
@Exelord
Exelord merged commit 628308b into main May 16, 2026
1 check passed
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