M. Semih Babacan

I Stopped Writing Prompts and Started Writing Identity Files

The people getting the best work out of coding agents aren't writing better prompts. They're writing SOUL.md, STYLE.md, SKILL.md. Here's the mechanism I think is actually doing the work, and the part of the idea I don't buy.

Mehmet Semih Babacan
Mehmet Semih Babacan

AI Technical Product Manager

March 4, 20269 min read19 views
I Stopped Writing Prompts and Started Writing Identity Files

I spent about six months trying to write better prompts. Longer ones, tighter ones, ones with examples, ones with explicit output schemas. The gains were real and small. Then I started keeping a file called SOUL.md in the repo, and the gains were neither.

The setups I keep seeing from people who get genuinely good work out of coding agents share a shape. The system prompt is thin, sometimes two lines. What actually sits in the context window is a 2,000-word markdown file that reads like a personality profile: values, taste, reasoning habits, the failure modes this agent should be paranoid about. It describes who to be, not what to do.

So, if you are still tuning prompt wording, this is the thing I'd swap your afternoon for. Not because identity files are magic. Because they solve a different problem than the one prompt wording solves, and it turns out to be the bigger one.

Instructions cover the cases you thought of

Here is the part that took me embarrassingly long to see.

A coding task is not one decision. Rename a function and you have made maybe 200 decisions: what to call it, whether to keep the old name as an alias, whether to touch the tests in the same commit, whether the docstring still describes reality, whether the four call sites that now read awkwardly get fixed now or noted for later. Nobody writes those down. You cannot. The list is longer than the task.

An instruction file answers the ones you enumerated. Everything else falls through to whatever the model does by default, which is some blend of the entire internet's average taste. That blend is not bad, it is just not yours, and it is inconsistent between sessions because it is being resolved fresh each time by whatever happens to be salient in the context.

An identity file does not enumerate. It shifts the default.

Rules answer the choices you listed. The identity file answers the ones you never thought to list.

That is the whole mechanism as I understand it. Instructions tell a model what to produce. An identity file tells it what to notice, and what you notice decides the hundred things you never argued about.

The human version is familiar. Tell a junior developer "write clean code" and you have given an instruction that does almost nothing. Sit them next to someone with strong opinions about naming, who visibly winces at a certain pattern, and six weeks later their code is different. Nobody enumerated the rules. The taste handled it.

What the two files actually look like

The difference reads smaller than it is, so here are both, trimmed to the same length.

INSTRUCTIONS.md
- Use TypeScript strict mode.
- Prefer named exports.
- Write tests for new functions.
- Keep functions under 40 lines.
- Don't add new dependencies.
- Use early returns, not nested ifs.
SOUL.md
You are suspicious of abstraction that
doesn't pay for itself. You would rather
ship an ugly function that is obviously
correct than an elegant one that hides
where the money is counted.

When two designs are close, you pick the
one that fails loudly. Silent fallbacks
are how bugs survive to production, and
you have been burned by them.

You say "I don't know" out loud instead
of producing a confident guess.
Same length. The left one runs out of answers on the first situation it didn't predict.

The left file is not wrong. I still ship one. But it has nothing to say the moment the agent hits a situation nobody predicted, and that is most situations. The right file has an answer for a case it never names, because it moved the prior instead of listing the outcomes.

Rules run out. Taste doesn't.

The three-file split, and why it holds

The convention that settled out looks like this:

SOUL.md carries values and worldview. What this agent cares about, what it refuses, what it treats as a smell.

STYLE.md carries voice and surface constraints. Naming, comment density, how it writes a commit message, how much it hedges in prose.

SKILL.md carries domain knowledge and method. The parts of your system it needs to know, the procedure it should follow for a migration, where the sharp edges are.

I like this split for a boring reason: the three files change on different clocks. Style churns weekly while you figure out what you like. Skill changes whenever the system changes. Soul barely moves at all. Keeping them apart means editing the fast-changing one without touching the file you got right eight months ago.

It also mirrors how people get good at things, roughly. You do not become a designer by learning Figma. You develop taste, then a recognisable approach, then the tool chops. Same order of importance, and the tooling for agents keeps landing on the same hierarchy without anyone coordinating it.

The ways I've watched this fail

Identity files are not free, and the failures are quiet, which is the annoying part. Four I keep running into.

The middle of a long file goes silent. Write 3,000 words and the first paragraph and the last paragraph shape the output while the ones in between may as well not be there. I have no clean explanation for this beyond the usual attention story, but I've seen it enough to plan around it. If a disposition matters, it does not live in paragraph nine.

Two dispositions can quietly contradict each other. "Ship the smallest thing that works" and "never leave a silent fallback in the money path" will collide, and when they do the agent picks one without telling you which. The fix is unglamorous: name the conflict yourself and say which side wins. The tie-break is the useful part of the file, not the values that were never in tension.

Aspirational writing produces an agent that argues with your codebase. If the file describes the developer you'd like to be rather than the code you actually have, you get an agent that keeps proposing the rewrite you are not going to do. Write what is true about this repo today, including the parts you're not proud of.

And identity does not substitute for facts. No disposition will tell an agent that money in your system is integer kuruş, or that one particular table is append-only. That knowledge has to be written down as knowledge. This is exactly the seam the three-file split is for, and mixing them is how a soul file turns into a 4,000-word junk drawer that nobody edits because nobody can find anything in it.

Where this goes once you take it seriously

The moment you accept that you are configuring an agent with prose, you start wanting everything you want from any other configuration. Modularity. Overrides. Reuse. One giant file stops scaling around the point where two of its paragraphs start competing for attention.

Jesse Vincent's Superpowers project is the version of this I've found most useful to think with. A skill there is a markdown file with YAML frontmatter. The frontmatter is metadata, what it's called and when it activates. The body is the prompt. That's the format, all of it.

The composition is where it earns its keep. Some skills are session hooks that inject themselves into every conversation, the always-on instructions you'd otherwise bury in a soul file. Some are slash commands, so the carefully built prompt for "think this through from several angles before committing" becomes one word you type. Some spawn a subagent to audit the first agent's work with different instructions, which sounds like overkill until it catches a real bug in something you were about to merge.

And there's a dispatch layer: project skills shadow personal ones, personal shadow the defaults. Exactly the specificity layering you already use for config, applied to behaviour.

That's the actual lesson, and it isn't about Superpowers. Soul.md was never going to stay one file. Once configuration is prose, prose gets a build system.

I wrote the longer version of that argument separately: The best prompting I've seen doesn't trust the model at all.

How I'd start, if I were starting today

  1. Write down the last three times an agent annoyed you

    Not bugs. The choices that were technically fine and still wrong. That list is your soul file's first draft, and it's specific to you in a way a template never is.

  2. Phrase each one as a disposition, not a rule

    "Don't use nested ternaries" is a rule and covers one case. "You optimise for the reader who is debugging this at 2am" is a disposition and covers a hundred, including nested ternaries.

  3. Split it when it starts arguing with itself

    One file until it stops working. When the voice notes and the domain notes start crowding each other out, that's the split into STYLE and SKILL, and you'll feel it before you can justify it.

The part I don't buy

There's a version of this argument that goes philosophical fast, and I used to tell it that way. It leans on Wittgenstein, on the line about the limits of my language being the limits of my world, and it lands on something like: a language model is made of language, so writing an identity file is bootstrapping a consciousness that lives for one context window and dies at the end of the session.

Honest answer: I think that's a good metaphor doing a bad job of pretending to be a claim. It feels profound and it predicts nothing. It doesn't tell me whether to split my files, or how long they should be, or why the agent still ignores the third paragraph. The boring explanation, that a prior applied across hundreds of unlisted micro-decisions beats a rule list applied to four of them, explains everything I've actually observed and asks me to believe much less.

What I'll say instead is that the format is funny. Markdown. The same thing I use for grocery lists. There is no ceremony to it, no schema, nothing that signals it's load-bearing. You open a text file, describe a way of seeing, save it, and the work that comes back changes shape. Six months of prompt tuning got me less than one afternoon of writing down what I actually think good code looks like.

I still don't fully know why the second thing works so much better than the first. The funnel explanation is the one I'd defend, and it's a description of a mechanism, not a proof of one.