← The Forge
Fire Lab · Week 5

Messages, Roles & the System Prompt

Lesson 14's FireSDK capstone had you typing {"role": "user", ...} without ever being told what that meant. This lesson stops there on purpose: what a "conversation" with a model actually is, what each role means, and where the trust boundary between them actually lives — or doesn't.
Theory 1 of 3

A conversation is an array, not a memory.

Lesson 11 already told you this once, in the abstract: context is "the conversation so far," fed back in as text on every call. Here it is for real. Fire's /v1/chat keeps no session, no memory, nothing tied to who you are between requests — every single call sends the entire conversation, from the top, as a messages array. If a turn isn't in that array, as far as the model is concerned, it never happened. "Remembering" the last thing you said isn't a feature the model has — it's a discipline your code has, of resending the transcript.
Theory 2 of 3

Three roles, one job each.

system_prompt

The developer's standing instruction. Set once, sits above the conversation — Fire keeps it as its own field, not a turn in the array, specifically because it isn't one.

user

Whoever — or whatever — is on the other end of that turn. Usually a real person typing. In an agentic pipeline, it can just as easily be an email, a ticket, a webhook payload your code dropped in verbatim.

assistant

The model's own prior words, replayed back to it. Not generated fresh each time — copied, by your code, from the last response, so the next call has something to react to.

Theory 3 of 3

The authority is a convention, not a lock.

system_prompt is supposed to outrank a user turn — that's the entire design intent, and models are trained to mostly honor it. "Mostly," "trained to," and "honor" are doing real work in that sentence: nothing in the architecture cryptographically seals that boundary the way a permission system seals a file. It's closer to a norm than a wall. Hold onto that discomfort — the next lesson in this track opens exactly there.
Before the Practicum

Same curl as before, one real endpoint.

  • Same terminal engine as the earlier curl/API labs — click it, type or paste the command shown, Enter runs it.
  • Every call below targets Fire's real test endpoint, https://fire.test1.prosaga.net/v1/chat, with the exact request shape documented in Fire's own API.md — nothing invented for this lesson.
  • $TOKEN stands in for a real Fire token (minted with fire:token ... --abilities=chat, per this project's own boot file) — you'd export one for real before any of this actually runs.
Done

You now know exactly what "role" means — and exactly where the door was left unlocked.

system_prompt carries more weight than a user turn because the model was trained to treat it that way, not because anything stops a user turn from trying to talk like a system_prompt anyway. That's not a flaw you're supposed to feel bad about noticing — it's the actual shape of the problem. The next lesson in this track, Prompt Injection & Secret Exfiltration, is what happens when someone finds that gap on purpose, and what a defense that doesn't depend on the model's good behavior actually looks like.
1 / 1
ends with a "mark complete" step