Build and Dependency Hygiene
This page is the English source-of-truth reference for Lumie's build and dependency hygiene. It documents what the repositories and active GitHub Actions workflows enforce today, plus the contract drift that operators should not smooth over.
Source Paths
| Path | Role |
|---|---|
lumie-backend/build.gradle.kts | Root Gradle build, shared verification wiring, license gate, and backend lint sweep |
lumie-backend/gradle/libs.versions.toml | Backend version catalog, including Spring Boot 3.4.13 |
lumie-backend/config/allowed-licenses.json | Backend allow-list for dependency license checks |
lumie-backend/app/src/main/resources/application-dev.yml | Dev-only Flyway seed location override |
lumie-frontend/package.json | Frontend Node engine, scripts, and production dependency license gate |
lumie-worker/pyproject.toml | Worker uv workspace members plus shared Ruff and mypy config |
lumie-worker/Makefile | Export contract from uv.lock to committed requirements.txt files |
lumie-worker/services/*/Dockerfile | Runtime packaging path that still installs from exported requirements.txt |
lumie-worker/Tiltfile | Dev live-update path that re-installs from service requirements.txt |
lumie-backend/.github/workflows/ci.yml | Active backend check, ARM image build, Zot push, and image-tag write-back workflow |
lumie-frontend/.github/workflows/ci.yml | Active frontend test, typecheck, lint, OpenAPI client drift, audit, image build, and image-tag write-back workflow |
lumie-worker/.github/workflows/ci.yml | Active worker lint, requirements drift, pytest, image build, and image-tag write-back workflow |
lumie-infra/applications/tekton/ci-cd/** | Disabled Tekton task and pipeline manifests retained as a reactivation path |
.github/tilt-up.sh | Workspace entrypoint for the hybrid frontend-local, cluster-backed dev loop |
Current State By Repo
| Surface | Active build contract | Dependency hygiene contract | Notable limits or drift |
|---|---|---|---|
lumie-backend | Gradle Kotlin DSL multi-module build with check, integrationTest, and jacocoTestReport wiring | Root check depends on license allow-list validation and scripts/lumie-lint/sweep.sh | Error Prone is warn-only, and jacocoTestCoverageVerification is defined but not wired into check |
lumie-frontend | npm with committed lockfile, test:unit, tsc --noEmit, lint, npm audit, and Orval-generated client drift checks in GitHub Actions | license:check enforces a production SPDX allow-list locally, but the active workflow does not run it today | package.json requires Node >=24.18.0 <25, while the active workflow still sets up Node 22 |
lumie-worker | uv workspace at repo root, service-local pyproject.toml, exported requirements.txt, and service pytest loops in GitHub Actions | Active workflow runs Lumie lint, Ruff, mypy, GPL or AGPL rejection, and requirements drift checks | Active workflow covers analysis, grading, report, and chatbot; temp-omr-grading is image-built but not part of the shared Python test loop |
| Workspace dev loop | .github/tilt-up.sh opens the cluster tunnel and starts Tilt from the shared workspace | Backend application-dev.yml adds classpath:db/seed so dev seed data is part of the backend profile | The repo roots do not currently contain committed .env.example files, despite older audit notes that claimed they did |
Backend Contract
lumie-backend/build.gradle.kts is the backend enforcement point.
Representative excerpt:
tasks.named("check") {
dependsOn("checkLicense")
}
tasks.named("check") {
dependsOn("lumieLint")
}
That file also proves these active rules:
- Java toolchain is pinned through the version catalog to
21. testexcludes@Tag("integration")by default.integrationTestis the explicit Testcontainers path.spotlessCheckis part ofcheck.- license enforcement is blocking, not advisory.
- JaCoCo coverage minimum
0.30exists, but it is not part ofcheck.
Frontend Contract
lumie-frontend/package.json is the frontend source of truth for local tooling:
- Node engine:
>=24.18.0 <25 lint: ESLint plusscripts/lumie-lint/sweep.sh frontend --paths '*'test:unit: Vitesttest:e2e:*: Playwright suites for API, flow, UI, SSR, and environment-specific runslicense:check: production dependency whitelist vialicense-checker-rseidelsohn
The active GitHub Actions workflow goes further than the local script surface:
npm ci --prefer-offlinenpx orval --config orval.config.ts- git diff check for
src/entities/*/api/generated.ts npx tsc --noEmitnpm run lintnpm audit --audit-level=high
Document the drift honestly: the repo declares a Node 24 engine, while the active workflow still uses actions/setup-node with node-version: "22".
Worker Contract
lumie-worker uses uv as the dependency source of truth, but runtime packaging still installs from exported requirements.txt.
Representative excerpt from lumie-worker/Makefile:
EXPORT = $(UV) export --frozen --no-dev --no-emit-project --no-header
regen-requirements:
$(EXPORT) --package grading-svc --output-file services/grading/requirements.txt
$(EXPORT) --package report-svc --output-file services/report/requirements.txt
$(EXPORT) --package analysis-svc --output-file services/analysis/requirements.txt
$(EXPORT) --package chatbot-svc --output-file services/chatbot/requirements.txt
The practical effect is:
uv.lockis the workspace lock source.- committed
requirements.txtfiles are generated artifacts for Docker and Tilt. - service Dockerfiles copy and install those exported requirement files.
- the active workflow rejects drift between
uv export --frozenoutput and the committed files.
Active CI coverage is intentionally service-oriented:
- requirements drift and pytest loops cover
analysis,grading,report, andchatbot - the image matrix builds those four services plus
temp-omr-grading temp-omr-gradingis still outside the shared Ruff, mypy, requirements-drift, and pytest loops because it is a temporary service shape
CI Gate Posture
The active CI gate posture is GitHub Actions based:
- backend
build-pushwaits for Gradlecheck - frontend
build-pushwaits for install, unit tests, typecheck, lint, OpenAPI client drift, and high-severity audit - worker
build-pushwaits for Lumie lint, Ruff, format check, mypy, license check, requirements drift, and service pytest loops
All three active workflows build ARM64 images, push short-SHA and main tags to Zot, and write the short-SHA tag into Lumie-Edu/lumie-image-tags on main.
Tekton is different. The checked-in Tekton tasks and pipelines still exist under lumie-infra/applications/tekton/ci-cd/**, and some tasks support advisory behavior such as INFORMATIONAL=true, but the Tekton Argo CD applications are disabled in lumie-infra/applications/kustomization.yaml. Treat Tekton drift as reactivation risk, not active CI behavior.
See CI/CD and Tekton for the deployment handoff and disabled Tekton boundary.
Dev Bootstrap Notes
The workspace dev loop is still the hybrid model from the root AGENTS.md:
- frontend local
- backend, workers, and stateful services in the dev cluster
.github/tilt-up.shis the supported entrypoint
Backend dev seed data is live and code-backed:
application-dev.ymladdsclasspath:db/seedR__dev_seed.sqlis rerun safely throughINSERT ... ON CONFLICT DO NOTHING
Do not claim stronger env bootstrap guarantees than the repo provides today. In the current tree, the repo roots do not contain committed .env.example files.
Verification
Use the narrowest relevant read-only or verification-oriented commands:
cd /Users/bluemayne/Projects/Lumie/lumie-backend
./gradlew check
./gradlew integrationTest
./gradlew jacocoTestCoverageVerification
cd /Users/bluemayne/Projects/Lumie/lumie-frontend
npm ci
npm run test:unit
npm run lint
npm run license:check
cd /Users/bluemayne/Projects/Lumie/lumie-worker
uv lock --check
uv run pytest services/analysis/tests services/grading/tests services/report/tests
uv export --frozen --no-dev --no-emit-project --no-header --package grading-svc | diff -u services/grading/requirements.txt -
cd /Users/bluemayne/Projects/Lumie
rg -n "actions/setup-node|orval|npm audit|uv export|docker/build-push-action|image-values" \
lumie-backend/.github/workflows/ci.yml \
lumie-frontend/.github/workflows/ci.yml \
lumie-worker/.github/workflows/ci.yml
Success means the repo-local checks pass, generated dependency exports stay in sync, and the active GitHub Actions workflows still match the documented enforcement.
Current Gaps
- Release tagging and automated release process are not encoded as a checked-in build gate in the inspected repos.
- Backend coverage enforcement is present as a task but not part of the default backend
checkgraph. - Frontend GitHub Actions runtime and declared Node engine are out of sync.
temp-omr-gradingis image-built by worker CI but remains outside the shared worker test and dependency-drift loop.- The older audit claim about committed
.env.examplefiles does not match the current repo tree.