Skip to content

Latest commit

 

History

History
78 lines (56 loc) · 4.15 KB

File metadata and controls

78 lines (56 loc) · 4.15 KB

AGENTS.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

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.

Commands

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 -k expression word-splits and fails. Run one keyword per invocation, or a substring matching all targets.
  • tests/test_unit.py + tests/test_fake.py need no Postgres and run directly under uv run pytest; tests/test_integration.py skips if POSTGRES_DSN is unreachable. The coverage gate is on by default, so a partial run trips it — pass --no-cov while iterating.
  • Nothing validates Markdown links outside docs/. just docs-build runs mkdocs --strict over the site only; root Markdown, .github/, and docs/agents/ are unchecked.

Architecture

Every module under faststream_outbox/ is named for what it does; read it. What a single-file read will not tell you:

  • subscriber/usecase.py is load-bearing: every terminal write filters on acquired_token, so a stale writer finds rowcount == 0 and is dropped. Any new fetch or terminal path must preserve that — tests/test_client_contract.py::test_delete_noop_on_token_mismatch is the claim.
  • client.py and testing.py implement 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, so tests/test_client_contract.py couples 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_ck CHECK are load-bearing, not decoration.
  • message.py — the DLQFailureReason Literal is a public contract; operator queries key off those strings, so changing one is API-breaking.
  • metrics/ (the recorder seam) and prometheus/ + opentelemetry/ (native middleware) are two seams, deliberately. Each fires for events the other physically cannot observe — fetched has no StreamMessage, lease_lost fires after consume_scope exits. 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.

Workflow

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.

Code Style

  • Never use local/inline imports — tests included, no if TYPE_CHECKING exception. ruff catches them; if # noqa: PLC0415 looks 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.

Agent skills

Issue tracker

GitHub issues on modern-python/faststream-outbox, via gh. See docs/agents/issue-tracker.md.

Triage labels

The five canonical roles, each label string equal to its name. See docs/agents/triage-labels.md.

Domain docs

Single-context: CONTEXT.md and docs/adr/ at the repo root. See docs/agents/domain.md.