-
-
Notifications
You must be signed in to change notification settings - Fork 2
Developer Guide
# Rust WASM toolchain
rustup target add wasm32-unknown-unknown
# Holochain + CLI tools
cargo install holochain hc --locked
# Verify
holochain --version # currently 0.6.0
hc --versioncd valichord/tests
npm installWarning: Never use
pack_dna.py— it is broken and embeds the same (attestation) DNA bytes for all four roles. Always usehc dna pack+hc app pack.
cd valichord
# Set PATH if needed
export PATH="/home/codespace/.cargo/bin:$PATH"
# 1. Compile WASM zomes (all four DNAs)
cargo build --target wasm32-unknown-unknown --release
# 2. Pack each DNA
hc dna pack dnas/attestation -o workdir/attestation.dna
hc dna pack dnas/researcher_repository -o workdir/researcher_repository.dna
hc dna pack dnas/validator_workspace -o workdir/validator_workspace.dna
hc dna pack dnas/governance -o workdir/governance.dna
# 3. Bundle the hApp
hc app pack . -o workdir/valichord.happThe compiled DNAs and happ land in valichord/workdir/.
Cargo.toml (workspace root) includes a release profile optimised for WASM size:
[profile.release]
opt-level = "z"
lto = "thin"This halves WASM binary size, which halves JIT compilation time at test startup — critical when each runScenario launches a fresh Holochain conductor that JIT-compiles all 8 WASM modules.
pkill -f holochain; pkill -f lair-keystore; sleep 2Orphaned Holochain or lair-keystore processes from a previous run will cause port conflicts or deadlocks. This cleanup is essential.
cd valichord/tests
npm testcd valichord
cargo test -p valichord_sweettest_integrationOr run both in one go via the CI matrix (cargo test in the workspace root picks up all test targets).
Per-test timeouts are set to 900,000 ms (15 minutes) in the Tryorama runner config. This is necessary because each runScenario call starts a fresh Holochain conductor that JIT-compiles ~30 MB of WASM. On slow hardware (e.g. a shared Codespace), startup alone can take 60 seconds per player.
166 passing, 1 skipped across two suites. Tests are integration tests — each launches independent Holochain conductors with real agent identities, source chains, and DHT participation.
- Study registration and retrieval
- Protocol registration and retrieval
- Snapshot creation and retrieval
- Deviation declaration and retrieval
- Data hash computation (return type, determinism, collision resistance)
- Immutability enforcement
- Source-chain querying
- Task reception and retrieval
- Private attestation sealing and retrieval
- Source-chain querying
- Privacy: Bob cannot read Alice's sealed private attestation
Key pattern: get_private_attestation_for_task uses query() (source-chain-only) not get() — private entries cannot cross cell boundaries.
- Membrane and joining (5 tests): valid proof, no proof, short proof, real Ed25519, wrong signature
- Blind commit-reveal (5 tests): two validators commit and reveal, late joiner, immutability
- Profiles and indexing (8 tests)
- Phase management and discipline filtering (2 tests)
- Cross-DNA coordination: seal triggers
notify_commitment_sealed(1 test) - Phase threshold: minimum validators triggers phase open (1 test)
- Badge issuance: Bronze (3), Silver (5), Gold SKIPPED (7 — RAM-limited on Codespaces)
- Failed reproduction badge (1 test)
- Validator self-assignment: claim, duplicate prevention, COI rejection, capacity limit, release (5 tests)
- Dropout recovery: timeout not elapsed, timeout elapsed, already attested (3 tests)
- Duplicate check logic
- Harmony Record creation from attestations
- Reputation update permissions
- Records by discipline, badge by study
- Badge thresholds (Bronze, Silver, Gold)
- Mixed outcome records
- Governance decisions
- Delete immutability
- Force finalize round
- S1: Duplicate attestation guard
- S2: Duplicate commitment guard
- S3: Researcher commitment idempotency
- S4.1/S4.2:
reclaim_abandoned_claimtimeout floor - S5:
force_finalize_roundconservative abort - S6:
reveal_researcher_resultidempotency
In-process tests using holochain_sweettest — faster startup, no external conductor process. Run in 5 parallel CI matrix jobs alongside the Tryorama suite. Covers:
- Full blind commit-reveal protocol end-to-end
- Badge issuance including GoldReproducible (7 validators — runnable in sweettest; RAM-limited only in Tryorama)
-
CertificationTierpromotion boundaries (Provisional → Standard) - Mixed outcome HarmonyRecord assembly
- Cross-DNA call chain: DNA 2 seal → DNA 3 anchor → DNA 4 record
Pure outcome unit tests (no conductor) run under cargo test -p valichord_shared_types:
-
derive_majority_outcomeandderive_agreement_level— run in < 1 s
valichord/
├── Cargo.toml # Workspace manifest
├── happ.yaml # Bundle (4 roles)
├── shared_types/
│ ├── Cargo.toml
│ └── src/lib.rs # Cross-DNA types (Discipline, outcomes, etc.)
├── dnas/
│ ├── attestation/
│ │ ├── dna.yaml
│ │ ├── zomes/
│ │ │ ├── attestation_integrity/ # Entry + link types, validate()
│ │ │ └── attestation/ # Coordinator: CRUD, membrane, protocol
│ │ └── workdir/
│ ├── researcher_repository/
│ │ ├── dna.yaml
│ │ └── zomes/
│ │ ├── researcher_repository_integrity/
│ │ └── researcher_repository/
│ ├── validator_workspace/
│ │ ├── dna.yaml
│ │ └── zomes/
│ │ ├── validator_workspace_integrity/
│ │ └── validator_workspace/
│ └── governance/
│ ├── dna.yaml
│ └── zomes/
│ ├── governance_integrity/
│ └── governance/
├── sweettest_integration/ # Rust sweettest suite
├── tests/
│ ├── package.json # Tryorama, @holochain/client
│ ├── src/
│ │ ├── researcher_repository.test.ts
│ │ ├── validator_workspace.test.ts
│ │ ├── attestation.test.ts
│ │ ├── governance.test.ts
│ │ └── security.test.ts
│ └── README.md # Test inventory
└── workdir/ # Compiled output
├── attestation.dna
├── researcher_repository.dna
├── validator_workspace.dna
├── governance.dna
└── valichord.happ
valichord-ui/ # Svelte 5 + TypeScript browser UI
├── dev.sh # Start conductor + install app + write auth token
├── dev-setup.mjs # Node.js bootstrap (installs hApp, issues token)
└── src/lib/
├── holochain.ts # AppWebsocket singleton + callZome wrapper
├── types.ts # TypeScript mirrors of all Rust types
├── ResearcherView.svelte
├── ValidatorView.svelte
└── GovernanceView.svelte
valichord_attestation/ # Python attestation library (AI evals)
├── valichord_attestation/
│ ├── builder.py # build_bundle()
│ ├── canonical.py # RFC 8785 JCS encoding + hash_bundle()
│ ├── merkle.py # Merkle root, proof, verify
│ ├── challenge.py # Probabilistic challenge-response
│ └── response.py # build_response(), verify_response()
├── examples/
│ ├── mistral_7b_gsm8k_demo/ # Real-data demo (Mistral-7B, GSM8K-100)
│ └── challenge_response_demo.py
├── spec/attestation_format_v1.md
└── tests/ # 142 tests, 100% line coverage
demo/
├── docker-compose.yml # 5-container decentralised demo
├── ai_validator.py # Python orchestrator (Claude API validators)
├── researcher-node.mjs # HTTP API wrapper for researcher conductor
└── validator-node.mjs # HTTP API wrapper for each validator conductor
cd valichord-ui
npm install
# Terminal 1: start conductor + install hApp + write auth token
bash dev.sh
# Terminal 2: start Vite dev server (once Terminal 1 prints "Token written")
npm run dev
# → http://localhost:5173dev.sh launches a local conductor via dev-conductor.yaml, installs the hApp with membrane-proof bypass, attaches the app interface, issues an auth token, and writes VITE_HC_TOKEN + VITE_HC_SIGNING_CREDENTIALS to .env.local.
Full UX walkthrough: valichord-ui/FRONTEND.md
export ANTHROPIC_API_KEY=sk-ant-...
docker compose -f demo/docker-compose.yml up --build -d
# Wait for all 4 node APIs to be ready
until [ "$(docker compose -f demo/docker-compose.yml logs 2>/dev/null | grep -c 'node API →')" -ge 4 ]; do sleep 3; done && echo "Ready"
python3 demo/ai_validator.py --mode decentralisedFive Docker containers — researcher, 3 validators, kitsune2 bootstrap server — each run their own Holochain conductor. The only communication between containers is the DHT.
Full guide: demo/DECENTRALISED_DEMO.md
A standalone Python library for producing cryptographically verifiable attestation bundles for AI evaluation runs.
cd valichord_attestation
pip install -e ".[dev]"
pytest tests/
# Real-data demo (no GPU required)
python examples/mistral_7b_gsm8k_demo/challenge_response_demo.pySee valichord_attestation/README.md and spec/attestation_format_v1.md.
Serde encoding for shared types — important for JS test interop:
| Type | Serde attribute | JS encoding |
|---|---|---|
Discipline |
#[serde(tag="type", content="content")] |
{type: "ComputationalBiology"} |
AttestationOutcome |
#[serde(tag="type", content="content")] |
{type: "Reproduced"} |
DeviationType |
#[serde(tag="type", content="content")] |
{type: "MethodVariant"} |
ValidationTier |
(no tag) | plain string "Basic"
|
AttestationConfidence |
(no tag) | plain string "High"
|
AgreementLevel |
(no tag) | plain string "ExactMatch"
|
ValidationPhase |
(no tag) | plain string "RevealOpen"
|
ExternalHash in JS: Use hashFrom32AndType(core32, HoloHashType.External) from @holochain/client. Do NOT construct manually (new Uint8Array(39).fill(byte)) — DHT location bytes must be a valid blake2b checksum.
Signal format: Signals use adjacent-tag serde (#[serde(tag = "type", content = "content")]), delivering { type: "RevealOpen", content: { ... } } over the AppWebsocket. Do not test for the variant name as a top-level key — unwrap type and content explicitly.
| Gap | Reason | Path forward |
|---|---|---|
| Gold badge — Tryorama (7 validators) | Requires 7 simultaneous Tryorama conductors; RAM-limited on Codespaces | Covered in sweettest; Tryorama version skipped |
force_finalize_round success (Tryorama) |
ROUND_TIMEOUT_SECS hardcoded; Tryorama cannot advance clock |
Parameterise timeout; mock time in test |
For institutional operators deploying ValiChord to a live network, see docs/DEPLOYMENT_CHECKLIST.md — a consolidated reference for all DNA properties, dev/test bypass values, production requirements, and misconfiguration failure modes.
Key properties to set correctly before going live:
-
authorized_joining_certificate_issuer(DNA 3) — empty string lets anyone join -
minimum_validators(DNA 3) —0lets a researcher bypass the multi-party protocol -
min_claim_timeout_secs(DNA 3) —0enables claim-cycling attacks
Currently running Holochain 0.6.0. When 0.6.1 is available:
cargo install holochain --version 0.6.1 --locked- In
valichord/tests/package.json:"@holochain/tryorama": "0.19.0"→"0.19.1" cd valichord/tests && npm install- Verify tests still pass
Why: tryorama 0.19.1 switches transport from WebRTC/tx5 → iroh/QUIC, requiring Holochain 0.6.1. Currently pinned to 0.19.0 (exact pin, not ^).