The platform owns the system prompt. You do not. You wrote one once, in the dashboard, and the dashboard saved it. Inside it you left a slot: . That slot is the tunnel. Everything you will ever say to the model about this session goes through it.
You do not know this on the first day. On the first day you read the SDK docs and find six fields that look like they should carry state. metadata. context. userVars. overrides.agent.prompt. You try them. The session starts. The model never sees the value. No error. No warning. The customer is greeted as there.
You try dynamicVariables. The session starts. The model says the name.
One session, one channel
Trace it. The browser holds a name. The SDK call carries dynamicVariables: { customer_name: "Maya" }. The platform substitutes the value into the saved template. The template becomes a system prompt with Maya baked into the string. The platform forwards the prompt to your proxy as messages[0]. The proxy parses the name back out with a regex. The proxy dispatches a tool call against the customer record for Maya.
Five hops. One channel. The system prompt is round-tripping the session state because nothing else was allowed to carry it.
The model never knew the name was a variable. The platform never knew the variable was state. Both rode the prompt.
Two failures, one cause
The first failure is loud. You pick the wrong SDK field. overrides.agent.prompt looked promising. The session refuses to start. The websocket closes. The user sees a spinner and then nothing.
The second failure is quiet. You drop the tools array from the proxy's passthrough on the way to the model. The session starts. The model speaks. It speaks JSON. Open brace, quote, name, quote, colon, quote, diagnose, quote. The voice is warm. The voice is reading a function call into the user's ear.
One field crashes the session. Another field is silently dropped and the model improvises with text. Both are the same shape. The platform decided which fields cross the boundary. You did not get a vote and you did not get a log line.
The realization
Stop fighting the SDK surface. Find the one field that survives the round trip and put your state in it. For variables, that is the slot in the template. For tools, that is the array the proxy must forward without touching. Everything else is decoration the platform may or may not honor on any given Tuesday.
The system prompt is not configuration. It is the wire. Treat it like one.
References: the companion posts The Tool the Model Wrote as Text and The Variable That Rode Through the System Prompt, and the ElevenLabs client tool recipe.
Hemingway said the dignity of an iceberg is due to only one-eighth of it being above water. A working system prompt has the same proportion. The slot is what you see. The session rides underneath.