Writing GEML — one-page cheatsheet
SkillDocs & knowledgeOne format, two readers. People and AI agents now co-write the same document. Legible for people; addressable, verifiable, and versioned for machines. GEML is plain text — organized by one typed block for everything, remembered by a .gemlhistory sidecar.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Writing GEML — one-page cheatsheet skill
What this skill tells your AI
The instructions your AI receives, as published by geml-spec/geml in geml-parser/bench/SKILL.md and read by ahel’s review.
GEML is plain text. Every structured thing is one typed block:
=== <type> {#id .class key=val}
<body>
===
The opening fence is ≥ 3 =. The closing fence must be the same length.
To nest a block inside a block, make the outer fence longer:
==== note
Example code:
=== code {lang=python}
print("hi")
===
====
Easier — close by name. Give a block an #id and close it with === #id.
That closes by name, not by length, so you can nest with all === fences and
never miscount:
=== note {#ex}
Example code:
=== code {#snippet lang=python}
print("hi")
=== #snippet
=== #ex
Body modes: code / diagram / math / table / embed are raw;
note are parsed prose; meta is one key=val per line.
Metadata
=== meta
title = "My doc"
version = 0.1
===
In prose, {{title}} inserts a meta value (an unknown key is a build error).
Headings & lists (ATX only)
# Title ## Section {#explicit-id}
- bullet 1. ordered
- nested by indentation (2 spaces)
- [ ] task - [x] done
Inline
*em* **strong** `code` ~~strike~~ $a^2$ (inline math)
[text](https://x) [text](#id) [[#id]] (auto text) [^note] 
A reference to a missing id is a build error. Define a footnote with
a note block (e.g. === note {#note}), then cite it inline with [^note].
Tables
=== table {#fy caption="Sales" format=csv header=1}
Seg, Q1, Q2, Q3, Q4
Cloud, 1, 2, 3, 4
===
=== view {#fy-report src=#fy compute="FY [%.1f] = Q1 + Q2 + Q3 + Q4" summary="Seg = 'Total'; Q1 = sum(Q1); FY = sum(FY)"}
===
- A
tableholds FACTS.compute/summary— andwhere/order/limit/select/by/aggregate— belong to aviewwhosesrc=names the table. - The attribute object
{…}is one physical line (don't wrap it). compute:Name = exprover+ - * / ( ), columns by header name (quote names with spaces:'Unit Price') or letterA,B,…;;-separate multiple formulas;[%.1f]sets number display.summary: one foot row; each cell is a literal ('Total') or an aggregate expression oversum/avg/min/max/count. A bare (non-aggregated) column is an error.- Visual form also works:
| a | b |rows with a|---|separator.
Diagrams & charts
=== diagram {#flow format=mermaid caption="Flow"}
graph LR
A --> B
===
Chart drawn from a table (empty body — the spec is in the attributes):
=== diagram {format=geml-chart data=#fy type=bar x=Seg y=FY}
===
type ∈ bar|line|area|pie|scatter; x/y are column names; data=#id must
point at a table; a typo'd column or dangling id is a build error.
Math
=== math {#g caption="Gaussian"}
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
===
Things that are build ERRORS — avoid them
- A reference / footnote / chart column /
{{meta}}key that does not resolve. - A duplicate
#id. - A block not closed by an equal-length fence (when nesting, the outer fence must be longer than any fence inside it).
- A
summarycell using a column that isn't wrapped in an aggregate. - Raw HTML (there is none in GEML).
Signals
- GitHub stars
- 26
- Forks
- 1
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
bench-geml-spec- Source
- github.com/geml-spec/geml