invaria
Invaria turns an ordinary command into a reproducible, cacheable and cryptographically attestable execution contract.
A build script normally has invisible causes: undeclared files, ambient environment variables, stale output and unverifiable claims about how an artifact was produced. Invaria makes the cause of a result explicit:
- copy only declared inputs into a fresh workspace;
- run an argument-vector command under a scrubbed environment;
- reject changed inputs and undeclared output files;
- hash every input and output;
- restore outputs from a content-addressed cache when the complete cause is identical;
- sign a canonical provenance attestation with Ed25519;
- optionally pack the manifest and inputs into one deterministic
.ivccapsule.
The project is a zero-dependency Node.js 20+ library and CLI. It uses only standard-library APIs.
Why this is different
Заголовок раздела «Why this is different»Traditional build caches trust a build tool’s dependency graph. Invaria computes an execution fingerprint from the validated manifest, complete input descriptors, OS, architecture and Node runtime. The cache and attestation use the same causal identity. A result therefore has one answer to three questions: “can this be reused?”, “what produced it?”, and “has that claim been altered?”.
Invaria is intentionally not tied to JavaScript builds. Its command can invoke any executable found
on PATH: a compiler, image converter, documentation generator, test runner or data transformer.
Requirements
Заголовок раздела «Requirements»- Node.js 20.11 or newer
- Windows, macOS or Linux
No package installation is required for the included repository.
Five-minute start
Заголовок раздела «Five-minute start»unzip invaria.zipcd invarianpm test
# Run the included contract. A local signing key is generated automatically.node src/cli.js run examples/basic/invaria.json
# Verify signature and current output bytes.node src/cli.js verify examples/basic/basic-report.attestation.json \ --root examples/basic \ --public-key examples/basic/.invaria/signing.public.pem
# The second run restores the output from the causal cache.node src/cli.js run examples/basic/invaria.jsonInstall the command locally when desired:
npm linkinvaria helpCreate a project
Заголовок раздела «Create a project»init refuses to overwrite a non-empty directory.
node src/cli.js init ../my-contractcd ../my-contractinvaria runinvaria verify hello-invaria.attestation.json \ --root . \ --public-key .invaria/signing.public.pemManifest
Заголовок раздела «Manifest»{ "version": 1, "name": "site-build", "command": ["node", "scripts/build.mjs"], "cwd": ".", "inputs": ["src/**", "scripts/build.mjs"], "outputs": ["dist/**"], "env": { "MODE": "production" }, "inheritEnv": [], "timeoutMs": 300000, "sourceDateEpoch": 0, "cache": true, "platform": { "os": ["linux", "darwin", "win32"], "arch": ["x64", "arm64"] }}| Field | Meaning |
|---|---|
version | Manifest format; currently exactly 1. |
name | Stable contract name used for the attestation filename. |
command | Executable and arguments. Invaria never implicitly invokes a shell. |
cwd | Relative working directory inside the execution workspace. |
inputs | Relative glob patterns copied into the workspace. Each pattern must match. |
outputs | Relative glob patterns accepted as results. Each pattern must match. |
env | Explicit environment values visible to the command. |
inheritEnv | Additional host environment names to inherit. Values are represented by hashes in the attestation. |
timeoutMs | Hard process timeout, from 1 ms through 24 hours. |
sourceDateEpoch | Value exported as SOURCE_DATE_EPOCH. |
cache | Enables content-addressed output reuse. |
platform | Optional allowlists for Node process.platform and process.arch; empty means unrestricted. |
Glob syntax supports *, ? and **. All paths are project-relative. Symbolic links are rejected
to make path containment unambiguous. Inputs and outputs may not overlap.
Signed provenance
Заголовок раздела «Signed provenance»Every successful run writes <name>.attestation.json. The signed payload records:
- canonical execution fingerprint;
- command and relative working directory;
- declared environment and hashes of inherited values;
- OS, architecture and Node version;
- SHA-256, byte size and mode of every input and output;
- hashes and sizes of stdout and stderr;
- cache-hit status and execution timestamps.
The attestation embeds its public key so tampering is detectable anywhere. To establish signer identity, verify against a separately distributed public key:
invaria verify site-build.attestation.json --root . --public-key release.public.pemUse --no-files to verify only the signed statement, without comparing outputs on disk.
Portable capsules
Заголовок раздела «Portable capsules»A capsule is a deterministic binary envelope containing a canonical manifest and all declared inputs. Entries are sorted, path-validated, length-bounded and individually SHA-256 verified. The same inputs and manifest produce identical capsule bytes.
invaria pack invaria.json release.ivcinvaria inspect release.ivcinvaria capsule-run release.ivc --out ./received-resultcapsule-run extracts into a temporary directory, executes the normal contract engine and leaves
only declared outputs, cache state, a public key and the signed attestation in the output directory.
invaria init [directory]invaria keygen [prefix]invaria run [manifest] [--key FILE] [--attestation FILE] [--no-cache] [--json]invaria verify <attestation> [--root DIR] [--public-key FILE] [--no-files] [--json]invaria pack [manifest] <capsule.ivc> [--json]invaria capsule-run <capsule.ivc> --out DIR [--key FILE] [--no-cache] [--json]invaria inspect <capsule.ivc> [--json]invaria clean [manifest]Library API
Заголовок раздела «Library API»import { runContract, verifyAttestation, packCapsule, extractCapsule} from './src/index.js';
const run = await runContract({ manifest: './invaria.json' });console.log(run.fingerprint, run.cacheHit, run.outputs);
const verification = await verifyAttestation(run.attestationPath, { root: '.', publicKey: './.invaria/signing.public.pem'});if (!verification.ok) throw new Error(JSON.stringify(verification.errors));Reproducibility boundary
Заголовок раздела «Reproducibility boundary»Invaria controls declared files, output classification, ambient environment and provenance. It is not an operating-system security sandbox and cannot stop a malicious executable from accessing the host or network. Use a container, VM or OS sandbox for hostile code; use Invaria inside that boundary to make the computation inspectable and repeatable. See SECURITY.md.
npm testnpm run checkThe suite exercises canonical serialization, glob behavior, deterministic capsules, corruption rejection, real command execution, cache restoration, signature verification, output tampering, input mutation, undeclared output detection and timeout handling.
License
Заголовок раздела «License»MIT
Исходный код · MIT