← All writing

EMBER: A Language Designed for the Third Reader

XML was designed for machines. Markdown was designed for humans. EMBER was designed for AI agents — and that distinction changes everything about what a language needs to be.

Michael Shatny··9 min read

After the Bug

The PDF debugging session ended in a single line of code. Executive briefs were using a technical flag — analysis depth — to determine document behavior. Wrong domain driving wrong behavior. WHAT and WHY had separated. One unified semantic check fixed it.

But fixing it in one variable wasn't enough.

The deeper question was: what happens to intent as it travels through a system? Through agents, through transformations, through time? In that codebase, the intent had drifted so gradually that nobody noticed until the output was visibly wrong. The fix was simple. The drift had taken weeks to accumulate and three more weeks to find.

I needed a format where intent couldn't drift. Not in code — in artifacts. A language that carried meaning from the moment it was captured to the moment it was used, without loss.

That language is EMBER. Its files are .sil — Semantic Intent Language. And building it required understanding something that most people working with AI haven't had to think about yet: who is actually reading the things you write?

The Three Readers

Every format that exists was designed for a specific reader. That reader shaped every decision — what structure was required, what was optional, what could be implicit, what had to be explicit.

XML was designed for machines. Parsers. Validators. Systems that needed rigorous structure and could tolerate verbose syntax because they never had to read it comfortably. It's technically human-readable. Nobody actually reads it without pain.

Markdown was designed for humans. Writers who needed lightweight formatting without the overhead of HTML. It assumes a human reader who brings context, inference, and patience to ambiguous structure. A machine can render it, but it can't reason about it.

JSON, YAML, TOML — designed for configuration. The reader is a system consuming structured data. Meaning is imposed by the application, not carried by the format. The same JSON object means entirely different things in different contexts.

None of these were designed for the third reader: the AI agent.

An agent reads differently than a machine and differently than a human. It reads with comprehension — it can extract meaning from plain language. But it also reads with uncertainty — it doesn't know what it doesn't know, and ambiguous structure produces ambiguous reasoning. It needs enough explicit structure to orient itself, enough plain language to reason about the domain, and enough honesty about gaps that it knows how much to trust what it's reading.

EMBER was designed for that reader.

The Design Decisions That Matter

Every decision in EMBER's design was made with the agent reader in mind. Some of them look obvious once stated. Others are counterintuitive until you understand who is doing the reading.

Non-executable by design

The most unusual property of EMBER is that nothing in a .sil file executes. There is no runtime. No interpreter. No validator that rejects malformed input with an error code.

This is a deliberate choice, not a limitation.

Executable formats couple meaning to tooling. If the tool changes, or disappears, or can't be installed, the artifact becomes unreadable. A .sil file from 2026 will be readable in 2040 with no dependencies, no toolchain, no migration. Open it. Read it. The meaning is there.

Non-executable also means an agent can read it without executing it — which is exactly what agents do. They read for understanding, not for output. A format designed to be executed is optimized for the wrong operation.

One construct per file

Every .sil file contains exactly one thing. One signal. One workflow trace. One screen sequence. One specification. One episode.

The reason is git. When you have one construct per file, every change to every artifact is a discrete, attributable diff. You can see exactly what changed, when, and in which artifact. You can trace the evolution of a single workflow across the entire engagement. You can audit the moment a requirement changed by reading the episode file that recorded it.

The artifact trail is not a byproduct of the pipeline. It is the audit log. And you only get that audit log if each artifact is atomic.

The header is mandatory — no exceptions

Every .sil file opens with exactly three lines before any content:

CONSTRUCT  signal
ID         cart.checkout
VERSION    1
─────────────────────────────────────────

An agent reading a .sil file knows what kind of artifact it holds before it reads a single line of content. That's not a small thing. Context shapes interpretation. An agent that knows it's reading a spec reasons differently about the content than one that thinks it's reading a workflow trace.

The separator line uses Unicode (U+2500), not ASCII hyphens. This is deliberate. An agent scanning for the separator can distinguish it unambiguously from content that might use hyphens in its own structure. One character does two jobs: terminates the header and visually signals the boundary.

Honest metadata over complete metadata

The signal construct — the first artifact A-00 produces — has a confidence field:

confidence:
  medium
  partial docs available, schema clean,
  no business requirements document found

Most formats don't have a field for admitting uncertainty. EMBER does because agents need to calibrate how much to trust what they're reading. A high-confidence brief built on complete documentation produces different downstream reasoning than a low-confidence brief inferred from a route table and a database schema.

An incomplete brief that is honest about its gaps is more useful than a complete brief that isn't. The agent that reads it knows where to be careful.

Episodes: explicit routing, not inference

When a requirement changes mid-engagement, an episode file is written. It records what changed, why, and — critically — which agents need to attend to it and which can skip it:

affects:
  A-01  → add guest.checkout workflow
  A-03  → update spec — guest vs authenticated intent
  A-05  → new UI pass and API route for guest flow

skip:
  A-00  → brief unchanged
  A-04  → stack unchanged

This is explicit routing. The agent reading the episode doesn't have to infer whether it's affected. It's told. That removes an entire class of reasoning error — the agent that applies a change it shouldn't, or misses a change it should have caught, because it had to guess.

Five Constructs, Five Questions

EMBER has exactly five construct types. Not four, not ten. Five — because there are exactly five questions a system needs answered before it can be rebuilt:

SIGNAL
A-00
What are we walking into?
Mission brief — orientation before extraction begins
WORKFLOW
A-01
What does the system actually do?
Server-side trace — every business process, flow and I/O
SCREEN
A-02
What does the user experience?
ASCII wireframes — every screen, every transition
SPEC
A-03
What was it trying to accomplish?
Semantic intent — WHAT and WHY unified into one artifact
EPISODE
Any
What changed, and who needs to know?
Change record — explicit routing to affected agents

Notice that SPEC — the output of A-03 — is where WHAT and WHY finally unify. The workflow trace (what the code does) and the screen trace (what the user experiences) are synthesized into a single artifact that answers: what was this actually trying to accomplish?

That's the PDF bug, solved at the language level. WHAT and WHY can't separate in a SPEC file because the SPEC file exists specifically to hold them together. The artifact format enforces the principle.

What Non-Executable Actually Means

When I describe EMBER as a non-executable language, the most common reaction is: “so it's just documentation.” It isn't.

Documentation describes a system after it exists. It explains what was built. It drifts from the code because the code changes and the documentation doesn't. Documentation is passive.

A .sil file is a working artifact. It is produced by an agent, read by the next agent, and its contents directly determine what gets built. A-05 builds from the SPEC files. A-06 certifies against them. If the spec is wrong, the build is wrong and the certification fails. The artifact is load-bearing — it just doesn't execute.

The distinction matters because it defines the relationship between the artifact and the system. Documentation describes what is. A .sil file is what was meant. The new system is built to match the artifacts, not the other way around.

That inversion — artifacts as source of truth, code as output — is the core of what Phoenix does. And it only works if the artifacts carry intent reliably from capture to use. That's what EMBER is for.

Every Input to AI Is a Language

There's a broader observation underneath EMBER that took time to articulate clearly.

Every input that goes through to an AI is a language of its own — structured or unstructured, formal or informal, named or unnamed. The moment you add structure, intent, and repeatability to what goes into an agent, you have moved from unstructured text to a language. Most people just haven't named it or treated it as one.

The primitives analogy is exact. An unstructured prompt is a primitive — it carries a value but no type information, no declared intent, no context about how it should be interpreted. A structured prompt with role, context, task, and constraints is an object. A .sil file is a typed object with a declared construct, a named ID, a version, and a body — the agent reading it knows the type before it reads the value.

EMBER is the first language I'm aware of that was designed explicitly for this layer — not for machines, not for humans, but for agents that read with comprehension and act on meaning. Every domain that uses AI repeatedly will eventually develop something like it, intentionally or by accident. The ones that do it intentionally will get more reliable, more auditable, more trustworthy results.

The Implementation

EMBER isn't just a specification. There's a runtime that implements it.

@semanticintent/phoenix-runtime is the open-source CLI that orchestrates the seven-agent pipeline, parses .sil files, manages artifact state, enforces human gates between every pipeline stage, and produces agent prompts ready to run in any AI interface. It doesn't call an API. It produces prompts. Model-agnostic. No API key management.

Install
npm install @semanticintent/phoenix-runtime
Run
phoenix init acme-order-system
phoenix run a-00
phoenix status
phoenix gate pass-1 --approve

Michael Shatny is a software developer and methodology engineer and founding contributor to .netTiers (2005–2010), one of the earliest schema-driven code generation frameworks for .NET, his work spans 28 years of the same architectural pattern: structured input, generated output, auditable artifacts. EMBER is the latest expression of that instinct — applied to the most important shift in software development in decades.

ORCID: 0009-0006-2011-3258