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.
bitcd commands carry over to a public network; the keystore does not. Onboarding covers your own organization.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"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 ministackRead 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 hereCheck 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=trueOnboard: 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 CLEANIt 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.
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.
| Command | What it proves |
|---|---|
| pnpm contend | Three 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 store | The 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 reconcile | A 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 redundancy | On 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-approve | Plain 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 escalate | Two 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.
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