Provenry
The facts and provenance engine behind Sourcey. It gives the facts you publish a history anyone can verify from the files alone.
- Version
- 0.1.1 · 30 Sept 2026
- Licence
- MIT
- Runtime
- Node 22.12+
- Dependencies
- zod
Install and run
The digests are the same on every machine, because every input has exactly one byte form.
The example
This is examples/basic.mjs from the v0.1.1 tag. It composes an instance with one adapter, seals its first release and verifies it from the bytes, using only the package's public exports.
import {
encodePublicationJson,
publicationChangeSchema,
publicationEnvelopeSchemas,
publicationOwnershipRegistry,
} from "provenry/contracts/publication";
import { digest } from "provenry/primitives";
import { sealPublicationChange } from "provenry/publication/changes";
import { createPublicationEnvelope } from "provenry/publication/envelope";
import { z } from "zod";
// Contract identifiers and adapter vocabulary belong to the composition.
const contracts = {
manifest: "example.object-manifest/v1",
snapshot: "example.snapshot/v1",
artifact: "example.artifact/v1",
release: "example.release/v1",
descriptor: "example.descriptor/v1",
diff: "example.diff/v1",
bundle: "example.bundle/v1",
resourceTransition: "example.resource-transition/v1",
};
const changes = publicationChangeSchema({
kind: z.literal("note.added"),
subjectTypes: ["note"],
tombstone: z.object({}).strict(),
});
const ownership = publicationOwnershipRegistry({
instanceId: "example",
adapters: [
{ adapterId: "notes", resources: ["note-index"], objects: ["notes/"], subjectTypes: ["note"] },
],
});
const envelope = createPublicationEnvelope({
schemas: publicationEnvelopeSchemas(contracts, changes),
ownership,
});
const note = { id: "n1", text: "A verifiable note" };
const change = sealPublicationChange({
kind: "note.added",
subject_type: "note",
subject_id: note.id,
revision_digest: digest(note),
basis_event_ids: [],
});
const initialIndex = digest({ notes: [] });
const draft = envelope.begin(new Map([["notes/n1.json", encodePublicationJson(note)]]));
const sealed = draft.seal({
snapshotCore: {
snapshot_contract: contracts.snapshot,
release_sequence: 1,
compiler_version: "example/1",
artifact_contract: contracts.artifact,
input_set_digest: digest({ input: note }),
artifact_digest: digest(note),
resource_digests: {
"note-index": envelope.resourceTransitionDigest("note-index", initialIndex, [change]),
},
root_set_digest: digest({ trusted_roots: ["example"] }),
signer_registry_digest: digest({ signers: ["example"] }),
trust_transition_digest: null,
policy_as_of: "2026-01-01T00:00:00Z",
},
parent: null,
changes: [change],
admittedInputDigests: [digest({ input: note })],
verifierDigest: digest({ verifier: "example/1" }),
resourceDigests: {},
});
// A real composition would retain these exact files and install its own
// semantic validator and trust roots before admitting a publication.
const files = new Map([...sealed.files].map(([path, bytes]) => [path, Buffer.from(bytes)]));
files.set("bundle.json", Buffer.from(sealed.bundleBytes));
const verified = envelope.verify(files);
envelope.assertSuccessor({ descriptor: verified.descriptor, diff: verified.diff, parent: null });
console.log(
JSON.stringify({
bundle_digest: verified.bundle.bundle_digest,
release_id: verified.descriptor.release_id,
objects: Object.keys(verified.manifest.objects).length,
}),
);
Sourcey runs on it
Sourcey seals its releases with Provenry. This is the current one.
- release
- sha256:76028f0d9041…
- parent
- sha256:c3935b69d100…
- bundle
- sha256:e8ae78c7c3cd…
- verifier
- sha256:c6d6f5a0f63d…
- published
Release pages
The release digest, its parent, the bundle and the verifier listed for a release are the envelope Provenry sealed.
Captures
Evidence is reserved before the fetch, sealed after it, and signed by a key the registry can place in time.
Identities
Companies merge, split and retire. Each transition is a record, and every reference keeps the exact revision it named.
Modules
Each module is its own subpath export.
provenry/primitivesCanonical JSON, SHA-256 digests, canonical string order and identifiers.
provenry/identityIdentity transitions: merges, splits, successions and retirements.
provenry/records/referencesTyped references between records, bound to an exact revision.
provenry/capture/methodsThe capture methods an instance installs.
provenry/capture/startThe reservation made before any capture happens.
provenry/capture/attemptsThe sealed result of a capture attempt.
provenry/capture/attestationEd25519 attestations of capture attempts, checked against a signer registry with history.
provenry/contracts/publicationEnvelope schemas, the change vocabulary and the ownership registry of an instance.
provenry/publication/envelopeSealing and verifying a release: manifest, change log, diff, descriptor and bundle.
provenry/publication/changesOrdering and sealing the changes in a release.
provenry/publication/objectsWriting release files to disk and reading them back within limits.
provenry/publication/deliveryContent-addressed delivery of release files.
provenry/publication/preparationBuilding a release, then verifying it over the installed code.
Files
- README.md
- What it proves, the install and the example.
- FORMAT.md
- The exact byte contract: preimages, verification stages and read limits.
- examples/basic.mjs
- Seal and verify a release in one file.
- CHANGELOG.md
- What changed in each release.
- RELEASING.md
- How a version is checked, tagged and published.
- SECURITY.md
- How to report a vulnerability privately.
- CONTRIBUTING.md
- Where a change belongs and what it has to show.