Skip to content

Native Bun APIs: measure and selectively migrate runtime boundaries #18

Description

@Igloczek

Problem Statement

iglo.code now runs its web environment server and first-party helpers on Bun, but several platform boundaries still use working Node-compatible APIs. Users want responsive clients and predictable CPU and memory use, and maintainers want to know which native Bun APIs could help without losing reliable provider execution, persistence, remote connections, or standalone installation.

The Bun migration established that the application works; it did not establish that replacing every compatibility API would improve it. Earlier measurements showed higher source-process RSS and idle CPU than Node, while the packaged RSS difference was small and macOS footprint told a different story. Those measurements do not identify a responsible adapter. Migration opportunities must become bounded, testable decisions rather than a blanket rewrite or knowledge that survives only in a conversation.

Solution

Profile and triage the documented native Bun opportunities before prototyping them. Bun's compatibility APIs already use native engines in important cases, so changing an API can remove a binding/shim without changing the underlying engine. Evaluate a replacement only for a demonstrated incompatibility or an actionable measured cost. Compare that candidate against the compatibility implementation on the same Bun version, and adopt it only with behavioral parity and the performance gates below.

Keep the client experience, provider behavior, persisted history, remote connections, and installation/update paths stable. Complete this issue with an accepted, retained, or inconclusive decision for every candidate and focused behavioral evidence for any replacement that lands. Retaining all four candidates is a successful outcome when that is what the evidence supports. Reuse existing Effect service boundaries and disposable source/archive acceptance harnesses; introduce no parallel production platform architecture or automatic migration of unrelated APIs.

This is a private fork with one user. Backward compatibility is not a requirement: a breaking runtime change may replace compatibility machinery when it makes an otherwise qualifying native migration simpler. Coordinated upgrades and a documented clean restart are acceptable. Future upstream imports must remain as easy as the current workflow; a breaking change that adds recurring merge work is rejected.

User Stories

  1. As a user, I want the environment to start promptly, so that I can begin work without unnecessary waiting.
  2. As a user, I want predictable idle CPU use, so that an open environment does not waste battery or compete with my work.
  3. As a maintainer, I want memory measurements to distinguish resident memory, JavaScript heap, and operating-system footprint, so that an optimization is judged using truthful evidence.
  4. As a user, I want chat and terminal streams to remain responsive under load, so that I can follow provider work without dropped output.
  5. As a user, I want Browser streams to remain bounded for slow viewers, so that a remote client cannot cause unbounded buffering in my environment.
  6. As a user, I want local, remote, relay, and tunnel connections to retain their behavior, so that the same client works wherever my environment runs.
  7. As a user, I want disconnections and reconnects to clean up resources, so that repeated connections do not accumulate sockets or processes.
  8. As a user, I want my projects, threads, settings, and authentication state to survive restart, so that a runtime optimization does not lose my work.
  9. As a user, I want events, projections, command receipts, and outbox effects to commit atomically, so that retries and recovery remain reliable.
  10. As a user, I want core and plugin databases to retain their ownership and recovery rules, so that workflows and ordinary threads remain usable together.
  11. As a user, I want simultaneous server and CLI database access to remain reliable, so that routine operations do not introduce locking failures.
  12. As a user, I want provider subprocesses to preserve input, output, exit status, and cancellation, so that optimized spawning does not alter my turns.
  13. As a user, I want Git and checkpoint operations to preserve their results and errors, so that my workspace and conversation remain consistent.
  14. As a user, I want stopping an environment or cancelling work to release the correct resources, so that my other environments and processes remain unaffected.
  15. As a user, I want Device tools and provider helpers to keep working locally and over SSH, so that supported device projects remain accessible.
  16. As a user, I want standalone archives to run without system Node, npm, or Bun, so that installation stays self-contained.
  17. As a user, I want a reliable upgrade and recovery route, including stop/replace/restart when a runtime break needs it, so that simplification does not strand my installation.
  18. As a user, I want file previews and downloads to preserve ranges, content, and cache behavior, so that native file serving does not produce stale or incorrect responses.
  19. As a user, I want file access to retain validated file identity and cancellation cleanup, so that a preview cannot switch to another file or hold resources indefinitely.
  20. As a user, I want hosted and locally served clients on the current build to work with my environment, so that I can upgrade them together without supporting stale versions.
  21. As a maintainer, I want native candidates compared against the same Bun/code/build baseline, so that a runtime-version or packaging difference is not credited to an API replacement.
  22. As a maintainer, I want measurements to include startup, idle CPU, memory, and the affected workload, so that a local speedup does not hide a larger regression.
  23. As a maintainer, I want inconclusive or rejected candidates recorded, so that future agents do not repeat unsupported rewrites.
  24. As a maintainer, I want platform-specific code confined to existing adapters, so that upstream imports and domain services remain manageable.
  25. As a maintainer, I want knowledge about already-native compatibility APIs retained, so that changing an import name is not mistaken for an optimization.
  26. As a maintainer, I want focused tests and manual archive evidence, so that native evaluation does not restore removed CI workflows or expensive matrices.
  27. As a maintainer, I want an implementation that can be reverted without a data migration, so that an unexpected runtime regression has a straightforward recovery path.
  28. As a maintainer, I want the fork's Bun pins, distribution defaults, branding, plugin/workflow extensions, and web-only scope preserved, so that an optimization does not undo intentional fork decisions.
  29. As the fork's only user, I want unnecessary backward-compatibility machinery removed when that simplifies a qualifying migration, so that preserving old runtime versions does not make my application harder to maintain.
  30. As a maintainer, I want native and breaking changes to pass an upstream-sync rehearsal, so that later upstream pulls do not acquire extra recurring repair steps.

Implementation Decisions

  • Architecture and composition: Keep features behind their existing Effect services. Preserve typed errors, interruption, stream semantics, scoped acquisition/finalization, and the pure event-sourced orchestrator. Bun-only adapter imports live in Bun-only modules reached from the production CLI entry composition, for both source and compiled builds. The server and persistence composition accept the platform HTTP-server/SQL-client layers rather than constructing the chosen driver themselves; Node-test composition provides compatibility layers without loading Bun-only imports. Confine injection changes to composition roots and existing layer-construction sites. If that cannot keep Node suites loadable without a broad dual architecture, retain the candidate. Do not detect the runtime to select a production fallback. Public RPC contracts, database schemas, and client controls remain unchanged. A candidate requiring a domain or public-interface change is retained rather than expanding this issue.
  • Backward compatibility: Do not require interoperability between pre-change and post-change service/helper binaries, stale client builds, or mixed server/helper versions. For these four platform candidates, permissible breaks are removal of mixed-version IPC support, a stop/replace/restart upgrade across a runtime break, coordinated upgrades of owned clients/helpers, and removal of Node-only server options that become obsolete. Record each removed option and affected invocation. Do not create version negotiation or compatibility shims solely to avoid those breaks, and do not break a working interface merely because it is allowed. The Node contributor/test toolchain remains for upstream reuse; that is tooling compatibility, not a requirement to run old production builds. Wire contracts, authentication/session behavior, and current feature controls stay unchanged because the native adapters do not require changing them.
  • Durable data and recovery: Preserve the current file formats, domain schemas, and persisted serialization for core/plugin databases, settings, secrets, authentication state, and other durable files. Normal writes remain normal writes; this is format compatibility, not identical file contents. Existing history remains usable. A candidate needing a durable format change is retained; such a migration belongs in a separately specified issue. This keeps manual cross-break recovery possible by stopping, restoring the previous build, and restarting without data conversion.
  • Baseline and scope: Start from the merged Bun migration and the repository's supported Bun pin. Compare compatibility and native variants on the same Bun version, same application revision apart from the candidate, same host, equivalent dependency graph, and equivalent source or packaged form. Retain Vite+/pnpm and their Node contributor toolchain. External provider CLIs may still require their own runtimes.
  • Attribution and stopping: Establish source and archive baselines, then use disposable CPU/allocation profiling and boundary latency/operation-volume measurements for idle and the declared workloads. Prototype only if a reproducible Bun-specific incompatibility exists or the attributed boundary cost is at least 5% of the preregistered end-to-end workload metric (CPU time, wall time, or allocations). Direct boundary latency/volume measurements may establish that cost when profiles are opaque; operation counts alone do not establish its fraction of total cost. Compatibility import names and absent JavaScript profile frames do not prove cost or its absence. Unresolved attribution with no incompatibility is inconclusive and receives no prototype; a boundary with no qualifying cost or incompatibility is retained after triage. Both outcomes keep the existing production backend. Profiling overhead is excluded from timed comparisons. Do not turn triage into an exhaustive profiler or engine investigation.
  • Sequence: Decide HTTP/WebSockets first, then scope file I/O according to that result, then decide SQLite and subprocesses. Apply the attribution gate to each boundary. Prototypes remain isolated; re-establish the baseline after an accepted change before evaluating another boundary, so its result cannot absorb unrelated changes.
  • HTTP/WebSockets: Scope the candidate to the main environment server and its Browser streams. Preserve routing, authenticated RPC, OAuth/MCP endpoints, CORS/cookies, streaming bodies, graceful shutdown, response-error behavior, socket compression behavior, and Browser-stream close/backpressure behavior. Loopback authentication callback servers and outbound HTTP calls remain compatibility users. A narrow local Effect-compatible adapter port or extension is allowed; a version-matched Effect Bun dependency is allowed only when it provides the required contracts without introducing another Effect context. The reference adapter alone is insufficient: it discards send backpressure/drop results and lacks the Browser transport's buffered-byte and immediate-close controls. Keep the required scoped upgraded-socket capabilities inside the existing transport boundary: buffered bytes, immediate close, correct handling of send/drop/drain, and route-specific compression. RPC compression parity includes actual wire bytes and server CPU for a preregistered representative workload; a dedicated per-socket compressor is permitted to preserve the existing context-takeover benefit. Preserve uncompressed JPEG frames and bounded pending Browser bytes without applying its limits to RPC sockets. The observable Browser contract does not require refusing extension negotiation when per-message compression can stay disabled. Switching only the bootstrap layer is insufficient. Retain this candidate if the supported Bun pin cannot preserve those behaviors; do not create a general transport framework.
  • SQLite: The shared core/plugin Effect SQL client is the candidate. A narrow local native-client port based on the version-matched Effect reference is allowed; a blind package swap is insufficient. Preserve boolean binding and every used row/result mode (including raw write results), safe integers, typed error classification, successful statement caching and eviction of failed prepares, writer locking, savepoints, read-only transactions, and existing migration behavior. Writable transactions retain their immediate writer-lock acquisition. Keep WAL/foreign-key/busy setup with its existing owner rather than duplicating setup in a new driver. Core event/projection/receipt/outbox writes remain one transaction; private plugin databases remain separate. The legacy V1-to-V2 consistent-backup initializer, external OpenCode/Antigravity usage readers, development database-copy command, SQLite state utility, and Node-test fixture setup remain compatibility users. Within a process, different bindings must not concurrently open the same underlying database file, including inode/path aliases. Sequential close-before-open handoff is allowed; the initializer completes its snapshot and closes before opening V2, usage readers own different external files, and state/copy utilities run in separate processes. Audit that ownership rather than assuming matching version strings prove shared locking state. If a candidate actually requires concurrent mixed access to the same file, prove both bindings share the pinned runtime's SQLite library and locking state or retain the candidate. Comparison fixtures run variants in separate subprocesses and use each variant's own binding for same-process contending connections. Native evaluation must not change the on-disk domain schema.
  • Subprocesses: Scope native spawning to first-party shared process/shell services and the service-lifecycle boundary. Provider SDK-internal spawning remains outside this candidate; Bun's compatibility child-process API already delegates to native spawning. Derive the contract from current callers and existing library behavior: stdin/stdout/stderr streaming, output limits, cancellation, cleanup, exit status, environment/PATH/cwd resolution, signals/process-tree cleanup as currently used, and service/workflow-worker IPC within the chosen runtime line. Do not add unused detached-process options or other speculative capabilities. Source self-invocation and compiled hidden-command dispatch both remain supported. Cross-break IPC interoperability is not required; keep same-line update handoff, checksum rejection, and automatic rollback. Document and verify stop/replace/restart for crossing the break and manual stop/restore/restart for recovery. If cross-break IPC is dropped, an ordinary update attempted by the actual pre-change archive must either complete or fail safely, back to a running pre-change service with data intact. It must never strand the installation. This proves safe failure/recovery, not an IPC compatibility bridge. Keep the already-native PTY adapter and provider protocol boundaries.
  • File I/O: Evaluate measured hot paths behind existing filesystem/file-access services. If HTTP is retained, this candidate covers only read/write operations; native HTTP file responses are considered only after a native HTTP decision. Retain validated descriptors, identity checks, non-blocking/no-follow behavior, range/HEAD requests, cache/compression semantics, and cancellation cleanup. Prove native descriptor-backed file ownership, lifetime, close behavior, and cancellation before adopting such responses. Do not reopen a validated file by pathname just to use a native API. A general filesystem replacement is not required.
  • Adapter inspection: Verify implementations rather than inferring native behavior from names. In the Effect 4.0.1 reference, the Bun filesystem and child-process modules delegate to shared Node implementations; swapping the aggregate platform layer alone would not make those operations native.
  • Diagnostics: Native JavaScriptCore heap statistics are optional support in disposable measurement tooling, separately from OS RSS/footprint and cross-process resource telemetry. Do not add production instrumentation or a new client diagnostics feature. The current heap snapshot compatibility call already delegates to Bun's native generator, so renaming it is not a migration benefit. Retain Bun-aware event-loop delay/sleep handling; stub utilization and V8-shaped heap counters are not authoritative evidence of native V8 behavior.
  • Adoption gate: Declare the workload, benefit metric, and measurement method before prototyping. A performance improvement must be at least 5% of the compatibility median and exceed the compatibility run range in that metric's units, reproduced in a second independent alternating batch. Alternatively, reproduce a concrete incompatibility and prove the replacement fixes it; that route does not require a speed gain. Both routes require behavioral parity and passing regression gates in startup, idle CPU, RSS, available platform footprint, affected-workload tail latency, and HTTP wire bytes when applicable. A harmful median shift larger than that batch's compatibility max-minus-min range is a regression; idle CPU additionally uses a 0.1 percentage-point floor, measured as percentage of one core. A regression reproduced in both batches rejects adoption; a regression in only one batch is inconclusive and also prevents adoption. Never average away a failing build form or supported host. Use the initial batch and at most one repeat batch; unresolved noise is inconclusive. These are conservative issue-specific thresholds, not a universal Bun performance promise.
  • Final shape and test runtime: Keep one chosen production implementation per boundary, with no public backend selector or production fallback matrix. The current compatibility implementation may remain solely for explicit Node-test composition where the contributor test runner cannot load Bun APIs. Run one shared observable contract fixture for compatibility and native variants under Bun in separate subprocesses; Node-suite success alone is not native-adapter evidence. Keep the native production composition and Node-test composition distinct. If keeping Node suites loadable would require a broad dual architecture, retain the candidate. Temporary benchmarking variants stay disposable or are removed; this test exception does not authorize a second production backend.
  • Upstream-sync gate: Native adapters live in fork-owned modules. Changes in shared upstream code stay as small replacements at existing layer-construction sites and entry composition, so domain/service code remains directly importable. Use the existing sync-upstream workflow without adding recurring manual procedures, global rewrites, a compatibility matrix, or a new sync system. Compare baseline and candidate in a disposable rehearsal using the same fixed actual upstream input: the complete range from the most recent upstream import touching the changed shared sites, or the latest 50 commits when there is no such recorded import. Replay a recorded change from its pre-change base if it is already present; an already-applied/no-op merge is not evidence. Record conflicted files/hunks and required repairs for both variants. A candidate must add no conflicts outside the existing construction/entry sites; additional conflicts inside them must be mechanically resolvable by a concise preservation rule in the current skill. If it needs broader repairs or a new step on every import, retain it. A one-time edit documenting the adapter's preservation rule is allowed. Apply this gate to every accepted native adapter and any permitted runtime break.
  • Distribution and reversibility: Preserve the packaged helper interpreter, single shared Effect context in executable bundling, file-backed native/SDK/browser assets, platform targets, fork release/npm defaults, and checksums. Within the new runtime line, ordinary service launch/update and automatic rollback retain their behavior. A break may use the clean-stop upgrade/recovery route rather than mixed-version handoff. Preserve the fork's current lightweight CI and run additional runtime/performance checks manually.
  • Completion: Record an accepted, retained, or inconclusive decision for all four boundaries, with workload/method/results, attribution limits, and the reason. Accepted replacements have qualifying benefit or a fixed incompatibility, passing current-build behavior and Bun-native source/archive evidence on all supported targets, passing regression gates, and passing the upstream-sync gate. Record any runtime break, the compatibility machinery removed, and its one-time upgrade/recovery steps, including redeployment of an owned hosted client when applicable. Retained decisions state the absence of an actionable problem or the specific behavioral/maintenance obstacle; inconclusive decisions state unresolved evidence and what could resolve it. Retained/inconclusive candidates land no production changes, including composition refactors. Record the preservation rules for every accepted local adapter in the existing runtime-boundary and sync guidance. Keep raw benchmark artifacts and implementation scratch outside the repository; publish sufficient summaries and artifact links on this issue. The issue owns the active work record.

Testing Decisions

  • Primary seam: Reuse the existing disposable environment-server fixture and authenticated transport/persistence smoke, running through the same public environment interface against Bun source and an actual standalone archive. This is the highest shared seam for proving adapter behavior. The contributor runner remains Node-based: native-adapter evidence comes from real Bun source/archive processes and Bun subprocess contract fixtures, following the existing SQLite, Browser-stream, and authentication runtime-fixture patterns. Node in-process tests continue to prove domain behavior through their test composition. Reuse their relevant assertions in the Bun-run fixture instead of treating Node success as native coverage. Add focused boundary tests only where the integrated interface cannot distinguish a required contract, and only extend candidate-specific parity coverage when triage justifies a prototype.
  • External behavior: Assert responses, frames, close behavior, emitted output, exit results, persisted/replayed state, typed failures, and cleanup for the current matched client/server/helper builds. The baseline comparison proves current features, not support for stale builds or cross-break protocols. Do not assert internal API selection, callback wiring, implementation-shaped mocks, or static component attributes.
  • HTTP prior art: Extend the existing authenticated HTTP/WebSocket/persistence smoke, Browser-stream runtime fixture, and development/shipped real-client regression harness. Cover failed or refused upgrades, compressed and uncompressed channels, slow viewers, cancellation, reconnects, streaming bodies, and graceful shutdown under Bun. Measure RPC wire bytes and CPU for repeatable representative frame sequences, preserving compression benefits for remote/relay/tunnel clients. Verify JPEG frames themselves remain uncompressed and pending bytes stay bounded, rather than asserting a particular extension-negotiation implementation. Test hosted-client compatibility and locally served assets as applicable, plus remote/relay/tunnel behavior at the existing transport seams.
  • SQLite prior art: Reuse the shared SQL client's Bun subprocess fixture and the observable contracts from core/plugin persistence/recovery tests. Exercise all execution/result modes, raw write results, failed-prepare recovery, safe integer/boolean behavior, rollback/savepoints, classified failures, contending writers, read-only access, restart/replay, and atomic event/projection/receipt/outbox behavior under each actual Bun adapter. Use persisted milestones or drain the effect worker; no sleep-based test synchronization. Node fixture database setup is permitted, but mixed native/compatibility database handles must obey the binding-ownership decision.
  • Process prior art: Reuse native/helper smoke, service-lifecycle source/compiled/archive cases, and focused process/provider replay fixtures. Exercise streamed partial output, bounded output, currently used signals/process-tree cancellation, environment/cwd resolution, same-line service/workflow-worker IPC, missing executables, nonzero exits, compiled self-invocation, checksum rejection, and automatic rollback under Bun. If runtime interoperability is intentionally dropped, test the first stop/replace/restart upgrade using the actual pre-change archive and verify manual stop/restore/restart recovery, then verify new-to-new handoff and rollback. Also attempt the ordinary update from the actual pre-change archive once: it must complete or return to a running pre-change service with data intact. A failed handoff that strands the installation blocks adoption. Do not add old/new IPC bridge tests or shims. Controlled provider fixtures cover supported adapter paths without requiring paid accounts or provider-side runtime migrations; unused spawn options need no new contract.
  • File prior art: Reuse HTTP/static/media and workspace-file tests for content, ranges/HEAD, cache behavior, validated descriptor identity, invalid/nonregular paths, interruption, and descriptor cleanup. Native APIs must satisfy the same observable contract, not a smaller substitute.
  • Performance method: Use fresh isolated homes and a declared workload; alternate compatibility/native launch order. Each batch contains at least five fresh launches per variant. Any accepted replacement requires two independent batches, including an incompatibility fix's regression evidence. A clearly rejected candidate can stop after the first batch; uncertain results receive at most one repeat. Report per-run results, medians, and full max-minus-min ranges, with latency distributions for repeated operations and per-run tail percentiles. Use identical idle observation windows of at least 60 seconds and consistent startup/readiness and memory sampling milestones. Derive CPU use from the same process-rusage user/system CPU-time source for all variants and report its resolution. Record host/OS, Bun pin, revision, build form, fixture size, warmup/caching choices, process attribution, and units. Keep profiler runs separate from timed measurements. Compare like build forms; source and actual archive results are separate. Profiles may investigate the HTTP compatibility connection-checking timer as a hypothesis, without attributing idle CPU to it in advance.
  • Memory interpretation: Keep OS RSS and platform footprint distinct, with JavaScriptCore heap details separately identified. Exclude browsers/provider children from server-only measurements or report them explicitly. Collect normal-operation measurements before any separate full-GC diagnostic. Do not treat a short flat heap sample as an endurance/leak proof or promise that native APIs universally reduce RAM.
  • Sync and upgrade evidence: Run the baseline/candidate upstream rehearsal in disposable checkouts, outside live runtime state. Report actual changed/shared sites, conflict and repair differences, and the preservation rule. Reject a no-op merge as evidence. For allowed runtime breaks, prove the documented upgrade/recovery route and name removed options or mixed-version support; retaining the old behavior is not a test requirement. Performance/adoption gates still apply: permission to break compatibility does not prove a native API is beneficial.
  • Safety and supported hosts: Use disposable state and captured server/process PIDs; never write to the live environment database or kill by name/path matching. Before accepting a native replacement, obtain Bun source and actual archive parity evidence on macOS arm64, Linux x64, and Linux arm64, including host-dependent spawn/file/locking semantics. A native Linux arm64 container/VM or an emulated Linux x64 container may count for observable parity when it runs the actual target source runtime and archive; report architecture, kernel, and emulation explicitly. Emulation never counts as performance evidence. Missing platform evidence leaves the candidate inconclusive and the production backend unchanged. A performance claim may be limited to the measured supported host, but must not imply gains on unmeasured hosts. Report retained/inconclusive evidence gaps honestly. Follow AGENTS.md for focused checks and browser consent. Extra suites remain manual; the existing small CI smoke job stays unchanged.

Out of Scope

  • Implementing migrations during specification/review, automatically replacing every node: import, or promising a speed/memory gain before measurement.
  • Restoring desktop/native mobile clients, adding Windows or other archive targets, replacing provider CLIs, or moving their own runtimes to Bun.
  • Replacing orchestration, wire schemas, persisted domain formats, the plugin/workflow architecture, the native cross-process resource monitor, or already-native PTYs/heap snapshot generation for naming consistency.
  • Adding a new client-facing diagnostics feature, continuously polling JavaScriptCore internals, forcing collection in production, or attributing the existing RSS/CPU differences to a specific adapter without evidence.
  • Migrating contributor Vite+/pnpm tooling, broad dependency upgrades, restoring removed CI workflows/checks/matrices, or automatically publishing/deploying releases.
  • Migrating loopback authentication callback servers, outbound HTTP clients, SDK-internal process spawning, standalone usage-reader SQLite bindings, development database-copy/state utilities, or creating permanent production backend choices.
  • Supporting stale client builds, mixed server/helper versions, cross-break IPC bridges, downgrade data migrations, or building a new upstream-sync system. Unnecessary breakage is also outside scope; permitted breaks must simplify a qualifying candidate and pass the existing-workflow sync gate.

Further Notes

  • This follows the completed Bun migration (#12) and merged PR #15.
  • Runtime boundaries and native candidates retain the architectural context. Fork synchronization guidance protects intentional differences during upstream imports.
  • Bun 1.4.2 measurements and limitations are historical context, not a native-versus-compatibility benchmark. Source RSS was 457.8 versus Node's 411.5 MiB; packaged RSS was 347.0 versus 342.4 MiB. Idle CPU was higher for Bun while separate macOS footprint measurements favored it. Reproduce the relevant baseline before drawing a new conclusion.
  • The maintainer confirmed the primary test seam during synthesis: existing disposable source/archive environment harnesses, plus focused boundary tests where needed.
  • The maintainer also confirmed that this fork has one user and does not need backward compatibility. Runtime breaks may simplify a migration when later upstream pulls remain as easy as the current workflow. That permission does not authorize deleting durable history or claim a performance benefit.
  • Primary API contracts: Bun WebSocket backpressure and limits, Bun SQLite, and SQLite's single-library locking requirement. Verify the repository-pinned runtime and Effect implementations; current online documentation is not proof of version-specific parity.
  • Specification synthesized using the to-spec skill with GPT-6.1-Sol through the Codex harness in T3 Code and independently reviewed by Claude Opus 5.5 in a separate T3 thread. Both agreed on 2026-10-08 that this specification is ready for agent implementation, with no remaining blockers: profile before prototyping, prove native behavior under Bun, apply measured adoption and upstream-sync gates, and permit simplifying runtime breaks with safe upgrade/recovery and unchanged durable formats. This work produced a specification, not a runtime migration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentSpecified and ready for agent implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions