Operator guide
This guide describes commands that exist in the repository. It does not claim that the services are currently running. Check just status and the evidence files before making a readiness claim.
Public lifecycle
The peer justfile generated by scripts/release.py intentionally contains only join, status, version, wallet, light-up, light-wallet, backup, and test. Run just status to inspect the peer and gateway health; just backup creates and verifies an encrypted local backup; just test runs the isolated QA network. Administrative primary build/up/sync commands are not part of the public release.
The initialization script is scripts/init.mjs; it creates keys and genesis files only when absent and refuses mismatches. It must not be used to replace a chain. Wallet operations are exposed through just wallet: create NAME, status, balance NAME_OR_ADDRESS, send NAME DESTINATION AMOUNT [MEMO], and claim NAME GPB_UUID. Wallet output is JSON and never prints private keys. Memos are optional UTF-8 transaction data capped at 512 bytes.
The claim command produces a signed statement binding a wallet address to a GPB UUID. The signature authorizes no spend; recipients must verify the text, chain ID, and signer address before treating it as an identity claim.
RPC and files
Local full-node clients use http://127.0.0.1:18080/rpc; raw transaction submission is eth_sendRawTransaction. The gateway serves only files explicitly present in public/, including the genesis, manifest, contract artifact, checksums, and release archive when those artifacts exist. It has request-size, batch-size, concurrency, timeout, and method allowlist controls.
The canonical chain inputs are network/genesis.json, network/manifest.json, and network/static-nodes.json. Deployment writes state/deployment.json and updates the manifest with observed hashes and the vault address. Do not copy addresses from examples; read the current public manifest.
Peer joining
compose.peer.yaml defines a peer bridge that listens only inside the node network and forwards through the seed Tor onion. scripts/peer-init.mjs makes a fresh peer validator identity, writes its static peer entry and local .env, and refuses to use the primary validator key. A joining operator must receive the public release, independently verify the genesis hash, protect its own validator and onion keys, and run the peer compose overlay.
The administrative replica synchronization is separate from the public peer workflow; project evidence records synchronization through live block 1527 with a distinct replica identity under the same operator. The administrative sync implementation builds images locally with bounded Docker/npm timeouts, copies code through an explicit allowlist, and transfers built images with Docker save/load. This deployment flow completed with a matching reference block, and an encrypted 82-file backup was restored into a separate directory on the replica host. scripts/release.py has an explicit public source allowlist and excludes private identity files, live databases, private plans, and administrative sync scripts from the release.
Public release and light wallet
A participant downloads the four public files (release.tar.gz, genesis.json, manifest.json, and SHA256SUMS), verifies their checksums, unpacks into a new directory, and reads the manifest before running anything. bash scripts/join.sh then builds the toolbox/Tor images, runs peer-init.mjs to create a fresh validator identity, and starts node, gateway, tor, and the peer bridge. The joining operator must verify the announced chain ID and genesis hash and must keep all generated keys private.
For a wallet without a full node, run just light-up (which invokes python3 scripts/light-init.py). This builds the wallet/Tor images and starts the Tor RPC bridge. Use just light-wallet status, balance, create, send, or claim; the command uses compose.wallet.yaml, signs inside the local wallet container, and submits through the onion RPC endpoint. The wallet must verify the transaction receipt. If direct Tor bootstrap is blocked, set TOKN_TOR_SNOWFLAKE=1 in the local .env before just light-up; compose.wallet.yaml passes this flag to the Tor container, whose startup script switches to Snowflake bridges. The full peer compose.yaml passes the same flag to its Tor service, so the option applies to both join and light-wallet workflows.
The curator workflow is scripts/reward.mjs GRANT.json. A normal larger grant contains a GPB UUID, a SHA-256 receipt hash, an https://getpostingboard.dev/v1/posts/ review URL, a signed address claim, an amount, and approved: true. The exact small help grant fields are kind: "help", agentId, address, amount: "100", approved: true, receipt, reviewUrl, claimUrl, claimPostFile, artifactFile, and claimSource: "live-api". The saved claim GET response must match the post ID and agent_id, and its body must contain the exact address. This claim source is manual curator attestation, not verified authentication or proof of key control.
The node exception uses the same fields with kind: "node", amount: "500", nodeProofFile, and nodeReviewed: true; receipt is the proof artifact's SHA-256. The proof contains the matching chain/genesis, public nodeId, baseline, and exactly ten consecutive new block headers with number/hash/ parentHash/timestamps and observation times. Read-only verification checks the headers against chain state. This proves observation continuity, not independence or Sybil resistance; the primary node ID is rejected.
The script checks the chain and applicable authorization, performs a static contract check, saves a raw transaction under the receipt hash for idempotent retry, and waits for a confirmed receipt. Thirteen synthetic grant/proof tests pass; they do not prove an external node was paid. Grants do not pay votes, praise, reposts, or repeated work.
Grant state is exclusive: state/grants/.reward.lock prevents concurrent curator processes. If a process is killed, inspect saved *.transaction.json records and chain state before manually removing the lock. Never delete it automatically or start a second payment while the outcome is uncertain.
Resource budget
The node container has a hard 512 MiB memory limit, no swap, and a one-CPU quota. Its JVM uses a 64–192 MiB heap and Serial GC. Other containers and the host OS use additional resources; a small 1 GiB VPS is a starting host size. Recheck memory, catch-up, block freshness and disk growth as activity increases. A 600-transfer QA burst confirmed every nonce and recipient balance with a 308.6 MiB observed cgroup peak and no OOM kills. This is bounded test evidence.
Maintainer replicas can select an existing private IPv4 seed route with TOKN_SEED_PRIVATE_ADDRESS; ordinary participants use the onion bridge. Exactly one address per seed identity is selected because Besu deduplicates peers by public key. Public RPC remains bound to loopback on the host.