CLAUDE.md · git:20260818.0164a05 · 2026-08-18 · sha256 f02a6e908bd4938a
CLAUDE.md git:20260818.0164a05A
Immutable. This exact content is served forever at /api/v1/blob/f02a6e908bd4938a.
# CLAUDE.md Arthur Engine is an AI/ML monitoring and governance platform. Each component has its own CLAUDE.md with commands and gotchas: - [genai-engine/](genai-engine/CLAUDE.md) — FastAPI REST API for LLM evaluation and guardrailing (Python 3.12, PostgreSQL + pgVector) - [genai-engine/ui/](genai-engine/ui/CLAUDE.md) — React 19 + TypeScript + Vite frontend - [ml-engine/](ml-engine/CLAUDE.md) — job-based evaluation engine for ML model monitoring (Python 3.13) - [arthur-observability-sdk/](arthur-observability-sdk/CLAUDE.md) — Python SDK for tracing and prompt management ## Workflow - `dev` is the default branch: feature branches come from `dev` and PRs target it. `main` is production releases. - Pre-commit hooks format code and run the unit test suites — a slow or failing commit is usually them, not git. - GenAI Engine API changes require a changelog entry: `uv run generate_changelog` from `genai-engine/`. - Repo skills cover environment setup and running the stack: `setup-genai-dev`, `start-genai-backend`, `start-genai-frontend`. - Full-stack local deployment: [deployment/docker-compose/genai-engine/](deployment/docker-compose/genai-engine/) (`cp .env.template .env`, then `docker compose up`). ## Dependencies Every Python project here is `pyproject.toml` + `uv.lock`, and the two must never disagree. CI installs with `uv sync --frozen`, which replays the lockfile and never looks at the manifest — so a manifest-only change is invisible at runtime while still looking merged. Change a pin, then `uv lock --directory <project>` and commit both files together. Never hand-edit `uv.lock`. `check-dependency-automation` in [the CI workflow](.github/workflows/arthur-engine-workflow.yml) enforces this across all four uv projects via [`.github/scripts/check-lockfile-drift.sh`](.github/scripts/check-lockfile-drift.sh), which you can run locally from the repo root. It reports one of two states: - **STALE** — the manifest resolves but the lock was not regenerated. Run `uv lock` and commit. - **UNRESOLVABLE** — nothing can satisfy the manifest, usually because a *transitive* constraint of another pinned dependency caps the package being bumped (`litellm` caps `openai<3.0.0`; `gliner` caps `transformers`; `presidio-anonymizer` caps `cryptography`). Move the lagging dependency forward — never cap or downgrade the one being updated. If nothing upstream lifts the ceiling yet, add an `allowedVersions` rule in [renovate.json](renovate.json) so Renovate stops re-proposing it, naming the blocker and the condition for removing the cap. Renovate opens PRs that edit the manifest without the lock whenever its lockfile step fails, and offers no way to fail closed — that gate is the only thing that catches it. See the `description` at the top of [renovate.json](renovate.json). ## Code style Write code that reads like the surrounding code: match its comment density, naming, and idiom. ## Frontend All UI work uses MUI components styled via `sx` with theme tokens — see [genai-engine/ui/CLAUDE.md](genai-engine/ui/CLAUDE.md) for the rules.