CURSO/0 semantic record profile
Naming note: the public product is Cursors and its home is
curso.rs.CURSO/0is retained here only as the stable v0 wire/profile identifier.
Status: executable draft. This document describes the current canonical semantic record format. It is not a frozen standard.
Canonical value encoding
Every value begins with one tag byte:
| Tag | Type | Payload |
|---|---|---|
00 |
null | none |
01 |
false | none |
02 |
true | none |
10 |
unsigned integer | minimal unsigned LEB128 |
11 |
negative integer | minimal unsigned LEB128 of -1 - n |
20 |
bytes | varuint length, then bytes |
21 |
UTF-8 text | varuint byte length, then strict UTF-8 |
30 |
list | varuint item count, then encoded items |
31 |
record | varuint pair count, then text keys and values |
Record keys are unique text values sorted lexicographically by their UTF-8 bytes. Floating-point values, undefined values, platform objects, and indefinite lengths are not part of CURSO/0.
Decoders must reject non-minimal integers, invalid UTF-8, duplicate or incorrectly ordered record keys, unknown semantic tags, trailing bytes, and excessive sizes before allocation.
What is actually committed
CURSO/0 canonical values are the byte representation used for signed semantic records. They are the layer whose stability matters for hashes, signatures, cursor IDs, capability grants, and receipts.
Other encodings remain intentionally separate:
- bencoding belongs to BitTorrent metadata;
- Cap'n Web is being evaluated for live browser/Worker object-capability RPC and promise pipelining;
- SQLite is operational/local/remote state, not a network serialization;
- TIP-inspired TLV islands are an implementation experiment only.
A .torrent being bencoded does not imply that mailbox envelopes or continuations become bencoded dictionaries. Likewise, an efficient TLV prototype must not become the Cursors wire format merely because code exists for it.
TLV/island experiment: not the public wire contract
protocol/islands.js and protocol/cloud-envelope.js are experimental packing code inspired by kedji/tip's independently bounded parcel idea. They are useful for measuring storage/framing overhead and bounded parsing, but they are not currently a required Cursors carrier format, negotiation format, signature format, or compatibility promise.
The current experiment uses short canonical lengths, raw 20-byte mailbox handles, and network-byte-order fixed integers. Those choices remain subject to removal or replacement after comparison with:
- plain CURSO canonical records;
- Cap'n Web's JSON-derived RPC representation plus compression;
- direct SQLite row storage;
- a future segmented/native frame if native and embedded bodies show a measured need.
No new endpoint should require application/cursors-islands, and no external implementation should rely on the current island type registry.
This is deliberate. Cursors needs evidence before acquiring another forever-format.
When a framing layer would earn its keep
A separate frame becomes justified only if measurements show meaningful wins for several of these at once:
- routers skipping fields without decoding semantic records;
- bounded allocation before decoding payloads;
- scatter/gather or immutable out-of-line blocks;
- low-copy native forwarding;
- constrained embedded parsers;
- stable extension islands that do not change signed semantic meaning;
- enough byte savings to matter after ordinary HTTP/WebSocket compression.
Until then, TLV code is research machinery.
Domain separation
Signature and digest input is:
UTF8(domain) || 0x00 || canonical(payload)
Current identifiers use sha256: followed by lowercase hexadecimal. Current signatures use Ed25519. Every operation has a distinct curso/.../v0 domain.
Cursor seal
curso/cursor/v0 signs the normalized cursor payload described in docs/crypto-cursors.md.
The cursor ID hashes a record containing payload, author identity, raw public key, and signature under curso/cursor-record/v0.
Parent, input, output, grant, and receipt lists are sorted and duplicate-free. Parent order therefore denotes a set, not an execution order. Programs that require ordered inputs encode the order in a referenced input object.
Capability seal
curso/capability-grant/v0 signs one grant. curso/capability-split/v0 signs an allocation vector. Resource containment in v0 uses exact equality or slash-delimited descendants of a normalized curso: resource string.
Endianness and low-copy work
CURSO/0 variable integers are minimal LEB128 and therefore do not expose a fixed-width byte order for ordinary semantic integers.
If a future native/embedded framing profile adds fixed offsets, lengths, counters, or segment tables, network byte order remains a sensible candidate, but it must be justified with cross-language fixtures and measurements rather than preference alone.
Likewise, Cursors should promise zero-copy-friendly structure, not zero copies. Browser crypto APIs, storage engines, HTTP stacks, and WebRTC implementations may copy bytes regardless of how aesthetically pleasing our offsets are.
Cap'n Web experiment
Cap'n Web is currently the higher-priority transport experiment because it already provides browser/Worker compatibility, object capabilities, HTTP batching, WebSocket sessions, MessagePort support, streaming, and promise pipelining.
The key architectural separation is:
CURSO canonical records = durable signed meaning
Cap'n Web = live capability invocation
cursor/checkpoint = recovery when live invocation disappears
See the public Cap'n Web, promise pipelining, and Cursors guide for the intended experiment.
Questions before any v1 wire change
- What real byte/CPU/latency problem exists after compression and batching?
- Which fields must intermediaries inspect without application plaintext?
- Which data should remain content-addressed and out-of-line?
- Can the same logical operations work over Cap'n Web, WebRTC, LAN, and offline mailbox replay?
- Does an embedded/native implementation actually need fixed segment tables?
- Can an old implementation safely skip new transport fields without accepting unknown signed semantics?
- Do fuzzing and cross-language vectors show one canonical representation?
Until those questions have measured answers, CURSO/0 remains intentionally small.