Package Management with Hinge
Package Management with Hinge
Section titled “Package Management with Hinge”Create, sign, verify, and publish sovereign packages.
Time: 45 minutes Level: Intermediate Prerequisites: Tutorials 1-2 (Hello World, CLI Tool) What you’ll learn: Project scaffolding, manifest files, packing, signing, verifying, publishing
Why Hinge?
Section titled “Why Hinge?”Janus ships its own sovereign package manager called Hinge. It is not a utility — it is a Sovereign Supply Chain Economy.
The Garden Wall doctrine:
“Trust is not assumed; it is proven.”
Unlike npm, cargo, or pip, Hinge treats every package as a Capsule — an atomic unit containing three indivisible elements:
- Source — The code (structs, functions, modules)
- Proof — Test results + a compiler-generated Proof Certificate
- Contract — A capability manifest declaring what the package touches (filesystem, network, etc.)
What makes Hinge different:
- Cryptographic signing — Every publish requires Ed25519 signatures (with Dilithium3 post-quantum hybrid coming)
- Federated trust — Chapters (communities of developers) independently verify and vouch for packages
- Content-addressed — Packages are identified by BLAKE3 hashes of their semantic graph, not build artifacts
- No single point of failure — No centralized registry required. Any Chapter can mirror. Trust is portable.
- Proof Certificates — The compiler attests code properties: test coverage, capability footprint, effect purity
Step 1: Scaffold a New Project (5 min)
Section titled “Step 1: Scaffold a New Project (5 min)”Create a project with janus init
Section titled “Create a project with janus init”janus init mylibThis creates a new project directory with the following structure:
mylib/ janus.kdl # Project manifest (KDL format) src/ main.jan # Hello world starter .gitignore # Sensible defaultsExplore the generated files
Section titled “Explore the generated files”src/main.jan — Your entry point:
func main() do println("Hello from Janus!")endjanus.kdl — The project manifest:
project { name "mylib" version "0.1.0" profile "core"}.gitignore — Keeps build artifacts out of version control:
zig-out/.zig-cache/*.jpkVerify it works
Section titled “Verify it works”cd mylibjanus build src/main.jan main./mainOutput:
Hello from Janus!Step 2: Understanding janus.kdl (10 min)
Section titled “Step 2: Understanding janus.kdl (10 min)”The manifest is your package’s identity
Section titled “The manifest is your package’s identity”janus.kdl uses KDL — a document language designed for configuration. It is human-readable and supports comments, unlike JSON. The compiler parses it and produces canonical JSON (RFC 8785) internally for cryptographic signing.
Manifest structure
Section titled “Manifest structure”project { name "mylib" version "1.0.0" profile "core" description "A sovereign math library" license "LUL-1.0"}
dependencies { crypto "^2.1.0" logging "~1.0.0"}Field reference
Section titled “Field reference”| Field | Required | Description |
|---|---|---|
name | Yes | Package name (lowercase, alphanumeric, hyphens) |
version | Yes | Semantic version: MAJOR.MINOR.PATCH |
profile | Yes | Target Janus profile: core, service, cluster, sovereign |
description | No | One-line summary of the package |
license | No | SPDX license identifier |
Version constraints
Section titled “Version constraints”Dependencies use version constraints to control which versions are acceptable:
| Syntax | Meaning | Example |
|---|---|---|
"^2.1.0" | Compatible: >=2.1.0 and <3.0.0 | Allows minor/patch updates |
"~1.0.0" | Approximate: >=1.0.0 and <1.1.0 | Allows patch updates only |
"3.2.1" | Exact: only 3.2.1 | Pinned, no updates |
Profile enforcement
Section titled “Profile enforcement”The profile field declares which Janus profile your Capsule targets. The compiler validates this at build time — a :core package cannot use :service features like channels or actors. This keeps dependencies honest about their requirements.
Step 3: Pack Your Package (5 min)
Section titled “Step 3: Pack Your Package (5 min)”Create a Capsule
Section titled “Create a Capsule”Once your code is ready, pack it into a .jpk (Janus Package) file:
janus pkg pack src mylib 1.0.0Output:
Packing capsule: mylib v1.0.0 Source directory: src/ Files included: 3 BLAKE3 content hash: blake3:a7f2c1... SBOM generated: 3 entries Output: mylib-1.0.0.jpkWhat happens during packing
Section titled “What happens during packing”- File normalization — Source files are normalized (consistent line endings, sorted entries) to ensure reproducible builds
- Content addressing — A BLAKE3 Merkle tree is computed over all files. The root hash becomes the CID:
blake3:<64-char-hex> - SBOM generation — A Software Bill of Materials is auto-generated listing every file, its hash, and its size
Two developers packing identical source code always produce the same CID. This is deterministic by design.
Inside a .jpk file
Section titled “Inside a .jpk file”mylib-1.0.0.jpk/ package/ manifest.kdl # Resolved manifest hash.b3 # BLAKE3 Merkle root sbom.json # Software Bill of Materials signatures/ # (Empty until sealed) src/ main.jan # Your source files math.janStep 4: Generate an Identity (5 min)
Section titled “Step 4: Generate an Identity (5 min)”Create your sovereign keypair
Section titled “Create your sovereign keypair”Before you can sign or publish, you need a cryptographic identity:
janus pkg keygen mykeyOutput:
Generated Ed25519 keypair: Private key: mykey.key Public key: mykey.pub DID: did:sovereign:z6Mks...Your DID is your identity
Section titled “Your DID is your identity”Hinge uses Decentralized Identifiers (did:sovereign) as the identity foundation. Your DID is derived from your Ed25519 public key:
did:sovereign:z<base58btc(public_key)>This identity is:
- Self-sovereign — You generate it locally. No registration with any authority.
- Cryptographically bound — Your DID is mathematically derived from your keypair.
- Portable — Works across any Chapter or registry node.
Key storage
Section titled “Key storage”Keys are stored in your sovereign keyring at ~/.hinge/keyring/, content-addressed by blake3(public_key). Guard your private key — it is your proof of authorship.
Future: Dilithium3 post-quantum hybrid keys will provide resistance against quantum computing attacks. The current Ed25519 foundation is designed to support seamless upgrade.
Step 5: Sign and Seal (5 min)
Section titled “Step 5: Sign and Seal (5 min)”Seal the Capsule
Section titled “Seal the Capsule”Attach your cryptographic signature to the package:
janus pkg seal mylib-1.0.0.jpk --key mykey.keyOutput:
Sealing capsule: mylib-1.0.0.jpk Signer DID: did:sovereign:z6Mks... Signature algorithm: Ed25519 Signed fields: content hash + manifest + SBOM Capsule sealed successfully.What sealing does
Section titled “What sealing does”- Computes a signing payload from the content hash, manifest, and SBOM
- Signs the payload with your Ed25519 private key
- Embeds the signature in the
.jpkunderpackage/signatures/
After sealing, the Capsule is tamper-evident. Any modification to the source, manifest, or SBOM will invalidate the signature.
Key references
Section titled “Key references”The --key flag supports multiple formats for flexibility:
# Direct file pathjanus pkg seal mylib-1.0.0.jpk --key mykey.key
# Explicit file: prefixjanus pkg seal mylib-1.0.0.jpk --key file:mykey.key
# Environment variable (useful in CI)janus pkg seal mylib-1.0.0.jpk --key env:HINGE_SIGNING_KEYStep 6: Verify (5 min)
Section titled “Step 6: Verify (5 min)”Check a Capsule’s integrity
Section titled “Check a Capsule’s integrity”Before installing any package, verify it:
janus pkg verify mylib-1.0.0.jpkOutput:
Verifying capsule: mylib-1.0.0.jpk Content integrity (BLAKE3): PASS Signature validity (Ed25519): PASS SBOM consistency: PASS Signer: did:sovereign:z6Mks... Capsule is valid.What verification checks
Section titled “What verification checks”| Check | What it validates |
|---|---|
| Content integrity | BLAKE3 hash of all files matches the declared CID |
| Signature validity | Ed25519 signature over the signing payload is mathematically valid |
| SBOM consistency | Every file listed in the SBOM exists with the correct hash and size |
| Signer identity | The signing DID is well-formed and the public key matches |
Trust policy
Section titled “Trust policy”Verification confirms the package is intact and authentically signed. But is the signer trustworthy? That depends on your trust graph:
- Does the signer’s DID appear in a Chapter you trust?
- How many independent Chapters have witnessed (cross-verified) this Capsule?
- What is the trust distance from you to the author?
Verification is offline-capable — no network access required.
Step 7: Publish (5 min)
Section titled “Step 7: Publish (5 min)”Announce your Capsule to the federation
Section titled “Announce your Capsule to the federation”janus pkg publish mylib-1.0.0.jpk --key mykey.keyOutput:
Publishing capsule: mylib-1.0.0.jpk CID: blake3:a7f2c1... Topic: $HINGE/{chapter_did}/mylib/announce Transparency ledger: entry appended Capsule published successfully.What publish does
Section titled “What publish does”- Submits the sealed Capsule to your local Chapter’s registry node
- Announces the package via DMP (Distributed Message Protocol) gossip on topic
$HINGE/{chapter_did}/{package_name}/announce - Appends an entry to the transparency ledger — a BLAKE3 Merkle tree that provides an auditable, append-only record of all publications
- Triggers cross-Chapter verification: other Chapters can independently download, verify, and witness (attest) your Capsule
The witness process
Section titled “The witness process”After you publish, independent Chapters:
- Receive the announcement via DMP gossip
- Download and verify the Capsule’s Proof Certificate
- Run their own verification checks
- Publish a witness attestation confirming the Capsule is valid
The more Chapters that witness your Capsule, the higher its trust score across the federation.
Step 8: Resolve Dependencies (5 min)
Section titled “Step 8: Resolve Dependencies (5 min)”Install dependencies from your manifest
Section titled “Install dependencies from your manifest”When your project depends on other Capsules, resolve them:
janus pkg resolveOutput:
Resolving dependencies from janus.kdl... crypto ^2.1.0 -> 2.3.1 (3 witnesses, trust distance: 1) logging ~1.0.0 -> 1.0.4 (5 witnesses, trust distance: 2)
Lockfile written: janus.lock 2 packages resolved All trust policies satisfiedWhat resolve does
Section titled “What resolve does”- Reads
janus.kdland parses dependency constraints - Queries configured registry nodes (your Chapter + federated mirrors)
- Resolves version constraints using BFS with trust filtering — untrusted packages are excluded
- Generates
janus.lock— a deterministic lockfile in canonical JSON (RFC 8785) that pins exact versions and CIDs - Fetches Capsules from the Content-Addressed Store (CAS) or downloads them via the transport layer
The lockfile
Section titled “The lockfile”janus.lock ensures reproducible builds. It pins every dependency to an exact version and CID:
{ "version": 1, "packages": { "crypto": { "version": "2.3.1", "cid": "blake3:b8e4d2...", "witnesses": 3 }, "logging": { "version": "1.0.4", "cid": "blake3:c9f5e3...", "witnesses": 5 } }}Commit janus.lock to version control. Anyone building your project gets the exact same dependency tree.
Incremental resolution
Section titled “Incremental resolution”Subsequent runs of janus pkg resolve only re-resolve changed dependencies. Unchanged packages are served from the local CAS at .janus/cas/blake3/<hh>/<hash>/.
What You Learned
Section titled “What You Learned”The Hinge workflow:
Section titled “The Hinge workflow:”janus init— Scaffold a project with manifest and starter codejanus pkg pack— Create a content-addressed.jpkCapsulejanus pkg keygen— Generate a sovereign Ed25519 identity (DID)janus pkg seal— Cryptographically sign the Capsulejanus pkg verify— Check integrity, signature, and SBOM consistencyjanus pkg publish— Announce to the federation via DMP gossipjanus pkg resolve— Resolve and lock dependencies
Key concepts:
Section titled “Key concepts:”| Concept | Description |
|---|---|
| Capsule | Atomic unit of distribution: source + proof + capability manifest |
| CID | Content ID: blake3:<64-char-hex> hash of the normalized package |
| DID | Decentralized Identifier: did:sovereign:z... — your sovereign identity |
| Chapter | A community of developers that attests and cross-verifies packages |
| Witness | A Chapter that independently verifies and signs an attestation for a Capsule |
| Proof Certificate | Compiler-generated attestation of test coverage, capabilities, and purity |
What’s Next
Section titled “What’s Next”- Trust Graphs and Chapter Federation — How Chapters form, govern membership, and cross-verify
- The Sovereign Supply Chain — Why federated trust eliminates single points of failure
- CI/CD Integration — Automate packing, sealing, and publishing with
HINGE_CI=1mode
You now know how to build, sign, and publish sovereign packages.
Practice by packaging the CLI tool from Tutorial 2 and publishing it to a local Chapter.