--- description: Spark IM V3 architecture invariants. Apply to every change in spark-server. alwaysApply: true --- # Spark IM V3 invariants Source: `docs/architecture-v3.md`. Do not re-open these decisions. - C1: Message body is MySQL. Snowflake `MsgId` is PK, sort key, and sync cursor. No `ConversationSeq`. - C2: gnet EventLoop must not call MySQL, Redis, object storage, or fanout. Inbound work goes to `TaskPool`. Fanout goes to Redis `deliver:queue` + worker. - C3: Confidentiality is TLS. Thin Frame + optional compress only. No ECDH/AES handshake. - C4: Public port is 443 via Nginx SNI. gnet/Gin bind loopback only. - C5: `SEND_ACK` only after MySQL COMMIT **and** deliver `Push`. Redis enqueue failure → no ACK. - C6: Rate limit / audit use PROXY `RealIP`, never gnet `RemoteAddr` (that is 127.0.0.1). - C7: Conversation list/unread/preview live in Redis ZSET. Do not upsert MySQL inbox rows on the group hot path. Forbidden: Kafka, K8s, microservices, Keyed Worker, `context.TODO()` on hot path, kick-on-push-timeout, `im:user:{uid}:node`, business `DELIVERY_ACK`, media bytes in `messages.content`.