OpenClaw Workspace Files: Which Line Goes in SOUL.md, AGENTS.md or TOOLS.md
Every OpenClaw workspace I have opened had a rule in the wrong file. Usually several, and usually the one that mattered most was sitting in SOUL.md dressed up as a personality trait.
The workspace is a folder of markdown (~/.openclaw/workspace unless you moved it) that the gateway injects into the agent's context at the start of a session. Which files load is configurable; the config walkthrough lists five in its bootstrapFiles, including a custom PREFLIGHT_INJECT.md that no template will ever give you.
The guides that rank for this topic are glossaries. Each file gets a heading, a definition, a template and a reminder to keep it focused, and they are fine as far as they go. They stop before the question you will actually face forty times a year, usually tired, usually right after the agent did something you did not want: where does this new line go?
What Each File Is For
Short version first, because the routing test below depends on it.
SOUL.md is temperament. How blunt the agent is with you and how much it hedges before saying so. Nothing in it should describe an action.
AGENTS.md is the operating manual: what needs your approval, which directories are off limits, how work gets handed off between agents. The security best practices guide keeps its authority boundaries here, and that is the right instinct. When an agent does something it should not have, the fix belongs in this file more often than in any other.
TOOLS.md is notes about your machine. The hostname of the box with the GPU, the camera's name, the CLI that only accepts absolute paths. It describes tools. It does not grant them, which trips people up constantly; access is set by the per-agent allow and deny lists in openclaw.json.
USER.md is about you. Time zone, what you want to be called, the hours when a ping had better be urgent.
MEMORY.md holds current facts the agent has learned and should keep. It should be short. Dated material goes in the daily files under memory/, and the memory system deep dive explains how the two layers split the work.
HEARTBEAT.md is the checklist for timed wake-ups and has its own heartbeat guide.
The Routing Test
Run every new line through these questions in order and stop at the first yes. The order is the opinion. The first four questions send a line out of the bootstrap files altogether, and in my experience that is where most lines belong.
- Is it a secret? Then it goes nowhere in the workspace. Keys and bot tokens belong in
openclaw.jsonor the environment, and the backup and migration guide has the.gitignoreand the grep I run before any push. - Does it only matter for one kind of task? Make it a skill. Fourteen formatting rules for the weekly newsletter should load when the newsletter is being written, and at no other time.
- Does it have an exact time or a yes-or-no answer? Cron. "Check the deploy queue at 8:00" is a schedule, and the cron automation guide covers the wrapper I use.
- Is it a fact that will change? A client list, a colleague's time zone, which project is active this month. Searchable memory, where it gets recalled when relevant instead of riding along on every turn.
- Does it govern what the agent may do?
AGENTS.md. - Does it govern how the agent sounds?
SOUL.md. - Is it about the machine?
TOOLS.md. - Is it about you?
USER.md.
Questions five and six catch the expensive mistakes, because the two files read differently to a model. A sentence in SOUL.md like "you are careful and polite about outreach" is flavor. It colors replies. It does not reliably stop the agent from sending an email at midnight to someone you have not spoken to since 2023. Write the same idea in AGENTS.md as "Never send email on my behalf without showing me the draft first," near the top, and you have a gate.
Lines I Have Moved
A tone rule about exclamation marks in Slack lived in AGENTS.md for most of a year, between two approval gates, making both look less serious. It went to SOUL.md. The staging server's address sat in AGENTS.md too, under a heading called "Deploys," and moved to TOOLS.md where every other address already was. A list of everyone I work with and their time zones had grown inside USER.md until it was the largest thing in the file; that went to memory, since it changes whenever someone changes jobs.
The approval rule above was the one that hurt. It had been a personality trait for months.
Find Contradictions Before the Agent Does
Some guides claim AGENTS.md wins when it disagrees with SOUL.md. I would not build anything on that. The model sees both files in one context and settles the conflict however it settles it on that turn, and the answer can change between turns. The fix is to never ask it to choose.
Contradictions creep in because the agent edits these files itself, usually after you say "remember that for next time." A cheap check catches most of them: pull every absolute out of every bootstrap file and read the list in one sitting.
cd ~/.openclaw/workspace
grep -n -i -E "\b(always|never|must|do not|don't)\b" \
SOUL.md AGENTS.md TOOLS.md USER.md MEMORY.mdTwenty lines of output take two minutes to read. You are looking for pairs. "Always confirm before deleting files" in AGENTS.md next to "Never interrupt me with questions during focus hours" in USER.md is a contradiction the agent will resolve at 10:30 on a Tuesday, without you, in whichever direction the last few messages happen to lean. Decide it now and write the exception into AGENTS.md, the file that owns permissions.
The Cap Applies Per File
Splitting by role has a mechanical payoff too. OpenClaw limits how many characters of each bootstrap file it injects (bootstrapMaxChars, default around 20,000 on the versions covered in the context budget guide), and the overflow is dropped without a warning. That guide's example is an AGENTS.md at 31,000 characters whose last third the model had never seen. Hostnames and contact lists stuffed into AGENTS.md push real rules past the cut. Move them out and the rules come back.
Size also costs money on every turn. The cost optimization guide found 3,000 tokens of redundant context in one SOUL.md, trimmed it to 800, and credits that with a 15% drop in context costs. A temperament file that long was almost certainly holding rules.
Not every turn sees every file, either. Heartbeats with lightContext skip bootstrap files entirely, and session types differ in what they load depending on your version. Run /context in a main session and then in a sub-agent if your build has the command, and compare the two. A rule the sub-agent never receives does not apply to the sub-agent.
IDENTITY.md
If your version created one, put the name and the emoji in it and never think about it again.
Common Failure Modes
The agent ignores a rule you wrote last week
Check the file's length against the cap first. Then check whether the rule is phrased as a trait in SOUL.md instead of an instruction in AGENTS.md.
The agent knows a tool exists but cannot use it
TOOLS.md describes it, and the agent's allow list in openclaw.json does not include it. Fix the config, not the markdown.
Behavior flips between sessions
Two files disagree. Run the grep above.
A file you never touched has changed
The agent edited it. Keep the workspace in git and read git log -p on the bootstrap files once a month.
Final Verdict
Treat the bootstrap files as the most expensive real estate in your setup, because every character in them is paid for on every turn and competes for the model's attention with the message you actually sent. Most new lines should leave the workspace, and the routing test tells you where to. What stays is mostly permissions, which go in AGENTS.md with the ones you care about on the first screen. SOUL.md gets a few paragraphs of temperament and nothing else.
When a line fits two files, it is a rule. Put it in AGENTS.md.
Ready to build?
Get the OpenClaw Starter Kit — config templates, 5 production-ready skills, deployment checklist. Go from zero to running in under an hour.
$14 $6.99
Get the Starter Kit →Also in the OpenClaw store
Get the free OpenClaw quickstart guide
Step-by-step setup. Plain English. No jargon.