What to build
Roll out Cluster-safe key naming across every key factory method in RedisKeys. Two independent things happen under REDIS_KEY_SCHEMA_VERSION=v2:
- Every key gains a
byai_gateway:v2: prefix (v1 stays unprefixed, unchanged, and remains the default).
- Keys belonging to the same logical entity (session, worker, task_group, trace, agent_type, service-discovery name) get a Redis Cluster hash tag around the shared ID, so multi-key operations against the same entity land on the same slot. Single-key methods, global-index keys (SETs shared across entities), and the small set of keys that are read together but never written together atomically do NOT get a tag.
The prefix + tag logic must be centralized in one formatting function that every key factory method calls — no per-method judgment calls about whether to add the prefix.
Same-entity groups requiring a shared tag: session (data_stream / consumer checkpoint / registry), worker (ctrl stream / lock / online-lease / status / executions / active_executions / active_execution_index / active_snapshots / history_snapshots / admin / declared_agent_types), task_group (main + results), agent_type (members + denied — this one is mandatory, not optional: the deny-worker-for-type write path already writes both keys together and must keep working atomically), service-discovery (active instances + instance details), trace (meta + spans).
Global-index keys (known-workers set, admin-workers set, service-discovery services set) do NOT get a tag — they're read/written across many different entities, not one.
Separately, trace keys get a bigger change: today Python's trace keys use a by_framework:trace:* namespace, while TS uses a different byai_gateway:trace:{id}:meta/spans namespace — these have never been the same. This is the SDK-wide decision to unify onto one v2 format used by all three languages: byai_gateway:v2:trace:{trace_id} for meta, byai_gateway:v2:trace:spans:{trace_id} for spans (type-then-id ordering, consistent with the rest of the key matrix). trace_meta/trace_spans share the trace_id hash tag. trace_index_session/worker/agent keep their existing path structure, only the prefix changes — they do NOT get a tag (they're written in the same pipeline as the trace group today, but splitting that apart is a separate, later issue, not this one).
Also add this SDK's contribution to a cross-language "golden key" test: given a fixed set of IDs (e.g. session_id="sess-abc123", worker_id="worker-01", trace_id="trace-xyz", etc.), Python's key factory must produce exact key strings matching a shared fixture (JSON/YAML) that Java and TS will also populate in their own equivalent issues. Under v1, trace keys are expected to still differ from what TS produces (pre-existing inconsistency, not a regression introduced here) — only assert full cross-language equality for trace keys under v2.
Acceptance criteria
Blocked by
#42
What to build
Roll out Cluster-safe key naming across every key factory method in
RedisKeys. Two independent things happen underREDIS_KEY_SCHEMA_VERSION=v2:byai_gateway:v2:prefix (v1 stays unprefixed, unchanged, and remains the default).The prefix + tag logic must be centralized in one formatting function that every key factory method calls — no per-method judgment calls about whether to add the prefix.
Same-entity groups requiring a shared tag: session (data_stream / consumer checkpoint / registry), worker (ctrl stream / lock / online-lease / status / executions / active_executions / active_execution_index / active_snapshots / history_snapshots / admin / declared_agent_types), task_group (main + results), agent_type (members + denied — this one is mandatory, not optional: the deny-worker-for-type write path already writes both keys together and must keep working atomically), service-discovery (active instances + instance details), trace (meta + spans).
Global-index keys (known-workers set, admin-workers set, service-discovery services set) do NOT get a tag — they're read/written across many different entities, not one.
Separately, trace keys get a bigger change: today Python's trace keys use a
by_framework:trace:*namespace, while TS uses a differentbyai_gateway:trace:{id}:meta/spansnamespace — these have never been the same. This is the SDK-wide decision to unify onto one v2 format used by all three languages:byai_gateway:v2:trace:{trace_id}for meta,byai_gateway:v2:trace:spans:{trace_id}for spans (type-then-id ordering, consistent with the rest of the key matrix).trace_meta/trace_spansshare the trace_id hash tag.trace_index_session/worker/agentkeep their existing path structure, only the prefix changes — they do NOT get a tag (they're written in the same pipeline as the trace group today, but splitting that apart is a separate, later issue, not this one).Also add this SDK's contribution to a cross-language "golden key" test: given a fixed set of IDs (e.g.
session_id="sess-abc123",worker_id="worker-01",trace_id="trace-xyz", etc.), Python's key factory must produce exact key strings matching a shared fixture (JSON/YAML) that Java and TS will also populate in their own equivalent issues. Underv1, trace keys are expected to still differ from what TS produces (pre-existing inconsistency, not a regression introduced here) — only assert full cross-language equality for trace keys underv2.Acceptance criteria
v2prefixagent_type_members/agent_type_deniedshare a mandatory tag (not marked optional)trace_meta/trace_spansmove to the unifiedbyai_gateway:v2:trace:{trace_id}/byai_gateway:v2:trace:spans:{trace_id}format;trace_index_*keeps its path structure, only the prefix changesCLUSTER KEYSLOTsemantics or a local CRC16 implementation)v2; underv1, trace keys are exempted from cross-language equality assertions (fixture is expected to be filled in incrementally as the Java/TS equivalents land)v1behavior/output is completely unchangedBlocked by
#42