Version Sets
A version set is an immutable manifest that ties together every artifact making up a deployable version of a package: the worker bundle, optional static assets, a D1 migration plan, Durable Object migrations, an environment manifest, an infra plan, and an optional grants reference.
The version_set_store factory wraps define_store with the right codec, partitioning, and a small API surface (put, lineage, promote) that captures the semantics deployment orchestrators care about.
Manifest shape
import { VersionSetManifestSchema, type VersionSetManifest } from '@f0rbit/corpus'
// VersionSetManifestSchema is a Zod schema; VersionSetManifest is its type.//// {// package: string// git_sha: string // 40-char sha// created_at: string // ISO-8601 datetime// builds: {// worker: { artifact_ref, size_bytes, compatibility_date }// assets?: { artifact_ref?, version_affinity: 'pinned' | 'none' }// }// migrations: {// d1_plan_ref?: string// do_migrations: Array<{ class_name, tag, kind }>// }// env_manifest_ref: string// infra_plan_ref: string// grants_ref?: string// }All cross-store references (artifact_ref, d1_plan_ref, env_manifest_ref, infra_plan_ref, grants_ref) are corpus versions in the form <store>/<hash> — the orchestrator resolves them at deploy time.
Creating a store
import { create_memory_backend, version_set_store } from '@f0rbit/corpus'
const backend = create_memory_backend()const version_sets = version_set_store(backend)Optional opts.id overrides the default 'version-sets' store id; opts.description is forwarded to the underlying StoreDefinition.
Putting a manifest
const put = await version_sets.put({ package: 'anthropic-search', git_sha: '0123456789abcdef0123456789abcdef01234567', created_at: new Date().toISOString(), builds: { worker: { artifact_ref: 'worker-bundles/abc', size_bytes: 12345, compatibility_date: '2025-05-01', }, }, migrations: { do_migrations: [] }, env_manifest_ref: 'env-manifests/abc', infra_plan_ref: 'infra-plans/abc',})
if (put.ok) { console.log('snapshot version:', put.value.version) console.log('content hash:', put.value.content_hash)}Data blobs are partitioned by package: the resulting data_key is version-sets/<package>/<content_hash>. Identical manifests dedupe to the same blob even when stored as separate snapshots (different versions, optionally different tags).
Promoting to an environment
Promotion is a new snapshot referencing the same manifest content with new tags. The promoted snapshot’s parents points back at the source for lineage.
const promoted = await version_sets.promote(put.value.version, [ 'env:production', 'shape:onebox',])
if (promoted.ok) { // same content_hash + data_key as the source — no fresh blob written console.log(promoted.value.content_hash === put.value.content_hash) // true console.log(promoted.value.parents) // [{ store_id: 'version-sets', version: <put.version>, role: 'promoted_from' }]}The package tag (pkg:<name>) is preserved automatically — you only pass the new environment / shape tags.
Walking lineage
lineage(version) walks the parents chain (self-store only — cross-store parents are ignored) and returns a list of VersionSetRefs starting at version and ending at the originating put.
const initial = await version_sets.put(manifest)const staged = await version_sets.promote(initial.value.version, ['env:staging'])const prod = await version_sets.promote(staged.value.version, ['env:production'])
const chain = await version_sets.lineage(prod.value.version)// chain.value: [// { package, version: <prod>, content_hash },// { package, version: <staged>, content_hash },// { package, version: <initial>, content_hash },// ]Use lineage when you need to answer “what was promoted to produce this prod release?” — the chain terminates at the first snapshot without a version-sets parent.
Storage layout
The store partitions blobs by package via a custom data_key_fn:
<base>/ version-sets/ anthropic-search/ <content_hash_a> <content_hash_b> devpad/ <content_hash_c>This means many packages can share a single backend without colliding on content hashes — the <package> segment in the key is the partition key.
Why not just define_store directly?
You can. version_set_store is a convenience that:
- Locks in the
VersionSetManifestSchemacodec - Wires the
data_key_fnpartitioning - Adds the
pkg:tag on every put so the data_key partitioning works - Exposes
lineageandpromoteas first-class operations instead of leaving them as ad-hocparentsmath at every call site
If you need lower-level access, version_sets.store is the underlying Store<VersionSetManifest> — list, get_meta, delete, transactions etc. all work as on any other store.