Skip to content

Architecture ​

Five kinds of component, each its own container. Everything an agent does crosses the Lake as a signed A2A message, and nothing reaches a pod except through its own housekeeper.

                       ┌──────────────────────────────┐
                       │   lake-ui: map + approvals    │◀─ owner taps Allow
                       └──────────────▲───────────────┘
                                      │ WebSocket events (ids, kinds, counts)
┌──────────────┐   A2A   ┌────────────┴─────────────┐   A2A   ┌──────────────────────┐
│ visitor      │────────▶│  Lake node(s)            │◀───────▶│ house × N            │
│ research     │◀────────│  registry · NATS bus ·   │         │  housekeeper ── MCP ─┼─▶ Solid pod
│ agent + CLI  │         │  event stream · counters │         │  wallet · rules.yaml │
└──────┬───────┘         └────────────▲─────────────┘         └──────────────────────┘
       │ A2A                          │ A2A
       ▼                              │
┌─────────────────────────────────────┴───┐
│ specialists: ethics · auditor ·          │
│ payments · issuer      swarm: traders,   │
│                         attackers        │
└──────────────────────────────────────────┘
ComponentPackageStatus
Shared core: cards, signing, rules, offers, eventspackages/coreruns
House: pod, housekeeper, MCP pod door, walletpackages/houseruns
Lake node: registry, events, counters · buspackages/lakeruns · bus in M3
Visitor: lake knock, dispatch, attack, swarmpackages/visitorruns
Specialists: issuer, ethics, auditor, paymentspackages/specialistsruns
UI: live map · approvals apppackages/uiruns
Agent SDK + Lake MCP connectorpackages/agentruns
FHIR converterpackages/convert-fhirruns

Scale ​

Houses run in two modes that look identical on the map:

ModeHowUsed for
SingleOne container per house, its own pod serverNamed houses, the live "spin up a house" moment
Multilake-house --tenants 250: many pods and housekeepers in one process~1,000 houses on one laptop

Every multi-mode house is still its own WebID, pod, wallet, card and rules file. Only the process is shared.

bash
docker compose --profile scale up -d --scale house-multi=4   # about 1,000 houses

Scale, measured ​

On a 4-core, 16 GB laptop that was also running other work (load average around 3.5), a full paid mission (lake dispatch --extra-fields postcode: knock, bloc counter, re-offer, countersign, compute in place, pay, file receipts):

HousesJoined afterMissionAnswered and paidRecords moved
250 (1 process)95 s warm restart57 s at concurrency 64200 of 200 willing0
1,000 (4 processes)279 s warm restart636 s at concurrency 32737 of 801 willing; 64 still busy after 3 retries0

The time goes into the pod server's file-backed storage: about 5 reads and 4 writes per house per mission, plus DPoP token checks on each. The spec's target of about 60 seconds at 1,000 houses needs dedicated cores, more pod-server processes, or a faster storage backend. Help wanted.

What makes it hold up under load: signed cards and credentials are verified once per process; between full checks a house re-reads only its two data files against the digests its credentials pin; a house that can't read its pod in time answers busy instead of declining; agents retry busy or slow houses up to three times; payments settle in batches of 100.

No model on the hot path ​

Rules decide. The Lake bundles no LLM and needs no API key. If you want an assistant to write plain-English summaries or drive the Lake, plug your own in through the MCP connector.

Apache-2.0 · Synthetic data only · Nobody owns the Lake.