1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! Redis L2 shared-cache storage driver for Agent Assembly.
//!
//! This crate implements three of the high-frequency [`aa_storage`] traits
//! against a Redis (or Valkey) instance so multiple Assembly processes can
//! coordinate through one shared cache instead of each hitting the L3 store:
//!
//! - [`RedisSessionStore`] — [`SessionStore`](aa_storage::SessionStore)
//! - [`RedisRateLimitCounter`] — [`RateLimitCounter`](aa_storage::RateLimitCounter)
//! - [`RedisPolicyStore`] — [`PolicyStore`](aa_storage::PolicyStore), used as a
//! read-through cache in front of the authoritative store
//!
//! Build a [`RedisBackend`] from a [`RedisStorageConfig`] and hand out the
//! individual stores, or construct each store directly over a shared [`Pool`].
//!
//! # Key layout
//!
//! Every key is namespaced under `aa:`:
//!
//! | Store | Key | Value |
//! |---|---|---|
//! | session | `aa:session:<session_id>` | hash (`agent_id`, `started_at_ns`) |
//! | rate limit | `aa:ratelimit:<key>` | integer counter |
//! | policy | `aa:policy:<agent_id>` | JSON [`PolicyDocument`](aa_storage::PolicyDocument) |
//!
//! `<session_id>` and `<agent_id>` are the lower-case hex encodings of the
//! 16-byte ids.
//!
//! # TTL and invalidation semantics
//!
//! - **Sessions** expire after [`SESSION_TTL_SECS`] seconds. The TTL is
//! re-armed on every [`save`](aa_storage::SessionStore::save) so an actively
//! written session never lapses; [`delete`](aa_storage::SessionStore::delete)
//! drops it immediately and is idempotent.
//! - **Rate-limit counters** carry the window length supplied to
//! [`increment`](aa_storage::RateLimitCounter::increment) as their TTL. The
//! expiry is armed exactly once — on the first increment that creates the key
//! — so the window is **fixed**: it starts at the first hit and is not pushed
//! forward by later increments within the same window.
//! [`reset`](aa_storage::RateLimitCounter::reset) deletes the key.
//! - **Policies** are cached with an explicit per-entry TTL via
//! [`RedisPolicyStore::cache_policy`] ([`DEFAULT_POLICY_CACHE_TTL_SECS`] is the
//! suggested default). [`invalidate`](aa_storage::PolicyStore::invalidate)
//! deletes the cached key so the next read misses and reloads from the
//! authoritative store; it is idempotent.
pub use RedisBackend;
pub use RedisStorageConfig;
pub use ;
pub use build_pool;
pub use RedisRateLimitCounter;
pub use register;
pub use ;
/// Pooled Redis connection handle, re-exported for callers that build stores
/// directly with [`RedisSessionStore::new`] and friends.
pub use Pool;
/// The name this driver registers under in storage configuration, i.e. the
/// `[storage.<name>]` subsection and the registry key (`storage.backend = "redis"`).
pub const DRIVER_NAME: &str = "redis";