Skip to content

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


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:

  1. Source — The code (structs, functions, modules)
  2. Proof — Test results + a compiler-generated Proof Certificate
  3. 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

Terminal window
janus init mylib

This creates a new project directory with the following structure:

mylib/
janus.kdl # Project manifest (KDL format)
src/
main.jan # Hello world starter
.gitignore # Sensible defaults

src/main.jan — Your entry point:

func main() do
println("Hello from Janus!")
end

janus.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/
*.jpk
Terminal window
cd mylib
janus build src/main.jan main
./main

Output:

Hello from Janus!

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.

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"
}
FieldRequiredDescription
nameYesPackage name (lowercase, alphanumeric, hyphens)
versionYesSemantic version: MAJOR.MINOR.PATCH
profileYesTarget Janus profile: core, service, cluster, sovereign
descriptionNoOne-line summary of the package
licenseNoSPDX license identifier

Dependencies use version constraints to control which versions are acceptable:

SyntaxMeaningExample
"^2.1.0"Compatible: >=2.1.0 and <3.0.0Allows minor/patch updates
"~1.0.0"Approximate: >=1.0.0 and <1.1.0Allows patch updates only
"3.2.1"Exact: only 3.2.1Pinned, no updates

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.


Once your code is ready, pack it into a .jpk (Janus Package) file:

Terminal window
janus pkg pack src mylib 1.0.0

Output:

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.jpk
  1. File normalization — Source files are normalized (consistent line endings, sorted entries) to ensure reproducible builds
  2. Content addressing — A BLAKE3 Merkle tree is computed over all files. The root hash becomes the CID: blake3:<64-char-hex>
  3. 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.

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.jan

Before you can sign or publish, you need a cryptographic identity:

Terminal window
janus pkg keygen mykey

Output:

Generated Ed25519 keypair:
Private key: mykey.key
Public key: mykey.pub
DID: did:sovereign:z6Mks...

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.

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.


Attach your cryptographic signature to the package:

Terminal window
janus pkg seal mylib-1.0.0.jpk --key mykey.key

Output:

Sealing capsule: mylib-1.0.0.jpk
Signer DID: did:sovereign:z6Mks...
Signature algorithm: Ed25519
Signed fields: content hash + manifest + SBOM
Capsule sealed successfully.
  1. Computes a signing payload from the content hash, manifest, and SBOM
  2. Signs the payload with your Ed25519 private key
  3. Embeds the signature in the .jpk under package/signatures/

After sealing, the Capsule is tamper-evident. Any modification to the source, manifest, or SBOM will invalidate the signature.

The --key flag supports multiple formats for flexibility:

Terminal window
# Direct file path
janus pkg seal mylib-1.0.0.jpk --key mykey.key
# Explicit file: prefix
janus 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_KEY

Before installing any package, verify it:

Terminal window
janus pkg verify mylib-1.0.0.jpk

Output:

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.
CheckWhat it validates
Content integrityBLAKE3 hash of all files matches the declared CID
Signature validityEd25519 signature over the signing payload is mathematically valid
SBOM consistencyEvery file listed in the SBOM exists with the correct hash and size
Signer identityThe signing DID is well-formed and the public key matches

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.


Terminal window
janus pkg publish mylib-1.0.0.jpk --key mykey.key

Output:

Publishing capsule: mylib-1.0.0.jpk
CID: blake3:a7f2c1...
Topic: $HINGE/{chapter_did}/mylib/announce
Transparency ledger: entry appended
Capsule published successfully.
  1. Submits the sealed Capsule to your local Chapter’s registry node
  2. Announces the package via DMP (Distributed Message Protocol) gossip on topic $HINGE/{chapter_did}/{package_name}/announce
  3. Appends an entry to the transparency ledger — a BLAKE3 Merkle tree that provides an auditable, append-only record of all publications
  4. Triggers cross-Chapter verification: other Chapters can independently download, verify, and witness (attest) your Capsule

After you publish, independent Chapters:

  1. Receive the announcement via DMP gossip
  2. Download and verify the Capsule’s Proof Certificate
  3. Run their own verification checks
  4. Publish a witness attestation confirming the Capsule is valid

The more Chapters that witness your Capsule, the higher its trust score across the federation.


When your project depends on other Capsules, resolve them:

Terminal window
janus pkg resolve

Output:

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 satisfied
  1. Reads janus.kdl and parses dependency constraints
  2. Queries configured registry nodes (your Chapter + federated mirrors)
  3. Resolves version constraints using BFS with trust filtering — untrusted packages are excluded
  4. Generates janus.lock — a deterministic lockfile in canonical JSON (RFC 8785) that pins exact versions and CIDs
  5. Fetches Capsules from the Content-Addressed Store (CAS) or downloads them via the transport layer

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.

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>/.


  1. janus init — Scaffold a project with manifest and starter code
  2. janus pkg pack — Create a content-addressed .jpk Capsule
  3. janus pkg keygen — Generate a sovereign Ed25519 identity (DID)
  4. janus pkg seal — Cryptographically sign the Capsule
  5. janus pkg verify — Check integrity, signature, and SBOM consistency
  6. janus pkg publish — Announce to the federation via DMP gossip
  7. janus pkg resolve — Resolve and lock dependencies
ConceptDescription
CapsuleAtomic unit of distribution: source + proof + capability manifest
CIDContent ID: blake3:<64-char-hex> hash of the normalized package
DIDDecentralized Identifier: did:sovereign:z... — your sovereign identity
ChapterA community of developers that attests and cross-verifies packages
WitnessA Chapter that independently verifies and signs an attestation for a Capsule
Proof CertificateCompiler-generated attestation of test coverage, capabilities, and purity

  • 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=1 mode

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.