Skip to content

Architecture & Security

Two locations define the whole model:

ReplicatedStorage.ChloeKernel replicates — generic primitives only
ServerScriptService.ChloeKernelServer NEVER replicates — everything privileged
  • The client is a renderer with opinions. It sends intents, never state. The server validates every intent through fail-closed hook chains and is the only thing that mutates state.
  • Code placement = attack surface. Validators, rate limits, drop tables, AI logic, data: ServerScriptService. The client holds only what it must execute — input, prediction, VFX. Anything in ReplicatedStorage will be read by exploiters; that is assumed, not feared.
  • Fail-closed everywhere. A crashing validator rejects the action. A failed data load kicks rather than risking a wipe. A schema-violating save is refused. An unmigratable record won’t load. A handler-bearing channel with no validator rejects every payload — missing permission is not permission (NetDriver).
  • Your character stays yours. The kernel never reassigns a character’s network ownership and never anchors character parts — the client keeps simulating its own character at all times, so movement always feels local. Anti-exploit corrections are plain CFrame writes (ownership intact), and movement abilities go through Prediction: the client moves itself instantly, the server validates, rejections roll back.
  • Explicit non-goals. Client code is always readable by exploiters — the defense is never trusting it, not hiding it. Cross-server trades can’t be made safe without a coordinator, so they’re refused. Obfuscation is not security.
You want to… The architectural answer
Let players buy an item Client sends SH_Buy intent → validators re-derive price and balance from server books → server grants. Client math is UI decoration.
Show fast, responsive abilities Prediction: client acts instantly, server reconciles, rejection rolls back. Authority never moves.
Punish speedhackers Movement Monitor detects; your hook decides policy. Detection is the kernel’s job; punishment is yours.
Validate shots from high-ping players Rewind rewinds position history to the client’s timestamp — server raycasts; the client never reports hits.
Know your surface is closed before shipping kernel:securityAudit() sweeps unguarded channels, Open escape hatches, fail-open gate hooks, defaulted rate limits — see Fuzz & Security Audit.

Every network intent passes, in order:

  1. Transport flood cap — Packet’s 8KB/heartbeat budget per player, checked before any decoding so garbage can’t buy CPU (Net.FloodDetected).
  2. Schema decode — buffer-typed arguments in the Packet transport; a payload that doesn’t decode is discarded.
  3. Session & per-channel rate limit — a session must exist, then the token bucket, per player (Net.RateLimited).
  4. Validator-absence check — a handler-bearing channel with no validator rejects outright.
  5. Declarative rulesRange/OneOf/MaxLength from the Registry, installed at priority 5.
  6. Your validators — the fail-closed hook chain, server state only.
  7. The handler — runs only after everything above passed.

The full pipeline costs well under a microsecond per packet (benchmarks). Rejected intents cost the client nothing and the server ~150ns through the chain.