Skip to content

Commerce Recommendations architecture

System boundary

The service produces property-local, catalog-local Recommendation Snapshots from configured relational sources. The isolation key is (data_source_id, tracking_id, catalog_id). External systems own catalog management, interaction capture, scheduling, authentication for ordinary training/serving APIs, and recommendation presentation.

The detailed as-built reference is technical-implementation.md. This page is the short navigation and dependency contract.

Processes and state

Component Owns Must not do
API process Training Run submission/status, snapshot reads, optional personalization endpoints Query merchant interactions or train synchronously
Worker process Source streaming, bounded reduction, training, evaluation, atomic publication Persist or export raw interaction rows
Control database Runs, leases, immutable snapshots, serving heads, bounded evidence and personalization projections Become a copy of the merchant source
Relational Data Source Merchant-owned catalog and interaction history Receive service-owned schema changes
Simulation harness Isolated mutable test source, storefront, deterministic visitors, evidence Claim production capacity or business outcomes
serving_limits Reusable in-process admission contracts Import application domain code or claim distributed enforcement
Sibling telemetry package Generic telemetry runtime and transport safety Own recommendation-domain signal meaning

Dependency direction

recommendations.domain and pure policy modules express domain values and invariants. Contracts, pipeline logic, personalization, simulation, storage, and delivery adapters depend inward on those values. recommendations.api and recommendations.worker are composition roots.

The reusable serving_limits package has no dependency on recommendations. Application telemetry is translated through recommendations.observability; deployment parsing in recommendations.config may use telemetry configuration values. Other modules must not import the platform package directly. make architecture-check enforces these repository-level boundaries.

Data and publication flow

  1. The API validates a Commerce Scope and records an idempotent pending Training Run.
  2. A worker claims and leases the run, then opens a consistent source read.
  3. Source rows are streamed into bounded group state and an ephemeral derived-only work store: DuckDB by default, or the configured Polars/Parquet aggregate engine.
  4. Strategies produce complete Recommendation Sets and aggregate evidence.
  5. The worker stages sets and Catalog feature companions, verifies the eleven-strategy manifest, and atomically publishes the snapshot, optional ANN artifact, and serving head.
  6. Serving resolves only the current head; a failed newer run leaves the previous successful head available.

Serving has several bounded paths

Ordinary GET requests retrieve a published list. Optional personalization reranks snapshot candidates against an authorized Shopper Profile. ANN-enabled Similar Items and For You may perform vector retrieval within the selected snapshot. Contextual POST requests compose configured Swimlanes from geographic and recent-seed variations, with all variation reads pinned to one head. These operations perform no merchant-source read and no synchronous training, but the optional paths do perform request-time computation.

serving.py owns ordinary/personalized application decisions; swimlane_service.py resolves snapshot variations and swimlane.py owns ordered composition; ann.py owns artifact validation, residency, and vector search. The API owns authentication/transport and maps application failures to response contracts. See engineering rationale for the tradeoffs and implementation workflow for how to modify these boundaries.

Public and durable contracts

  • FastAPI/Pydantic request and response models in recommendations.contracts;
  • domain values and strategy identifiers in recommendations.domain;
  • deployment JSON loaded by recommendations.config;
  • Alembic migrations and SQLAlchemy repositories for durable state;
  • data-source query and canonical row contracts in recommendations.source;
  • Training Evidence and telemetry schema versions in recommendations.schema_versions;
  • console entry points declared in pyproject.toml.

Changes to these surfaces require contract tests and updates to their governing specification or operations document.

Security and failure boundaries

Configuration is trusted deployment input but connection targets and secret references are still validated before side effects. SQL comes only from reviewed configuration; runtime values are bound parameters. Logs, metrics, evidence, and manifests contain bounded identifiers and aggregates, not credentials or raw interaction payloads. Personalization is separately authorized and retains a bounded, property-local projection.

Failures before atomic publication cannot replace a serving head. Lease loss, source failure, invalid configuration, incomplete strategy output, and evidence incompatibility remain explicit states rather than partial success.