# Decision: Redis configuration shape

Captures the standing rules adopted by Edge Gateway when it joined the
project-wide Redis topology described in `ARCHITECTURE.md`.

## Context

Gateway intentionally stays Redis-light. The only Redis state served by
gateway is the replay reservation namespace (short-lived `SETNX` per
authenticated request, bounded by
`GATEWAY_REPLAY_REDIS_RESERVE_TIMEOUT`). Session lookup goes through
backend's REST surface, and inbound events are delivered through the
gRPC `Push.SubscribePush` consumer (see
`gateway/internal/backendclient`).

The shared rule is: every Galaxy service uses one master plus
zero-or-more replicas with a mandatory password, no TLS, and no Redis
ACL username; the connection is configured by the shared
`pkg/redisconn` helper.

## Decisions

### One shared `*redis.Client` owned by the runtime

`cmd/gateway/main.go` constructs a single `*redis.Client` via
`internal/redisclient.NewClient`, attaches OpenTelemetry tracing and
metrics via `internal/redisclient.InstrumentClient`, performs one
bounded `PING` via `internal/redisclient.Ping`, and registers
`client.Close` for shutdown. The replay store is the only adapter
backed by Redis.

### One env-var prefix for the connection

Connection topology is loaded from a single `GATEWAY_REDIS_*` group via
`redisconn.LoadFromEnv("GATEWAY")`:

- `GATEWAY_REDIS_MASTER_ADDR` (required)
- `GATEWAY_REDIS_REPLICA_ADDRS` (optional, comma-separated; currently
  unused, reserved for future read-routing)
- `GATEWAY_REDIS_PASSWORD` (required)
- `GATEWAY_REDIS_DB` (default `0`)
- `GATEWAY_REDIS_OPERATION_TIMEOUT` (default `250ms`)

Per-subsystem behavior env vars (namespace and timing only):

- `GATEWAY_REPLAY_REDIS_KEY_PREFIX`,
  `GATEWAY_REPLAY_REDIS_RESERVE_TIMEOUT`

### Retired env vars (hard removal)

The following variables are no longer read or honored:

- `GATEWAY_SESSION_CACHE_REDIS_ADDR` — replaced by
  `GATEWAY_REDIS_MASTER_ADDR`.
- `GATEWAY_SESSION_CACHE_REDIS_USERNAME` — Redis ACL not used.
- `GATEWAY_SESSION_CACHE_REDIS_PASSWORD` — replaced by
  `GATEWAY_REDIS_PASSWORD`.
- `GATEWAY_SESSION_CACHE_REDIS_DB` — replaced by `GATEWAY_REDIS_DB`.
- `GATEWAY_SESSION_CACHE_REDIS_TLS_ENABLED` — TLS disabled by policy.

`pkg/redisconn.LoadFromEnv` rejects `GATEWAY_REDIS_TLS_ENABLED` and
`GATEWAY_REDIS_USERNAME` at startup with a clear error pointing to
`ARCHITECTURE.md §Persistence Backends`.

> **Compound legacy prefixes (`GATEWAY_SESSION_CACHE_REDIS_USERNAME` etc.)
> are not actively rejected.** `pkg/redisconn`'s deprecated-env detector
> only watches the canonical `GATEWAY_REDIS_*` form. The compound legacy
> vars become silently inert. The architecture rule explicitly accepts this
> ("no backward-compat shim — fresh project, no production deploys to
> migrate"); operators upgrading should remove the variables from their
> deployment manifests.

### Telemetry

`redisconn.Instrument` wires `redisotel.InstrumentTracing` (with
`WithDBStatement(false)`) and `redisotel.InstrumentMetrics`. This is the
first gateway release that emits Redis tracing and connection-pool metrics;
downstream dashboards will start populating without further changes.

## Consequences

- Gateway test code constructs one shared client and passes it to the
  replay-store adapter under test (see `internal/replay/redis_test.go`).
- Operators must set `GATEWAY_REDIS_PASSWORD`. A passwordless local Redis
  is still acceptable as long as a placeholder password is supplied to the
  binary; Redis without `requirepass` accepts AUTH unconditionally.
- The integration test harness passes `GATEWAY_REDIS_PASSWORD =
  "integration"` alongside `GATEWAY_REDIS_MASTER_ADDR` (see
  `integration/internal/harness/gatewayservice.go`).
