diff --git a/docs/adr/0009-bun-runtime-and-native-tooling.md b/docs/adr/0009-bun-runtime-and-native-tooling.md new file mode 100644 index 0000000..2abfdf1 --- /dev/null +++ b/docs/adr/0009-bun-runtime-and-native-tooling.md @@ -0,0 +1,18 @@ +--- +status: proposed +--- + +# Bun Runtime and Native Tooling + +VacOptimizer will use Bun as the runtime for project-owned JavaScript in +development, CI, and production, adopting its native test runner, linter, +formatter, type checker, and HTTP server even without measured performance gains. +This deliberately accepts Bun-specific tooling and migration work while retaining +Angular's standard compiler and build pipeline, including TypeScript 6 for +Angular compilation alongside `bun check` for standalone TypeScript checking. + +Existing behavior, tests, lint rules, coverage reporting, and benchmark budgets +must be preserved; incompatibilities must be fixed or reported as blockers before +declaring completion, and a Node.js fallback does not meet the runtime requirement. +The [development spec](../bun-adoption.md) records the agreed boundaries, +acceptance criteria, and remaining verification. diff --git a/docs/bun-adoption.md b/docs/bun-adoption.md new file mode 100644 index 0000000..d0c0c45 --- /dev/null +++ b/docs/bun-adoption.md @@ -0,0 +1,199 @@ +# Bun Runtime and Native Tooling — Development Spec + +Status: local draft synthesized from the agreed individual decisions. Integration +feasibility remains unverified; ADR 0009 remains proposed. + +## Problem Statement + +The maintainer wants VacOptimizer to use Bun as its actual JavaScript runtime and +adopt its native tooling wherever agreed, even without measurable performance +gains. Today Bun installs dependencies, generates the language registry, and runs +the deployed server, but development commands can launch Node-based CLIs, CI uses +Node containers, and the Docker build explicitly installs Node. + +The toolchain is also inconsistent: the local Bun installation is 1.3.14, CI pins +1.4.2, and Docker uses a floating Bun image. Merely prefixing commands with Bun +does not establish which runtime executes their JavaScript. + +## Solution + +Use Bun for project-owned JavaScript in development, CI, and production. Adopt +Bun's native test runner, linter, formatter, standalone type checker, and HTTP +server. Retain Angular and its standard compiler and build pipeline, running the +JavaScript tooling under Bun. + +Preserve the application's existing behavior and verification standards. The +planner remains client-side: planning horizons, planning rules, leave placements, +planning outcomes, plan statistics, and plan explanations retain their current +meaning. Browser code and Web Workers continue to run in the user's browser. + +## User Stories + +The following acceptance criteria define completion: + +1. **Actual Bun execution.** Development serving and watch mode, production + builds, language generation, repository CI scripts, tests, and the production + server execute their project-owned JavaScript under Bun, including spawned + tools and test fixtures. A Node.js fallback does not satisfy this criterion. +2. **Reproducible setup.** Development instructions, CI, and both Docker stages + specify the same exact, verified Bun version. Frozen dependency installation + succeeds from a clean checkout without changing the lockfile, and the + production image installs only production dependencies. +3. **Native tests with preserved behavior.** All existing functional and Angular + component tests execute under `bun test`, preserving assertions, parameterized + cases, clock control, global mocks, cleanup, isolation, and real worker + integration. Tests cannot be dropped or weakened to make the migration pass. +4. **Preserved coverage.** Functional tests retain coverage reporting and CI + artifacts, including useful output when tests fail. Preserve the current + production-code coverage scope and exclusion of the frozen engine baseline; + report unsupported coverage capabilities or report formats as compatibility + gaps rather than silently removing them. +5. **Native linting and formatting.** Bun's native linter and formatter replace + ESLint and Prettier, preserving the current rule severities, type-aware checks, + unused-name exceptions, formatting options, and Angular-template formatting. + CI continues to reject violations. Checks cover the same application, + repository-script, and workflow content as before. +6. **Type checking alongside Angular.** `bun check` checks application and test + TypeScript. Angular's compiler retains its supported TypeScript 6 dependency + and continues to check templates during builds. Type errors still fail the + appropriate checks; successful standalone checking does not replace a + successful Angular build. +7. **Native HTTP serving.** `Bun.serve` replaces Express, preserving Angular's + request-handler integration, configured rendering modes, static assets and + cache behavior, configurable port, error handling, and container health check. + Development and production routes continue to work, including direct visits + to the benchmark page. The current catch-all route uses client rendering; + this migration does not enable server rendering for that route. +8. **Existing CI guarantees.** Policy and image-publication regression checks, + security scans, production builds, artifact retention, and required checks + continue to work. The separate required seven-scenario benchmark preserves + its calibration protocol, warm-up, measured repetitions, determinism checks, + timeouts, and performance budgets. A runtime change cannot justify weakening + these gates. +9. **Honest completion.** Fix incompatible required tooling before declaring the + migration complete. If a fix proves infeasible, report the failing behavior, + evidence, and remaining blocker. Local success must be distinguished from + successful live Gitea checks. + +## Implementation Decisions + +- **Agreed: runtime and native tools.** Bun adoption is a requirement independent + of speed gains. Use its native test runner, linter, formatter, standalone type + checker, and HTTP server. Compatible Node API imports may remain when executed + by Bun; rewriting every import is not required to satisfy the runtime goal. +- **Agreed: Angular boundary.** Keep Angular's standard compiler, bundler, + development server, and framework build support. Preserve the existing + rendering configuration and browser-based planner, consistent with ADR 0002. +- **Agreed: TypeScript coexistence.** Keep TypeScript 6 for Angular compilation + and use Bun's TypeScript 7-based checker for standalone checking. An Angular + upgrade is not required for this arrangement. +- **Agreed: tests and server integration.** Adapt the Angular test compilation + and setup, mocks, DOM environment, worker harnesses, and subprocess fixtures to + the chosen runtime and runner. Use Angular's web request API with Bun's HTTP + server, preserving its development/build handler contract and static-file + protections. +- **Migration reach.** Update package commands, test configuration and typings, + generated executable fixtures, server entry and exports, container build and + runtime stages, project-owned CI invocations, and development documentation. + Remove superseded dependencies and configuration after checking their callers. +- **Proposed implementation order.** Verify the Bun release, an Angular + production build, representative Angular component tests, and native + lint/format/type checks first. Extend that verified setup to the full suite, + server, containers, and CI before removing the replaced tools. +- **Proposed version.** Bun 1.4.3 is the initial candidate based on the researched + native-tool documentation. Select the exact version only after verifying the + required capabilities together. + +## Testing Decisions + +- Test observable behavior and failure outcomes, rather than configuration text + or internal adapter shapes. Reuse the existing behavior-level tests and change + harnesses only where the runtime or runner requires it. +- **Runtime and installation:** exercise clean frozen installs, development and + production commands, and project-owned subprocesses with Node unavailable to + those commands. Verify actual execution by Bun, rather than relying on a + command's name. Keep any CI-platform Node requirement separate from this check. +- **Angular and planning:** use the existing TestBed-based component and service + suites as prior art for compilation and DOM behavior. Retain the planning + integration, property-based, migration, date-sensitive, and cancellation tests + to check planning outcomes, saved inputs, and plan explanations. +- **Workers and subprocesses:** preserve the existing real-worker tests for + submitted-configuration isolation, outcome and explanation delivery, and worker + cleanup. Run policy and publisher regression scripts with Bun, keeping their + temporary Git repositories and fake Docker executable so verification remains + independent of real registry writes. +- **Lint, format, and types:** compare the current checks with the native tools. + Use small representative invalid inputs to establish that unused variables, + deprecated APIs, formatting violations, application/test type errors, and + Angular template errors still fail the intended command. Verify formatting + options and representative Angular templates without an unrelated reformat. +- **HTTP and containers:** add focused HTTP behavior checks around the native + server, since the explored test suite provides no equivalent server coverage. + Exercise configured routes, direct navigation, static JavaScript/CSS assets, + cache and content-type headers, missing assets, error responses, and traversal + protection. Smoke-test the production container and its health check. +- **Coverage and benchmark:** verify functional coverage artifacts, including + failure-path uploads, and run the existing benchmark outside coverage. Keep the + frozen-engine calibration and current budget assertions. Record Bun results as + new measurements rather than claiming browser or phone speedups from them. +- **CI:** use the existing policy/publisher regression scenarios as prior art for + push, pull-request, fork, manual, and release-event behavior. Obtain successful + required checks on the final PR revision; live publication and activation + validation remain subject to the repository's existing Gitea process. + +## Out of Scope + +- Replacing Angular's build pipeline with Bun's bundler, rewriting the framework, + or bypassing Angular's TypeScript support checks. +- Moving leave planning to the server, changing planning rules or objectives, + altering saved data, or adding accounts, synchronization, or backend services. +- Changing configured rendering modes or treating Bun as the browser runtime. +- Dropping tests, weakening lint rules or benchmark budgets, or silently using + Node to complete otherwise incompatible project commands. +- Replacing security scanners, changing registry publication policy, provisioning + CI credentials, modifying branch protections or activation settings, creating + releases, publishing this spec, or deploying the application. +- Rewriting compatible Node API imports solely because their names mention Node. + +## Further Notes + +This spec records the decisions made in the interview. The architecture record +remains proposed, and no migration implementation or compatibility proof exists. +The glossary receives no new terms because the choices concern general tooling, +rather than new leave-planning concepts. + +Remaining verification and unresolved requirements: + +- Angular compilation, test-resource loading, serializers, mocking, isolation, + and the existing worker harnesses must work under the native Bun runner. +- Standalone TypeScript 7 diagnostics must be checked alongside Angular's + TypeScript 6 diagnostics; their coexistence is agreed, but project-specific + differences have not been measured. +- Current Istanbul reports include text, HTML, and Cobertura. Native coverage + equivalence and report-format support have not been established; accepting a + reduced capability or different downstream format has not been agreed. +- Third-party Gitea checkout and artifact actions may impose their own Node + requirement. Identify the actual platform constraint; no exception allowing + project commands to fall back to Node has been agreed, and CI infrastructure + changes beyond the migration require a separate decision. +- The exact Bun release and container compatibility remain to be verified. + The local installation currently lacks the documented native lint, format, + and standalone type-check commands. + +Research checked on 2026-10-17: + +- [Bun runtime selection](https://bun.sh/docs/runtime#--bun) explains why a Bun + command can still launch a Node executable. +- [Bun 1.4.3](https://bun.sh/blog/bun-v1.4.3), + [native linting](https://bun.sh/docs/lint), + [formatting](https://bun.sh/docs/format), and + [type checking](https://bun.sh/docs/runtime/check) describe the candidate tools. +- [Angular build guidance](https://angular.dev/ecosystem/custom-build-pipeline) + recommends retaining its standard CLI pipeline. +- [Angular's web request engine](https://angular.dev/api/ssr/AngularAppEngine) and + [Bun's HTTP server](https://bun.sh/docs/runtime/http/server) provide the intended + server integration contracts; their compatibility here remains untested. +- [Angular version compatibility](https://angular.dev/reference/versions) and + [compiler roadmap](https://angular.dev/roadmap) establish the current Angular + compiler boundary. [Microsoft's coexistence guidance](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#typescript-and-embedded-languages) + describes standalone TypeScript 7 checks alongside Angular-specific tooling.