Resources // TERSE

Syntax Cheatsheet

Quick reference for mapping JSON to TERSE — objects, nesting, attributes, text, references, queries, and mutations at a glance. For normative rules and edge cases, see the TERSE Specification.

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.

JSON
{
  "name": "Ada Reyes",
  "id": 88231,
  "tier": "enterprise",
  "active": true
}
TERSE
# Customers
Ada Reyes(id: 88231; tier: enterprise; active)
The name carries what it is (Ada Reyes), attributes carry one property each, separated by ; — a flag (active), or an identifier (id: 88231). Attributes never span lines.

02Nested objects

Hierarchy is parenthood, expressed with # depth markers. Objects are bare name lines under a container. Depth is meaning, not outline decoration.

JSON
{
  "party": {
    "kell": {
      "class": "fighter",
      "health": {
        "hp": 25,
        "maxHp": 80,
        "wounded": true
      }
    }
  }
}
TERSE
# 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)
Navigation note: after ## D.E, a following ## F is a sibling of D, not a child of E. Want it under E? Use a deeper marker: ### F.

03The three attribute kinds

Every slot inside (...) is exactly one property of this thing.

TERSE
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 namePut it as a flagPut it as id: valueMake 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.

JSON
{
  "inventory": {
    "capacity": "almost full",
    "items": [
      { "name": "steel sword",
        "damage": "+1" },
      { "name": "plate armor",
        "condition": "creaky" },
      { "name": "wooden shield" }
    ]
  }
}
TERSE
# Inventory(almost full)
steel sword(good condition; damage: +1)
plate armor(creaky)
wooden shield(standard)
✗ Wrong — attributes as a shopping list
### Inventory(sword; shield; armor)
✓ Right — items are objects with their own atoms
### Inventory(almost full)
steel sword(damage: +1)
wooden shield(standard)
almost full is one property of the inventory. The sword is not a property of the inventory — it is an object under it. That is the whole game.

05Primitive arrays & tags

Simple string arrays that describe a thing collapse into flags on that thing.

JSON
{
  "id": 4412,
  "title": "outage",
  "priority": "high",
  "status": "open",
  "tags": ["billing", "auth"]
}
TERSE
# 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.

JSON
{
  "places": {
    "resort": {
      "description": "A mountain lodge
        above the tree line."
    }
  },
  "notes": "Subject improved on the
    second block.\nKeep the same
    equipment next visit."
}
TERSE
# Places
## Resort
"A mountain lodge above the tree line."

# Notes
## Session 3
"""
Subject improved on the second block.
Keep the same equipment next visit.
"""
Append instead of overwrite with [APPEND]: # Log [APPEND "second entry."] joins new text to standing TEXT with a single newline. Two non-append payloads under one container resolve last-wins — with a warning.

07References

@Path.With.Dots points at a container, object, or identifier elsewhere — no duplicated state, no ID bookkeeping.

JSON
{
  "mind": {
    "currentLocationId": "resort-01",
    "exit": "hall-03"
  },
  "locations": {
    "resort-01": {  },
    "hall-03": {  }
  }
}
TERSE
### Mind
current location @Places.Resort
exit(door to @Resort.Hall)

// quoted strings keep @ literal:
reporter(email: "ada@example.com")
Absent targets don't fail the declaration — they warn as dangling refs, because the state may arrive later. Display or handle form both resolve: @Places.New York@Places.New_York.

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.

JSON
{
  "count": "5",
  "class": "fighter",
  "shipped": "2026-07-08",
  "schedule": "at 12:00",
  "ratio": "3:1"
}
TERSE
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 / falseboolean
25  ·  0.95int · float
2026-07-08 · 2026-07-08T14:30 · 07/08/2026date
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 nameDerived handle
New YorkNew_York
O'BrienOBrien
4412 outage_4412_outage
Forbidden in names (and identifier keys / path segments): ( ) ; " # @ . [ ] and the two-character sequence (colon-space). Fine: letters of any script, digits, spaces, hyphens, apostrophes, most punctuation.

10Queries

Start with ?. Pure queries never mutate, and results are real TERSE — re-parseable, with ancestors preserved so location is clear.

TERSE
?                                            // 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]
Missing attribute or type mismatch in WHERE is silently false — including ==. Don't grep the raw file when CONTAINS or WHERE will do.

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.

Replacement — the list becomes the whole set
## Kell(wounded; hp: 25)
Modify — every attribute prefixed
## Kell(+wounded; -healthy; +hp: 30)
Merge — add without prefixing everything
## Kell(saved; ending) [MERGED]
## Kell()                      // clear all attrs
Remove a node
broken shield [REMOVED]
-old map                       // shorthand
Mixing prefixed and bare attributes in one list is an error — no attribute change is applied. Fix: prefix all, prefix none, or add [MERGED]. Multi-word flags in mutations take brackets: status(+[very confident]; -[under review]).

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.

TERSE
## 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 declarationsMeaning
[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-placeMeaning
[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