Repository command reference¶
Run these commands from the repository root unless a command says otherwise. This is the single entry point for the supported developer, simulation, generated-source, benchmark, service, and documentation workflows. Follow the linked guides for configuration and interpretation; this page is a command reference, not a production deployment plan.
Before you start¶
Python 3.14 is the development default; the package supports 3.12–3.14. Install uv, and keep the
pinned sibling telemetry checkout at ../telemetry. Docker workflows need Docker Compose and the
same sibling checkout as a build context. Keep database URLs and passwords in environment variables
or an untracked .env, never in committed configuration or command arguments.
make setup # install locked development, PostgreSQL, observability, and torch extras
make doctor # inspect tools, Python, lock, sibling telemetry, and dependencies
make setup uses uv sync --locked; if it says the lockfile needs updating, diagnose the lock or
sibling checkout before changing it. make lock intentionally rewrites uv.lock and needs review.
See testing and troubleshooting.
Develop, test, and package¶
| Command | Purpose |
|---|---|
make test-focused TEST=tests/path.py::test_name |
Run one test or test file. Replace the example path. |
make lint |
Check Ruff rules. |
make format |
Format source files in place; inspect the diff afterward. |
make type-check |
Run strict mypy checks. |
make docs-check |
Validate repository documentation links and command references. |
make docs-site |
Build the strict MkDocs site into .build/docs-site/. |
make architecture-check |
Check import boundaries. |
make test-static |
Run lint, types, docs, and architecture checks. |
make test-unit |
Run unit tests. |
make test-contract |
Run contract and delivery tests. |
make test-integration |
Run non-PostgreSQL integration tests. |
make test |
Run the normal static, unit, contract, and integration gates. |
make migration-check |
Check migration round trips. |
make compose-check |
Validate both Compose configurations without starting services. |
make build |
Build wheel and sdist in .build/. |
make smoke |
Build and test an installed wheel in an isolated environment. |
make verify |
Run make test and make smoke. |
make lock |
Regenerate uv.lock; review dependency changes before committing. |
PostgreSQL tests can drop generated-source tables. Point TEST_CONTROL_DATABASE_URL only at a
database you explicitly regard as disposable, then run:
export TEST_CONTROL_DATABASE_URL='postgresql+psycopg://.../disposable_test_db'
make test-postgres
Run the local service¶
The API and worker are separate processes. Provide a service-owned PostgreSQL control database,
a deployment JSON file, and the source URL variable named by that file's connection_url_env.
Copy and adapt config/data_sources.example.json first;
the example identifiers below must match your configured Commerce Scope.
export RECOMMENDATIONS_CONTROL_DATABASE_URL='postgresql+psycopg://...'
export RECOMMENDATIONS_DATA_SOURCES_FILE="$PWD/config/data_sources.json"
export MERCHANT_PLATFORM_DATABASE_URL='postgresql+psycopg://...'
uv run --frozen alembic upgrade head
uv run --frozen recommendations-api
In a second terminal with the same environment:
uv run --frozen recommendations-worker
Check the HTTP contract, submit a Training Run, inspect its returned ID, and request an anchored Recommendation Set:
curl http://127.0.0.1:8000/openapi.json
curl -X POST http://127.0.0.1:8000/v1/training-runs \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: local-example-1' \
-d '{"data_source_id":"merchant-platform","tracking_id":"store-42","catalog_id":"main"}'
curl http://127.0.0.1:8000/v1/training-runs/RUN_ID
curl 'http://127.0.0.1:8000/v1/catalogs/main/items/SKU-1/recommendations/frequently-bought-together?data_source_id=merchant-platform&tracking_id=store-42&limit=20'
Replace RUN_ID and scope values with real values. Do not run sample Training Runs against a
production source by accident. For configuration, personalization, and operational behavior, see
the README, technical implementation, and
operations guide.
Simulate a Commerce Property locally¶
The default Compose stack starts separate control and mutable Simulation Data Source databases, the API, worker, and storefront. It is local/test-only and does not exercise payments or real Shoppers. It uses named Docker volumes, so stopping containers preserves state.
make compose-check
docker compose up --build
Open the storefront at http://127.0.0.1:8080 and API at http://127.0.0.1:8000. In another terminal, run the default Independent-Behavior Scenario or inspect stack state:
docker compose --profile runner run --rm simulation-runner
docker compose ps
docker compose logs api worker storefront
docker compose down
The installed CLI also exposes init, storefront, and run for a separately configured local
environment; run sends requests to the configured storefront URL:
uv run --frozen recommendations-simulation --help
uv run --frozen recommendations-simulation init
uv run --frozen recommendations-simulation storefront --host 127.0.0.1 --port 8080
uv run --frozen recommendations-simulation run \
--scenario config/simulation-scenarios/default-independent.json
storefront is a long-running process; run run from another terminal after it and the API are
ready. Do not start another storefront on port 8080 while the Compose stack is using it.
Use config/simulation-scenarios/default-feedback.json only when deliberately studying a
Recommendation-Feedback Scenario; it is not independent recommendation-quality evidence. See the
simulation guide for run controls, checkpoints, reports, reset,
and safety limits. docker compose down --volumes deletes the local databases and reports;
use it only when those volumes are intentionally disposable.
Generate a relational source¶
The smoke profile creates a verified SQLite source and evidence files. The much larger
development profile can use a dedicated PostgreSQL database; the CLI does not expose the
qualification profile. Output paths below are gitignored.
uv run --frozen recommendations-generate-source \
--profile smoke --output-dir artifacts/generated-smoke
uv run --frozen recommendations-generate-source --help
For direct PostgreSQL materialization, export the credential-bearing SQLAlchemy URL without
putting its value in the CLI invocation. The destination must not already contain the five source
tables unless --replace is deliberately supplied.
export GENERATED_SOURCE_DATABASE_URL='postgresql+psycopg://.../generated_source'
uv run --frozen recommendations-generate-source \
--profile development --database-url-env GENERATED_SOURCE_DATABASE_URL \
--workers 4 --output-dir artifacts/generated-development
Alternatively, configure GENERATED_SOURCE_POSTGRES_PASSWORD in an untracked root .env, then
use the dedicated Compose file. Its default one-shot generator replaces the five generated
tables in that dedicated database on rerun.
mkdir -p artifacts/generated-development
docker compose -f compose.generated-source.yaml up -d generated-source-db
docker compose -f compose.generated-source.yaml run --build --rm generator
docker compose -f compose.generated-source.yaml exec generated-source-db \
psql -U generated_source -d generated_source -c 'SELECT COUNT(*) FROM views;'
docker compose -f compose.generated-source.yaml down
To extend an existing PostgreSQL generation, keep the original manifest and use a newer UTC
cutoff. --append inherits profile, seed, capabilities, and Commerce Scope from that manifest;
do not combine it with --replace or use the default Compose generator command for this step.
docker compose -f compose.generated-source.yaml run --rm generator \
recommendations-generate-source --append \
--database-url-env GENERATED_SOURCE_DATABASE_URL \
--output-dir /app/artifacts/generated-development \
--cutoff 2026-10-01T00:00:00Z
The cutoff above is illustrative: choose one later than the manifest cutoff. See the
generated-source guide
for verification, storage cost, and exact retry behavior. Adding --volumes to the dedicated
Compose down command deletes its generated database.
Benchmark and qualify¶
These first four commands use synthetic data and do not establish production capacity or recommendation relevance. Make passes the quoted arguments to the corresponding script.
make benchmark-training BENCHMARK_ARGS='--threads 4'
POLARS_MAX_THREADS=4 make benchmark-training \
BENCHMARK_ARGS='--aggregation-backend polars --threads 4'
make benchmark-cooccurrence-suite \
SUITE_ARGS='--profile smoke --backends duckdb sparse --power off --output .build/cooccurrence-smoke.json'
make benchmark-ann ANN_BENCHMARK_ARGS='--items 2000 --queries 40'
make benchmark-ann-representation ANN_REPRESENTATION_ARGS='--components 128 256'
The co-occurrence suite also has quick, matrix, and resource-heavy out-of-core profiles.
Keep thread, memory, and case settings identical between backend comparisons. See the
co-occurrence benchmark, ANN experiment,
and testing guide for bounds and interpretation.
The separate qualification driver acts on a deployed, preloaded service: it submits a real Training Run and sends serving and training-API requests. Run it only in an approved qualification environment with the required source counts, then retain its artifact:
uv run --frozen python scripts/qualify.py \
--base-url http://service:8000 \
--data-source-id qualification --tracking-id qualification-store \
--catalog-id qualification-catalog --anchor-product-id SKU-000001 \
--artifact artifacts/qualification.json
Documentation, CI, and deployment¶
Build and inspect the site locally with make docs-site; its output is .build/docs-site/.
The documentation site GitHub Actions workflow builds pull requests and deploys pushes to
main to the recommendations-docs Cloudflare Pages Direct Upload project when the repository
has CLOUDFLARE_ACCOUNT_ID and a Pages-write CLOUDFLARE_API_TOKEN Actions secret. The Pages
project publishes the selected Markdown publicly; it does not need access to this private repo.
Workflow dispatch from main provides a manual redeploy. See testing
for the publication boundary.
make docs-check
make docs-site
gh workflow run docs-pages.yml --ref main
gh run list --workflow docs-pages.yml --limit 5
For a local service image, docker compose up --build above is a simulation deployment only.
The repository does not contain a general production service deployment command or approved
hosting configuration; follow the owning environment's release process rather than treating the
Compose defaults as production settings. Build artifacts or an HTTP schema separately when needed:
make build
make smoke
mkdir -p artifacts
uv run --frozen python scripts/export_openapi.py artifacts/openapi.json
Run make migration-check after migration edits and make compose-check after Docker/Compose
edits. For telemetry release evidence and incident procedures, use the
operations guide; evidence inputs must come from actual passed
gates, not invented local results.
Operations and release evidence¶
Validate the backend-neutral dashboard, alert, and runbook contract, or checksum evidence files without opening them in a log:
uv run --frozen python scripts/validate_observability_operations.py
uv run --frozen python scripts/sha3sum.py uv.lock operations/recommendations.toml
scripts/build_telemetry_evidence.py --help lists the release-evidence arguments. The builder
requires a candidate telemetry wheel, a digest-pinned Collector image and configuration, the
consumer revision, and six already passing gate JSON files: candidate_install,
api_and_durable_parity, context_and_cardinality, privacy_canaries, failure_isolation, and
domain_operations. It checks that all six identify the same wheel; it does not run the gates.
Use the operations guide and the owning telemetry release process
for the required inputs. There is no safe generic one-command substitute for those gates.