The kaiv ecosystem
Four registries, one validator compiled into everything, and a data store that refuses invalid files. On the network a format builds around itself — and what falls out when every piece of it keeps the same promises.
A data format, by itself, is a grammar and a document. What you actually live with is the ecosystem — the registries that serve the artifacts, the validators that disagree with each other in interesting ways, the tools that half-support the spec, the schema languages bolted on after the fact. JSON the grammar fits on a napkin; JSON the ecosystem is a dozen subtly incompatible parsers, four schema languages, and a validation story that depends on who’s asking.
kaiv ships as an ecosystem on purpose, and it is deliberately small: four registries with one address scheme, one validator compiled into every checkpoint, and — because of the regular grammar — every line-oriented tool you already own.
Four registries, one address scheme
Each kind of artifact has a home: type libraries on
ktaiv.com (.taiv), schemas on ksaiv.com (.saiv),
unit definitions on kfaiv.com (.faiv — the custom units
beyond the built-in SI set), and data files themselves on
kdaiv.com (.kaiv/.raiv/.daiv). One namespace claim
spans all four; a name, once published, is bound to its bytes
forever. During the
current alpha the registries live on the kaiv.io staging
subdomains (t., s., f., d.), with the production
domains dormant until the eternity contract switches on at
beta.
Reads are anonymous HTTP; the artifact is a text file:
$ curl -s https://t.kaiv.io/std/net.taiv | head -3
.!taiv 1 std/net
// Network identifiers. Patterns are pinned to their defining
That is the entire read-side infrastructure story. No SDK, no lockfile format, no resolution algorithm with a versions matrix — a name maps to one URL which serves one immutable text file that the six-rule classifier reads like any other.
One validator, compiled into everything
Here is the design decision this article turns on. The kaiv
reference validator — the open-source kaiv crate — is not
one implementation among several. It is:
- the CLI on your laptop (
cargo install kaiv-cli), - the playground in your browser (demo.kaiv.io — the same crate compiled to WebAssembly, running entirely client-side), and
- the gate in the registries’ edge workers — the write path compiles the crate in, so every deposit is validated by it before an eternalink goes live.
The reference validator and the platform validator are the same code, byte for byte. A whole genre of ecosystem grief disappears with that sentence: there is no “validates locally, rejected by the server,” no “the registry runs an older draft,” no reference implementation drifting from production reality. The verdict you get in your shell is the verdict the edge will reach, because it is not an equivalent check — it is the same check.
Schemas are the connective tissue
What the pieces exchange is contracts. A kaiv schema answers the question most formats punt — what does absence mean? — and the ecosystem enforces the answer end to end. A schema cannot even compile while dodging it:
$ printf '.!saiv 1 acme/deploy\n\nhost=\n!int\nreplicas?=\n' > bad.saiv
$ kaiv schema bad.saiv
kaiv: SchemaOptionalWithoutDefaultError
Optional means answered — a default, or an explicit !null
alternative:
$ cat deploy.saiv
.!saiv 1 acme/deploy
host=
!int
replicas?=2
!null|str
canary?=
And when a document declares this schema, the build materializes the answers into the artifact — the author writes one field, the document carries three:
$ mkdir -p acme
$ kaiv schema deploy.saiv > acme/deploy.csaiv
$ printf '.!kaiv\n.!registry acme=.\n.!schema:acme/deploy\n\nhost=edge-1\n' | kaiv build
.!daiv
.!registry acme=.
.!schema:acme/deploy
!str'::host=edge-1
!str'::replicas=2
!null'::canary=
Validated kaiv is total: defaults live in the artifact,
once, instead of in every consumer’s config.get("retries", 3). The validator then holds documents to it in strict
lockstep — and because validation is the parallel scan of the
regular-grammar
article, a
violation names the exact line where the two files disagreed:
$ printf '.!kaiv\nreplicas=4\n' | kaiv build > nohost.daiv
$ kaiv validate nohost.daiv deploy.saiv
kaiv: RequiredFieldSchemaError: declared field ::host missing (scan reached ::replicas) (line 2)
Contracts scale up from single values, too. An array of namespaces can graduate to a table — unique keys, foreign keys, cardinality — and the relational essentials hold in a plain text file:
$ cat cluster.saiv
.!saiv 1 acme/cluster
[/@nodes name=! min=1]
name=
!int
cpus=
[]
[/@volumes node=/@nodes/*::name]
node=
!int
gb=
[]
$ printf '/@nodes+:=name=a1|cpus=8\n/@volumes+:=node=ghost|gb=100\n' | kaiv build > fk.daiv
$ kaiv validate fk.daiv cluster.saiv
kaiv: ReferentialIntegrityError: /@volumes: node=ghost has no match in /@nodes/*::name
A data store with a bouncer
The registries do not merely serve these contracts — they
enforce them at the door. kdaiv.com is the ecosystem’s file
repository for data files, and it has a built-in validation
gate: every deposited file is validated against its declared
schema — by that same compiled-in reference crate — before its
URL goes live. A file that doesn’t validate doesn’t get
stored. There is no --force, no admin bypass, no “upload now,
fix later”: the write path and the validator are one thing.
And the store is immutable by
design like its
siblings — deposits are write-once, with canonical .daiv
content addressed by its own hash.
Stack the guarantees and something uncommon falls out. The file was validated at the door, by the same validator you run. The schema it was validated against can never change. The validation itself is a constant-memory scan any conforming implementation reproduces exactly. So for everything the store serves, schema-validity is a permanent property — established once at write, true at every read, forever, with no reader ever re-checking. The registry isn’t a bucket that happens to hold kaiv; it is infrastructure that structurally cannot serve an invalid document.
And every tool you already own
The ecosystem’s outer ring was never written for kaiv at all.
Because canonical files are flat, self-contained lines,
grep is a subtree selector, awk is an aggregator, diff
is a semantic differ — the regular-grammar
article works
these transcripts. And for the formats everyone else speaks,
the toolchain is a hub: JSON, YAML, TOML, XML, CBOR, Avro,
Protocol Buffers, ASN.1, GraphQL in and out, with schema
conversion (JSON Schema, XSD, proto, Avro schemas) and
inference beside it — all of it in the CLI, and all of it in
the browser at demo.kaiv.io, where the
wasm build of the same crate does every one of these
operations client-side.
That is the whole ecosystem: registries that cannot drift, a validator that cannot disagree with itself, contracts the infrastructure itself enforces, and a grammar plain enough that forty years of Unix tooling joined the ecosystem retroactively. Small on purpose — and every piece keeping the same promises.
kaiv is an immutable structural type system for data at rest. The User Manual covers schemas, registries, and the toolchain hands-on; the specification defines resolution, requiredness, and the Level 2 table pass precisely; the playground runs the whole toolchain — including every example above — in your browser.
Going deeper
Each piece of this picture earns its own page, one aspect at a time, every claim a verified transcript. The first:
- Publish one edge —
.maivmappings and microschemas: the mapping file as a statically validated name-to-name rewrite table, composition as a join on namepaths, the hub network effect, and derived registry addresses. - Start from the data — schemas inferred from examples and tightened by hand, compiled to a constant-memory contract, hub extension as a door into the graph, and foreign schemas converted as a sound weakening.
- Types you can link to — named types as published, frozen, fully-qualified citizens: resolved by address, lowered into validators, carried by name in the data itself.
- Ten of what? — units as part of the
type: curated and canonicalized, byte-compared and never
silently converted, bits and bytes first-class,
KBrefused as ambiguous, and custom unit packages on the registry.