Status: Last Call · Date: 2026-07-17 · Editors: Untilum project — hello@untilum.com
Part of the TSP RFC series; see the series index for the Last Call window and how to comment. The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in this document are to be interpreted as described in BCP 14 [RFC 2119] [RFC 8174] when, and only when, they appear in all capitals.
This document specifies storage independence for Untilum capsules: a capsule is a document, not a record in any provider’s system, and opening works from raw capsule bytes regardless of where — or whether — they were ever stored. It defines the normative rules R1–R5 (locators advisory, digests authoritative; storage sees only public data; the storage list mutable and appendable), the storage-adapter contract, and the consequences for 50–100-year retention.
A capsule is a document, not a record in someone’s system. Storage is where capsule bytes happen to sit — never part of what a capsule is. The conformance rule, inherited from TSP v1 and unchanged forever:
Opening MUST work from raw capsule bytes regardless of where — or whether — they were ever stored.
ar://<txid>, memory://<id>, later ipfs://, https://, …) is a hint about where bytes might be found. Every implementation MUST byte-hash-verify fetched data — payload.hash for ciphertext, dataHash for storage entries — before use, and MUST treat a hash mismatch as failure, not fallback.storage: [] lives outside the signed/hashed immutable core, precisely so replicas can be appended for the capsule’s whole lifetime without invalidating signatures. Nothing in it is a claim; claims come from digests."<scheme>://<ref>" in payload.ciphertext; payload.hash (inside the immutable core) is what actually binds the bytes. A substituted blob fails R1 before any decryption is attempted.type — adapter family, e.g. "arweave" | "memory"
scheme — ref scheme it serves, e.g. "ar" for "ar://<txid>"
put(bytes, opts) -> StorageEntry (must include dataHash of what was stored)
get(ref) -> bytes (caller verifies; adapter SHOULD too)
verify(entry) -> { ok, error? } (re-fetch + digest comparison — nothing more)
The reference TypeScript interface: tsp-v1.md §10.1.5.
An adapter that cannot honestly implement verify as fetch-and-compare (e.g. it would have to trust a provider’s attestation) does not conform.
Because of R1–R5, the 50–100-year storage strategy is additive: seed the capsule anywhere permanent, append replicas as the landscape shifts (new networks, institutional archives, a USB stick in a drawer), and let any surviving copy — verified by digest — suffice. Storage death is an availability event (RFC-0002 §T1), never a confidentiality or integrity event.
Rules R1 and R2 are what reduce a fully compromised storage provider (RFC-0002 §T1) to a mere availability event: every fetched byte is digest-verified before use, and adapters only ever see ciphertext and public parameters. Skipping digest verification, treating a hash mismatch as a soft fallback, or letting an adapter observe plaintext or key material reintroduces the confidentiality and integrity losses this document exists to exclude. The mutable, unauthenticated storage list (R3) is safe precisely because nothing in it is a claim — implementations MUST NOT derive any trust from it.
../spec/tsp-v1.md — §10.1.5 storage adapter interface.Untilum project — Editors of the TSP RFC series Email: hello@untilum.com · Issues: https://github.com/untilum/protocol/issues
| Date | Status | Change |
|---|---|---|
| 2026-07-07 | Draft | Initial version. |
| 2026-07-17 | Last Call | Publication pass: BCP 14 boilerplate, Abstract, Security Considerations, References, Revision History added; no normative changes. Entered Last Call per RFC-0008 §4. |