bitcd

Quickstart

Deploy an organization on a local devnet and give up the admin role. Then run each proof stage from the bitcd-core checkout and read what it prints. About fifteen minutes.

Nothing here touches a public network. The chain is a Starknet devnet in Docker, the store is a local S3, and the signers are the devnet’s predeployed accounts. The bitcd commands carry over to a public network; the keystore does not. Onboarding covers your own organization.
0

Prerequisites

git, Docker with Compose, Node 22 and pnpm. The devnet is reached directly, so a local proxy must not intercept it.

$ git clone https://github.com/bitcdorg/bitcd-core.git && cd bitcd-core
$ corepack enable && pnpm install
$ export NO_PROXY="localhost,127.0.0.1,0.0.0.0,ministack"
1

Start the chain and the store

A fresh Starknet devnet on :5051 and an S3-compatible store on :4566. The ceremony renounces ownership, so a second run needs a fresh chain: docker compose down -v first.

$ docker compose up -d --wait devnet ministack
2

Read the organization

Signers, roles, quorums, the kinds of change and who approves them are one file, e2e/bitcd.yaml: three operator accounts, two of them marked human, and three executor accounts. One connector and the intent type bound to it:

connectors:
  demo-iam:
    type: s3-demo                      # the live side is an object in the store
    role: EXEC_IAM                     # the executors' role, and only theirs
    executors: [exec1, exec2, exec3]

intent_types:
  iam-acct:
    connector: demo-iam
    prefix: iam/acct
    key: "iam/acct/{name}"
    quorum:
      threshold: 2                     # two operators,
      min_humans: 1                    # one of them a person,
      max_per_operator: 1              # from two different operators
    attest: { k: 1 }                   # one executor report is enough here

Check it offline. Schema errors and security lints are errors, not warnings:

$ node core/bin/bitcd.mjs validate e2e/bitcd.yaml
OK e2e/bitcd.yaml: org=bitcd-core v1 — 6 signers, 1 connector(s), 2 intent type(s), 1 governed value(s), 1 lock surface(s), 15 policies to seed, renounce=true
3

Onboard: deploy, seed, renounce

One command runs the bitcd CLI four times: validate, apply-ceremony (deploy the contract, seed signers and policies, renounce ownership), publish-manifest (commit the compiled definition as a governed value, through its own quorum) and diff (read everything back and compare it with the file).

$ cd e2e && pnpm onboard
…
onboard complete: org seeded from the declaration, manifest committed, diff CLEAN

It writes e2e/deployment.json and a keystore from the devnet accounts at e2e/.onboard-tmp/keys.json. There is no admin now: the owner is zero, and policies and signers change only through quorums from here on.

4

Run the proofs

Each stage is one script. It prints what it does, ends with a PASS or FAIL summary and exits non-zero on failure. Run them in order.

CommandWhat it proves
pnpm contendThree wallets contend for one lock in turn. The first acquires it, the next two are refused with acquire: held, and after chain time passes the TTL the second acquires it.
pnpm storeThe lock holder writes a document to the store and commits its fingerprint. Reading it back reports VERIFIED; after the object is tampered with, MISMATCH, and the reader refuses it.
pnpm reconcileA quorum commits a document; the executor applies it and the derived state is SYNCED. An edit behind the executor’s back derives OUTOFSYNC with desired unchanged. A new revision lags, then applies. A failing apply is attested FAILED and desired is unchanged.
pnpm redundancyOn a prefix that asks for two agreeing executors, one report stays pending; a second agreeing one promotes SYNCED; a report that lies produces DISAGREE; two honest executors outvote it.
pnpm human-approvePlain approvals from the human-labelled accounts cannot satisfy min_humans. Signed SNIP-12 approvals bound to the exact change do. The same path authorizes a force-unlock.
pnpm escalateTwo machine approvals commit a routine change on a prefix with no human floor. On the next proposal an agent requests human review; the same two approvals are blocked until a human signature lands it.

Every TTL in these stages is crossed with devnet_increaseTime, never a wall-clock wait.

5

All of it in one run

The same stages, in order, against a fresh chain. From the checkout root, pnpm demo runs them on the host. The Docker route on the main page runs them in a container and needs no Node on the host.

$ docker compose down -v && docker compose up -d --wait devnet ministack
$ pnpm demo                                   # from the bitcd-core root
$ docker compose down -v                      # when done

Where next