Loretia compiles every parsed prose, script, or transcript into NCDL (Narrative Continuity DSL) — a strict, event-sourced statement log the engine checks for contradictions in fact, time, and knowledge. This is the developer-facing quick reference; the full normative grammar lives in the repo's dsl-spec/SPEC.md.

1. Core principles

  • Event sourcing: nothing is mutated in place — the current state is a projection of the append-only statement log. Retractions, revocations, and forgettings are themselves log entries, not deletions.
  • One content statement: there is no separate "event" keyword. REL covers an entity's own attribute, an entity→entity link, and a discrete action — which of those it is comes from the predicate's declared aspect (punctual vs. durative, see §3).
  • Named tags, not clocks: story time is a set of short tags (a scene, a flashback, a chapter), related to each other only by explicit BEFORE/AFTER/EQUAL declarations — never real-world units.

2. Declarations (entities & rules)

  • ENT { "[ID]" CREATE } / ENT { "[ID]" DESTROY }
    • Example: ENT { "John" CREATE }
  • ALIAS { <term> <term> } — fuses two names into one entity (e.g. resolving a secret identity, or identifying an unresolved reference once the story reveals who they are).
    • Example: ALIAS { "Clark Kent" "Superman" }
  • ?name — an unresolved reference: a particular individual whose identity isn't known yet ("a man with a scar"). Mints itself on first use, persists as the same individual everywhere it's reused, and needs no declaration.
    • Example: REL { ?man "PUNCH" "John" }
  • DEF { "[keyword]" "[description]" [TAGS...] } — registers a predicate's behavior. PUNCTUAL marks an action (an occurrence, like ATTACK); everything else defaults DURATIVE (a lasting state). FUNCTIONAL/SET control cardinality for durative predicates; SYMMETRIC/TRANSITIVE add relation algebra; ASSERTIVE marks a punctual verb that transmits content (must be wrapped in CLAIM, never a bare REL).
    • Example: DEF { "ATTACK" "A kinetic strike." PUNCTUAL }
  • RULE #Handle { ... } — a standing physical law, using REQUIRE, FORBID, or IMPLY directives, matched with WHERE. Every directive body is written in the same REL triple syntax as a plain assertion.
    • Example:
      RULE #RequireKey {
        FORBID REL { $actor "UNLOCK" $door }
        WHERE NOT REL { $actor "has" "Key" }
      }
      

3. Relations & time (the action log)

  • TIME { "[Tag]" } — declares or re-enters a named moment.
    • Example: TIME { "Chapter 1" }
  • TIME { "[Tag]" IS BEFORE/AFTER/EQUAL "[OtherTag]" } — relates two tags; chain with AND.
    • Example: TIME { "Chapter 2" IS AFTER "Chapter 1" }
  • REL { "[Subject]" "[Predicate]" [Value] } / NOT REL { ... }
    • A durative predicate (the default) is a lasting state or link — NOT REL retracts it.
    • A punctual predicate (declared PUNCTUAL via DEF) is a one-off occurrence — it can never be retracted, and accumulates rather than overwriting.
    • Example: REL { "John" "location" "Florida" }
    • Example: NOT REL { "John" "has" "purple pen" }
    • Example (action): REL { "John" "ATTACK" "Jane" }
  • AT "[Tag]" / BETWEEN "[Tag]" AND "[Tag]" / FROM "[Tag]" UNTIL "[Tag]" — an optional trailing clause anchoring a relation's own content time, independent of where it's narrated from. BETWEEN is punctual-only; FROM/UNTIL is durative-only.
    • Example: REL { "Sam" "married_to" "Maria" } FROM "The Wedding" UNTIL "The Divorce"

4. Epistemics

  • CLAIM { REL { ... } } BY "[Speaker]" [TO "[Listener]"] [AT "[Tag]"] — a character's assertion, checked against their own knowledge view (not the objective ledger). The optional AT extent is for reported speech about an earlier moment — "Mother told me you were wounded" said long after the fact.
    • Example: CLAIM { REL { "Watson" "wounded_in" "Shoulder" } } BY "Watson" AT "The War"
  • ... IMPLICIT — a trailing marker (no value) on a CLAIM/SUSPECT saying the speaker knows this as ordinary background the story never had to establish: what people in their trade, place, or era simply know. It waives only the "you had no way of knowing that" check for that one statement — the claim is still checked for contradicting canon, and no other statement is affected.
    • Example: CLAIM { REL { ?investigators "USE" ?notepad } } BY "Hart" IMPLICIT
  • SUSPECT { ... } BY "[Speaker]" — a fuzzy theory or hunch; never raises a contradiction.
  • PROMISE #Handle { REQUIRE/FORBID REL { ... } } BY "[Speaker]" — a forward-looking vow.
  • CLAIM { ALIAS { <term> <term> } } BY "[Speaker]" — an identity claim: dialogue that reveals (or, under SUSPECT, merely guesses) two names are the same individual. Merges the two only inside that character's own belief tree — the objective world stays undecided until the narrator writes a bare, unwrapped ALIAS. A claimed identity contradicting the speaker's own known facts is flagged.
    • Example: CLAIM { ALIAS { "Masked Man" "Don Quijote" } } BY "Sancho"

5. Groups

A group is nothing but a declared entity plus the reserved predicate member_of (built-in DURATIVE SET; cannot be re-DEFed). Joining is the left edge of the membership's extent, leaving is the right edge or a retraction:

ENT { "City Guard" CREATE }
REL { "Aldo" "member_of" "City Guard" } FROM "The Oath"
REL { "Bren" "member_of" "City Guard" } FROM "The Oath" UNTIL "The Desertion"

Wherever the group's name appears in a WIT/TO list or a SCENE roster, it expands to whichever members' extent covers that statement's own moment — a briefing reaches Aldo and Bren, but not a recruit who joined afterward. The group itself remains a real node (it can hold relations, be gossiped about) — only audience and witnessing auto-expand; NCDL never silently distributes an action over every member.

6. Logical operators

  • $variable — the $ prefix binds a pattern variable inside a RULE/PROMISE directive; ranges over every match. Never legal in a plain assertion.
  • _ — wildcard: matches/leaves a slot unspecified, binds nothing.
  • ==, IN (...), NOT, MENTIONS <term>, BETWEEN ... AND ..., KNOWS — the WHERE operator set. KNOWS also derives from a captured-statement pattern (IMPLY KNOWS $x { _ AS $s WHERE $cam IN $s.wit }) — the mechanism behind recordings, letters, and portraits: whatever a witness recorded, a later viewer now knows.