dd878bc498
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Failing after 7s
CI & Build / TypeScript typecheck (push) Successful in 35s
CI & Build / integration (push) Successful in 39s
CI & Build / Python tests (push) Successful in 47s
CI & Build / Build & push image (push) Successful in 21s
Per-job installs, not an image change. CI-runner's docs/process.md decision checkpoint is explicit: "If only one project needs the dep, prefer that project installing it per-job in their workflow — at least until a second consumer arrives." Scribe is the only consumer, and shellcheck is not a natural extension of a Python image's purpose. Promotion into ci-python is filed as an issue on CI-runner rather than assumed here — same doc, step 1: the maintainer's call goes in the issue, then the PR. This also corrects something I got wrong earlier in this work: I cited rule #5 as blocking a per-job install. Rule #5 is about language TOOLCHAINS via setup-* actions, not small lint utilities, and CI-runner's own process doc positively recommends per-job installs in exactly this case. jq is load-bearing rather than convenient. Every hook opens with `command -v jq || exit 0`, so without it a "runs and stays silent" smoke test passes while exercising nothing — a green tick proving less than no test at all. That is why the smoke test didn't ship with the first cut. The smoke test pins the fail-open contract: each hook, with no credentials and then against a refused connection, must exit 0. Three must also stay silent; scribe_session_context.sh must NOT, because its static behavioural floor is meant to survive having no credentials and no network — asserting silence there would encode the opposite of the design. Verified it can actually fail, rather than assuming: injected a non-zero exit and separately a stray stdout write, and confirmed each is caught. shellcheck and jq are both optional at runtime — missing either SKIPs its check loudly rather than passing. A check that quietly no-ops is the exact failure mode this file exists to prevent. ci-requirements.md updated: jq + shellcheck recorded under per-job installs (the input CI-runner's maintainer uses for the next promotion decision), plus two stale entries corrected — the sheet claimed four jobs when there are six, and listed `uv` as a per-job install when it has been in the image since the ci-python Dockerfile started pip-installing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs
54 lines
2.2 KiB
Markdown
54 lines
2.2 KiB
Markdown
# 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 six jobs in `.forgejo/workflows/ci.yml`: typecheck (Vue/TS),
|
|
plugin (hook checks), lint (ruff), test (pytest), integration (pytest +
|
|
real Postgres), 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)
|
|
- uv (test + integration jobs run `uv sync --locked`; installed in the
|
|
image since the ci-python Dockerfile started pip-installing it)
|
|
- 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.
|
|
|
|
- `jq` + `shellcheck` — apt-installed in the **plugin** job, which lints
|
|
the four Claude Code hook scripts and runs their fail-open smoke test.
|
|
Per `docs/process.md`'s decision checkpoint, single-consumer deps stay
|
|
per-job until a second consumer wants them; Scribe is the only one so
|
|
far. Both are small (jq ~1 MB, shellcheck ~20 MB) and would be
|
|
promotion candidates the moment another project lints shell.
|
|
**jq is load-bearing for the smoke test specifically**: every hook
|
|
starts with `command -v jq || exit 0`, so without it the test passes
|
|
while exercising nothing.
|
|
|
|
## 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.
|