This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
faststream-outbox is a FastStream broker whose transport is a Postgres table (transactional
outbox pattern), Postgres-only at v0. CONTEXT.md opens with what it does and owns
the vocabulary — read it before naming a concept in code, a test name, or an issue title.
just (task runner) and uv (package manager). The justfile is the source of truth —
just --list, or read it. Every recipe carries its intent as a comment. The things it does not say:
just test [args]forwards args unquoted, so a spaced-kexpression word-splits and fails. Run one keyword per invocation, or a substring matching all targets.tests/test_unit.py+tests/test_fake.pyneed no Postgres and run directly underuv run pytest;tests/test_integration.pyskips ifPOSTGRES_DSNis unreachable. The coverage gate is on by default, so a partial run trips it — pass--no-covwhile iterating.- Nothing validates Markdown links outside
docs/.just docs-buildrunsmkdocs --strictover the site only; root Markdown,.github/, anddocs/agents/are unchecked.
Every module under faststream_outbox/ is named for what it does; read it. What a single-file read
will not tell you:
subscriber/usecase.pyis load-bearing: every terminal write filters onacquired_token, so a stale writer findsrowcount == 0and is dropped. Any new fetch or terminal path must preserve that —tests/test_client_contract.py::test_delete_noop_on_token_mismatchis the claim.client.pyandtesting.pyimplement the same rules twice, in SQL and in Python, because one runs in the database and one in the process. They cannot share an implementation, sotests/test_client_contract.pycouples them by behaviour — a change to either adapter's fetch, terminal, or DLQ semantics belongs in that suite.schema.py— the three partial indexes and the<table>_lease_ckCHECK are load-bearing, not decoration.message.py— theDLQFailureReasonLiteralis a public contract; operator queries key off those strings, so changing one is API-breaking.metrics/(the recorder seam) andprometheus/+opentelemetry/(native middleware) are two seams, deliberately. Each fires for events the other physically cannot observe —fetchedhas noStreamMessage,lease_lostfires afterconsume_scopeexits. Don't collapse them.
TestOutboxBroker swaps in FakeOutboxClient. Sync mode is the default; run_loops=True runs the
real fetch and worker loops against the fake, which retry, lease-expiry, and scheduling tests need.
Every link in README.md must be absolute: https://github.com/modern-python/<repo>/blob/main/<path>,
or .../tree/main/<path> for a directory. Never a relative path: README.md is also the PyPI long
description, and PyPI does not rewrite relative links, so a relative one 404s on the package page.
tests/test_invariant_census.py checks every invariant test's docstring for a second paragraph naming
what breaks it.
- Never use local/inline imports — tests included, no
if TYPE_CHECKINGexception.ruffcatches them; if# noqa: PLC0415looks like the fix, hoist the import instead. - Docstrings: public API documents the contract; internal helpers get a one-line contract, plus at most 1–2 lines for a genuinely non-obvious constraint. Never narrate implementation or justify code to a reviewer — cross-file rationale lives in an invariant test's docstring.
- Lint suppressions are intentional and carry their reason at the site. The recurring cluster is
everything downstream of
BrokerUsecase's invariance on its config type.
GitHub issues on modern-python/faststream-outbox, via gh. See docs/agents/issue-tracker.md.
The five canonical roles, each label string equal to its name. See docs/agents/triage-labels.md.
Single-context: CONTEXT.md and docs/adr/ at the repo root. See docs/agents/domain.md.