shim developer guide
August 29, 2026 ยท View on GitHub
Read docs/CURRENT_ARCHITECTURE.md before changing provider routes, privacy,
streaming, authentication, accounting, or package boundaries.
Place code by product
src/shim/ community runtime and public contracts
tests/ community and architecture tests
openapi/community.json community HTTP contract
ee/src/shim_enterprise/ enterprise runtime and adapters
ee/tests/ enterprise tests
ee/alembic/ enterprise schema history
ee/openapi/enterprise.json enterprise HTTP contract
Community code must run without ee/, PostgreSQL, Redis, Supabase, or managed
secret clients. Enterprise may import only the exact shim modules and symbols
declared in architecture/module_ownership.toml. Do not bypass the boundary
with lazy imports, TYPE_CHECKING, re-export bags, or compatibility packages.
When ownership is unclear, use this rule: code belongs in shim only when it
is useful to a local developer and can build, start, and test without enterprise
infrastructure.
Runtime invariants
- Provider request and response bodies stay provider-native.
- Each admitted request makes at most one provider attempt; SDK retries remain disabled.
- Provider credentials are invocation-scoped, consumed once, and absent from logs, events, responses, and persistence.
- Missing privacy-continuation state fails closed in community mode.
- PostgreSQL is the enterprise lifecycle and accounting truth. Redis is an accelerator and continuation store, never a second ledger.
- No database transaction spans a provider call. Reservation, provider-start, heartbeat, finalization, and reconciliation keep their existing commit boundaries.
- External side effects are emitted through the transactional outbox.
- Existing table names, constraints, functions, revision IDs, and migration order are not changed as a side effect of moving code.
Local environments
Community:
cp .env.example .env
uv sync --locked --package shim-gateway
uv run --locked --package shim-gateway shim serve
Enterprise with local services:
cp ee/.env.example ee/.env
docker compose up --build
Enterprise from the source environment:
uv sync --locked --all-packages
uv run --locked --package shim-enterprise alembic -c ee/alembic.ini upgrade head
uv run --locked --package shim-enterprise uvicorn \
shim_enterprise.application:create_enterprise_app --factory
The optional manual dashboard is installed only by the enterprise application.
Set MANUAL_TEST_DASHBOARD_ENABLED=true in ee/.env, start the enterprise API,
and open http://localhost:8000/_dev/manual-test. Never enable it in a shared
or production environment.
Database workflow
shim has one independent enterprise baseline and one linear Alembic history
under ee/alembic/. Validate schema changes against disposable data:
uv run --locked --package shim-enterprise alembic -c ee/alembic.ini heads
uv run --locked --package shim-enterprise alembic -c ee/alembic.ini upgrade head
uv run --locked --package shim-enterprise alembic -c ee/alembic.ini check
uv run --locked --package shim-enterprise alembic -c ee/alembic.ini downgrade base
uv run --locked --package shim-enterprise alembic -c ee/alembic.ini upgrade head
Never downgrade a production database. Roll production back to the previous schema-compatible application image.
Contact-only plan activation is an enterprise operation:
uv run --locked --package shim-enterprise python ee/scripts/activate_plan.py --help
Required gates
Run the locked full gate before merging a cross-package or enterprise change:
uv lock --check
uv sync --locked --all-packages
uv run --locked ruff format --check src ee/src tests ee/tests scripts ee/scripts ee/alembic
uv run --locked ruff check src ee/src tests ee/tests scripts ee/scripts ee/alembic
uv run --locked ty check
uv run --locked python -m pytest -q
uv run --locked --package shim-gateway python scripts/export_openapi.py --profile community --check
uv run --locked --package shim-enterprise python scripts/export_openapi.py --profile enterprise --check
git diff --check
Build both distributions when package metadata or package data changes:
uv build --package shim-gateway --wheel --sdist
uv build --package shim-enterprise --wheel --sdist
Inspect the artifacts and install them in clean environments. The community
artifacts must contain no ee, shim_enterprise, enterprise migrations, or
enterprise direct dependencies. The enterprise wheel must include its runtime
assets and require the exact matching shim-gateway version.
Changing an API or dependency
- Trace the route through authentication,
GatewayService,GatewayKernel, provider execution, streaming, and usage finalization. - Change the owning product; keep the other product unchanged unless a public contract truly moves.
- If a public Python symbol changes, update the exact enterprise allowlist and both compositions in the same change.
- If an HTTP contract changes, regenerate both affected OpenAPI documents and the enterprise dashboard client.
- Run the smallest focused test first, then the required gates.
Do not add generic factories, plugin discovery, provider-neutral payload models, compatibility aliases, branch-bridge migrations, or a second gateway implementation. Reuse the existing stage and adapter before adding another abstraction.
Legal boundary
Apache-2.0 applies outside ee/; Elastic-2.0 applies under ee/. Preserve both
regions' LICENSE, NOTICE, and matching package metadata. Do not add a CLA,
runtime licence check, or commercial-validation policy without owner approval.
Never move enterprise source or assets outside ee/ merely to simplify
packaging.