# CI Requirements — FabledScribe

> Spec lives in [`docs/process.md`](https://git.fabledsword.com/bvandeusen/CI-runner/src/branch/main/docs/process.md)
> in the CI-Runner repo.

## Runtime image

```
git.fabledsword.com/bvandeusen/ci-python:3.14
```

Used by all four jobs in `.forgejo/workflows/ci.yml`: typecheck (Vue/TS),
lint (ruff), test (pytest), build (docker buildx).

## Image deps used

- python 3.14
- node 24 (used for `npm ci` + `vue-tsc` in the typecheck job, and as the
  frontend builder stage inside the production `Dockerfile`)
- ruff (lint job runs `ruff check src/` with zero install overhead)
- docker CLI + buildx (build job pushes the production image to the
  Forgejo registry)

## Per-job tool installs

Anything CI installs at job time that isn't in the image. Promotion
candidates if more than one project needs them.

- `uv` — installed inline in the test job (`curl -LsSf
  https://astral.sh/uv/install.sh | sh`). **Temporary**: belongs in the
  ci-python image so every consumer doesn't re-install on cold start.
  Tracked at [CI-Runner](https://git.fabledsword.com/bvandeusen/CI-runner).
- `http-ece` is `--no-build-isolation`-installed before the editable
  package install because http-ece doesn't declare `setuptools` as a
  build dep and uv creates bare venvs without it. Not promotion-worthy
  (one project, one wheel).

## Notes

- Production runtime image (`Dockerfile`) also tracks Python 3.14 — the
  CI image and runtime image stay aligned by design so test results are
  representative.
- Build wall time: dominated by `pytest` (full async test suite). Cold
  ci-python pulls add ~30s; not a blocker.
- Registry-backed BuildKit layer cache (`type=registry,ref=…:cache,mode=max`)
  gives ~80% speedup on warm builds — see the build job comment.
- `pyproject.toml` pins `requires-python = ">=3.14"` to match the CI +
  runtime target; lockfile (`uv.lock`) is committed and resolves against
  Python 3.14.
