01Objects
In TERSE, intrinsic identity lives in the name, not in a bag of attributes. Booleans become flags; machine-read values become key: value identifiers.
{ "name": "Ada Reyes", "id": 88231, "tier": "enterprise", "active": true }
# Customers Ada Reyes(id: 88231; tier: enterprise; active)
02Nested objects
Hierarchy is parenthood, expressed with # depth markers. Objects are bare name lines under a container. Depth is meaning, not outline decoration.
{ "party": { "kell": { "class": "fighter", "health": { "hp": 25, "maxHp": 80, "wounded": true } } } }
# Party ## Kell(class: fighter) ### Health(hp: 25; max hp: 80; wounded) // path shortcut — open deep without replaying the stack: # Party.Kell.Health(hp: 25; max hp: 80; wounded)
03The three attribute kinds
Every slot inside (...) is exactly one property of this thing.
plate armor(creaky; enchanted) // flags — no colon, atomic descriptors health(hp: 25; max hp: 80) // identifiers — `key: value`, machine-facing confidence(0.95; verified) // raw — unkeyed value, human context only
| Put it in the name | Put it as a flag | Put it as id: value | Make it an object |
|---|---|---|---|
| What it is | Human descriptor | A machine will read / filter it | It has its own attrs or children |
| steel sword | creaky | damage: +1 | steel sword(...) under Inventory |
04Arrays of objects
JSON arrays of things become sibling object lines under a container. This is the hard rule of TERSE modeling: attributes are atomic — never a list of other things.
{ "inventory": { "capacity": "almost full", "items": [ { "name": "steel sword", "damage": "+1" }, { "name": "plate armor", "condition": "creaky" }, { "name": "wooden shield" } ] } }
# Inventory(almost full) steel sword(good condition; damage: +1) plate armor(creaky) wooden shield(standard)
### Inventory(sword; shield; armor)
### Inventory(almost full) steel sword(damage: +1) wooden shield(standard)
05Primitive arrays & tags
Simple string arrays that describe a thing collapse into flags on that thing.
{ "id": 4412, "title": "outage", "priority": "high", "status": "open", "tags": ["billing", "auth"] }
# Cases ## 4412 outage(priority: high; open; billing; auth)
06Multi-line text
Only containers hold multi-line TEXT. A bare "..." line is sugar for single-line TEXT; """ blocks hold prose verbatim.
{ "places": { "resort": { "description": "A mountain lodge above the tree line." } }, "notes": "Subject improved on the second block.\nKeep the same equipment next visit." }
# Places ## Resort "A mountain lodge above the tree line." # Notes ## Session 3 """ Subject improved on the second block. Keep the same equipment next visit. """
07References
@Path.With.Dots points at a container, object, or identifier elsewhere — no duplicated state, no ID bookkeeping.
{ "mind": { "currentLocationId": "resort-01", "exit": "hall-03" }, "locations": { "resort-01": { … }, "hall-03": { … } } }
### Mind current location @Places.Resort exit(door to @Resort.Hall) // quoted strings keep @ literal: reporter(email: "ada@example.com")
08Value typing & quoting
After : (colon then space), values type in order: bool → int → float → date → string. Unquoted fall-through is a string. Quote to force string when the text would type differently.
{ "count": "5", "class": "fighter", "shipped": "2026-07-08", "schedule": "at 12:00", "ratio": "3:1" }
order(count: "5"; class: fighter; shipped: 2026-07-08) // bare `:` without a space is literal — not a split: schedule(at 12:00) ratio(3:1)
| Input after : | Types as |
|---|---|
| true / false | boolean |
| 25 · 0.95 | int · float |
| 2026-07-08 · 2026-07-08T14:30 · 07/08/2026 | date |
| fighter ≡ "fighter" | string (unquoted fall-through) |
| "5" · "true" | string, forced by quoting |
09Naming & handles
Names are natural language — spaces fine, telegraphic. Handles (for programs and WHERE) are derived, never stored: spaces → _, punctuation dropped, leading digit gets a _ prefix. Display always wins on render.
| Display name | Derived handle |
|---|---|
| New York | New_York |
| O'Brien | OBrien |
| 4412 outage | _4412_outage |
10Queries
Start with ?. Pure queries never mutate, and results are real TERSE — re-parseable, with ancestors preserved so location is clear.
? // whole state ? Chars.Kell // Kell + subtree ? Chars.* // each child of Chars (* = one segment) ? Places.Resort [DEPTH 2] // bound subtree depth ? Items.* [WHERE Its.damage > 3] // filter on identifiers ? Chars.* [WHERE Its HAS wounded] // attribute exists (flag or key) ? Notes [CONTAINS "billing"] // grep-in-language: line + TEXT ? Events.* [WHEN 2026-07-08] // temporal filter ? RunLog.Records.* [LAST 5] // slice the match set, state order ? Cases.* [WHERE Its.priority == "high"; DEPTH 2]
11Mutations
A declaration applied to empty state is the state. Applied to live state, silence preserves: what you don't restate, you don't change.
## Kell(wounded; hp: 25)
## Kell(+wounded; -healthy; +hp: 30)
## Kell(saved; ending) [MERGED] ## Kell() // clear all attrs
broken shield [REMOVED] -old map // shorthand
12Directive tails
One bracketed tail per line, at the absolute end. Segments split on ;, each starting with an ALL-CAPS keyword. Order is state — placements are assertions, and reapplying is idempotent.
## New Team [WAS Old Team] // rename — old name resolves for a beat smoke test [FIRST] // first within its own kind-run billing dispute [AFTER outage 4412] // anchor to a same-kind sibling # Log [APPEND "second entry."] // join to standing TEXT steel sword(damage: +2) [AFTER plate armor]
| On declarations | Meaning |
|---|---|
| [WAS old name] | rename |
| [REMOVED] | drop node (-name shorthand) |
| [MERGED] | merge attrs without prefixing all |
| [FIRST] · [LAST] · [BEFORE x] · [AFTER x] | placement within the item's kind-run |
| [APPEND "text"] | container only — append to TEXT |
| On queries / in-place | Meaning |
|---|---|
| [WHERE expr] · [WHEN date] · [CONTAINS "text"] | filters |
| [DEPTH n] · [FIRST n] · [LAST n] | bound depth · slice the match set |
| [REFERENCES] · [CONTAINERS] | also pull @ targets · containers only |
| [NEW] · [FILL] · [MOVED] · [AS name] | declarative-command conflict modes |