feat(decisioning): add full stack registry factory#862
Merged
Conversation
There was a problem hiding this comment.
LGTM. Right shape — thin composition over already-reviewed primitives, with the canonical layer order documented in registry_cache.py:37-62 materialized as a one-call factory.
Things I checked
- Layer order matches the docstring claim:
Caching(RateLimited(Auditing(self))), cache outermost so hits skip rate-limit accounting and DB work (buyer_agent_registry.py:464-486). audit_sink/sink_timeout_secondsthreaded through all three wrappers;time_sourcethreaded through the two that accept it (Cache, RateLimited) —AuditingBuyerAgentRegistry.__init__doesn't taketime_sourceand the factory correctly omits it (registry_cache.py:613-619).- Observer wiring at
buyer_agent_registry.py:486is the samelambda _op, _agent_url: cache.clear_sync()pattern aswith_cachingat L419. Sameadd_mutation_observerlock guard, same single-instance scope caveat. - Defaults track the wrapper classes:
ttl_seconds=60.0,max_entries=4096,rps_per_tenant=100.0,burst=None→rps,time_source=time.monotonic— all matchCachingBuyerAgentRegistry.__init__andRateLimitedBuyerAgentRegistry.__init__. - Test outcome accounting is consistent with the "terminating layer emits, fallthrough does not" rule (
registry_cache.py:27-31): Test 1 produces[resolved, cached_hit, resolved], Test 2 produces[miss, rate_limited]. Both assertions match. - Type-only
AuditSinkimport is correctly guarded byTYPE_CHECKING; theregistry_cacheimport sits inside the method to dodge the same import cyclewith_cachingdodges. - Public-API audit: purely additive new method on a public class.
feat:is the correct conventional-commit prefix — no!needed. security-reviewer: no High/Critical findings._credential_keyemitsapi_key:<key_id>/oauth:<client_id>— non-secret identifiers; no new credential-leak path versus pre-factory composition. Tenant isolation preserved (both wrappers key on(tenant_id, lookup_key)from_current_tenant_id()).
Follow-ups (non-blocking — file as issues)
security-reviewerflagged a doc-framing Medium: the rate limiter is bucketed per-(tenant_id, lookup_key), so an attacker rotatingagent_urls within one tenant context sustains ~100 RPS ofmissaudit events per probed URL. Already documented behavior ofRateLimitedBuyerAgentRegistry, butwith_full_stack's "canonical production" framing oversells it. Worth a sentence in thewith_full_stackdocstring spelling out the per-key keyspace, and considering a future per-tenant-global knob.- Calling
with_full_stack()more than once on the samepginstance stacks twoclear_syncobservers and two caches — fine semantically (each lambda clears its own cache) but worth a one-line "call once at startup" note in the docstring to head off the per-request footgun. CapturingAuditSinkandFakeClockattest_pg_buyer_agent_registry.py:47-63look duplicative of patterns already intests/conformance/decisioning/test_registry_cache.py. Shared fixture would be tidier; not blocking.
Approving. Tests are conformance-gated on ADCP_PG_TEST_URL so the CI Postgres job is the real validation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces #765 on a repo-owned branch, stacked on top of #861 / #696 so required base-repo checks can run normally.
Closes #697.
This adds
PgBuyerAgentRegistry.with_full_stack()as the one-call factory for the documented production wrapper order:Caching(RateLimited(Auditing(pg))).What changed
with_full_stack()toPgBuyerAgentRegistry.CachingBuyerAgentRegistry.audit_sinkandsink_timeout_secondsthrough all three layers.time_sourcebetween cache and rate limiter for deterministic tests.Local validation
PYTHONPATH=src ruff check src/adcp/decisioning/pg/buyer_agent_registry.py tests/conformance/decisioning/test_pg_buyer_agent_registry.pyPYTHONPATH=src pytest tests/conformance/decisioning/test_pg_buyer_agent_registry.py -q(skips locally: no Postgres fixture in this workspace)