{
  "$schema_note": "UFN starter dictionary — machine-readable. Senders and receivers share a dictionary verbatim; a producer SHOULD emit the dictionary it used so a generic receiver self-orients. Only the control tokens are reserved; classes/keys/enums are per-profile.",
  "ufn_version": "2",
  "spec": "https://ufn.kovanex.dev/",
  "control_tokens": {
    "field_separator": ";",
    "kv_separator": ":",
    "scope_close": "/",
    "escape": "\\",
    "prose_separator": " ::: "
  },
  "escapes": {
    "\\;": ";",
    "\\/": "/",
    "\\\\": "\\"
  },
  "token_kinds": {
    "field": "key:value (contains ':') — a scalar record; split on the FIRST ':'. Value may contain ':'.",
    "open": "bare token, no ':', not starting '/' — opens a container of that class.",
    "close": "'/' closes the nearest open scope (a stack); '/acr' (named) is an optional resync mode."
  },
  "failsoft": {
    "unknown_token": "skip, continue",
    "unclosed_scope_at_eol": "close implicitly (truncation-safe)",
    "unmatched_close": "ignore",
    "no_tokens_recognized": "treat whole line as prose",
    "empty_value": "skip the field"
  },
  "profiles": {
    "task_edge": {
      "description": "kovanex ctl/MCP edge: tasks, repos, pipelines, PRs.",
      "field_separator": ";",
      "classes": {
        "t": "task (object)",
        "rp": "repos (array)",
        "r": "repo (item object)",
        "pl": "pipeline (object)",
        "pr": "pull request (object)"
      },
      "keys": {
        "i": "id (short 8-hex prefix, not UUID)",
        "n": "number",
        "s": "status",
        "y": "type",
        "p": "priority",
        "ti": "title",
        "nm": "name",
        "b": "body",
        "c": "created"
      },
      "enums": {
        "s": { "b": "backlog", "t": "todo", "i": "in_progress", "r": "review", "d": "done", "x": "cancelled" },
        "y": { "f": "feature", "b": "bug", "r": "refactor", "d": "docs", "i": "infra" }
      },
      "defaults": { "p": "3", "y": "f" },
      "example": "t;i:9c92;n:241;s:d;ti:kovasite skill;rp;r;i:ce37;nm:pr;/r;r;i:94be;nm:kovanex-server;/r;/rp;/t"
    },
    "game_frame_v1": {
      "description": "Tormund GM output (UFN v1 profile). Flat, no nesting.",
      "field_separator": " ; ",
      "default_frame": "n",
      "keys": {
        "f": "frame type",
        "@": "agent role (entity_id[|name])",
        "^": "patient role",
        "~": "location role",
        "#": "npc present",
        "*": "item referenced",
        "+": "instrument used",
        "s": "sounds (comma list)",
        "m": "smells (comma list)",
        "l": "light tag",
        "c": "weather tag",
        ">": "state change (verb target [| data])"
      },
      "enums": {
        "f": { "n": "narrate", "d": "dialogue", "a": "action", "w": "warn", "dsc": "describe", "em": "emote", "tr": "trade", "q": "quest", "sys": "system" },
        ">": { "mv": "move", "tk": "take", "eq": "equip", "dr": "drop", "tlk": "talk", "atk": "attack", "use": "use", "tr": "travel", "sv": "save_character", "svn": "save_npc", "em": "emote" },
        "l": ["dim", "bright", "torchlit", "moonlit", "dusk", "noon", "night", "dawn"],
        "c": ["clear", "fog", "rain", "storm", "snow", "wind", "overcast", "hot"]
      },
      "example": "f:a ; @:player|Grond ; ^:shadow_figure|dark figure ; ~:tavern|Rusty Mug ; >:atk shadow_figure ::: The air freezes for one long second..."
    }
  }
}
