Turn documentation · May 30, 2026

# Expand CI Quality Gates

Added explicit formatting and linting to the Forgejo CI workflow, kept the existing Bun-first validation path, and formatted the current source tree once so the new formatter gate starts from a clean baseline.

## Summary

The CI workflow now checks formatting, lint, type safety, tests, public API route wiring, Docker workspace snapshot drift, and the web production build. This gives pull requests a broader health signal without introducing a separate Node package manager or changing the repo's Bun-centered workflow.

## Changes Made

- Added `@biomejs/biome` as a pinned root development dependency.
- Added root scripts: `fmt`, `fmt:check`, `lint`, and `check`.
- Created `biome.json` with scoped includes for source, configs, scripts, and workflow files.
- Expanded `.forgejo/workflows/ci.yml` with separate format, lint, and public API route checks.
- Ran the formatter across existing in-scope files so `fmt:check` passes immediately.
- Synced `deployment/docker/workspace-root` package and lock snapshots after dependency and script changes.

## Context

The previous CI workflow already installed dependencies, ran typecheck, ran tests, checked the Docker workspace snapshot, and built the web app. The main gap was that style and lint regressions could land silently. Biome is a good first step because it gives fast formatter and linter coverage with one dependency and works cleanly with Bun.

## Important Implementation Details

- The Biome scope excludes generated and build-heavy paths such as `node_modules`, `.next`, `dist`, `coverage`, and `apps/web/tsconfig.tsbuildinfo`.
- Some stricter recommended lint rules are disabled for now because the existing codebase has known legacy patterns. This keeps CI useful today while leaving a path to tighten rules incrementally.
- The new CI order catches cheap failures first: formatting and lint run before typecheck, tests, route checks, snapshot checks, and build.

## Relevant Diff Snippets

Rendered with `@pierre/diffs/ssr`. These snippets focus on the CI and configuration changes; the broader diff also includes the formatter baseline pass.

### .forgejo/workflows/ci.yml

.forgejo/workflows/ci.yml
+9

    35 unmodified lines36373839404142434445464735 unmodified lines      - name: Install dependencies        run: ~/.bun/bin/bun install --frozen-lockfile
          - name: Run typecheck        run: ~/.bun/bin/bun run typecheck
          - name: Run tests        run: ~/.bun/bin/bun test
          - name: Check Docker workspace snapshot        run: ~/.bun/bin/bun run check:docker-workspace
    35 unmodified lines36373839404142434445464748495051525354555635 unmodified lines      - name: Install dependencies        run: ~/.bun/bin/bun install --frozen-lockfile
          - name: Check formatting        run: ~/.bun/bin/bun run fmt:check
          - name: Run lint        run: ~/.bun/bin/bun run lint
          - name: Run typecheck        run: ~/.bun/bin/bun run typecheck
          - name: Run tests        run: ~/.bun/bin/bun test
          - name: Check public API routes        run: ~/.bun/bin/bun run check:public-api-routes
          - name: Check Docker workspace snapshot        run: ~/.bun/bin/bun run check:docker-workspace

### package.json

package.json
+5

    14 unmodified lines1516171819205 unmodified lines26272829303114 unmodified lines    "dev:desktop:remote": "bun run scripts/dev-desktop.ts --remote",    "dev:web": "bun --cwd=apps/web run dev",    "dev:services": "bun run scripts/dev-services.ts",    "package:desktop": "bun --cwd=apps/desktop run package",    "make:desktop": "bun --cwd=apps/desktop run make",    "deploy": "bun run scripts/deploy.ts",5 unmodified lines    "check:docker-workspace": "bun run scripts/check-docker-workspace.ts"  },  "devDependencies": {    "@types/bun": "^1.3.3",    "@types/ws": "^8.18.1",    "typescript": "^5.9.3",14 unmodified lines151617181920212223245 unmodified lines3031323334353614 unmodified lines    "dev:desktop:remote": "bun run scripts/dev-desktop.ts --remote",    "dev:web": "bun --cwd=apps/web run dev",    "dev:services": "bun run scripts/dev-services.ts",    "fmt": "biome format --write .",    "fmt:check": "biome format .",    "lint": "biome lint .",    "check": "biome check .",    "package:desktop": "bun --cwd=apps/desktop run package",    "make:desktop": "bun --cwd=apps/desktop run make",    "deploy": "bun run scripts/deploy.ts",5 unmodified lines    "check:docker-workspace": "bun run scripts/check-docker-workspace.ts"  },  "devDependencies": {    "@biomejs/biome": "^2.4.16",    "@types/bun": "^1.3.3",    "@types/ws": "^8.18.1",    "typescript": "^5.9.3",

## Expected Impact for End-Users

End users should see fewer regressions from accidental formatting drift, obvious lint mistakes, broken public API route wiring, Docker workspace snapshot drift, or web build failures. Product behavior is unchanged; this is a delivery-quality improvement.

## Validation

passed `bun run fmt:check`
passed `bun run lint`
passed `bun run typecheck`
passed `bun test` (250 tests)
passed `bun run check:public-api-routes`
passed `bun run check:docker-workspace`
passed `bun --cwd=apps/web run build`

## Issues, Limitations, and Mitigations

- Lint is intentionally conservative at this stage. Several Biome recommended rules are disabled because enabling them all would require unrelated refactors across the terminal UI, services, and scripts.
- The formatting baseline touched many files. These changes are mechanical and were validated with typecheck, tests, route checks, Docker snapshot checks, and the web build.
- The workflow still installs Bun via the existing shell install path. A future improvement could switch to a reusable Forgejo-compatible setup action if one becomes preferred for this runner environment.

## Follow-up Work

- Incrementally re-enable stricter Biome rules once existing code patterns are cleaned up in focused PRs.
- Add a dependency/security audit gate if the Forgejo runner has stable network access for that check.
- Consider splitting CI into fast source checks and heavier build/test jobs if runtime becomes a bottleneck.
- Consider adding artifact or coverage reporting after the current quality gates settle.