diff --git a/AGENTS.md b/AGENTS.md
index 3382753..d3a50cc 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -6,18 +6,18 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
`faststream-outbox` is a FastStream broker whose transport is a Postgres table (transactional
outbox pattern), Postgres-only at v0. [`CONTEXT.md`](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.
+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`](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` (task runner) and `uv` (package manager). The [`justfile`](justfile) is the source of truth:
+run `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.
+ 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.
@@ -28,18 +28,17 @@ 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.
+ 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 insert, fetch,
+ `tests/test_client_contract.py` couples them by behaviour. A change to either adapter's insert, fetch,
terminal, or DLQ semantics belongs in that suite.
-- `schema.py` — the three partial indexes and the `
_lease_ck` CHECK are load-bearing, not
- decoration.
-- `message.py` — the `DLQFailureReason` `Literal` is a **public contract**; operator queries key off
+- `schema.py`: the three partial indexes and the `_lease_ck` CHECK are load-bearing.
+- `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.**
+ seams on purpose. Each fires for events the other cannot observe: `fetched` has no
+ `StreamMessage`, and `lease_lost` fires after `consume_scope` exits. **Don't collapse them.**
`TestOutboxBroker` swaps in `FakeOutboxClient` and nothing else on the publish side: the real producer
and publish middlewares run, and a thin wrapper dispatches what the fake stored once the producer
@@ -57,11 +56,11 @@ what breaks it.
## Code Style
-- **Never use local/inline imports** — tests included, no `if TYPE_CHECKING` exception. `ruff`
+- **Never use local/inline imports**, tests included, with 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.
+ most one or two lines for a 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.
diff --git a/CONTEXT.md b/CONTEXT.md
index 4fdbb54..46f5eb1 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -11,7 +11,7 @@ docs must agree on it. General programming vocabulary does not belong here, howe
project uses it.
**Row**:
-One outbox record — the unit the transport moves. There is no `state` column: a row exists until it
+One outbox record: the unit the transport moves. There is no `state` column: a row exists until it
is delivered or terminally fails.
_Avoid_: job, task, event
@@ -33,7 +33,7 @@ statement matches nothing.
_Avoid_: lease id, owner id
**Claim**:
-Acquiring a lease on a row via the fetch CTE. Increments `deliveries_count` — including on an
+Acquiring a lease on a row via the fetch CTE. Increments `deliveries_count`, including on an
expired-lease reclaim.
_Avoid_: fetch (that is the loop and the client method), dequeue
@@ -50,7 +50,7 @@ The bounded wait on stop for in-flight rows to reach a terminal write.
_Avoid_: graceful shutdown (that names the whole phase, not this wait)
**Outcome**:
-The single disjoint result `dispatch_one` matches on — `Ack`, `Retry(delay_seconds)`, or
+The single disjoint result `dispatch_one` matches on: `Ack`, `Retry(delay_seconds)`, or
`Terminal(reason)`.
_Avoid_: status, result, state
@@ -64,7 +64,7 @@ _Avoid_: schedule, delayed message
**`timer_id`**:
The dedup key for at most one *live* row per `(queue, timer_id)`. It is not a global once-ever
-idempotency key — a delivered row's id is reusable.
+idempotency key; a delivered row's id is reusable.
_Avoid_: idempotency key, message key
**Relay**:
@@ -73,7 +73,7 @@ _Avoid_: bridge, forwarder
**DLQ**:
The opt-in sibling audit table terminal failures are archived to. Off by default.
-_Avoid_: dead-letter queue as a transport — nothing consumes it
+_Avoid_: dead-letter queue as a transport (nothing consumes it)
**Recorder seam**:
The `MetricsRecorder` callable the library invokes for events outside the FastStream bus.
diff --git a/docs/adr/0002-free-threading-is-compat-only.md b/docs/adr/0002-free-threading-is-compat-only.md
index 99e3dbc..3b7b18e 100644
--- a/docs/adr/0002-free-threading-is-compat-only.md
+++ b/docs/adr/0002-free-threading-is-compat-only.md
@@ -1,10 +1,10 @@
# Free-threading is a compatibility guarantee, not a parallelism redesign
Free-threaded support means proving that `faststream-outbox` runs correctly on free-threaded CPython
-3.14t with the GIL disabled; it does not mean rearchitecting the subscriber to use multiple cores.
+3.14t with the GIL disabled. The subscriber is not rearchitected to use multiple cores.
The package is pure-Python asyncio, one event loop with N worker tasks rather than OS threads, so
free-threading changes none of its runtime semantics and the guarantee costs a CI job, a
-`Free Threading :: 2 - Beta` classifier, and a docs note rather than a source change. Exploiting the
+`Free Threading :: 2 - Beta` classifier, and a docs note, with no source change. Exploiting the
parallelism was rejected because the two-loop subscriber, the lease-token invariant, and
drain-on-stop all assume one loop, throughput is dominated by Postgres I/O, and scaling today means
running more subscriber processes. The guarantee was bounded by SQLAlchemy until 2.0.54, whose