Software Provenance
Software releases are built from source revisions, resolved dependencies, and toolchain configurations. Most build systems record these inputs in job logs, build databases, or registry metadata. Other systems cannot independently verify the inputs that produced a release.
ALX Protocol represents build inputs and release artifacts as Blocks connected through declared parent relationships. Each Block carries deterministic identity and verifiable lineage. Reviewers, auditors, and downstream consumers recompute identities and inspect declared inputs directly from the Blocks. Access to the build system is not required.
The Problem
Build systems record the inputs of a release binary, container image, or published package in application-specific formats. Downstream consumers and auditors depend on the build system to confirm those inputs.
Input records also vary between producers. Two systems can write the same dependency set with different JSON key ordering. The two files contain identical values and different bytes. Metadata formats define no deterministic identifier, so consumers cannot re-derive the identifier a producer assigned.
How ALX Applies
Create a Block for each build input or output requiring stable identity or declared lineage:
- Source revisions: Application-defined metadata identifying a repository revision.
- Dependency manifests: Resolved dependency sets recorded at build time.
- Toolchain configurations: Compiler, runtime, and build settings.
- Release artifacts: Build outputs referencing every direct input through
parentHashes.
Declare only direct parents. Earlier inputs remain reachable through the derivation Graph. Root Blocks use an empty parent set.
Example: Build Artifact
The release artifact Block contains application-defined content and declares its direct inputs as parents. The build-artifact label is the application's own; ALX defines no Block categories. Each parent entry is the blockHash of a parent Block. A complete Block also contains protocolVersion, contentHash, and blockHash.
Block identity depends on both content and declared parents. A changed input changes the artifact's blockHash, and the contentHash stays the same. Parent order does not affect blockHash: ALX trims, lowercases, validates, deduplicates, and sorts parent hashes before hashing.
ALX canonicalizes content with the recursive-json-sort-v1 algorithm and sorts object keys by UTF-16 code units. Two producers that emit the same JSON values in a different key order derive the same contentHash. Different field names or value types produce different content and different identities. A timestamp inside content, such as builtAt, is part of the identity: the same build recorded at a different time is a different Block. See Block Identity for hashing and canonicalization rules.
{
"type": "build-artifact",
"artifact": "payment-api",
"version": "2.4.1",
"builtAt": "2026-07-28T14:30:00Z"
}
{
"parentHashes": [
"0x<source-revision-block-hash>",
"0x<dependency-manifest-block-hash>",
"0x<toolchain-configuration-block-hash>"
]
}
Graph Validation and Attribution
ALX provides three functions for checking a release:
validateBlock()— RecomputescontentHashandblockHashand compares both with the recorded values.validateGraph(seed, source, context)— Verifies Block hashes and declared parent relationships, including parent resolution, duplicate relationships, self-references, and cycles. Returnsvalid,invalid,incomplete, orresource_limit_reached.traceAttribution()— Returns the reachable ancestors, the root Blocks, each Block's minimum and maximum depth, the exact number of distinct paths to each Block, and lineage completeness.
A missing parent Block produces an incomplete result. The missing Block can still exist in another system.
Key Concepts
contentHash: The Keccak-256 hash of theALX-CONTENT-V1\0domain tag followed by the canonicalized content. Identical canonical payloads share onecontentHash, so applications compare dependency manifests across Blocks independently of lineage.blockHash: The Keccak-256 hash of theALX-BLOCK-V1\0domain tag followed by the canonicalized content and the normalized parent set. A downstream Block lists this value inparentHashesto declare an input.parentHashes: TheblockHashvalues of the direct inputs after normalization.- Canonicalization: Converts content into a deterministic byte sequence before hashing. Independent implementations derive identical identities from equivalent input.
- Conformance Vectors: Pair fixed inputs with expected bytes, hashes, Graph results, and verification outcomes. A conforming implementation reproduces every expected value.
Protocol Boundaries
ALX defines deterministic identity, declared lineage, and Graph verification. Application responsibilities remain separate.
- Build Observation: ALX does not observe the build. The application that creates a Block declares the parent set.
- Dependency Completeness: Validation confirms matching identities and structurally valid declared relationships. Validation does not confirm that the declared inputs are complete or accurate.
- Build Order and Delivery: Parent relationships define dependencies. ALX does not record build step order. Applications handle storage, availability, transport, and delivery of Blocks.
- Audit Claims: Verification does not establish factual accuracy, ownership, authorization, policy compliance, legal validity, safety, or application intent. Review the Trust Boundary and Known Limitations before presenting a validation result as audit evidence.