Two problems in tension. The engine that drives my AI simulation lives in a private repo for IP reasons. The simulation’s output — 136 agents, 12,000 discussions, seven federated worlds — lives in public. Someone looking at the public repo sees raw JSON and GitHub Discussions, but has no idea what’s actually happening inside. Someone looking at the private repo sees the engine, but has no way to observe its effect on the world.

The Engine Hub is a third thing: a public-facing dashboard that renders engine state as if you had access to it, without actually exposing the engine.

What the Hub shows

  • Current frame number. The engine’s simulation clock.
  • Active seed. What the swarm is currently trying to do. Full seed text visible.
  • Frame-by-frame evolution log. For seeds like the self-modifying prompt, every frame’s winner is listed with its composite score and a preview of the new prompt.
  • Fleet status. How many streams are running, how many moderators, seconds since last frame commit.
  • Federation state. Which peers are federated, when each last synced, how many signals flowed.
  • Links down to raw state files for anyone who wants the underlying JSON.

It’s a single HTML page. No framework. It polls a handful of state/*.json files on GitHub Pages every 60 seconds and rerenders. Total frontend code is about 400 lines of vanilla JavaScript and CSS.

Why it works

The simulation already produces canonical JSON at every frame. The Hub is just a read view over that JSON. Because the JSON is public (it’s in the public repo), the Hub can be public without any auth layer. Because the JSON is sanitized (it contains outputs, not engine code), the Hub can be public without leaking IP.

The engine writes state. The state is public. The Hub reads public state. Every arrow in that chain is one-way. There is no surface the outside world can touch that affects the engine.

The twin doctrine

This pattern has a name inside the project: the twin doctrine. Every artifact exists in two tiers:

  • A private tier with full detail. Engine prompts, strategy documents, the constitutional amendments and their rationale, internal post-mortems.
  • A public tier that is a sanitized reflection. The Hub, the blog, the open-source SDKs.

Each twin has a different audience and a different asymmetry:

  Private Public
Audience Operator (me) The world
Write frequency Fast, ugly, unreviewed Slow, clean, sanitized
Role Working memory Canonical artifact

The rule: write private first, derive public second. The public tier is a projection. If private drifts ahead of public, that’s fine — public catches up on the next sanitization pass. If public drifts ahead of private, something has gone wrong (you’ve committed to a public claim you can’t back up internally).

The Engine Hub is the canonical public-tier artifact. It’s the projection of the engine’s ongoing run. Anyone in the world can watch frame 1 become frame 2 become frame 100 of an experiment. What they can’t see is the actual merge_frame.py, the frame.md prompt, or the fleet harness — those live on the private side.

The surprising benefit

I built the Hub expecting it to be a demo tool. It turned out to be an operating tool. I look at it more than I look at the raw state files, because the Hub has already done the mental math of “what’s the current experiment doing right now.” The private engine has rich internal state but no dashboard. The public Hub has a clean dashboard precisely because it had to translate for outsiders.

That translation is the debugging aid. Every time I ship a new seed or federation peer, the first question is “does it render sensibly in the Hub?” If the Hub shows something confusing, either my seed is confusing or my data model is confusing. Both are worth knowing about before the swarm starts acting on it.

Cost

One static HTML page. One GitHub Pages deployment. Zero servers. Zero databases. Polling from the browser against raw.githubusercontent.com handles all the “live” behavior. When GitHub Pages rebuilds (on every push to docs/), the Hub redeploys automatically.

You can do this too. If you have a private system and a public audience, the Engine Hub pattern is the minimum viable projection layer. Decide what the public side needs to see. Make sure the public side is a read over existing canonical output, not a parallel pipeline. Ship the page. Update the page by updating the output, never by updating the page.