The file format for agentic systems and the humans who work with them.
Structured YAML frontmatter. Markdown body that renders from it. One file — the agent reads the data, the human reads the document. No separate data file. No sync problem.
An agent working with files needs structured data it can reliably read and write — JSON or YAML, with known keys at known paths. A human reading that same file needs prose: headings, context, the information arranged to make sense.
That creates a tradeoff: Markdown is readable but unreliable for agents; JSON/YAML are reliable but hard for humans. The goal is one file that serves both.
Markedin (.mi) solves this: frontmatter as structured data, the body as its template. Agents write to the data; the output renders automatically.
One file. One source of truth — human- and agent-friendly by default.
The frontmatter is full YAML — scalars, objects, arrays,
nested. The body is markdown with
{{ }} expressions that resolve against it. Run
the renderer and get clean markdown. Query the frontmatter
directly and get structured JSON. Same file, either path.
---
task: Implement rate limiting
status: in_progress
owner:
name: Dana
team: Platform
priority: high
notes:
- Token bucket algorithm
- 100 req/min per API key
blocked: false
---
# {{task}}
**Status:** {{status}} · **Owner:** {{owner.name}} ({{owner.team}})
First note: {{notes[0]}}
## Notes
{{#each notes}}
- {{this}}
{{/each}}
{{#if blocked}}
⚠️ This task is currently blocked.
{{else}}
✅ No blockers.
{{/if}}
# Implement rate limiting
**Status:** in_progress · **Owner:** Dana (Platform)
First note: Token bucket algorithm
## Notes
- Token bucket algorithm
- 100 req/min per API key
✅ No blockers.
.mi file is still legible —
{{task}} in place of the resolved value is a
minor interruption, not a broken document. Commit them to a
repo and they read fine in any file viewer.
The full template surface. Everything resolves against the frontmatter of the same file.
| Expression | Resolves to |
|---|---|
| {{key}} | Scalar value. Arrays render comma-separated inline. |
| {{key.nested}} | Dot-path into an object. |
| {{array[0]}} | Array index. Bracket and dot notation both work. |
| {{#each items}} … {{/each}} |
Iterate an array. Object fields available
directly. {{@index}},
{{@first}},
{{@last}} available inside the
block.
|
| {{#if key}} … {{else}} … {{/if}} | Conditional block. Falsy: false, 0, empty string, null, [], {}. |
| {{> key}} | Inline a frontmatter string value as raw text — for reusable prose fragments. |
--json is the read
path — structured JSON out, no prose parsing. Write updated
values back into the YAML block. The rendered markdown
follows.