Skip to main content

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

PathRole
lumie-backend/build.gradle.ktsRoot Gradle build, shared verification wiring, license gate, and backend lint sweep
lumie-backend/gradle/libs.versions.tomlBackend version catalog, including Spring Boot 3.4.13
lumie-backend/config/allowed-licenses.jsonBackend allow-list for dependency license checks
lumie-backend/app/src/main/resources/application-dev.ymlDev-only Flyway seed location override
lumie-frontend/package.jsonFrontend Node engine, scripts, and production dependency license gate
lumie-worker/pyproject.tomlWorker uv workspace members plus shared Ruff and mypy config
lumie-worker/MakefileExport contract from uv.lock to committed requirements.txt files
lumie-worker/services/*/DockerfileRuntime packaging path that still installs from exported requirements.txt
lumie-worker/TiltfileDev live-update path that re-installs from service requirements.txt
lumie-backend/.github/workflows/ci.ymlActive backend check, ARM image build, Zot push, and image-tag write-back workflow
lumie-frontend/.github/workflows/ci.ymlActive frontend test, typecheck, lint, OpenAPI client drift, audit, image build, and image-tag write-back workflow
lumie-worker/.github/workflows/ci.ymlActive 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.shWorkspace entrypoint for the hybrid frontend-local, cluster-backed dev loop

Current State By Repo

SurfaceActive build contractDependency hygiene contractNotable limits or drift
lumie-backendGradle Kotlin DSL multi-module build with check, integrationTest, and jacocoTestReport wiringRoot check depends on license allow-list validation and scripts/lumie-lint/sweep.shError Prone is warn-only, and jacocoTestCoverageVerification is defined but not wired into check
lumie-frontendnpm with committed lockfile, test:unit, tsc --noEmit, lint, npm audit, and Orval-generated client drift checks in GitHub Actionslicense:check enforces a production SPDX allow-list locally, but the active workflow does not run it todaypackage.json requires Node >=24.18.0 <25, while the active workflow still sets up Node 22
lumie-workeruv workspace at repo root, service-local pyproject.toml, exported requirements.txt, and service pytest loops in GitHub ActionsActive workflow runs Lumie lint, Ruff, mypy, GPL or AGPL rejection, and requirements drift checksActive 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 workspaceBackend application-dev.yml adds classpath:db/seed so dev seed data is part of the backend profileThe 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.
  • test excludes @Tag("integration") by default.
  • integrationTest is the explicit Testcontainers path.
  • spotlessCheck is part of check.
  • license enforcement is blocking, not advisory.
  • JaCoCo coverage minimum 0.30 exists, but it is not part of check.

Frontend Contract

lumie-frontend/package.json is the frontend source of truth for local tooling:

  • Node engine: >=24.18.0 <25
  • lint: ESLint plus scripts/lumie-lint/sweep.sh frontend --paths '*'
  • test:unit: Vitest
  • test:e2e:*: Playwright suites for API, flow, UI, SSR, and environment-specific runs
  • license:check: production dependency whitelist via license-checker-rseidelsohn

The active GitHub Actions workflow goes further than the local script surface:

  • npm ci --prefer-offline
  • npx orval --config orval.config.ts
  • git diff check for src/entities/*/api/generated.ts
  • npx tsc --noEmit
  • npm run lint
  • npm 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.lock is the workspace lock source.
  • committed requirements.txt files are generated artifacts for Docker and Tilt.
  • service Dockerfiles copy and install those exported requirement files.
  • the active workflow rejects drift between uv export --frozen output and the committed files.

Active CI coverage is intentionally service-oriented:

  • requirements drift and pytest loops cover analysis, grading, report, and chatbot
  • the image matrix builds those four services plus temp-omr-grading
  • temp-omr-grading is 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-push waits for Gradle check
  • frontend build-push waits for install, unit tests, typecheck, lint, OpenAPI client drift, and high-severity audit
  • worker build-push waits 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.sh is the supported entrypoint

Backend dev seed data is live and code-backed:

  • application-dev.yml adds classpath:db/seed
  • R__dev_seed.sql is rerun safely through INSERT ... 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 check graph.
  • Frontend GitHub Actions runtime and declared Node engine are out of sync.
  • temp-omr-grading is image-built by worker CI but remains outside the shared worker test and dependency-drift loop.
  • The older audit claim about committed .env.example files does not match the current repo tree.