Virtual Lab · Intro Deck 1 / 15

Hello,
lab.

A working twin of every instrument, every service, every facility node. In a browser tab.

virtual lab digitaltwin.l7esp.com turn the page →

Break every instrument.
Tuesday afternoon.

Train the rare cases. Demo the integration. Spin up a tenant in thirty seconds. Burn nothing.

no reagents no booking no waiting
Intro Deck · 2026

A browser-resident twin of every instrument, service, and facility node. Clickable, breakable, integrated with L7|ESP.

What it is, what you can do with it, and who already gets value from it.

In plain English

A practice lab. So the real one keeps doing real work.

For the reader who hasn't worked in a pharmaceutical or food-science lab before, here's what we mean.

Real labs are expensive places. A single instrument can run half a million dollars. The reagents are restricted, the access is gated, the schedule is full. Every hour the lab spends on training, on integration testing, or on a customer demo, is an hour it isn't doing the work it was built for.

Virtual Lab is a software stand-in for that whole environment. It runs in a web browser. Every instrument acts like the real one, with the same controls and the same readings. People can train on it. Software can be tested against it. Customers can be shown what their workflow will look like. None of it touches a real machine, a real sample, or a real schedule.

The same digital twin can also reflect a real lab back. Live readings from real instruments stream into the same panels. You can see what's happening across a site without being there, and you can rehearse the rare failures (the leaking seal, the dropped connection) on the practice version before they happen for real.

01 · What it is

A working simulator, not a mockup.

Every instrument, every service, every facility node lives as a state machine the operator can click, drive, and break, using the same surfaces and the same wire formats they'd touch in a real plant.

Twins, not screens

65 instruments + services modeled as live Python state machines. Phase transitions, derived metrics, fault states, sensor noise. All real, not paper.

The bus is the spine

One event bus. Frontend, MQTT subscribers, and ESP pipelines all read the same stream of instrument_state, command_result, log. No second source of truth.

Multi-tenant by design

Per-org subdomains (amaryllis.digitaltwin.l7esp.com). Instances, layouts, and MQTT topics scope to the tenant; cross-org access surfaces as 404.

Fault injection built-in

Every twin declares its failure modes. Operators inject them on demand (agent offline, calibration drift, comms lockup, probe slip, transit excursion) to rehearse the rare cases.

L7|ESP integrated

Twins are reachable from real ESP pipelines, applets, and notifications. Workflows that run against real hardware run unchanged against the simulator.

Standards-aware

ISA-88 procedural framing on chains (procedure / unit procedure / operation / phase). ISA-95 enterprise model documented. NE 107 + ISA-101 stylings on faceplates.

02 · Tour the surfaces

Five views, one source of truth.

Every twin auto-publishes to every surface via shared row builders + a faceplate registry. Click a balance from any view; you see the same state machine.

① Bench

The training-bench grid: status cards with in-card controls (PH 4 CAL, MEASURE, START RUN). The "Hello world" of the platform. Fastest path to "this works."

② Map / floor

A 2-D plan view of a real site. Drop assets, draw bench-link references that fan out on hover, click any node for its faceplate. JSON-authored. No designer required.

③ Globe

A 3-D globe rolls up every layout to its physical site — crossfading to political boundaries on zoom. Live status dots, fault propagation, chip-per-layout fan-out on hover. Briefing room view.

④ Faceplate

The HMI-style operator panel that pops out of any tile: phase, setpoints, command buttons, active-fault banner. The same panel an operator would use on the real instrument.

⑤ Inventory + Admin

All assets, all faults, all WS hooks in one place. Designer for layouts. Org provisioning. Fault rotation toggle. Docs section embedded. ISA standards reference.

Live everywhere, all at once

WS bus pushes state to every open surface simultaneously. Faulting a centrifuge on the bench lights it red on the floor map and the globe in the same tick.

03 · The system, on one page

The moving parts — and where truth lives.

Four pieces, each with a single job. Everything the browser shows, ESP consumes, or the database remembers comes off one event stream.

ORG TENANCY — amaryllis. · foodlab. · shelley. · … — scopes everything inside this frame Operators browser, tablet L7|ESP chains workflow steps API / MQTT clients customer systems COMMANDS LIVE TWINS 220+ instruments & services as stateful simulators OWNS: behavior + current state phases · readings · faults EVENT BUS — one stream BROWSER SURFACES — bench · map · globe · assets views onto the stream — they own nothing, deleting one loses nothing DATABASE — event log · engagements · utilization system of record for history — who did what, to which asset, when MQTT + L7|ESP — external consumers notifications, dashboards, customer subscribers — same stream
What's happening now → the event bus What happened → the database What exists → the asset registry (twins) How it's shown → layouts — disposable views Why twins sit before the bus → commands are requests; the bus carries only what actually happened (next slide)
03b · Technical appendix — one command, start to finish

Commands are requests. The bus carries facts.

Every caller — human, ESP, or customer system — goes through the twin. The twin validates, then either refuses (error returns to the caller only) or changes state — and only what actually happened is published. Nothing writes the bus directly; that's why there's exactly one truth.

CALLER operator · ESP chain · API client TWIN EVENT BUS CONSUMERS browsers · database · MQTT · ESP ① command: start_run(sample_id, method) a request — authenticated, org-scoped, actor recorded ② validate preconditions busy? door open? fault active? args typed correctly? ②b refused → error to the caller only · no event, no state change ③ publish what happened command_invoked (who asked) · instrument_state (what changed) ④ fan-out, same tick browser paints · DB appends history · MQTT republishes · ESP wait_for advances ⑤ result returns to the caller but every other consumer already saw the same fact via the bus
Operators input — faceplate button presses (tare, calibrate, start run), sample drag-and-drop, setpoint edits, engagement start/end. Human-paced, one twin at a time. ESP chains input — the same command vocabulary, programmatic: typed args from workflow variables, steps sequenced across many twins, batch/engagement context attached, wait_for gating on results. API / MQTT clients input — REST commands under API tokens (customer systems, scripts, CI); MQTT is primarily the read side — subscribers consume the state stream like any real instrument feed.
04 · Scenario one — simulation

Practice mode: nothing real gets touched.

L7|ESP runs the same workflow it would run in the cleanroom — but the commands land on simulators. Train people, demo integrations, and rehearse failures without consuming an instrument-hour.

L7|ESP workflow chain: receive → prep → run → capture PROVIDER: drives commands CONSUMER: waits on results command: start_run(sample) SIMULATED TWIN behaves like the real instrument idle busy done same phases, same timings, same failure modes as the hardware it stands in for live state + results PEOPLE WATCHING trainee sees the faceplate react prospect sees the demo run engineer sees the chain survive an injected fault wait_for phase == done → chain advances · notifications fire
Training — build muscle memory on rare failures, cheaply Sales demos — a full plant in a browser tab Integration tests — ESP chains rehearse against every declared fault before touching a customer site
05 · Scenario two — live monitoring

Same glass, real feed.

The views, the history, and the audit trail don't care where events come from. Today they run against the simulated fleet; pointing them at a real site is a change of feed, not a rebuild.

SIMULATED FLEET 220+ twins, streaming now RUNNING TODAY REAL SITE instruments · sensors · PLCs ROADMAP: protocol adapters same event shape SAME BUS LIVE VIEWS — exec globe · site map · bench · assets table a fault at any site lights its marker on the globe in the same tick HISTORY + AUDIT — event log · batch/engagement context · utilization who commanded what, on which asset, during which customer engagement L7|ESP — consumer of events, provider of workflow context notifications on faults · dashboards · batch records enriched with twin telemetry
Built and accumulating today — views, event history, utilization rollups, per-batch audit The flip — swap the feed, keep the glass. No UI rebuild, no retraining
06 · The fault catalog

Rehearse the rare cases on demand.

Every twin declares its failure modes in code. The Faults admin tab lets you inject one with a click, or run an automatic rotation that walks the whole catalog at a steady cadence. Perfect for live demos, training scenarios, and integration regression.

Declared, not guessed

Each twin's FAULTS tuple enumerates its real-world failure modes (agent_offline, calibration_drift, comms_lockup, probe_slip, seal_breach). No surprises in prod.

Faceplate banner

An active fault paints a red banner across the faceplate with the fault name + a "clear" affordance. Operators learn to recognize the visual signature before they meet it in the wild.

Avatar fault states

Hero twins (bioreactor, centrifuge, HPLC, reactor, plate robot, AGV) animate their fault state with leaks, smoke, error glyphs. Training videos write themselves.

Geo + globe propagate

A site with any faulted instrument lights its marker amber/red and flips the layout chip color. Briefing-room view turns into a live incident map.

Demo rotation

Admin → Faults → toggle "auto-rotate" picks a random twin every N seconds, injects a random fault, then clears it. Survives a long demo without operator input.

WS-disconnect surfaced

Bus disconnect drops a banner across every open page, so operators never debug a stale view thinking the data is live. Comes back automatically on reconnect.

07 · Multi-tenant

One backend, many orgs.

Each customer (or internal team) gets their own subdomain: amaryllis.digitaltwin.l7esp.com. The leading label routes to a single shared backend; instances, layouts, and MQTT topics are scoped so tenants are opaque to each other. Falls through to a single-tenant default install when no org is configured, so existing deployments aren't affected.

Subdomain routing

Caddy fronts the container with a wildcard cert for *.digitaltwin.l7esp.com; backend reads X-Forwarded-Host and resolves the org. One cert, infinite tenants. Onboarding a new org is zero DNS work.

Scoping

Instances, layouts, MQTT topics, WS bus traffic. Cross-org access surfaces as 404. The MQTT broker enforces it too: SUBSCRIBE filters outside vlab/<own-org>/… are rejected with SUBACK 0x80.

First-class Org records

Orgs aren't just slugs. They carry display name, owner contact, branding accent, billing tier, status. Provisioning + drop is a one-click admin operation with cascade-delete confirmation.

Auth modes

Claim mode (dev): X-Org header is trusted at face value. Enforce mode (prod): VLAB_TOKEN_MAP env var flips on bearer-token auth (REST + WS + MQTT CONNECT), and the token's org must match the subdomain.

Topbar identity

Browser tabs read Amaryllis · Alzey, Germany · Parenteral fill/finish (EMEA). An org chip in the topbar lets you switch contexts; the chosen org survives across page loads and the geo/globe routes.

Demo content built-in

Three orgs ship out of the box. Amaryllis (10 GLP-1 pharma sites), FoodLab (food-science workflows), Shelley Group (25 layouts across a literary multinational). Open any subdomain; the model is immediately clickable.

08 · L7|ESP integration

Workflows hit twins like real hardware.

vlab is the simulator side of an L7|ESP pairing. ESP chains drive twin commands; twins push state and events back through the bus; the operator runs the same workflow against the simulator that they'd run in the cleanroom.

What flows from ESP to vlab

  • Chains walk procedures across multiple twins: sample receipt, LIMS submission, instrument run, results capture, label print.
  • Chains call DE functions (VirtualLab.command, VirtualLab.wait_for) keyed by instrument_id.
  • Twin commands take typed args and return structured results that ESP writes back into the chain's variables.
  • ESP applets render the chain's onrender JS, so the same buttons appear in vlab as in a live ESP deployment.

What flows from vlab to ESP

  • State events stream over MQTT. ESP subscribers (or the customer's own consumer) read them like any real instrument feed.
  • Chains can wait_for a twin's phase === 'done' before advancing.
  • Fault events propagate up so ESP notifications surface them.
  • Smoke scripts walk a chain end-to-end on demand, useful for ESP integration regression.

Today's shipping examples: Amaryllis carries 4 GLP-1 chains + 10 per-site smoke scripts. FoodLab carries a carrageenan-texture chain spanning material intake, LIMS, prep, TA.XTplus run, and label print.

09 · Who uses it, when

Four jobs vlab is already doing.

Not a hypothetical. These are the active uses today across sales, services, engineering, and customer success.

Sales · live demo

Pop a tenant subdomain in the browser, click through the bench → map → globe progression, inject a fault to show NE-107 status propagation. No hardware, no booking, no ramp-up. Works on a laptop in a coffee shop.

Services · onboarding

Spin up a customer-shaped org (literary, pseudonymous, or real) ahead of kickoff. Reference layouts let a CS team walk a new customer through "this is what your floor would look like" before the first deployment workshop.

Engineering · integration prototyping

Build the ESP chain against the twin. Iterate against the twin's fault catalog until the chain handles every declared failure. Ship to the customer site with confidence the workflow already survived the unhappy paths.

QA · regression

Smoke scripts walk every chain end-to-end. Twin state machines have a deterministic mode for tests. CI catches the "we changed the chain and forgot the bus envelope" bug before a customer does.

Operators · training

Run the carrageenan texture chain. Watch the TA.XTplus avatar animate compression. Inject probe_slip. Recognize the fault on the faceplate before you ever see it in the lab. Build muscle memory cheap.

Product · feature dogfooding

Every ESP-side feature gets exercised against vlab before the first customer call. The product team uses the same surfaces a customer would. Bugs surface inside the team, not in a deployment retrospective.

10 · What's next

The roadmap.

Each step is independently shippable. Listed in rough priority order.

NowConnector contract spec

Standardize the interface every connector implements (health(), idempotent command(), subscribe(), replay()) as a schema + Python ABC. Every existing twin refactors to conform. The spec becomes the deliverable.

NowFault catalog harness

Promote the existing fault-injection mechanism to a regression suite. CI runs every twin × every declared fault and asserts the contract behavior. Output is a per-instrument certification badge.

NextTwin as benchmark — conformance reporting

The twin stays a simulator and acts as the yardstick: it embodies how the instrument should behave (phase timings, declared fault modes, recovery rules). Customers see their real unit + connector measured against that contract — expected vs. actual, side by side. Nothing real flows into the twin.

NextDeeper ISA adoption

NE 107 status pyramid in operator overlays. ISA-101 styling rules across faceplates. Optional ISA-88 physical hierarchy + ISA-18.2 alarm classes once a customer asks for them.

'27Twin as mirror — reverse-twin

The twin stops simulating: the same faceplates, bench cards, and globe markers get fed by the real device's telemetry instead of the internal state machine. Real data flows in; the twin reflects instead of predicts. Remote monitoring wearing a UI operators already know.

'27SLA + alerting per connector

Latency, drop rate, replay gap. Emitted by every connector via the standard contract. Dashboards built once, reused across vendors. Alerts route to support before customers notice.

11 · The landscape

Memory, refinery, brain — and the nervous system.

The adjacent platforms each own one direction of data flow. None of them can command an asset, and none can rehearse.

AVEVA PI — the plant's memory

The process-industry historian: millions of tags, decades of retention, bulletproof collectors. Records what happened. Read-only by design — it never tells an instrument to do anything. Its moat is validated interfaces and operator trust, not technology.

TetraScience — the lab's data refinery

Harmonizes raw instrument files into analytics-ready scientific data in the cloud. Refines what was produced. One-way, after the fact. Its moat is a large validated connector library.

Cognite — the brain that has read everything

Knowledge graph over historians, ERP, P&IDs, and 3D models; AI agents on top. Contextualizes and recommends. Its "twin" is descriptive — it knows about the pump. It doesn't act, and it consumes PI rather than replacing it.

L7|C2 — the nervous system

Executable twins with live state: validates and executes commands, rehearses before acting (simulation), and mirrors real fleets (reverse-twin). C2's twin is the pump — it can exist before the instrument does, and refuse a bad command after it does.

All three are natural consumers of C2's fact stream — cleaner than scraping historians. The honest gap runs the other way: their integration libraries are mature where C2's real-hardware lane is young. Complementary, not competitive.

12 · How it packages

One codebase, two products: the Engine and the Console.

The seam between them is the API — and it's already proven by four clients that aren't the UI.

C2 Engine headless

Event bus · executable twins · reservation + engagement ledger · time-series store · protocol adapters (MQTT today). Consumed over REST, WebSocket, and MQTT with token auth; OpenAPI spec included. Can sit under ESP, a customer's dashboards, or any existing operations UI.

C2 Console reference client

The views in this deck — bench and floor twins, World/US sites, the asset Network, the equipment ledger — organized as one navigation bar that descends the ISA-95 hierarchy: Enterprise → Sites → Work center → Equipment.

The seam is real today

Four non-UI clients already ride the same API the Console uses: the ESP integration plugins, the phone provisioning flow, the MQTT mirror lane for real devices, and the automated QA harness. Separating the products is a packaging decision, not an engineering project — and until a second consumer of the Engine exists, building them together is why features ship in days, not quarters.

13 · Open question

The hierarchy exists. The story doesn't lead yet.

Three honest gaps, then three proposals to ponder. They blend — this is a menu, not a ballot.

Landing is generic

Everyone signs in to the same bench, whatever their role. The navigation bar descends ISA-95 — Enterprise → Sites → Work center → Equipment — but nothing about the first screen says "you are an executive, start at the network" or "you run Alzey, here is Alzey."

The descent doesn't pull

You can click from World to a site to a bench to an instrument. But no level gives you a reason to go down — no "this site is the one that needs you today" scent leading from altitude to detail.

Statistics have no home

Analysis lives where it happened to land: an admin System tab, sparklines on the asset table, rhythm sparks on the network view. There is no answer to "where do I go to understand utilization, trends, or capacity?" — at any level.

13 · Proposal A

Statistics live in the descent.

Every level of the hierarchy gets the same three-part anatomy. Analysis is wherever you're standing, scoped to what you see.

The anatomy, at every level

The picture (the live view you have today) · the numbers strip (KPIs + sparklines rolled up from the level below: utilization, runs, faults, OEE) · the children (each child row carries its own spark; clicking descends). Org shows per-site numbers, site shows per-facility, facility per-instrument, instrument its own time series.

The story it tells

Sign in → land at your role's altitude (exec at Network/World, site lead at their site, tech at their bench). The numbers strip says which child is off-trend; that's the scent that pulls you down a level. Repeat until you reach the faceplate that explains it.

ForWhy it's attractive

"Where are the stats?" stops being a question — one recurring widget grammar (spark → trend → distribution), narrower scope each level. Builds directly on the deep rollups and role lens already in motion. No new navigation.

AgainstThe honest cost

Touches every surface — each view grows a numbers strip, each level needs its rollup queries. Incremental and independently shippable per level, but it's a season of work, not a sprint.

Landing — Indiana ops lead signs in → the region map, numbers strip on top
AMARYLLIS|INDIANA, US|OPERATIONS NetworkWorldTwinTabletAssets
76%utilization · 30d ▲ +4
128runs · 30d
91.2%OEE · 30d
2open faults
3,412 hengaged · 30d
Children — rolled up from below · click descends
▦ Indianapolis Campus map · 13 instr 84%·61 runs+7%
≡ Lebanon LEAP Site bench · 10 instr 52%·18 runs−11% ← off-trend · click descends
Open faults in this rollup
lebanon-hplcPRESSURE HIGH · pump B4.2 hLebanon LEAP
indy-tech-envRH DRIFT · +6% vs setpoint0.8 hTechnology Center
Detail — bottom of the descent: the instrument, same anatomy
AMARYLLIS|LEBANON, IN|LEAP SITE|LEBANON-HPLC TwinTabletAssets
52%utilization · 30d ▼ −11
212runs · 30d
3.4 hmedian run
11 dMTBF
Faceplate · live
Pressure342 bar ▲ HI
Flow1.18 mL/min
BatchAPX-2607-233 · 2:14 elapsed
FaultPRESSURE HIGH · pump B · 4.2 h
Pressure trend · 30d its own series — narrowest scope
creeping toward the 380 bar limit for 9 days — the fault was visible a week early
Recent runs
APX-2607-2333.6 hcomplete2 h ago
APX-2607-2313.2 hcomplete9 h ago
APX-2607-2285.1 haborted · pressure1.1 d ago
13 · Proposal B

The command deck — one analytical home.

A new org Home at sign-in: everything statistical at a glance, deep-linking into the live hierarchy to act.

What's on the deck

Site-health tiles (worst-state colored, one per site) · top-line KPIs · run-rate and OEE trends · fault Pareto · capacity vs. commitment from the reservation ledger. Every tile is a door: click a site tile → that site's map; click a fault bar → the instrument's faceplate.

The story it tells

Sign in → the deck tells you how the operation is doing in ten seconds → you jump into the live views only to act. Analysis concentrates in one place (and grows into a real /analytics view); the hierarchy views stay purely operational and calm.

ForWhy it's attractive

One obvious answer to "where do I look?" — and the most exec-ready landing page the product could have. Fastest of the three to demo credibly; most of the queries already exist behind the System and Network views.

AgainstThe honest cost

A second surface to keep truthful — dashboards drift. Partially duplicates Network and System. And it weakens the descent story: people bookmark the deck and stop living in the hierarchy.

Landing — FoodLab's org Home: 16 sites + both sides of the business, ten seconds
FOODLAB|HOME NetworkWorldTwinTabletAssets
16sites
92assets
88.4%OEE · 30d ▲ +1.2
144customer runs · 30d
87%capacity committed
WAYZATA94%
MPLS91%
CHARLOTTE89%
WICHITA83%
MECHELEN90%
VILVOORDE77%
HAMBURG95%
KRAKÓW58%
BOGOTÁ81%
SÃO PAULO88%
CAPE TOWN72%
MUMBAI93%
SHANGHAI1 fault
SINGAPORE96%
SYDNEY85%
TOKYO92%
OEE trend · 90d
Fault pareto · 30d
texture 9 hplc 6 env 4 agv 3 other 2
Supply & demand — dual-role every tile and row is a door →
◂ buying fromAmaryllis · 3 assets (analytical)Shelley · 2 assets (testing)
selling to ▸Meridian · 16Cascade · 7Sable · 3131 runs · 30d
Detail — click the Shanghai tile → the live site view, deliberately unchanged
← Home FOODLAB|SHANGHAI, CN|PILOT PLANT TwinTabletAssets
Texture analyzer · TA-01
FaultPROBE OVERLOAD · 6.2 h
Last sampleMER-2607-118 · firmness 42 N
Extruder · EX-2
PhaseRUNNING · MER-2607-121
Barrel temp78.3 °C · setpoint 78
Live event log
14:22:07fault_raised · ta-01 · probe_overload
14:19:44phase · ex-2 · mixing → extruding
14:18:02engagement_started · MER-2607-121 · Meridian Foods
Where the analysis went
This level shows now — trends, paretos, and capacity stayed at Home. One click back.
13 · Proposal C

Two tenses, one hierarchy: the NOW ⇄ TRENDS lens.

Statistics aren't a place — they're a lens over the descent you already have. Position chooses scope; the toggle chooses tense.

How it works

A global toggle + time-range control in the topbar, next to the view switch. Flip it and the level you're on re-skins: map markers trade status dots for trend arrows, bench cards flip from live state to 30-day utilization / fault-rate chips, the Assets table becomes a stats table, an instrument's detail becomes its trend explorer.

The story it tells

There is exactly one geography of the operation, and you read it in two tenses: what is happening and what has been happening. Navigate the same way in both; nothing moves, only the ink changes meaning.

ForWhy it's attractive

Zero new navigation and the deepest respect for the hierarchy discipline. The per-instrument trend explorer — the top item on the PI-parity list — becomes simply the TRENDS face of the Tablet level. Very Tufte: maximum reuse of the reader's spatial memory.

AgainstThe honest cost

Every surface needs a stats variant, and the mode must be unmistakable (obvious chrome shift — a mode users forget they're in is a support ticket). Likely blend: A's numbers strip as the spine, C's toggle where a surface earns it, B only if execs demand a poster page.

Landing — Shelley's Ingolstadt floor, flipped to TRENDS tense
SHELLEY|INGOLSTADT, DE|PROCESS FLOOR NowTrends ◂ 30d ▸
Same floor, same positions — the ink changed meaning
▦ API Manufacturing Bay ↗ 88%+6 41 runs·228 h
▦ QC Release Bay ↘ 44%−17 12 runsBluepeak reservation idle 9 d
⚙ Site utilities → 99.9%uptime · flat
Vendor network · trends
Gradgrind Testing↗ 61 samples/wk+18%Manchester
Harker Plasma→ stable6.2 d leadDublin
Rossum Automation↘ throughput −22%3 late lotsTokyo
Detail — an instrument in TRENDS = the trend explorer
SHELLEY|INGOLSTADT, DE|API BAY|INGOLSTADT-HPLC NowTrends ◂ 90d ▸
Overlay any variable, any range — pressure · — utilization · ⚠ 380 bar
● two faults in window — both preceded by the same pressure signature
Run durations · 90d
<2h 2–3h 3–4h 4–5h >5h
Statistics · 90d
p50 / p95 run3.4 h / 5.9 h
Runs · faults641 · 2
MTBF · drift31 d · +0.3%/wk
13 · Proposal D

One network view, from two suppliers to two thousand.

Not a big-org mode and a small-org mode — one paradigm whose unit of display adapts to the population. Breadth collapses at scale; depth expands at intimacy.

Rank + a first-class tail

Supply chains are brutally Pareto — the top 20 relationships are the picture. Always show the top-K as full ribbons; collapse the rest into a tail node — "⊞ 1,847 more · 12% of volume" — with its own ribbon (ink stays honest), its own spark, and click-through to a searchable table. For a two-supplier org the tail is empty and the view is byte-for-byte today's view.

Segments — the missing altitude

Between one org and 3,000 sits the counterparty segment: API suppliers, packaging, contract labs, logistics. Past ~100 counterparties the columns show ~8 segment bands (count · volume · trend · worst-state); clicking one re-renders the same ego view scoped to the segment — the maps-on-maps recursion, applied to the business graph.

Reciprocity: depth for breadth

The view has a fixed attention budget. When breadth is small, spend it on depth automatically — the two-supplier shop sees reservation terms, recent runs, and per-asset sparklines expanded inline; Lilly's view pushes those one click down. The small org's page feels made for them; the giant's feels in control — one codebase.

The thresholds — data-driven, never a setting

≤ 12 counterparties → everything expanded (today's view) · 13–100 → top-10 + tail node · > 100 → segments + top movers + tail · > 1,000 → search becomes the front door, segments the backdrop. The 3D graph stays capped as the top-relationships showpiece.

At scale — Amaryllis ego with a Lilly-sized network: segments, movers, tail
AMARYLLIS|NETWORK ⌕ find counterparty… NetworkWorldTwinAssets
1,862suppliers
214customers
412assets reserved out
94%volume in top 20
Supplier segments · 30d click a band → same view, scoped
API & intermediates412 orgs38% vol↗ +3
Packaging & devices623 orgs22% vol
Contract labs388 orgs18% vol↘ −9
Logistics · cold chain439 orgs10% vol
tail — all others1,847 orgs12% volopens searchable table
Top movers · 7d
+Northstar Labsnew reservation · 4 assets · testing2 d ago
Bluepeak Pharmareservation expires in 12 d · 2 assetsrenewal unsent
Contract labs segmentthroughput −9% · 3 orgs off-trendinspect →
At intimacy — Sable Ingredients ego: one supplier, depth expanded by default
SABLE|NETWORK NetworkTwinTabletAssets
1supplier
3assets reserved in
9runs · 30d
84 dto reservation review
FoodLab — your supplier same components — depth got the budget
foodlab-wayzata-texture 61% utilidle
foodlab-wayzata-rheometer 48% utilRUNNING · SBL-2607-031
foodlab-wayzata-env 24/722.1 °C · 43% RH
Reservationopen-ended · since 2026-03 · 3 assetsreview 2026-09-29
Recent runs on reserved capacity
SBL-2607-031rheometer1:42 elapsedrunning
SBL-2607-029texture2.8 hcomplete · 1.2 d ago
SBL-2606-994texture3.1 hcomplete · 4 d ago
14 · Cross-instance federation — the handshake

Two self-hosted twins, one verified handshake.

Each org holds its own keypair; the private half never leaves its walls. An invite is signed by the sender and encrypted to the recipient, lands in a request queue an admin accepts, and both sides derive the same shared key locally — no secret ever crosses the wire.

ORG A its C2 instance · asset owner BLIND HUB relay only · can't decrypt ORG B its C2 instance · consumer ① keypair Ed25519 + X25519 · priv stays home ① keypair Ed25519 + X25519 · priv stays home ② out-of-band: B shares its public org-key + fingerprint → A verifies it (TOFU) 🔒 blind ③ invite — signₕ(offer) + encrypt→B_pub ④ lands in B's request queue B's admin reviews → Accept K = ECDH(B_priv, A_pub) persist {A_pub, K, channel} ⑤ accept — signᵇ(ack) + encrypt→A_pub ⑥ K = ECDH(A_priv, B_pub) · persist channel live · the same shared key K, derived on both sides · no secret ever crossed the wire
One keypair per org — an Ed25519 identity/signing key + an X25519 key-agreement key. Only the public halves are ever exchanged; the private keys stay inside each deployment. Trust bootstrap = TOFU — the two admins verify a short fingerprint over an already-trusted channel (the contract email, a call), like SSH host keys. No central CA to stand up for beta. Nothing secret is transmitted — each side derives the shared key locally from its own private key + the peer's public key. Revocation = drop/rotate; the peer can't derive keys for new epochs.
14b · Cross-instance federation — steady state

The hub relays ciphertext it can't read.

Once paired, the owner encrypts each asset update with the shared key and wraps it in a thin routing envelope. The hub sees only opaque metadata; the consumer verifies the signature and decrypts. The federated asset appears as a read-only twin in Partner Assets.

Org A asset state · faults · trend encrypt + sign with shared key K (owner-side) BLIND HUB routes on channel_id holds ciphertext · no key verify + decrypt with shared key K (consumer-side) Partner Assets read-only twin, in B The message on the wire PLAINTEXT envelope — what the hub needs to route/store channel_id (opaque) · seq · timestamp · key-epoch · TTL · signature every field here is metadata — kept to the irreducible minimum CIPHERTEXT payload — sealed with K asset id · field names · values · schema · owner + consumer org the hub never holds the key, so it never sees any of this
What the hub can see — “channel 7f3a… carried a 412-byte message at 14:03:22.” Who-talks-to-whom is inferable from channel activity (traffic analysis); pad + opaque IDs blunt it. That’s the irreducible leak. What it can’t — identities, asset ids, field names, or a single value. Content authorization is enforced at the edges (owner encrypts per-consumer); the hub only does coarse routing. Same visibility contract as inside one instance — the grant grants existence; an open reservation/engagement gates activity. Control stays owner-only — no cross-instance commands.
14c · Cross-instance federation — the build

Assembled from mature, self-hostable parts.

Nothing exotic, nothing cost-prohibitive: a blind relay, an end-to-end layer, org keys, and a bit of app glue. We don’t invent crypto — we compose it.

Transport · the blind relay
NATS  ·  or Mosquitto / EMQX (MQTT)
Accounts (per-org isolation), leaf nodes that dial outbound (firewall-friendly), JetStream for store-and-forward. NATS exports/imports with activation tokens maps almost 1:1 to invite→grant. Self-hosted, ~free.
End-to-end encryption · the blindness
libsodium  ·  or MLS (RFC 9420)
Layered above the broker — because TLS-to-broker still lets the broker read plaintext. crypto_box for pairwise (simple, beta); MLS for group-scale membership + key rotation done to standard.
Identity & invites
Ed25519 org keys + TOFU  ·  or NATS NKeys / JWT
Decentralized — no CA. Fingerprint-verified on first contact. The invite/accept is a mutual-auth + key-agreement handshake; revoke = drop/rotate.
App glue · what we actually write
the thin layer that’s ours
Invite queue + admin accept, key persistence, the federation grant record, and the Partner Assets landing. The rest is off-the-shelf.
Three transport options, one model — blind E2E hub (firewall-friendly default) · direct point-to-point mTLS (the strict-customer option) · self-hostable hub (consortium / neutral jurisdiction). The grant is transport-agnostic. Closest prior art: Matrix — federated self-hosted homeservers, invite-into-a-room, E2E by default. A great mental model to borrow; too chat-oriented to adopt as the stack. Why this fits L7|C2 — “we are not a data pipeline you must trust with your data.” A blind relay makes that literally true and independently verifiable.