kova ecosystemI. Podtsebnev
Request for Comments: UFN-2Kovanex
Obsoletes: UFN-1 (game profile)June 2026
Category: Standards Track
Status: Stable (locked)

UFN — USE Frame Notation

A flat, single-line, token-economical notation for LLM structured output

Status of This Memo

This document specifies a Standards Track notation for the kova ecosystem and requests discussion and suggestions for improvements. UFN v2 is the current, stable (locked) revision. It generalizes the original game-frame profile (UFN v1, see Section 10) into a domain-agnostic, nesting-capable wire format for the agent edge.

Distribution of this memo is unlimited. The notation is published openly: UFN is a frame, not a moat — it carries no proprietary semantics of its own.

Abstract

UFN (USE Frame Notation) is a one-line, dictionary-driven notation for structured output produced by Large Language Models. Where JSON spends a per-token tax on { } [ ] " , on every structured reply, UFN moves structure into named, self-delimiting tags and a tight separator, so a model spends its tokens on content, recovers cleanly from truncation, and streams its header before its prose.

UFN is intended for the edge between a model and a consumer — not for storage. Storage stays JSON; UFN is the token-economical wire format an LLM emits and a parser ingests. On a representative task list it is approximately 59% smaller than compact JSON on the structural portion, raises parse-failure-on-truncation from JSON's total loss to a usable partial frame, and cuts time-to-first-content from tens of seconds to roughly 1.5 seconds by streaming the header ahead of the prose.

Copyright © 2026 Kovanex / I. Podtsebnev. This specification is licensed under the Apache License, Version 2.0. Implementations are unrestricted.

Table of Contents

1.Introduction

UFN is the smallest legal notation that gives a producer tagged records plus a free prose tail on a single line. It is what git log --pretty and mail headers do, conceptually: a tight set of keyed records, no nesting ceremony, robust to a line that gets cut short. The conceptual model is 1990s SMS / ICQ / IRC compression — sender and receiver share a tiny convention dictionary, every byte counts, and a partial message still makes sense.

1.1.Motivation

JSON was the obvious first choice for LLM structured output: models are well trained on it and every language ships a parser. In production over local models, three costs become visible:

1.2.Requirements Language

The key words MUST, MUST NOT, REQUIRED, SHALL, SHOULD, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in BCP 14 (RFC 2119) when, and only when, they appear in all capitals.

1.3.Design Scope

Normative scope UFN is a wire/edge format, not a storage format. Producers and consumers SHOULD keep their system of record in JSON (or any structured store) and emit UFN only at the LLM edge — model output and tool I/O. UFN saves structure, never content: a UUID or a long title is incompressible.

2.Notation Model

Everything is one line, ;-separated. A token is classified by its shape alone — there are exactly three kinds:

ShapeKindMeaning
key:value (contains :)field A scalar record. Split on the first :; the value may itself contain :.
acr (no :, no leading /)scope open Opens a container of class acr.
/scope close Closes the nearest open scope (a stack). /acr (named) is an optional resync mode.

2.2.Fields

A field is key:value. The key MUST come from the shared dictionary; the value is free text up to the next field separator. The field separator is ; (tight, no surrounding spaces) at the general edge. (The v1 game profile uses ; with surrounding spaces; see Section 10.)

2.3.Scopes and Nesting

A bare token that is not a field and does not start with / opens a scope; a bare / closes the top of the stack. This is how UFN expresses nesting without JSON's {}/[] brittleness: an unclosed scope at end-of-line is simply closed implicitly, so a truncated object is still usable.

2.4.Arrays vs Objects

A class is array-typed or object-typed by the dictionary, not by punctuation. An array scope holds repeated item scopes. There is no separate array syntax to get wrong.

2.5.Prose Tail

Everything after the first top-level ::: (triple colon with surrounding spaces — the one readability exception) is verbatim prose to end-of-line: no escaping, no structure. This is the streaming seam — a producer emits the header, then streams prose token by token. The prose tail is top-level only; nested free text is carried as a field.

3.Grammar (ABNF)

line     = element *( ";" element ) [ " ::: " prose ]
element  = field / open / close
field    = key ":" value
open     = acr                  ; bare token, no ":", not starting "/"
close    = "/" [ acr ]          ; bare "/" closes top-of-stack;
                                ; named "/acr" = robustness/resync mode
key      = token                ; from the shared dictionary
acr      = token                ; class name from the shared dictionary
value    = *( vchar / escape )  ; "\;" "\/" "\\" escaped (Section 4)
prose    = *VCHAR               ; verbatim to end-of-line
Figure 1: UFN v2 grammar (ABNF-style).

4.Literals and Escaping

This section is normative and mandatory. Correct round-tripping depends on exactly these rules and no others.

4.1.Reserved Control Tokens

Only the following are reserved. Everything else is data.

;
Field separator.
:
Key/value separator — the first : in a field only.
/
Scope close, when it is a token's leading character.
\
Escape character.
:::
Prose-tail separator (with surrounding spaces).

4.2.Escape Sequences

A backslash escapes a control character that must appear literally in data. There are exactly three sequences; an implementation MUST NOT define others:

SequenceProducesUse when
\;literal ;a value contains a semicolon
\/literal leading /a value would otherwise be read as a scope close
\\literal \a value contains a backslash

4.3.What Does Not Require Escaping

Deliberately, almost nothing needs escaping — this keeps producers reliable:

Contrast with JSON JSON forces \" on every embedded quote and \\n on every newline — the exact boundary where models trip on long prose. UFN's prose tail removes that failure mode entirely.

4.4.Scalar Lists

A short list of scalar values is carried inside one value, comma-separated, e.g. lb:bug,infra. No scope is opened for the common small-list case.

4.5.Display Names

A reference value MAY carry a human-readable name after a literal |: @:player|Grond. If the name is omitted, the consumer resolves it from its catalogue. For improvised or unknown entities the producer MUST include the name.

5.Fail-Soft Processing

UFN keeps JSON's brittleness out. A conforming parser MUST:

ConditionRecovery
Unknown key or classSkip the token, continue.
Scope still open at end-of-lineClose it implicitly (truncation-safe; partial object is usable).
/acr with no matching openIgnore.
No tokens recognized at allTreat the whole line as prose.
Empty value after a keySkip the field.

Principle: a partial frame is always better than a parse error. A syntactic failure MUST NOT trigger a consumer's hard fallback; only genuine semantic failure should.

6.Dictionaries

UFN is dictionary-driven: senders and receivers share a token dictionary verbatim — no inference, no fuzzy matching. Object/array classes and field keys are per-domain and declared by the producer.

Acronyms and markers MAY be letters, symbols, or sequences; only the control tokens of Section 4.1 are reserved.

7.Encoding Economy

UFN saves structure, not content. The levers below are ranked by measured impact on a 50-task list (against compact JSON at 8201 characters).

7.1.Levers, Ranked by Impact

#LeverImpactNotes
1Short ids, not UUIDs−37% Emit an 8-hex prefix (ce3760ed), not the 36-char UUID. Bigger than all dictionary tweaks combined.
2Enum value codes + 1-char keys−11…16% s:in_progresss:i, ty:featurey:f. Pays most on lists.
3Anonymous close /−16%* On nested output. Stack-based; /acr only for resync.
4Omit defaults A field equal to its declared default is dropped (p:3, y:f).

* on the nested portion. Combined, these reach approximately −59% vs compact JSON and about −44% vs naive UFN.

7.2.Measured Results

MetricJSONUFNImprovement
Header tokens (4-field frame)~110~3865% fewer
Short response (60-token prose)1709842% smaller
Long response (600-token prose)71063810% smaller
50-task list, structure~59% smaller vs compact JSON
Parse failure on truncationtotal losspartial framealways recoverable
Time to first visible content30–60 s~1.5 s20–40× faster

The shorter the response, the bigger the win — structural overhead amortizes across less content. Quest updates, warnings, and tool acknowledgements (the most frequent outputs) see the largest savings.

7.3.Latency and Robustness

UFN splits naturally into two phases: a header (~38 tokens, arriving in ~1.5 s on a 25 tok/s decoder) and a streamed prose tail. The consumer can set scene/type/roles from the header while prose appears live, instead of waiting tens of seconds for a complete, parseable JSON document.

7.4.Ligatures

Atomic tokens (keys, enum codes) are tier 1. Ligatures are tier 2: one dictionary token that expands to a combination — the way ROFL or :-) carried whole phrases or states, not glyphs.

A producer SHOULD encode only the Pareto-frequent combinations and SHOULD declare the ligatures it used so a generic receiver can expand them. Because both producer and consumer are LLMs, the shorthand vocabulary can be far richer than IRC ever was, and savings compound exactly where structured output repeats.

Honest baseline The fair comparison is compact JSON (no indentation, empties dropped). Against a bloated JSON (pretty-printed, all empty fields) UFN looks like ~−89%, but the cheap dual win is to make the JSON side compact too — then UFN's real, structural advantage is ~−59%. This document quotes the fair baseline.

8.Recommendations

Use UFN when…Use JSON when…
Output is LLM-generated, especially on local modelsData is machine-generated and machine-consumed
You mix metadata with long proseData is purely structured, deeply nested
You stream and want time-to-first-content lowYou need a one-shot document with a fixed schema
Truncation is a real riskYou are storing the system of record

Operational guidance:

9.Examples

9.1.Flat record (v1-style)

t:241;s:done;ty:feature;ti:kovasite skill

9.2.Nested — a task with a repos array

t;id:9c92;n:241;s:done;ti:kovasite skill;rp;r;id:ce37;nm:pr;/r;r;id:94be;nm:kovanex-server;/r;/rp;/t

Parse: t…/t is an object task; rp…/rp an array of repos; each r…/r an item object.

9.3.Header plus prose tail (game frame)

f:a ; @:player|Grond ; ^:shadow_figure|dark figure ; ~:tavern|Rusty Mug ; s:steel clash, muffled gasp ; l:torchlit ; c:clear ; >:atk shadow_figure ::: The air freezes for one long second...

One line. The header is the structure; everything after ::: is verbatim prose the consumer streams as it arrives.

9.4.The same frame in JSON, for comparison

{"frame":"action","roles":[{"type":"agent","entity_id":"player","name":"Grond"},
{"type":"patient","entity_id":"shadow_figure","name":"dark figure"},
{"type":"location","entity_id":"tavern","name":"Rusty Mug"}],
"atmosphere":{"sounds":["steel clash","muffled gasp"],"light":"torchlit","weather":"clear"},
"state_changes":[{"type":"attack","target":"shadow_figure"}],"prose":"The air freezes..."}

~110 structural tokens against UFN's ~38, and a single missing brace renders all of it unparseable.

10.Versioning

UFN v1 (game profile)UFN v2 (general)
OriginTormund GM output (replaces a JSON HybridResponse)Generalized for the agent edge
ShapeFlat: header records + prose tail, no nestingNesting-capable via scope open/close
Field separator ; (spaces); (tight)
DictionaryFixed game dictionary (frame/role/atmosphere)Per-domain, producer-declared
StatusLocked (v1.x adds only)Stable (locked)

v2 is backward-compatible in spirit: a flat v1 line is a valid v2 line with no open scopes. v2 adds nesting, the tight separator, enum/ligature economy, and the domain-agnostic dictionary model. The original "is UFN worth it" question resolved yes — flat v1 roughly matched JSON, but v2 nesting plus ligatures win decisively.

11.Implementations

kovanex-server/internal/ufn
v2 encoder + parser, nesting, ligatures (reference implementation).
kovanex-server/internal/ufnpb
Protobuf → UFN, shared by the ctl CLI and the MCP server.
tormund/internal/game
v1 game-frame producer/parser (ufn.go, ufn_bridge.go, bundle_ufn.go).
prompt-a-porte/internal/ufn
A second independent implementation.

Shipped surfaces: kovanex-ctl --ufn (list economy + nested get) and MCP tool output in UFN v2 (with a compact-JSON fallback).

12.Conformance (for Agents)

UFN's producers and consumers are LLM agents. The standard is published in agent-consumable form: a curated /llms.txt, the full spec as plain text at /llms-full.txt (single-fetch ingestion), and a machine-readable /ufn.dict.json starter dictionary.

12.1.A conforming producer

12.2.A conforming consumer (parser)

13.References

Normative.

Informative.


Author's Address
I. Podtsebnev — Kovanex — [email protected]https://kovanex.dev