The eternalink promise

kaiv’s registries bind a name to bytes exactly once, forever. On what breaks when registries can change their minds, a validator standing at the door, names that outlive their publishers — and why the promise begins by refusing to be made early.


On March 22, 2016, one author unpublished eleven lines of JavaScript called left-pad, and build pipelines across the industry stopped dead — React’s among them. npm restored the package within hours and tightened its unpublish policy, but the restoration was the smaller half of the lesson. The larger half: every build that broke had been holding a reference whose meaning could change, and nobody had priced that in. The package didn’t fail; the reference did. It had always been revocable. Someone finally revoked it.

Mutable references are a quiet tax on everything downstream. A dependency you audited last year has to be re-audited, because its name may resolve differently now. A schema URL in a config is a hope, not a fact. Documentation links rot, latest tags move, registries yank, accounts get deleted and take their artifacts with them. None of these are outages; they are the system working as designed — the design just never promised that a name would keep meaning what it meant.

kaiv’s registries make exactly that promise, and are built backwards from it.

A name, bound once

The kaiv ecosystem runs on four registries: type libraries (ktaiv.com, serving .taiv), schemas (ksaiv.com), unit definitions (kfaiv.com), and documents (kdaiv.com). For the three name-addressed registries the rule has no fine print: the URL is the storage key, a path is published to exactly once, and the published artifact is frozen forever. No edits. No deletions. No retractions. And — stricter than any package registry — no versions: there is no “latest”, no version selector, no range resolution, because a name is bound to bytes once and that binding is the meaning. Evolution happens the only honest way it can: a new version is a new name, and the old name keeps meaning what it always meant. The document store goes one step further and addresses .daiv content by its BLAKE3 hash — there the name isn’t just bound to the bytes, it is derived from them.

These URLs are called eternalinks, and the intended lifetime is in the word. They outlive their publishers by design: deleting your account stops your tokens from minting, but everything you published stays resolvable — permanence attaches to the artifact, not to you. (The one concession, on the document store only: visibility of a private document can be flipped — the GDPR posture — but the URL is then retired, never reassigned. No path is ever reclaimed, ever.)

A registry artifact, concretely, is about as unassuming as infrastructure gets — a plain text file at a URL:

$ curl -s https://t.kaiv.io/std/net.taiv | head -10
.!taiv 1 std/net

// Network identifiers. Patterns are pinned to their defining
// documents; the \x27 escape carries the apostrophe that RFC 3986
// sub-delims and the e-mail grammar admit but a pattern body
// cannot contain literally.

// URI — RFC 3986 generic syntax, exactly: scheme, optional
// authority (userinfo, reg-name / IPv4 / IP-literal host, port),
// the path forms, query, fragment, percent-encoding.

Reads are public and unauthenticated — the name registries don’t even have a read scope. No API to version, no negotiation: GET returns the bytes, and returns the same bytes every time:

$ curl -s https://t.kaiv.io/std/net.taiv | sha256sum
87757da79c1e5926b86115589a24980b824409c840cd3cf897b67db4e54eaf74  -
$ curl -s https://t.kaiv.io/std/net.taiv | sha256sum
87757da79c1e5926b86115589a24980b824409c840cd3cf897b67db4e54eaf74  -

What forever buys

Schemas become contracts instead of coordinates. A kaiv document declares the schema it validates against by name; that name resolves to an artifact that cannot drift. Validate the document today and in twenty years and the inputs are the same bytes — the data, the compiled schema, both plain text, both frozen. There is no “the schema changed under me,” because changing a published schema is not an operation the system has. For the safety-critical deployments of the previous article, this is load-bearing: the .csaiv your audit certified against is immutable not by your process discipline but by the registry’s construction.

Caches never expire. An immutable artifact is served with Cache-Control: immutable and cached without revalidation — there is nothing to revalidate; a 304 conversation with a frozen object is wasted motion. The reference toolchain caches fetched artifacts on first use and never asks again; offline operation is not a degraded mode but the same mode with the network calls already answered. Taken to its limit, the cache moves into the binary itself — the standard libraries ship embedded in the toolchain, so this works with the network switched off entirely:

$ printf '.!kaiv\n.!types std/enc\n\n&bin\nid=deadbeef\n' | KAIV_OFFLINE=1 kaiv build
.!daiv
!std/enc/bin'::id=deadbeef

Look at the canonical line: the type is !std/enc/bin, a logical path. Where the bytes came from — network, cache, embedded copy — leaves no trace, because with immutable artifacts every source is equivalent. Identity is the name; resolution is a deployment detail. (The certified runtime, per the previous article, resolves nothing at all: it reads .daiv and .csaiv, both already local, both already frozen.)

Enforced in depth

A forever promise is only as good as its enforcement, so the write path is built like a lock with two independent bolts. Publishing walks five steps: authenticate; verify you own the namespace and that the path has never been published; upload into a pending/ staging prefix via a pre-signed URL; pass the validation gate; promote to the canonical path. The “never been published” check is the first bolt — the broker refuses to issue an upload for a path that exists. The second bolt is in the storage layer itself: promotion uses a conditional write (If-None-Match: *) that the object store rejects if anything already sits at the canonical path. Either bolt alone would keep the promise; together they close every race window between check and write. There is no code path — not an admin tool, not a support script — that overwrites a published artifact, because the storage substrate is write-once and the eternalink guarantee is enforced below the application.

And one more gate, before promotion: nothing invalid ever gets an eternalink. Every deposited artifact is validated before its URL goes live — by the reference validator itself, the same open-source crate the toolchain runs, compiled to WebAssembly inside the registry’s edge worker. The validator at the door is byte-for-byte the validator on your laptop, so “every artifact resolvable from a registry is schema-valid by construction” is not a service-level aspiration but a property of the write path. An eternalink is a permanent claim, and the registry refuses to make a permanent claim about malformed bytes.

Names without squatting

Bind names forever and you inherit a classic problem: what stops someone from claiming every good name on day one and sitting on them? The answer is that permanence attaches to artifacts, not claims. A name is permanently burned only by its first publish; a claimed namespace with zero publishes lapses after a twelve-month grace period and is released — which breaks no eternalink, because an eternalink never existed for it. Namespaces are eight characters or longer — shorter names are reserved by the system, which is why the standard libraries live under compact names like std and hub while everyone else’s are unmistakably theirs. And a domain you demonstrably control — proven by a challenge code in a DNS TXT record — can be claimed as a namespace verbatim, dot and all: acme.com/…, syntactically unmistakable from ordinary names, with proof of control beating first-come-first-served for the names that mean something. The policy is written in from day one, on the theory that retrofitting expiry after names are parked is a fight nobody wins.

The promise not yet made

Here is the strictest clause, and the easiest to miss: the promise is not yet in force. Through the current alpha series, artifacts are served from the kaiv.io staging subdomains — t.kaiv.io for types, s.kaiv.io for schemas, f.kaiv.io for units — and no permanence is promised there: alpha artifacts may still change, and the alpha registries may be reset. Even std/net, whose URI pattern you saw above, might still be revised before it freezes. The k*aiv.com production domains stay dormant until beta, and the write-once, read-forever contract begins exactly there. The staging hosts already serve the same Cache-Control: immutable headers and run the same write-once gate — the machinery of the promise is fully built and rehearsing; what alpha withholds is only the commitment itself.

This is not hedging; it is the promise taken seriously. A forever guarantee cannot be issued incrementally, walked back, or patched — the first artifact published under it is as permanent as the millionth. The only way to keep a promise like that is to not make it one day earlier than you can keep it. Eternity starts at beta; until then, kaiv says so in plain text.


kaiv is an immutable structural type system for data at rest. The User Manual covers registries and resolution from the user’s side; the specification defines the resolution layers and the alpha-hosting policy; the playground runs the toolchain — with the standard libraries embedded, eternalink-style — in your browser.