Skip to content

ta10101/holochain-ballot

Repository files navigation

holochain-ballot

Lightweight voting hApp: elections, voter registration, ballots, and tallies on Holochain, plus a static showcase UI in showcase/.

Status: Experimental software for learning, demos, and controlled org/community pilots; not for certified public/government elections.

Scope: Built for learning, demos, and community/org-style pilots where participants accept a transparent DHT tally and agent-key identity—not for binding government elections or certified public voting. Read docs/SCOPE.md (intent and non-goals) and docs/THREAT_MODEL.md (risks and limits).

Roadmap: docs/ROADMAP.md — phases P0–P5 complete; secret-ballot P5.3 is N/A under SCOPE.md NO-GO (not unfinished work).

Eligibility & lifecycle (P1): docs/ELIGIBILITY.md (allowlist), docs/ELECTION_LIFECYCLE.md (phases & advance_election_phase), docs/CAPABILITIES.md (who may call what).

Transparent ballot / audit (P2): docs/VOTE_PATH.md (invariants), docs/TALLY_AUDIT.md (vote_action_hashes, recount steps), docs/LIMITS.md (global + per-election max_registrations), docs/schemas/tally-export.schema.json (optional JSON export).

Operations & releases (P3): docs/OPERATIONS.md (runbook), docs/VERSIONING.md (artifact/version strategy), docs/BACKUP_RECOVERY.md (pilot backup notes), CHANGELOG.md.

Real client path (P4): docs/CLIENT_INTEGRATION.md (admin/app websocket flow, auth token, zome call payloads), scripts/minimal-client.mjs (create -> register -> vote -> tally), docs/OBSERVABILITY.md (consistent error surfacing + logging hooks).

Secret ballot / P5: docs/SECRET_BALLOT_RESEARCH.md (P5.1 research). Go/no-go (P5.2): docs/SCOPE.md — current decision NO-GO for secret-ballot DNA in this repo until criteria there are met.

Sister project (E2E, private GitHub): holochain-ballot-e2e — secret ballot + end-to-end verifiable design (roadmap, access required). Bridge: docs/holochain-ballot-e2e-plan.md.

Share / awareness: docs/LAUNCH_KIT.md (copy-paste posts, 30-second pitch, first-week checklist).

Prerequisites

  • Docker (recommended on Windows), or local Nix + nix develop with Holonix.

Build the .happ (Docker)

npm run docker:build:happ

Produces workdir/holochain-ballot.happ and dnas/voting/workdir/voting.dna.

Tests (Tryorama)

After the .happ exists:

npm run docker:test

Vitest files under tests/: two-player smoke, four-player tally, guard cases, P1 lifecycle/allowlist (voting-p1.test.js), P2 registration cap (voting-p2.test.js).

CI: GitHub Actions (.github/workflows/ci.yml) runs the same Docker build + Tryorama on push/PR to main or master.

See the real hApp in the terminal (play-by-play)

Same multi-conductor setup as the tests, but each step is printed (with optional pauses):

npm run demo:visible

Optional: slow the narration — PowerShell: $env:DEMO_STEP_MS='2000'; npm run demo:visible — bash: DEMO_STEP_MS=2000 npm run demo:visible.

Four conductors: DEMO_PLAYER_COUNT=4 npm run demo:visible (Linux/macOS) or set the env in PowerShell before running.

Phased lifecycle is on by default (draft → register → open voting). To run the older single-phase flow: DEMO_LEGACY_FLOW=1 npm run demo:visible (bash) or $env:DEMO_LEGACY_FLOW='1'; npm run demo:visible (PowerShell). Same variable applies when the dashboard spawns the shared scenario (restart the dashboard container after changing env in docker-compose.yml if needed).

Browser dashboard (live Tryorama + SSE)

npm run demo:dashboard

Then open http://localhost:3456/ (leave the terminal running; Ctrl+C stops the server). Requires workdir/holochain-ballot.happ (run docker:build:happ first if needed).

If the port is busy (e.g. an old demo-dashboard-run-* container still mapped to 3456), either:

docker compose -f docker/docker-compose.yml down --remove-orphans

or start cleanly in one step:

npm run demo:dashboard:fresh

Dashboard behavior

  • Event stream URL uses a path, not only query params, so manual mode is reliable:
    /events/auto/4, /events/manual/4, /events/auto/2, /events/manual/2
    (fallback: /events?step=manual&players=4).
  • Lifecycle: the shared scenario (scripts/lib/voting-scenario.mjs) creates a draft election and calls advance_election_phase before registration and before voting (see docs/ELECTION_LIFECYCLE.md). Set DEMO_LEGACY_FLOW=1 to skip that and use the legacy active flow.
  • Auto pacing uses real conductor/DHT time only (no artificial delay between steps), unless you set DEMO_AUTO_STEP_MS (e.g. in docker/docker-compose.yml for the demo-dashboard service).
  • Manual mode: use Next step in the UI; the server accepts POST /advance or GET /advance.

With Nix/Holochain on the host (no Docker): npm ci && npm run demo:dashboard:local.

Minimal real client (local conductor)

Run a basic app install + zome flow against a real conductor:

npm run client:minimal

Script: scripts/minimal-client.mjs (supports env overrides like HC_ADMIN_URL, HC_APP_PORT, HC_HAPP_PATH).

Showcase (Vite + React)

Educational UI + interactive lab (Alex, Blake, Casey, Dana — same names as the default four-player live demo):

npm run showcase:install
npm run showcase:dev

The showcase mentions the live DNA dashboard on port 3456 when you run demo:dashboard alongside.

Local Nix shell

nix develop
npm run build:happ
npm run test:only

Rules enforced (summary)

  • Integrity: election title/options bounds (length and count caps), non-empty options, optional allowlist size cap, vote choice_index in range for the referenced election.
  • Coordinator: register before vote; one registration per agent per election; one vote per agent; duplicate checks use VoterRegistration / Ballot links from the election entry. Phases (draft, open_registration, open_voting, closed, legacy active) gate registration and voting; only the creator may call advance_election_phase (see docs/ELECTION_LIFECYCLE.md). Optional max_registrations caps distinct registrants (docs/LIMITS.md).

Holochain is not HTTP: there are no classic request rate limits on the DHT. Production deployments should use capabilities, client UX, and operational monitoring as appropriate. See docs/SCOPE.md and docs/THREAT_MODEL.md before relying on this in a pilot.

Repo layout

  • dnas/voting/ — integrity + coordinator zomes
  • workdir/happ.yaml — app manifest
  • tests/voting-smoke.test.js — two-player smoke
  • tests/voting-four-players.test.js — four players, tally [2,1,1]
  • tests/voting-guards.test.js — registration / vote ordering
  • tests/voting-p1.test.js — allowlist + phased lifecycle
  • tests/voting-p2.test.js — registration cap (max_registrations)
  • scripts/dashboard-demo.mjs — SSE dashboard server
  • scripts/lib/voting-scenario.mjs — shared Tryorama scenario (demos + dashboard; phased lifecycle by default)
  • scripts/minimal-client.mjs — P4 minimal real-conductor client flow
  • docs/SCOPE.md, docs/THREAT_MODEL.md, docs/ROADMAP.md — scope, risks, delivery plan
  • docs/ELIGIBILITY.md, docs/ELECTION_LIFECYCLE.md, docs/CAPABILITIES.md — P1 eligibility, phases, roles
  • docs/VOTE_PATH.md, docs/TALLY_AUDIT.md, docs/LIMITS.md, docs/schemas/tally-export.schema.json — P2 vote path, audit, caps
  • docs/OPERATIONS.md, docs/VERSIONING.md, docs/BACKUP_RECOVERY.md, CHANGELOG.md — P3 operations, versioning, recovery, release notes
  • docs/CLIENT_INTEGRATION.md — P4 conductor app install + token + zome-call flow
  • docs/OBSERVABILITY.md — P4 client/demo error envelope and logging
  • docs/SECRET_BALLOT_RESEARCH.md — P5.1 research note (no implementation); P5.2 NO-GO in docs/SCOPE.md

About

Experimental Holochain voting hApp with transparent tallies for demos and org/community pilots

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors