Athomic Capability Map — "Look here before you build"
Purpose: a single index of which cross-cutting capability lives in which
src/nala/athomic/ module, and the entry point to reuse it. This exists to
enforce DRY: before writing any infrastructure code (retry, cache, lock,
backoff, secrets, …), find it here and reuse/extend it instead of
reinventing it inside your consumer module.
Rule of thumb: cross-cutting concerns belong to their owning athomic module
and are injected at the composition root (DIP). If the capability is
missing, add it to the owning module (generic + reusable), never ad-hoc in
the consumer. The code is the source of truth — this table is a pointer and
may lag; verify the entry point exists before relying on it.
How to use this map
- Name the concern (e.g. "retry a flaky call", "rate limit", "cache result").
- Find its module + entry point below.
- Reuse the factory/protocol; inject it via the composition root.
- If it doesn't exist, implement it in that module so every other module gets
it for free — then add a row here.
Resilience — resilience/
Reach for these before writing any retry/timeout/throttle/failover logic.
| Need |
Entry point |
Notes |
| Retry a failed call (exp. backoff + jitter) |
retry.RetryFactory → RetryHandler |
tenacity wait_random_exponential; do not use the @retry decorator in DI code (hides a Service Locator) |
| Retry + circuit breaker as one pipeline |
ResilienceOrchestratorFactory.create(...) → ResilienceOrchestrator.execute(fn) |
canonical way to protect a backend call; CB(outer) → retry(inner) → fn |
| Trip/fail-fast on a failing dependency |
circuit_breaker.CircuitBreakerFactory |
one service, many named circuits — use distinct names per backend for failure isolation |
| Delay sequencing inside your own poll/consume loop |
backoff.BackoffFactory → BackoffHandler (wait()/reset()) |
stateful sequencer, not a call wrapper — wrong tool for "retry a call" |
| Fallback chain (try A, then B…) |
fallback.FallbackChain / fallback_handler |
|
| Cut tail latency on a replicated idempotent backend |
hedging.HedgingFactory → HedgingHandler / @hedge(idempotent=True) |
races a speculative backup after a fixed/latency-percentile delay; first success wins, losers cancelled. Only for idempotent calls (guardrail enforced). Layer inside retry/CB (wraps the raw call); point bulkhead_policy at a bulkhead to bound hedged load |
| Limit concurrency (isolation) |
bulkhead.bulkhead / BulkheadFactory |
|
| Rate limiting |
rate_limiter (rate_limited, RateLimiterProtocol) |
|
| Per-call / total timeout |
timeout (decorators, controller) |
|
| Adaptive concurrency / throttling |
adaptive_concurrency, adaptive_throttling |
|
| Distributed lock (mutual exclusion) |
locking.LockingFactory / LockingProtocol |
degrades to in-process when disabled |
| Leader election / exclusive lease |
leasing.LeaseFactory / LeaseManager |
|
| Idempotent execution |
idempotency.idempotent / protocol |
|
| Distributed sagas (compensations) |
sagas (builder/manager) |
|
| Workload sharding |
sharding.ShardingFactory |
|
| Hardware/VRAM admission guard |
resource_guard |
|
| Backpressure |
backpressure.BackpressureFactory / BackpressureManager |
|
Observability — observability/
| Need |
Entry point |
| Structured logging |
get_logger(name) (Loguru) |
| Tracing spans |
get_tracer(name), SpanKind, StatusCode |
| Prometheus metrics |
observability/metrics/... (declare in metrics/usage/) |
| Health checks |
observability health hooks |
Database — database/
| Need |
Entry point |
| Resolve KV / Vector / Doc / Graph stores |
ConnectionManager (injected) |
| KV store |
KVStoreFactory / KVStoreProtocol |
| Vector store |
vector factory / VectorStoreProtocol |
| Document DB (Mongo/Beanie) |
DocumentsDatabaseFactory / DocumentDBManager |
| Graph (Neo4j) |
GraphDatabaseFactory / GraphManager |
| Relational (Postgres) |
RelationalDatabaseFactory / RelationalManager |
| Relational tenant isolation (Postgres RLS) |
database/relational/rls.py: tenant_rls_policy_sql(...) for the canonical deny-all-on-empty policy DDL (put in your migration); per-transaction GUC stamping is auto-installed by PostgresRelationalClient when context.multi_tenancy_enabled + rls_enabled (no call-site changes); bypass_rls() for auditable migrations/admin. The 4th context-aware member alongside Graph/Vector/KV. |
| Outbox pattern |
database/outbox |
Security — security/
| Need |
Entry point |
| Secrets (Vault/GCP/AWS) |
SecretsFactory / SecretsManager |
| Auth (authN) |
AuthProviderFactory |
| Authorization (authZ) — RBAC or ReBAC, switchable |
security/auth/authz: build_authorization_provider(settings, …) → AuthorizationProvider (check/list_objects/expand). One setting authorization.provider flips rbac (roles→permissions) ↔ rebac (relation tuples: direct/union/tuple-to-userset, default-deny) with zero call-site changes. ReBAC store: embedded (in-memory/KV, no infra) or openfga (prod). mode (disabled/dry_run/enforce) orthogonal. The requires(...) route guard is provider-agnostic. |
| Crypto (Fernet) |
CryptoProviderFactory |
Integration — integration/
| Need |
Entry point |
| Kafka produce/consume |
MessagingManagerFactory / MessagingManager |
| Service discovery (Consul) |
ServiceDiscoveryFactory / ConsulClientFactory |
| Remote config providers |
SettingsProviderFactory |
| Background tasks |
TaskBrokerFactory |
HTTP — http/
| Need |
Entry point |
| Resilient HTTP client |
http factory (composes ResilienceOrchestrator) |
AI / ML — ai/
| Need |
Entry point |
| Embeddings |
EmbeddingFactory / EmbeddingManager |
| Feature engineering platform |
FeaturePlatformFactory (see ai/features deep-dive in CLAUDE.md) |
| LLM access |
LLMFactory |
| RL decision loop |
ReinforcementLearningFactory |
| Normalize an observation vector (online MinMax/Z-Score, per-key persisted stats) |
ai/normalization — NormalizerFactory + OnlineStatsAccumulator + NormalizationStateStore; decorate an encoder with NormalizingFeatureEncoder. For per-feature-column scaling inside the AOT platform use ai/features MinMaxTransformation/StandardScalerTransformation instead |
| Agents / cognition |
AgentFactory / CognitiveFactory |
Other infrastructure
| Need |
Module / entry point |
| Caching, compression, uvloop |
performance/ (CacheFallbackFactory, CompressionMiddlewareFactory) |
| Serialization |
serializer/ (SerializerFactory) |
| Event bus |
events/ (EventBusFactory) |
| Temporal workflows |
workflows/ (WorkflowClientFactory) |
| Stream processing |
streaming/ (StreamingServiceFactory) |
| Plugin loading |
plugins/ (PluginManager) |
| Settings (Dynaconf + Pydantic) |
config/ (get_settings()) |
When the capability is missing
- Confirm it truly doesn't exist (grep the module + this map).
- Implement it in the owning module, generic and reusable, with a factory
and/or
Protocol (Factory Rules + DIP — see
solid-rules.md).
- Inject it at the composition root; never call the factory from business
logic.
- Add a row here so the next person reuses it.
See also: design-patterns.md, solid-rules.md,
code-smells.md, and the Module Map in CLAUDE.md.