Get ECCA Running Locally
Clone the repo, spin up all 24 services with Docker Compose, deploy contracts, and test every endpoint — in under 10 minutes.
Prerequisites
1 — Clone & Install
Clone the repository
git clone https://github.com/aarong11/dhf.git
cd dhf
Install all dependencies
pnpm install
This installs all packages, services, and workers across the monorepo via pnpm workspaces.
Build the TypeScript packages
pnpm build
Turborepo builds everything in dependency order: proto → crypto → bus → db → chain → service-base → services → workers
2 — Environment Configuration
Copy the example environment file and customize if needed:
cp .env.example .env
.env.example ships with working values for local Docker development. You only need to edit it if you want to use OpenAI/Anthropic instead of Ollama, or change ports.
Key Environment Variables
| Variable | Default | Purpose |
|---|---|---|
| DATABASE_URL | postgresql://ecca:quellcrist@... | PostgreSQL connection |
| NATS_URL | nats://axonal-bus:4222 | Event bus (JetStream) |
| REDIS_URL | redis://working-memory-cache:6379 | Ephemeral cache |
| CORTEX_RPC | http://cortex-evm:8545 | EVM chain RPC |
| MEDULLA_RPC | http://medulla-pow:8332 | PoW chain RPC |
| HIPPOCAMPUS_API | http://hippocampus-dag:5001 | DAG storage API |
| ECCA_EPOCH_INTERVAL_MS | 4000 | Epoch tick interval |
| ECCA_DRIFT_MAX | 15 | Max drift before desync |
| ECCA_FIDELITY_MIN | 0.6 | Minimum recall fidelity |
| SIYANA_PORT | 7070 | Main API port |
| LLM_PROVIDER | ollama | ollama | openai | anthropic |
3 — Start All Services
Build and launch all 24 services
pnpm compose:up
This runs docker compose up -d --build. First build takes 3-5 minutes; subsequent starts are faster.
Watch the logs (optional)
pnpm compose:logs
Verify services are healthy
# Check all containers are running
docker compose ps
# Health checks
curl http://localhost:7070/healthz # Siyana API
curl http://localhost:8332/health # Medulla PoW
curl http://localhost:15001/health # Hippocampus DAG
4 — Deploy Smart Contracts
Once Cortex EVM is running on port 8545, deploy the 7 Solidity contracts:
pnpm contracts:deploy
This deploys StackIdentity, BandwidthToken, QuellistTreasury, ResidueRegistry, SleeveRegistry, EpochAnchor, and NeedlecastRouter to the local Cortex EVM chain. Contract addresses are written to deployments/cortex.json.
5 — Verify Everything Works
# Run the test suite
pnpm test
# Or run the full end-to-end demo
pnpm demo
🧪 Run Tests in Your Browser
Test every endpoint end-to-end with live request/response output, blockchain verification, and log guidance — no tools to install.
▶ Open Test RunnerDemo Flow
The demo script exercises the full cognitive cycle:
Run the Demo
pnpm demo
This creates a Stack, spawns human + AI sleeves, writes 5 perceptions, syncs, recalls with fidelity check, needlecasts between sleeves, triggers an epoch, and prints token balances + residues.
API Testing
Two ways to test every endpoint against your local Docker services:
Browser Test Runner
Run all 25 tests end-to-end right here. See requests, responses, blockchain state, and where to check logs — zero install required.
Postman Collection
30 requests with test scripts. Import into Postman desktop or web.
↓ Download .jsonHow to Import
Open Postman
Use the desktop app or web.postman.co (browser version).
Import → Upload Files
Click Import in the top-left, select the downloaded .json file.
Run requests in order
Start with Create Stack → Spawn Sleeve → Drip Faucet → then test perceive, recall, needlecast. Variables auto-populate from responses.
localhost.
Siyana API
:7070The main gateway. All client requests go through Siyana.
Stack Management
Create a new identity stack. Returns the stack ID, token ID, public key, and initial balances.
// Request
{ "name": "quellcrist-01", "kind": "autonomous" }
// Response
{ "id": "stk_...", "tokenId": 1, "name": "quellcrist-01",
"kind": "autonomous", "pubKey": "0xabc...", "epoch": 0,
"cpv": { "compute": 0.5, "memory": 0.3, "sync": 0.15, "routing": 0.05 },
"binding": "cortex-mainnet" }
List all stacks with their sleeves.
Get a single stack with sleeves and anchor history.
Sleeve Lifecycle
Spawn a new sleeve (embodiment) attached to a stack.
// Request
{ "stackId": "stk_...", "embodimentType": "human", "hostname": "local-01" }
// Response
{ "id": "slv_...", "stackId": "stk_...", "embodimentType": "human",
"alive": true, "drift": 0, "syncEpoch": 0,
"tokens": { "compute": 1000, "memory": 1000, "sync": 500, "routing": 500 } }
List all alive sleeves.
Decommission a sleeve. Marks it as not alive.
Perceive & Recall
Write a perception to memory. Costs 0.5 compute tokens and increments drift by 1.
// Request
{ "input": "The sunset cast long shadows across the rooftops of Harlan's World." }
// Response
{ "cid": "bafk...", "thought": "perception stored" }
Reconstruct memory from the DAG. Traverses depth levels and decrypts fragments.
// Query params: ?depth=6&memoryToken=1000
// Response
{ "fragments": ["decrypted memory text...", ...],
"broken": [],
"fidelity": 0.95 }
Sync a sleeve to the current epoch. Resets drift to 0, costs 1 sync token.
Needlecasting
Transfer consciousness from one sleeve to another (re-sleeving). Runs a 6-step atomic saga.
// Request
{ "from": "slv_source", "to": "slv_target" }
// Response (delegated to needlecast-router-svc)
{ "ok": true, "sagaId": "saga_...", "route": [...], "shards": [...] }
Coordination & Epochs
Get the current epoch number, block height, and chain tip.
Trigger a Proof-of-Work block on Medulla. Returns the block hash and new epoch.
List all sleeves with drift exceeding the threshold (default: 15).
Get the last 50 coordination residues (errors as economic objects).
Tokens
Get aggregated token balances across all alive sleeves for a stack.
Bandwidth Faucet
:7075Rate-limited token dispenser for development. Grants 100 of each token type per drip, with a 60-second cooldown.
Request free tokens. Rate-limited to once per 60 seconds per stack.
// Request
{ "stackId": "stk_..." }
// Response
{ "ok": true, "granted": { "compute": 100, "memory": 100, "sync": 100, "routing": 100 },
"sleeves": ["slv_..."] }
Thalamus Router
:7072Epoch tick engine. Folds all chain roots into a single coherence root each epoch.
Get the current epoch number.
Force an epoch fold. Computes the coherence root from EVM, IPFS, and sleeve Merkle roots and anchors it to Medulla.
DHF Compositor
:7073Memory reconstruction engine. Walks the DAG and decrypts fragments using epoch keys.
Reconstruct memory for a stack. Decrypts all DAG nodes within the given depth.
// Request
{ "stackId": "stk_...", "sleeveId": "slv_...", "depth": 6 }
// Response
{ "ok": true, "fragments": ["memory text...", ...],
"broken": [], "fidelity": 0.92 }
Needlecast Router
:7071Atomic re-sleeving saga. Handles the 6-step consciousness transfer between sleeves.
Initiate needlecast transfer. Runs: freeze → snapshot → shard → transmit → reassemble → activate.
// Request
{ "from": "slv_source", "to": "slv_target" }
// Response
{ "ok": true, "sagaId": "saga_...",
"route": ["freeze","snapshot","shard","transmit","reassemble","activate"],
"shards": ["shard_1", "shard_2", "shard_3"] }
Quellist Treasury
:7074Token emission engine. Issues bandwidth tokens based on the CPV curve and epoch delta.
Get the last 100 emission events for a stack.
Claim pending token emissions for a stack.
// Request
{ "stackId": "stk_..." }
// Response
{ "stackId": "stk_...", "claimable": { "compute": 50, "memory": 30, "sync": 15, "routing": 5 } }
Sleeve Runtime
:varies4-in-1 parametric embodiment. Each sleeve instance exposes its own identity endpoint.
Returns the sleeve's identity, kind, parent stack, and hostname.
// Response
{ "sleeveId": "slv_...", "kind": "human",
"stackId": "stk_...", "hostname": "local-01" }
Port Map
| Service | Port | Protocol | Notes |
|---|---|---|---|
| Siyana API | 7070 | HTTP + WS | Main gateway |
| Needlecast Router | 7071 | HTTP | Internal |
| Thalamus Router | 7072 | HTTP | Internal |
| DHF Compositor | 7073 | HTTP | Internal |
| Quellist Treasury | 7074 | HTTP | Internal |
| Bandwidth Faucet | 7075 | HTTP | Public |
| Cortex EVM | 8545 | JSON-RPC | Ethereum-compatible |
| Medulla PoW | 8332 | HTTP | Custom PoW chain |
| Hippocampus DAG | 15001 | HTTP | Content-addressed store |
| PostgreSQL | 5432 | TCP | Main database |
| Redis | 6380 | TCP | Cache (mapped 6380→6379) |
| NATS | 4222 | TCP | Event bus |
| MinIO | 9000 | HTTP | S3-compatible object store |
| Grafana | 3030 | HTTP | Dashboards |
| Prometheus | 9090 | HTTP | Metrics |
| Jaeger | 16686 | HTTP | Traces |
Infrastructure Services
These are started automatically by Docker Compose and don't need manual setup:
- PostgreSQL — Stack/sleeve/epoch registry (
ecca_registrydatabase) - Redis — Ephemeral working memory cache
- NATS JetStream — Axonal event bus for inter-service communication
- MinIO — S3-compatible shard storage for Hippocampus
Observability
Full observability stack is included:
- Grafana — Dashboards at
:3030(admin/admin) - Prometheus — Metrics at
:9090 - Jaeger — Distributed traces at
:16686 - Loki — Log aggregation at
:3100
Common Issues
Another process is using a required port. Stop it or change the port in .env.
# Find what's using port 7070
lsof -i :7070 # macOS/Linux
netstat -ano | findstr :7070 # Windows
PostgreSQL may not be ready yet. Wait a few seconds or check the container:
docker compose logs cortical-registry-db
Make sure Cortex EVM is fully initialized before deploying. The geth init + mining takes ~10 seconds.
# Check cortex is ready
curl http://localhost:8545 -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
Nuclear option — tear down everything and start fresh:
pnpm compose:down # removes containers + volumes
pnpm compose:up # rebuild from scratch
Reading Logs
# All services
pnpm compose:logs
# Single service
docker compose logs -f siyana-api
# Last 50 lines of a service
docker compose logs --tail 50 thalamus-router