Skip to content

Commit fbdcb31

Browse files
bokelleyclaude
andauthored
feat(decisioning): PgBuyerAgentRegistry — durable Tier 2 commercial-identity store (#364)
Postgres-backed BuyerAgentRegistry implementation for adopters who need durable commercial-identity gating without forking the SQLAlchemy reference example. Mirrors the design of adcp.signing.pg.PgReplayStore — caller-owned ConnectionPool, table-name validation, idempotent ``create_schema()``, raw DDL ships separately for migration tools (Alembic, Flyway, psql). * ``src/adcp/decisioning/pg/buyer_agent_registry.py`` — sync psycopg-pool implementation; the async BuyerAgentRegistry Protocol methods bridge via ``asyncio.to_thread`` so the framework's dispatch event loop stays responsive. * ``src/adcp/decisioning/pg/buyer_agent_registry.sql`` — canonical schema for migration tools. JSONB columns for billing_capabilities, default_terms, allowed_brands, ext. CHECK constraint on status. Partial index on api_key_id for the bearer-credential lookup path. Partial index on status WHERE status <> 'active' for admin tools. * Admin CRUD: upsert(), set_status(), delete(). Status validated against the framework's literal enum. * SQL injection / Unicode-homoglyph defenses on the table_name kwarg matching PgReplayStore's posture. * 15 conformance tests gated on ADCP_PG_TEST_URL — all 15 pass against postgres:16. CI's existing pg job (renamed pg-replay-store → pg-conformance) now runs them too. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent dc37318 commit fbdcb31

6 files changed

Lines changed: 830 additions & 3 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ jobs:
3939
run: |
4040
pytest tests/ -v --cov=src/adcp --cov-report=term-missing
4141
42-
pg-replay-store:
43-
name: PgReplayStore tests (Postgres 16)
42+
pg-conformance:
43+
name: Postgres conformance tests (Postgres 16)
4444
runs-on: ubuntu-latest
4545
services:
4646
postgres:
@@ -73,12 +73,13 @@ jobs:
7373
python -m pip install --upgrade pip
7474
pip install -e ".[dev,pg]"
7575
76-
- name: Run PgReplayStore tests (unit + full-wire e2e)
76+
- name: Run Postgres conformance tests
7777
env:
7878
ADCP_PG_TEST_URL: postgresql://postgres@localhost:5432/adcp_test
7979
run: |
8080
pytest tests/conformance/signing/test_pg_replay_store.py \
8181
tests/conformance/signing/test_pg_replay_store_e2e.py \
82+
tests/conformance/decisioning/test_pg_buyer_agent_registry.py \
8283
-v
8384
8485
conventional-commits:
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""PostgreSQL-backed implementations for the decisioning module.
2+
3+
Ships durable backends behind the ``[pg]`` optional extra so the
4+
base ``adcp.decisioning`` import path stays free of SQL dependencies
5+
for adopters who only need the in-memory primitives.
6+
7+
Available when ``adcp[pg]`` is installed:
8+
9+
* :class:`PgBuyerAgentRegistry` — durable Tier 2 commercial-identity
10+
layer for v3 sellers. The framework calls the registry on every
11+
request to gate dispatch on the seller's commercial relationship
12+
with the buyer agent (allowlist + onboarding state + billing
13+
capabilities).
14+
15+
The schema DDL ships alongside the Python code (e.g.
16+
``adcp/decisioning/pg/buyer_agent_registry.sql``) so adopters can run
17+
it through whatever migration tool they use (Alembic, Flyway, psql).
18+
"""
19+
20+
from __future__ import annotations
21+
22+
from adcp.decisioning.pg.buyer_agent_registry import (
23+
DEFAULT_TABLE_NAME,
24+
PG_AVAILABLE,
25+
PgBuyerAgentRegistry,
26+
)
27+
28+
__all__ = [
29+
"DEFAULT_TABLE_NAME",
30+
"PG_AVAILABLE",
31+
"PgBuyerAgentRegistry",
32+
]

0 commit comments

Comments
 (0)