API Reference
Protocols
Section titled “Protocols”AIAuditStore
Section titled “AIAuditStore”Protocol for audit event persistence backends.
Implementations must be async and should treat record() as
fire-and-forget safe — governance/LLM hot-paths must never block
on audit persistence.
Persist a single audit event.
| Parameter | Type | Description |
|---|---|---|
| `event` | AIAuditEvent | The audit event to store. |
Retrieve audit events matching the given filter.
| Parameter | Type | Description |
|---|---|---|
| `query` | AuditQuery | Filter criteria. |
| Type | Description |
|---|---|
| list[AIAuditEvent] | List of matching events ordered by timestamp descending. |
Compute aggregated statistics for matching events.
| Parameter | Type | Description |
|---|---|---|
| `query` | AuditQuery | Filter criteria that scope the aggregation. |
| Type | Description |
|---|---|
| AuditSummary | Summary statistics for the matching events. |
AIAuditStoreProtocol
Section titled “AIAuditStoreProtocol”Protocol for AI audit event persistence backends.
Implementations must be async and treat record() as
fire-and-forget safe — hot-paths must never block on audit persistence.
Persist a single audit event.
| Parameter | Type | Description |
|---|---|---|
| `event` | AIAuditEvent | The audit event to store. |
AIGovernanceProtocol
Section titled “AIGovernanceProtocol”Protocol for AI Governance and cost tracking.
Check if request is allowed by governance policies.
Check if operation fits within budget.
Track cost for an operation.
ContentPolicyGateProtocol
Section titled “ContentPolicyGateProtocol”Gate that decides whether a request should reach the LLM.
Implementations are responsible for a single evaluation concern (e.g. abuse detection, quota enforcement, age gating, jurisdictional restrictions). Complex policies are composed via CompositeGate.
The method must be async and must never raise for domain-level
outcomes — DENY is returned as a PolicyDecision,
not raised as an exception. Infrastructure failures (DB down, etc.)
may raise.
Evaluate request and return a policy decision.
| Parameter | Type | Description |
|---|---|---|
| `request` | PolicyRequest | Contextual information about the content and caller. |
| Type | Description |
|---|---|
| PolicyDecision | A PolicyDecision with one of ``ALLOW``, ``DENY``, or ``THROTTLE``. |
CostTrackingProtocol
Section titled “CostTrackingProtocol”Protocol for tracking costs.
GaugeReconciliationCallback
Section titled “GaugeReconciliationCallback”Source-of-truth interface for an INSTANTANEOUS gauge.
Implementations are domain-specific — e.g. for
concurrent_episodes_in_production_per_tenant, count_active queries
the saga store for RUNNING episode-production sagas owned by tenant_id.
Return all tenant IDs to reconcile this cycle.
Return the ground-truth held count for tenant_id.
GovernancePersistence
Section titled “GovernancePersistence”Storage protocol for governance counters and spend tallies.
Implementations must be safe for concurrent async access. All methods are coroutines to allow either local (in-process) or remote (Redis, database) storage without changing the call-site.
Record a new request and return the request count within the window.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Bucket key (e.g. ``"global"`` or a user/tenant id). |
| `window` | float | Rolling window size in seconds. |
| Type | Description |
|---|---|
| int | Number of requests (including the current one) inside the window. |
Add amount to the spend accumulator and return the new total.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Bucket key (e.g. ``"global:2025-06"``). |
| `amount` | float | Cost amount to add. |
| `ttl` | int | Time-to-live for the accumulator entry in seconds. |
| Type | Description |
|---|---|
| float | Updated total spend. |
Return the current accumulated spend for key.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Bucket key. |
| Type | Description |
|---|---|
| float | Current spend; ``0.0`` if no data recorded. |
Read the current gauge value for key.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Gauge key (e.g. ``"tenant:gpt4:remaining"``). |
| Type | Description |
|---|---|
| float | Current gauge value; ``0.0`` if no data recorded. |
Set the gauge value for key with a TTL.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Gauge key. |
| `value` | float | Float gauge value. |
| `ttl` | int | Time-to-live in seconds. |
Atomically increment (or decrement) the gauge for key.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Gauge key. |
| `delta` | float | Amount to add (can be negative). |
| `ttl` | int | Time-to-live in seconds. |
| Type | Description |
|---|---|
| float | The gauge value after applying *delta*. |
Record a timestamp entry in a calendar-style bucket.
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Calendar bucket key. |
| `timestamp` | float | Unix timestamp to record. |
| `ttl` | int | Time-to-live in seconds for the bucket. |
Return all timestamps in key that fall within [start, end].
| Parameter | Type | Description |
|---|---|---|
| `key` | str | Calendar bucket key. |
| `start` | float | Unix timestamp, start of range (inclusive). |
| `end` | float | Unix timestamp, end of range (inclusive). |
| Type | Description |
|---|---|
| list[float] | List of matching timestamps (chronological order). |
Decrement a gauge key by amount.
Default implementation delegates to incr_gauge with a negative delta.
Accumulate amount in a calendar-window bucket.
Delegates to add_spend with a period-scoped key (key +
: + period).
Read the calendar-window accumulator for key + period.
Delegates to get_spend with a period-scoped key.
PolicyObserverProtocol
Section titled “PolicyObserverProtocol”Side-effect hook called after every gate evaluation.
Observers receive the original request and the final decision. They must not mutate the decision. Use for metrics, external audit streams, or custom structured logging.
Observers are invoked asynchronously by CompositeGate and ContentPolicyService. Infrastructure errors inside an observer must be handled by the observer implementation.
Called after a gate produces a decision.
| Parameter | Type | Description |
|---|---|---|
| `request` | PolicyRequest | The original policy request. |
| `decision` | PolicyDecision | The decision that was produced. |
Classes
Section titled “Classes”AIAuditEvent
Section titled “AIAuditEvent”Structured representation of an auditable AI operation.
Concrete data class shared across AI packages via lexigram-contracts.
Attributes:
event_type: Category of the operation.
model: Model identifier (if applicable).
provider: Provider name (if applicable).
user_id: User who triggered the operation.
status: Outcome — "allowed", "denied", "success", "error".
tokens: Token count consumed (if applicable).
cost: Dollar cost incurred (if applicable).
latency_ms: Request latency in milliseconds (if applicable).
metadata: Free-form key/value bag for additional context.
event_id: Unique UUID for the event (auto-generated).
AIGovernanceManager
Section titled “AIGovernanceManager”Enforces AI usage policies: budget limits, rate limits, model restrictions.
Implements AIGovernanceProtocol from contracts.
Governance state (request counts, spend totals) is delegated to a GovernancePersistence backend so the storage strategy is swappable without changing policy logic. When no explicit persistence is given, an InMemoryGovernancePersistence instance is created automatically using the optional cache argument to build a RedisGovernancePersistence when a cache backend is available.
| Parameter | Type | Description |
|---|---|---|
| `config` | Governance policy configuration. | |
| `cache` | Optional cache backend used to auto-create a Redis persistence backend. Ignored when *persistence* is supplied explicitly. | |
| `persistence` | Explicit persistence backend. Takes precedence over *cache*. | |
| `on_soft_limit` | Optional async callback invoked when the monthly spend crosses the ``soft_limit_pct`` threshold. Signature: ``async def cb(user_id, current_spend, budget) -> None``. | |
| `audit_store` | Optional audit store for recording governance decisions. When provided, every governance check (allowed or denied) and every cost-tracking call is recorded as an audit event. |
The ResourceUnitTracker instance, or None when no
resource units are configured.
Exposed for DI registration so the same tracker is shared across the
application (consume/release calls go through here regardless of
whether the caller resolves AIGovernanceManager or
ResourceUnitTracker from the container).
Check if a request is allowed under governance policy.
| Parameter | Type | Description |
|---|---|---|
| `model` | str | Model identifier. |
| `provider` | str | Provider name. |
| `user_id` | str | None | Optional user identifier for per-user limits. |
| Type | Description |
|---|---|
| bool | True if request is allowed, False if blocked by policy. |
Check if user is allowed to use the given model.
Evaluates per-user model_allowlist and model_denylist from
GovernanceConfig. Both support glob
patterns (e.g. "gpt-4*", "claude-3-*").
Logic:
- If
model_allowlisthas an entry for user_id, the model must match at least one pattern in the allowlist. - If
model_denylisthas an entry for user_id, the model must not match any pattern in the denylist. - When no entry exists for user_id, access is allowed.
| Parameter | Type | Description |
|---|---|---|
| `user_id` | str | None | User identifier, or ``None`` for anonymous / global. |
| `model` | str | Model name to check. |
| Type | Description |
|---|---|
| bool | True if access is permitted, False if denied. |
Check if a cost would exceed the monthly budget.
Emits a structured warning when the spend crosses the configured
soft_limit_pct threshold and invokes the optional
on_soft_limit callback. Returns False only when the hard
limit (monthly_budget) would be exceeded.
| Parameter | Type | Description |
|---|---|---|
| `cost` | float | Estimated cost of the request. |
| `user_id` | str | None | Optional user identifier. |
| Type | Description |
|---|---|
| bool | True if within hard budget, False if would exceed. |
Check if a single request cost is within the per-request budget.
Validates estimated_cost against max_request_cost (per-request
cap) first, then against the monthly budget via check_budget.
| Parameter | Type | Description |
|---|---|---|
| `estimated_cost` | float | Estimated cost in USD for this request. |
| `request_id` | str | None | Optional request identifier for logging context. |
| Type | Description |
|---|---|
| Result[None, GovernanceError] | ``Ok(None)`` if within all budget limits. ``Err(GovernanceError)`` if either per-request or monthly limit is exceeded. |
Record AI usage cost.
| Parameter | Type | Description |
|---|---|---|
| `cost` | float | Cost to record. |
| `model` | str | Model that generated the cost. |
| `user_id` | str | None | Optional user identifier. |
Hot-reload governance configuration without restart.
Atomically swaps the internal config reference so that subsequent policy checks use the new limits. Does not touch persistence state — only the thresholds and rules are updated.
| Parameter | Type | Description |
|---|---|---|
| `config` | GovernanceConfig | New governance configuration to apply. |
Consume amount of a resource unit for tenant_id.
Delegates to ResourceUnitTracker if configured.
Release amount of a held resource (INSTANTANEOUS units only).
Return current usage snapshot for tenant_id + unit_name.
AlwaysAllowGate
Section titled “AlwaysAllowGate”Trivial gate that allows every request.
Use as a default/no-op gate in development, testing, or when the application does not yet have a content policy.
Always return ALLOW.
| Parameter | Type | Description |
|---|---|---|
| `request` | PolicyRequest | Policy request (ignored). |
| Type | Description |
|---|---|
| PolicyDecision | ``PolicyDecision(outcome=ALLOW, reason="")``. |
AuditEventType
Section titled “AuditEventType”Categories of auditable AI operations.
Shared across the AI governance and observability layers
via lexigram-contracts.
AuditQuery
Section titled “AuditQuery”Filter criteria for querying audit events.
All fields are optional — None means no constraint on that axis.
Attributes: start: Inclusive lower bound on timestamp. end: Inclusive upper bound on timestamp. event_types: Restrict to these event types. user_id: Restrict to a specific user. model: Restrict to a specific model. provider: Restrict to a specific provider. status: Restrict to a specific status string. limit: Maximum number of results to return. offset: Number of results to skip (for pagination).
AuditSummary
Section titled “AuditSummary”Aggregated audit statistics for a given query period.
Attributes:
total_events: Total number of events matching the query.
total_spend: Sum of cost across matching events.
total_tokens: Sum of tokens across matching events.
denied_count: Events where status is "denied".
by_model: Event count per model.
by_user: Event count per user.
by_event_type: Event count per event type.
CompositeGate
Section titled “CompositeGate”Combines multiple ContentPolicyGateProtocol gates.
Evaluation algorithm:
- All member gates are evaluated (no short-circuit on DENY so that all observers receive the full picture).
- If any gate returns
DENY→ the composite returnsDENY. - Otherwise the most-restrictive outcome across all gates wins
(
THROTTLEbeatsALLOW). - All non-empty reason strings from member gates are aggregated,
separated by
"; ". - After the final decision is produced, each registered PolicyObserverProtocol is notified.
| Parameter | Type | Description |
|---|---|---|
| `gates` | One or more gate instances to compose. | |
| `observers` | Optional observers notified after each composite evaluation. |
Evaluate request against all member gates and return a composite decision.
| Parameter | Type | Description |
|---|---|---|
| `request` | PolicyRequest | Contextual information about the content and caller. |
| Type | Description |
|---|---|
| PolicyDecision | The most-restrictive PolicyDecision across all member gates, with aggregated reasons. |
ContentPolicyService
Section titled “ContentPolicyService”Evaluates content policy before an LLM request is dispatched.
This service is the primary DI-injectable surface for content gating. It wraps a single gate (which may itself be a CompositeGate) and adds structured logging for every decision so that operators have an audit trail without coupling gate implementations to a specific logger.
| Parameter | Type | Description |
|---|---|---|
| `gate` | The gate (or composite) to delegate to. | |
| `observers` | Additional observers notified after each evaluation. These are layered on top of any observers already configured in the gate itself. |
Evaluate request and emit a structured log event.
Apps call this method before dispatching to an LLM. If the returned
outcome is DENY, the caller must not proceed
decision = await policy_service.evaluate(request)if decision.outcome == PolicyOutcome.DENY: raise ContentPolicyViolation(decision.reason)decision = await policy_service.evaluate(request)if decision.outcome == PolicyOutcome.DENY: raise ContentPolicyViolation(decision.reason)| Parameter | Type | Description |
|---|---|---|
| `request` | PolicyRequest | Context about the content and the requesting principal. |
| Type | Description |
|---|---|
| PolicyDecision | A PolicyDecision. Never raises for domain-level outcomes; infrastructure errors propagate normally. |
Convenience predicate — True for ALLOW or THROTTLE outcomes.
| Parameter | Type | Description |
|---|---|---|
| `decision` | PolicyDecision | A decision previously returned by evaluate. |
| Type | Description |
|---|---|
| bool | ``False`` only when *outcome* is ``DENY``. |
GaugeReconciliationWorker
Section titled “GaugeReconciliationWorker”Periodically reconciles INSTANTANEOUS gauges against ground truth.
Each cycle: for every (unit_name, callback) registered, list the
tenants and call count_active to obtain the correct value; write
it via ResourceUnitTracker.reconcile. Per-tenant errors are
logged and skipped — a single bad callback never poisons the cycle.
Default cadence is 5 minutes; tunable per-instance.
Register a reconciliation callback for unit_name.
Remove the callback for unit_name (no-op if absent).
Snapshot of currently-registered callbacks.
GovernanceAuditRecordedHook
Section titled “GovernanceAuditRecordedHook”Payload fired when governance audit logging records an event.
GovernanceConfig
Section titled “GovernanceConfig”Configuration for AI Governance.
Loaded from the ai_governance: key in application.yaml, with environment
variable overrides via LEX_AI_GOVERNANCE__* prefix.
Check config is safe for the target environment.
GovernanceModule
Section titled “GovernanceModule”AI Governance policy enforcement and cost-tracking integration.
Call configure to register AIGovernanceProtocol and CostTrackingProtocol implementations for injection.
Usage
from lexigram.ai.governance.config import GovernanceConfig
@module( imports=[ GovernanceModule.configure( GovernanceConfig(monthly_budget=100.0) ) ])class AppModule(Module): passfrom lexigram.ai.governance.config import GovernanceConfig
@module( imports=[ GovernanceModule.configure( GovernanceConfig(monthly_budget=100.0) ) ])class AppModule(Module): passError Handling
Governance violations surface as typed exceptions that can be caughtdirectly or handled via the Result pattern::
from lexigram.ai.governance.exceptions import ( GovernanceError, # base — catch-all BudgetExceededError, # monthly spend cap breached RateLimitExceededError,# RPM / TPM limit exceeded ModelAccessDeniedError,# policy denied model access )Governance violations surface as typed exceptions that can be caughtdirectly or handled via the Result patternfrom lexigram.ai.governance.exceptions import ( GovernanceError, # base — catch-all BudgetExceededError, # monthly spend cap breached RateLimitExceededError,# RPM / TPM limit exceeded ModelAccessDeniedError,# policy denied model access) from lexigram.ai.governance.exceptions import ( GovernanceError, # base — catch-all BudgetExceededError, # monthly spend cap breached RateLimitExceededError,# RPM / TPM limit exceeded ModelAccessDeniedError,# policy denied model access )Exports: AIGovernanceProtocol, CostTrackingProtocol, GovernanceError, BudgetExceededError, RateLimitExceededError, ModelAccessDeniedError
Create a GovernanceModule with the given configuration.
| Parameter | Type | Description |
|---|---|---|
| `config` | GovernanceConfig | None | GovernanceConfig, a plain ``dict`` of the same keys, or ``None`` to read from environment variables. |
| Type | Description |
|---|---|
| DynamicModule | A DynamicModule descriptor. |
| Exception | Description |
|---|---|
| TypeError | If *config* is not a ``GovernanceConfig``, ``dict``, or ``None``. |
Create a GovernanceModule suitable for unit and integration testing.
Uses in-memory or no-op implementations with minimal side effects.
| Parameter | Type | Description |
|---|---|---|
| `config` | GovernanceConfig | None | Optional config override. Uses safe test defaults when None. |
| Type | Description |
|---|---|
| DynamicModule | A DynamicModule descriptor. |
GovernancePersistenceWrittenHook
Section titled “GovernancePersistenceWrittenHook”Payload fired when governance persistence writes a record.
GovernancePolicyEvaluatedHook
Section titled “GovernancePolicyEvaluatedHook”Payload fired when the governance policy layer evaluates a policy.
GovernanceProvider
Section titled “GovernanceProvider”Provider for AI Governance.
Registers AIGovernanceManager.
Factory method for DI container setup.
Register the governance services.
Boot phase.
Shutdown phase.
Health check — always healthy (in-process domain provider).
No external backend to ping.
| Parameter | Type | Description |
|---|---|---|
| `timeout` | float | Ignored for in-process providers. |
| Type | Description |
|---|---|
| HealthCheckResult | Always HEALTHY — no external backend to ping. |
InMemoryAuditStore
Section titled “InMemoryAuditStore”In-memory audit store for testing and development.
Not suitable for production — events are lost on process restart.
The store is intentionally simple: append-only list with linear scan
queries. For production use, implement AIAuditStore with a
durable backend (e.g. via DatabaseProviderProtocol).
Append event to the in-memory list.
Linear scan with filter, ordered by timestamp descending.
Compute summary statistics over matching events.
InMemoryGovernancePersistence
Section titled “InMemoryGovernancePersistence”Process-local governance persistence using plain Python dicts.
Request counts are tracked with a sliding-window approach (list of monotonic timestamps). Spend totals are stored as plain floats.
This implementation is not suitable for multi-process or multi-replica deployments. Use RedisGovernancePersistence in production.
PolicyDecision
Section titled “PolicyDecision”Result produced by a ContentPolicyGateProtocol.
Decisions are values, not exceptions — even a DENY is returned
normally. The caller decides what to do.
Attributes:
outcome: One of ALLOW, DENY, or THROTTLE.
reason: Human-readable explanation (shown in logs / returned to the
app; may be empty for ALLOW).
metadata: Additional context produced by the gate
(e.g. {"threshold": "5", "current_count": "6"}).
PolicyEvaluatedEvent
Section titled “PolicyEvaluatedEvent”Emitted when a governance policy evaluation completes.
Consumed by: audit, compliance, cost management.
PolicyOutcome
Section titled “PolicyOutcome”Result of a content policy gate evaluation.
ALLOW— request is permitted.DENY— request is blocked; the caller must not proceed.THROTTLE— allow now but record; future requests may be denied.
PolicyRequest
Section titled “PolicyRequest”Context passed to a ContentPolicyGateProtocol.
Attributes:
principal_id: Identifies the caller (user-id, session token, etc.).
None for fully anonymous requests.
content_type: Application-defined label for what is being submitted
(e.g. "image", "text", "document").
content_metadata: Free-form key/value pairs describing the content
(e.g. {"species": "cat", "mime_type": "image/jpeg"}).
history_summary: Aggregated counters from prior requests by this
principal (e.g. {"non_pet_images": 3}). None when no
history is available.
RedisGovernancePersistence
Section titled “RedisGovernancePersistence”Distributed governance persistence backed by a Lexigram CacheBackendProtocol.
Request windows use a sorted-set approach:
- Each request is stored as a member with its Unix timestamp as score.
- Expired members (score <
now - window) are pruned on every read.
Spend totals are stored as plain string floats with a configurable TTL so that monthly counters expire automatically.
| Parameter | Type | Description |
|---|---|---|
| `cache` | A CacheBackendProtocol that has been connected and is ready to accept commands. The backend is expected to be Redis-compatible. |
Use a sorted set to implement a sliding window counter.
Falls back to an approximate counter if the backend does not support sorted-set operations (e.g. a simple in-memory mock).
ResourceUnitRegistry
Section titled “ResourceUnitRegistry”In-memory registry of known ResourceUnit definitions.
Populated at boot from GovernanceConfig.resource_units via the DI
provider. Lookup is by unit name (ResourceUnit.name).
Register (or overwrite) a resource unit definition.
Look up a resource unit by name, or None.
Return all registered resource units.
Create a registry pre-populated with units.
ResourceUnitTracker
Section titled “ResourceUnitTracker”Tracks per-tenant resource consumption via the persistence layer.
Routes consume / release / usage calls to the right
persistence method based on the unit’s window_kind:
SLIDING→incr_requests(existing sliding-window counter)CALENDAR→incr_calendar/get_calendarINSTANTANEOUS→incr_gauge/decr_gauge/read_gauge
| Parameter | Type | Description |
|---|---|---|
| `registry` | Registry of known ResourceUnit definitions. | |
| `persistence` | Backend that implements GovernancePersistence. | |
| `get_quota` | Callable ``(tenant_id, unit_name) → limit``. Return ``0.0`` to deny all usage. |
Consume amount of a resource for tenant_id.
| Type | Description |
|---|---|
| Result[ResourceUsageSnapshot, ResourceExhaustedError] | ``Ok(snapshot)`` on success, ``Err(ResourceExhaustedError)`` if the quota would be exceeded. |
Release amount of a held resource (INSTANTANEOUS units only).
For SLIDING and CALENDAR windows this is a no-op — windows decay naturally.
Reset the gauge for an INSTANTANEOUS unit to expected_amount.
Used by GaugeReconciliationWorker to repair drift caused by crashed processes that consumed without releasing. No-op for non-INSTANTANEOUS units.
Return current usage snapshot for tenant_id + unit_name.
Exceptions
Section titled “Exceptions”BudgetExceededError
Section titled “BudgetExceededError”Error raised when budget is exceeded.
GovernanceError
Section titled “GovernanceError”Base class for governance-related errors.
ModelAccessDeniedError
Section titled “ModelAccessDeniedError”Raised when a user is denied access to a model by policy.
Attributes:
model: Model identifier that was denied.
reason: Why access was denied ("restricted", "not_in_allowlist",
"in_denylist").
RateLimitExceededError
Section titled “RateLimitExceededError”Raised when RPM or TPM limits are exceeded.
Attributes:
limit: Configured limit value.
current: Current counter value.
limit_type: Type of limit exceeded ("rpm" or "tpm").
ResourceExhaustedError
Section titled “ResourceExhaustedError”Raised when a resource quota is exhausted.