Experiments
realbook · the jazz fake book · open it to any tune, play it instantly

Point it at a schema.
Get the whole product.

WordPress ate the web on two moats: a deployment story anyone could execute, and a plugin economy — and its permanent wound is that every plugin is a root shell. Directus and PocketBase modernized the derive-from-schema idea, but each kept only half. Realbook is the full set: PocketBase's deployment, Directus's data platform, WordPress's economy — behind a gate. One binary you scp. One Postgres. Plugins that can't name what they weren't granted.

postgres:// your schema — existing, or declared in G#
derive admin UI · REST + realtime APIs · auth · roles · files
one binary self-contained · scp it, run it
plugins signed · capability-scoped · hot-loaded
The tension nobody resolved

The economy that ate the web is also its wound

The pattern keeps winning: give me a schema, I'll give you the product. WordPress ran it on posts and pages and took forty percent of the web. Directus and PocketBase ran it on real databases and took the developers who'd sworn off PHP. And every winner kept a fatal flaw — because the three things that matter have never fit in one runtime. Each kept one:

wordpress kept

The economy.

60,000 plugins, each one arbitrary PHP with database root. The economy is why it won; the trust model is why it's the most attacked application surface on the internet. Every install is an act of faith, renewed on every update.

directus kept

The clean data platform.

Point it at Postgres, get the admin and the APIs — the right idea, on Node: a runtime, a node_modules tree, a compose file. Deployment is someone's job again, and the someone is you.

pocketbase kept

The single binary.

Brilliant, SQLite-shaped, scp-and-run — the WordPress install story finally modernized. But the extension story tops out at hooks compiled into your own build. There is no economy, and by design there can't be one.

nobody kept

All three at once.

The economy, the platform, and the binary — because nobody had a runtime that could load governed native plugins into one process. Interpreters can't gate what they can't see; compiled binaries can't load what they didn't ship.

The one-sentence mind-blow: the CLR can. Assemblies are the plugin format, AssemblyLoadContext is the isolation seam, and a capability manifest is the contract — so the plugin economy gets what npm never had: a gate. This is the streng/kern discipline arriving through the side door, wearing a .NET badge.
How it runs

Introspect. Derive. Serve. Admit.

Four verbs, one binary. Realbook is written in G# — David Obando's modern .NET language, real and public at v0.3 with a compiler, an MSBuild SDK, and VS Code tooling — and compiles to ordinary CLR assemblies, which means every BCL type and NuGet package is already inside the tent. The framework ships no scaffolds and generates no code you own. It derives, continuously.

introspect — the schema is the score

Point it at an existing Postgres, or declare data classes in G# and let it create the tables. Either way: tables, relations, and enums become the catalog — the single model everything downstream is derived from. Legacy databases walk in as they are.

derive — the product follows the schema

The admin UI, REST + realtime APIs over SignalR, auth, roles, row-level rules, and file handling — derived, not scaffolded. There is no generated code to drift. Change the schema and the product follows, the same way a view follows a table.

serve — the WordPress install story, no PHP

One self-contained binary: realbook serve. scp it to a $4 VPS, write a systemd unit, done. No runtime to install, no node_modules to ship, no compose file to explain. The deployment story is the onboarding story.

admit — plugins enter through a gate

Signature checked against the publisher's key. Capability manifest read aloud — charges.write, not contacts.read — and granted explicitly. Then loaded hot into an isolated AssemblyLoadContext, without a restart. Revoke unloads it just as cleanly.

The stack

What each ancestor contributes — and what only realbook has

Realbook the framework's own
wordpress economy · directus platform · pocketbase deploy — one artifact The derivation engine plus the plugin gate. Everything below is a known good idea; what's new is that they cohabit one process — a product derived from your schema, extended by an economy of strangers, without handing the strangers root. Nobody has shipped that combination, because nobody had the runtime.
Charts the catalog
the real book metaphor — every table gets a chart Schema introspection produces the catalog: for every table, a chart — the admin view, the API surface, the permission grid. Like the fake book, a chart is enough to play the tune competently on sight; virtuosity comes later, in owned code.
Plugins the economy
clr assemblies · signed · capability-manifested A plugin is a G# or C# data class plus hooks, compiled to an ordinary assembly, signed by its publisher, and hot-loaded into an isolated AssemblyLoadContext. Its manifest names the capabilities it needs; the gate hands it those objects and nothing else exists in its world.
Wire the surface
rest + signalr realtime · webhooks out Every chart is a REST resource and a realtime subscription: query it, page it, subscribe to its changes over SignalR. Webhooks fire outward on the same events the plugins hook inward. One event stream, two audiences.
Data the truth
postgres as truth · rls compiled from roles Postgres is not a backend detail — it is the product's memory and the source the catalog is derived from. The roles model compiles down to row-level security, so a rule declared once in the admin holds even for a connection that bypasses realbook.
Substrate substrate
the only two things on the server One self-contained CLR binary and one Postgres. No Node, no PHP, no sidecar, no orchestrator. The entire operational surface of the product is a process and a database — which is to say, the two things your operator already knows how to keep alive.
Admission

A plugin can't name what it wasn't granted

The canonical exchange: a publisher ships an assembly, and the gate answers — before anything runs — with a transcript. Everything on the left is plain G#, faithful to the shipped language tour — @-style attributes, Go-style parameters, if let over a nullable result; everything on the right happens before the plugin's first instruction executes.

a pluginstripe-payments.gs
package Stripe.Payments

import Realbook.Plugin
import Stripe

@Plugin("stripe-payments",
  Capabilities: ["charges.write", "orders.read"])
class StripePayments {
  let charges Granted[Charges]  // injected by the gate

  async func onOrderPaid(order Order) {
    if let charge = await charges.create(order.total) {
      order.receipt = charge.id ?? ""
    }
  }
}
the gate
the transcriptrealbook install stripe-payments
install stripe-payments v1.4.2 · publisher: acme-labs

signature         acme-labs key · pinned
manifest         charges.write   orders.read 
                 contacts.* — not requested, not granted
load              isolated AssemblyLoadContext · no restart
hooks             onOrderPaid ⇠ orders.paid
admin             new card: Payments

→ live. revoke = unload —
no orphaned tables, no zombie hooks.

The capability object is the only door. An ungranted API isn't rejected at runtime — it is absent from the plugin's world at load time; the code that would call it has nothing to call it on. And because plugins are CLR assemblies — and gsc really does emit ordinary managed assemblies, this is a fact about the shipped compiler, not a hope — the economy is polyglot from day one: C# shops publish, G# shops publish, F# shops publish if they like — the gate doesn't care what compiled you, only what you're asking to touch.

Admission, performed

The manifest says may. The audition shows does.

Signature and manifest are paperwork — necessary, static, and silent about behavior. So before a grant, realbook makes its own metaphor literal: the candidate plugin performs. The gate forks a snapshot of the data, loads the plugin into an isolated context with every outbound call captured, and replays yesterday's real event stream against it. What comes back is not a claim. It is a transcript of what the plugin actually did with your actual traffic — produced before its first instruction ever runs live.

the audition · before the grantrealbook audition stripe-payments
$ realbook audition stripe-payments

stage         forked snapshot · isolated ALC · outbound captured
replay        yesterday's event stream · 41,882 events · 24h
behavior     charges.write      312   ✓ within manifest
             orders.read      1,102   ✓ within manifest
             contacts.*           0   · never attempted
webhooks     3 fired · captured, not delivered
verdict      clean audition · transcript pinned to listing

grant? the transcript is the argument.

Auditions re-run on every update, which turns the transcript history into a drift detector: a v1.5 that suddenly reads tables v1.4 never touched is a headline at the gate, not a diff buried in a changelog. And because the latest transcript is pinned to the marketplace listing, “what does this plugin actually do” is answered with evidence instead of a README — WordPress can't do this (arbitrary PHP, no event stream) and npm can't do this (no runtime gate); realbook can because the stream and the gate already exist.

What we won't pretend

What the gate costs

In-process isolation is not a security boundary.

Code Access Security died for a reason; AssemblyLoadContext isolates loading, not malice. The capability gate is discipline plus review plus signing — a strong deterrent and a clean contract, not a sandbox. Real sandboxing means out-of-process or WASM plugin hosts, and realbook holds that lane in reserve for hostile-plugin tiers, stated plainly rather than implied away.

Hot-loading forecloses Native AOT.

An AOT-compiled binary cannot load assemblies at runtime. So realbook with plugins ships as self-contained CoreCLR — roughly 80 MB, still one file — and a lean AOT build exists only for plugin-free deploys. Two artifacts, one honest tradeoff, chosen in favor of the economy.

Auditions can be gamed.

A plugin can play beautifully in replay and differently on stage — detect the sandbox, wait thirty days, trigger on an event yesterday's stream didn't contain. The audition raises the cost of malice and catches sloppiness nearly for free, but it is a screen, not a proof: re-audition on update, runtime capability accounting, and the out-of-process tier remain the deeper walls behind it.

Economies cold-start.

WordPress's moat is twenty years of plugins solving twenty years of niches. Realbook starts at zero, and its gate — the whole point — is also a barrier to the sloppy long tail that made WordPress huge. The bet is that a smaller, vouched-for catalog beats a vast untrusted one; the bet is not yet won.

Derivation has a ceiling.

Real products outgrow generic admin. The escape hatch — eject a chart into owned G# code, chord's territory — must be genuinely first-class, or realbook becomes a prototype trap: wonderful for the first month, resented by the twelfth.

Zero training corpus, v0.3 language.

Models write C# fluently and G# barely. The language is further along than a sketch — a full written spec, a compiler, dozens of releases — but it is v0.3 from one primary maintainer, and no model has trained on it. Plugins can be C#, and the G# surface a plugin author touches is thin — but the loss is real and stated, not waved away with "the models will catch up."

Schema-first inherits your schema's sins.

A bad legacy schema derives a bad product: cryptic column names become cryptic admin labels, missing foreign keys become missing relations. Introspection is honest, not redemptive — realbook shows you your database as it is, and fixing it is still your job.

The pitch, in one sentence: point realbook at a Postgres and get the admin, the APIs, the auth, and the files as one binary you scp — then grow it through a plugin economy where every extension is signed, capability-scoped, and unable to name a single thing it wasn't granted.