Last updated: September 25, 2026

Guides

Each guide follows a document in the Go repository. Output is shown only where it was actually recorded; otherwise you get the command and what it should do.

Run a real cluster on one machine

Build the binaries and start 3 control-plane members and 4 hosts as separate processes, with real keys, signatures, Raft and WireGuard — all on loopback. The outputs below were recorded on the reference machine.

NeedsGo 1.26+ · git and make · macOS (Linux not yet validated)
  1. 01Clone and build

    Produces dh, dh-control, dh-noded, dh-conformance and dh-beacon in bin/.

    shell
    $ git clone https://github.com/CodesbyFebin/Decentralized-.git decentralized.host
    $ cd decentralized.host
    $ make build
  2. 02Start the cluster

    Bootstraps Raft, joins 4 hosts (one edge), pushes the sample artifact and deploys a 3-replica app.

    shell
    $ ./bin/dh dev up --dir ./devcluster
    recorded output
    cluster dev: root key EYpyLqc4JrBBnN9oKo9uR2PzyItlmh0W_thMZdRAI24 (dh1moxcikagjbglhwfnm3yhzxyi2i)
    root CA ./devcluster/operator/dev/root-ca.pem
    Keep ./devcluster/operator/dev/root/identity.key private: it is the trust anchor every host pins.
    • starting 3 control-plane member(s)
    bootstrapped dh1cqtai3x2ugv27ajz6x6xvg43ob: cluster dev initialized
    member dh1wy2x6dkhlmcdzay46pdsiu3rc4 added (roster v2, 2 members)
    member dh1qn4s24gwcmp7ugv4c6ietg2u53 added (roster v3, 3 members)
    • starting 4 host(s) (1 edge)
    • pushing the dh-beacon artifact and applying the sample app
    attestation stored for b3:87f2505fb60558d69744209dc3540a9ac54c53d87a6e68c2966ebd01981ae34f
      web: created (generation 1)
    
    Cluster "dev" is running: 3 control-plane member(s), 4 host(s), 1 edge.
      console:   http://127.0.0.1:17701/#token=<session capability — redacted>
      operator:  export DH_HOME=./devcluster/operator
      edge:      curl -H 'Host: web.dev.test' -H 'X-DH-No-Redirect: 1' http://127.0.0.1:18103/
      logs:      ./devcluster/logs
      stop:      dh dev down --dir ./devcluster
  3. 03Point the CLI at it

    The operator home holds the dev cluster's root key and CA.

    shell
    $ export DH_HOME=./devcluster/operator
  4. 04Compare desired, admitted and observed

    Three separate numbers. If a host refused a replica, ADMITTED would be lower than DESIRED and describe would show why.

    shell
    $ ./bin/dh get apps
    recorded output
    APP  GEN  IMAGE                                                                          RUNTIME  REPLICAS  DESIRED  ADMITTED  OBSERVED  DRIFT  STATE
    web  1    dh-beacon@b3:87f2505fb60558d69744209dc3540a9ac54c53d87a6e68c2966ebd01981ae34f  process  3         3        3         3         0      active
  5. 05Verify the audit ledger yourself

    The chain and signed checkpoints are verified on your machine, not reported by the server.

    shell
    $ ./bin/dh audit verify
    recorded output
    audit verified locally: 48 entries, head b68dc824b42b, 2 signed checkpoint(s) by roster members
  6. 06Stop everything

    Stops every process and workload of the cluster.

    shell
    $ ./bin/dh dev down --dir ./devcluster
    recorded output
    stopped 7 process(es) and 3 workload(s) of ./devcluster
  • Dev clusters serve the API without TLS unless you pass --tls.
  • Ports start at 17700 by default; change with --base if something else uses them.

Install a TLS cluster across machines

The production shape: three members serving TLS from their first start, and hosts joining with single-use tokens that pin the root. The runbook is scripted (validation/pv1/tls-install.sh) and passed on the reference machine — but it has never been run across separate machines. That is PV-1 stage 2.

Needs3 machines for control-plane members · 1 or more host machines · an operator machine that keeps the root key · reachable ports: API 7700, Raft 7800, WireGuard 51900 (members) and 51820 (hosts)
  1. 01Create the trust root

    On the operator machine. Keep root/identity.key offline.

    shell
    $ export DH_HOME=~/.dh
    $ dh init --cluster prod
  2. 02Start each member

    Repeat on cp2 and cp3 with their own names. Each prints a certificate fingerprint and writes bootstrap.code and bootstrap.fingerprint.

    shell
    $ dh-control --data /var/lib/dh-control --api 0.0.0.0:7700 --api-advertise cp1.example.net:7700 --raft 0.0.0.0:7800 --raft-advertise cp1.example.net:7800 --mesh 0.0.0.0:51900 --mesh-advertise cp1.example.net:51900 --tls
  3. 03Bootstrap and add members

    Copy each member's bootstrap.code and bootstrap.fingerprint to the operator machine over a trusted channel first. The CLI pins the fingerprint.

    shell
    $ dh cp bootstrap --api cp1.example.net:7700 --code-file ./cp1/bootstrap.code
    $ dh cp add-member --api cp2.example.net:7700 --code-file ./cp2/bootstrap.code
    $ dh cp add-member --api cp3.example.net:7700 --code-file ./cp3/bootstrap.code
  4. 04Check the control plane

    Expect one leader, two followers, three voters.

    shell
    $ dh cp status
  5. 05Invite a host

    One token per host; tokens are single-use. Add --roles edge for an edge host.

    shell
    $ dh node invite --out host-1.token
  6. 06Start the host

    On the host. It writes its sovereign policy.yaml on first start.

    shell
    $ dh-noded --data /var/lib/dh-noded --join-file host-1.token --name host-1 --region eu-west --zone a --host rack1-u12 --mesh 0.0.0.0:51820 --mesh-advertise host-1.example.net:51820
  7. 07Approve it

    Unless the invite used --auto.

    shell
    $ dh get nodes
    $ dh node approve host-1
  8. 08Verify

    Ledger, mesh consistency, protocol vectors, and a backup you can check offline.

    shell
    $ dh audit verify
    $ dh mesh doctor
    $ dh-conformance run -self
  • Browsers must trust root-ca.pem to open the TLS console, or put your own TLS terminator in front of it.
  • If a join token was already used, the host says so; give it a new token and restart it with --join-file.

Deploy your own service

Push the executable into the cluster's content-addressed store, reference it by digest, and apply a manifest. Hosts fetch it from peers, verify every chunk and run it only if their policy admits it.

Needsa running cluster (local or installed) · an executable built for the hosts' OS and architecture that listens on $PORT and answers a health path
  1. 01Push the artifact

    --sign attests it with the root key, so hosts with requireImageSignature: true accept it.

    shell
    $ dh artifact push ./myservice --name myservice --sign
  2. 02Write the manifest

    Replace <digest> with the one printed above. Unknown fields are rejected.

    shell
    $ cat > web.yaml <<'EOF' apiVersion: dh/v1 kind: Application metadata: {name: web} spec: replicas: 2 image: myservice@b3:<digest> resources: {cpu: 100m, mem: 32Mi} placement: {tiers: [trusted], spread: failure-domain, antiAffinity: hard} ports: [{name: http}] health: {http: /healthz, interval: 1s} EOF
  3. 03Preview placement

    The scheduler plan, per host and replica, with reasons — before anything is signed.

    shell
    $ dh explain app web
  4. 04Apply and wait

    Completes when every replica is observed running the current generation.

    shell
    $ dh apply -f web.yaml
    $ dh rollout status app web
  5. 05Inspect

    Every replica with desired, admitted and observed state and each admission check.

    shell
    $ dh describe app web
    recorded output
    App web  generation 1  bf7ae06f6642  image dh-beacon@b3:87f2505fb60558d69744209dc3540a9ac54c53d87a6e68c2966ebd01981ae34f (process)
    DESIRED 3   ADMITTED 3   OBSERVED 3   DRIFT 0
    
    Replica 0 on host-c (dh1ucato7pd2)
      Desired:   RUNNING generation 1
      Admitted:  ADMITTED generation 1  [ADMITTED] already admitted; digest and policy unchanged
      Observed:  RUNNING generation 1  pid 7100 container - mesh port 20000 restarts 0
      Health:    ok=true HTTP 200 in 186µs (consecutive failures 0)
      Status:    RUNNING   evidence FRESH ee65134b7d4a (1s ago)
        ✓ ledger               host ledger verifies
        ✓ plane                roster and bundle signer chain to the pinned root; state index not rolled back
        ✓ assignment-signature signed by roster member dh1cqtai3x2u
        ✓ audience             assignment is for dh1ucato7pd2zb3tjjznoasoqjdt2
        ✓ generation           assignment generation 1, admitted 1
        ✓ clock                bundle issued -2ms relative to host clock (limit 30000ms)
        ✓ capability           chain of 2 block(s) anchored in the pinned root
        ✓ revocation           host approval is current
        ✓ frozen               control plane is not frozen
        ✓ fresh                bundle within 10000ms fresh window
        ✓ unchanged            same generation already admitted and running
    
    Replica 1 on host-a (dh1h4qewobc5)
      Desired:   RUNNING generation 1
      Admitted:  ADMITTED generation 1  [ADMITTED] already admitted; digest and policy unchanged
      Observed:  RUNNING generation 1  pid 7101 container - mesh port 20000 restarts 0
      Health:    ok=true HTTP 200 in 251µs (consecutive failures 0)
      Status:    RUNNING   evidence FRESH afc772f5f71a (0s ago)
        ✓ ledger               host ledger verifies
        ✓ plane                roster and bundle signer chain to the pinned root; state index not rolled back
        ✓ assignment-signature signed by roster member dh1cqtai3x2u
        ✓ audience             assignment is for dh1h4qewobc5hcr4dhlvl3323xgrd
        ✓ generation           assignment generation 1, admitted 1
        ✓ clock                bundle issued -4ms relative to host clock (limit 30000ms)
        ✓ capability           chain of 2 block(s) anchored in the pinned root
        ✓ revocation           host approval is current
        ✓ frozen               control plane is not frozen
        ✓ fresh                bundle within 10000ms fresh window
        ✓ unchanged            same generation already admitted and running
    
    Replica 2 on host-b (dh13hn4aq4xu)
      Desired:   RUNNING generation 1
      Admitted:  ADMITTED generation 1  [ADMITTED] already admitted; digest and policy unchanged
      Observed:  RUNNING generation 1  pid 7102 container - mesh port 20000 restarts 0
      Health:    ok=true HTTP 200 in 177µs (consecutive failures 0)
      Status:    RUNNING   evidence FRESH 23b04a3bb285 (0s ago)
        ✓ ledger               host ledger verifies
        ✓ plane                roster and bundle signer chain to the pinned root; state index not rolled back
        ✓ assignment-signature signed by roster member dh1cqtai3x2u
        ✓ audience             assignment is for dh13hn4aq4xuycgzoej4nabt3qpvr
        ✓ generation           assignment generation 1, admitted 1
        ✓ clock                bundle issued -4ms relative to host clock (limit 30000ms)
        ✓ capability           chain of 2 block(s) anchored in the pinned root
        ✓ revocation           host approval is current
        ✓ frozen               control plane is not frozen
        ✓ fresh                bundle within 10000ms fresh window
        ✓ unchanged            same generation already admitted and running
  • The recorded output above is from the sample app on a dev cluster; yours will name your app and hosts.
  • For a container, use image: <ref>@sha256:<digest>; the docker runtime is selected and enforces --memory and --cpus.
  • The process runtime does not enforce CPU or memory limits.
Intermediatefollows pkg/chaos

Break it on purpose: chaos scenarios

Each scenario starts its own disposable cluster, drives traffic through the edge, injects a real fault (SIGKILL, packet loss at UDP fault proxies, clock offset, ENOSPC …) and checks an invariant. Reports are signed.

Needsa built checkout · Docker for the oom scenario, Postgres for postgres-outage (they SKIP otherwise)
  1. 01List scenarios

    Topology, injection and invariant for each of the 17.

    shell
    $ dh chaos list
  2. 02Run one

    Kills the Raft leader under traffic; a new leader must be elected with no failed request.

    shell
    $ dh chaos run --scenario leader-crash
  3. 03Run all of them

    About 6–7 minutes on the reference machine.

    shell
    $ dh chaos run --scenario all --out ./chaos-reports
  • `dh chaos soak --duration 10m` runs randomized faults on one cluster; the 24-hour soak has not been run yet.

Check the evidence behind this site

The status on this site comes from signed validation records in the repository. You can re-verify them: the signature, every log and report hash, and the source digest they pin.

Needsa clone of the Go repository at main · a build of dh
  1. 01Verify the baseline record

    Checks the signature and re-hashes every file in the record.

    shell
    $ dh evidence verify --dir evidence/REF-MAC-A03
  2. 02Check you are looking at the same source

    Must print b3:2a23e1da… for commit ef849e2.

    shell
    $ git checkout ef849e2
    $ dh evidence digest
  3. 03Read the history

    Every attempt, including the failed and infrastructure-failed ones, and the defects each found.

    shell
    $ cat evidence/INDEX.md evidence/PV1-S1-HISTORY.md
  • A record verifying means it is intact and signed; it does not make its scope wider than it states. REF-MAC-A03 is one macOS machine over loopback.

Help validate on Linux (PV1-S1)

The first production-validation gate reproduces the macOS baseline on Linux. An offline kit (Go toolchain, module cache and the exact source) runs the whole gate with no network access and writes a signed evidence record.

Needsan independent Linux x86_64 machine or VM (≥ 4 vCPU, 8 GB RAM, 40 GB SSD) · gcc, python3, tar, sha256sum · optional: Docker
  1. 01Fetch the kit

    Published in parts on its own branch. reassemble.sh checks every part and the rebuilt archive's SHA-256 before extracting.

    shell
    $ git clone --branch pv1-offline-kit --depth 1 https://github.com/CodesbyFebin/Decentralized-.git dh-kit
    $ cd dh-kit
    $ sh reassemble.sh
  2. 02Verify the kit and the machine

    Inputs, the official Go checksum, architecture and prerequisites.

    shell
    $ cd dh-pv1-offline-kit-linux-amd64
    $ sha256sum -c KIT-SHA256SUMS
    $ sh verify-kit.sh
  3. 03Run the gate

    State the machine exactly: VM or bare metal, provider, vCPU, RAM, disk. It stops unless the source digest is b3:2a23e1da….

    shell
    $ sh run-pv1-s1-a03.sh "Ubuntu 24.04 VM on <provider>, 4 vCPU / 8 GB / 40 GB SSD, KVM"
  • Keep evidence/validator/identity.key private.
  • A failing run is still evidence. Keep it; failures are recorded, never overwritten.