RS2 — Positioning One-Pager

Working draft for website / publicity. Internal — refine voice before publishing.


Hero

The backend runtime for the agent era — where code is safe to run before anyone reads it.

RS2 is a runtime where every service — prebuilt, custom, or composed into a pipeline — is a sandboxed function on an HTTP message. The sandbox is cheap enough (sub-10µs dispatch overhead) to run untrusted code safely by default, so agents can author and assemble entire backends without a human auditing the code. And every system they build is automatically agent-consumable: enforced schemas that can't drift from what's advertised, declared effects, and safe-retry semantics baked into the core.


Elevator (≈3 sentences)

RS2 is a runtime where every service — prebuilt, custom, or composed into a pipeline — is a sandboxed function on an HTTP message. Because the sandbox is cheap enough to run untrusted code safely by default, agents can author and assemble whole backends without a human auditing the code. Everything they build is automatically agent-consumable — schemas that are enforced exactly as advertised, declared effects, and safe-retry semantics — and a generic admin UI drives any of it without a line of per-service code, because it reads the same surface an agent does.


The one idea

Everything is a function on an HTTP message. A prebuilt service, your custom code, a multi-step pipeline, a stored query — all the same contract, all the same store pattern, all mounted per tenant and composable. You don't learn a framework; you mount and compose functions.


Why now

Agents can write code, but you can't run code you didn't review — so today agents are stuck generating code that humans must audit and deploy. RS2 removes the audit by making the sandbox the default, not the exception. That single shift is what makes agent-authored backends practical instead of theoretical.


What's actually different

Every primitive here exists somewhere already — V8-isolate multitenancy (Cloudflare Workers, Deno Deploy), Wasm-component runtimes (Spin, wasmCloud), message-functions-into-pipelines (Apache Camel, n8n), schema-driven stores (headless CMS). RS2's contribution is the synthesis under one contract, plus two properties that fall out of it rather than being bolted on:

  1. Untrusted code is the normal case. Sub-10µs sandbox dispatch + capability default-deny + per-tenant containment. Under a hostile-tenant flood, an infinite loop holds a neighbour to 1.5× baseline p99; an allocation bomb is contained to structured 503s. The sandbox is trustworthy enough to be load-bearing.

  2. Systems are agent-consumable by construction. Every mount auto-emits OpenAPI 3.1 and a /.well-known/rs2/* surface where the advertised schema is the enforced schema (no drift, by design), effect classes and idempotency guidance are published, and the whole thing is permission-filtered per caller.


One substrate, three categories of tool

The same primitives — and the same UI — span what today takes three separate products:

  • Automation (n8n / Zapier territory): typed pipelines with serial/parallel/conditional/tee modes, JSONata transforms, fan-out, retries, idempotency in the core, outbound HTTP with host allowlists, and unmodified npm SDKs (Stripe, OpenAI, Anthropic, Supabase, GitHub… 9/10 of a real SDK corpus run as-is). More robust than the visual-automation incumbents, not less.

  • Content management: file/static-site serving, schema-validated structured data, container listings — with a working editorial admin UI on top (tree browser, JSON-Schema forms, create/edit/delete).

  • Backend assembly (low-code): mount prebuilt services from a catalogue, configure them with schema forms, author and deploy custom code — all from the UI, hot-swapped atomically, with no glue code.

These aren't three subsystems glued together. They're one contract used three ways — which is why one generic UI can drive all of them.


The UI is the proof, not a side feature

rs2-ui is a generic admin/explorer (Vite + React 19 + TypeScript) that builds itself from the same surface an agent reads — the well-known catalogue, the dir+json listings, the schema= content types, the uniform store contract. One client codepath drives every mount; nothing is hand-coded per service. It already delivers: browse + view, JSON-Schema forms for any schema'd resource, full CRUD, a tenant config + mount editor (catalogue → mount → schema-form config, atomic hot-swap with optimistic concurrency), and custom-code authoring/deploy.

The point: a human GUI and an AI agent operate RS2 through the same surface. The admin UI didn't need per-service code because the runtime already publishes everything needed to drive it. If a generic UI can run any mount with zero service-specific code, so can an agent. The agent-friendliness isn't a claim — it's load-bearing enough that our own product surface is built on it.


Fourth product story: a capability-sandboxed agent harness

Give an agent exactly one tool — "send an RS2 message" — and it lands inside a fully configurable security sandbox whose powers are pure config.

  • The toolset is the mount table. One uniform contract collapses the agent's whole action space to one verb; its available tools are exactly the exposed mounts — auto-generated, self-describing, and permission-filtered per principal (/.well-known/rs2/agent-surface + OpenAPI). You get the tool manifest for free, and it is precisely what you granted.
  • Expose/deny is declarative and enforced two ways. Mount-level (which services exist for this agent) and capability-level (default-deny grants: Some(handle) = granted, None = the capability doesn't exist). The agent can be a principal with scoped RBAC roles — the same enforcement that governs human users — and it can't escalate by composing, because internal hops re-enter the same choke point and elevate is the explicit opt-in.
  • Secrets the agent can't exfiltrate — built and tested. The host owns every I/O edge (HttpOut and the socket capability are host-implemented choke points) and now injects credentials the guest never sees. A grant carries an inject ref — either "infra:<name>" (the operator supplies the whole strategy + secret in infras.json) or an inline strategy drawing on a granted tenant secret:<name> — resolved host-side at tenant build into the outbound injector, never written back into any guest- or tenant-visible config. Strategies cover Bearer / header / Basic / query-param / HMAC / AWS SigV4 (adapters/credential.rs), applied in the httpOut grant path and in a no-code proxy service (fixed-target forward-with-auth). Proven by tests/credential_inject.rs and tests/proxy.rs, which assert the secret is absent from both the guest ctx and GET /services/raw. So an agent can use an API key it can never read.
  • The exfiltration gap is closed by design, not just by discipline. Hiding the raw secret only stops exfiltration when paired with a tight egress restriction — and both injection points enforce one: the httpOut grant has its hosts allowlist, and proxy fixes the target ("the mount is the allowlist"). The capability model still makes every hop auditable; the safe configuration is now the structural default at these seams, not a manual precaution.

Why this is differentiated: most agent harnesses sandbox coarsely, at the process/container level. RS2 sandboxes at the capability-and-message level, declaratively — and the action space is self-describing and per-principal.


Why RS2 is so adaptable (the deep version)

It is adaptable because it is not really a framework — it is a small closed algebra with four orthogonal properties, and the breadth (CMS, low-code, automation, agent harness, unified repo) is their product, not a feature list:

  1. One universal type, one universal operation, closed under composition. Everything is an HTTP message; every service is message → message; outputs are the same type as inputs, so anything composes with anything. Power comes from closure, not a big API. (Unix pipes / lambda calculus / a monoid of endomorphisms.)
  2. One uniform interface; differences are feature-detected facets, not new shapes. Low shape-cardinality means every consumer — the generic UI, an agent, any client — generalizes across every producer for free. (REST's actual uniform-interface thesis, whose stated purpose was evolvability.)
  3. Reflective: the system describes and edits itself in its own terms. The instruction plane (config + code + pipelines + queries + schemas) is data in the same store, reached through the same contract as the content it serves. Self-modification needs no new mechanism — which is why self-config, agent authoring, and the git workflow all fall out for free. (Homoiconicity.)
  4. Externally decoupled: the only coupling to the world is a swappable capability. The same logic runs against any infrastructure by changing an adapter in config (local fs ↔ S3 ↔ a JS bundle speaking raw Mongo). (Dependency inversion at the root.)

Breadth is the product of these, not a sum. The tell that the power is multiplicative rather than additive is exactly the experience of "it naturally does one more thing" — the historical signature of the designs that lasted (Unix, Lisp, the relational model, the Web).

Corollary: one repository for front end and back end

This is not a new claim — it falls straight out of (2) + (3), which is itself evidence for the thesis. Because the UI is generic (no per-service code; it renders itself from the schemas and contracts the backend publishes — property 2), the front end is largely not code — it is a projection of the backend's self-description. And because that description is data in the instruction plane (property 3), the whole application — services, mounts, pipelines, queries, schemas, and the UI configuration the generic front end consumes — can live as one source of truth in one repository, already mechanically extractable for git. Front end and back end are not two artifacts kept in sync; the front end is derived from the back end's description, and "schema-advertised == schema-enforced" means there is no drift to manage by construction. An application becomes a declarative description + generic runtime + generic UI + a little sandboxed custom logic.

Honest boundary: strongly enabled, partially realized. Schema-driven forms and the mount catalogue already work this way; pushing all UI configuration (views, layouts, the eventual pipeline graph) into the instruction plane completes it. Bespoke/branded UIs still need real front-end code — the claim holds for the large class of CRUD/admin/config/automation apps, where the front end is a projection, not a separate build.


Adjacent work: agent-native (Builder.io) — convergent thesis, different layer

Builder.io's agent-native framework (BuilderIO/agent-native) is the closest public peer, and the convergence is validating: it independently arrives at the same thesis — define a capability once, fan it out to every surface with no drift, let a human GUI and an agent operate the same system through the same capabilities under one permission model ("anything the UI can do, the agent can do"). A serious, well-resourced team is proving the demand. It also means "agent-native" is now a named category, not an unclaimed novelty — RS2's distinctiveness must rest on the layer it operates at, not on the idea of agent-nativeness.

They bet on a different layer, and that is the whole difference:

agent-native (Builder.io) RS2
Layer Application framework Infrastructure runtime / primitive
Unit defineAction (typed RPC action) HTTP message (message → message), REST/store-shaped
Stack TypeScript, React, Nitro, Drizzle/SQL Rust crate + server; V8/Wasm engines
Agent role Participant in a developer-built app Author + operator — writes & deploys services
Trust model Human auth parity (session, guards, RBAC) Capability sandbox — untrusted code safe by default
Sandboxing None (agents run within trusted app code) sub-10µs dispatch, default-deny, per-tenant containment (benchmarked)
Composition Write TS; jobs/skills Declarative pipelines (idempotency, retries in core)
State SQL coordination + real-time human+agent "multiplayer" Stores/capabilities; no built-in bilateral sync
Protocols MCP + A2A first-class OpenAPI 3.1 + well-known surface; MCP-aware (?surface=mcp)
Maturity Builder.io-backed, templates, npx create Pre-1.0, embeddable, multi-tenant

The one-line difference: agent-native makes agents safe participants in an app you wrote, governed by your auth; RS2 makes agents safe authors of backends nobody audited, governed by a sandbox. Their "governed execution" is authorization; RS2's is code isolation. Different threat models — and the sandbox is the thing they explicitly don't have.

Positioning consequence — complement, don't compete: don't out-app-framework them (they have a company, React, templates, polish). Their existence sharpens the wedge. Lead with the sandbox + declarative infra composition + embeddable multi-tenant runtime — a layer below them. The strongest framing: "agent-native app frameworks need a runtime where agent-written code is safe to run; that's RS2." Cite the convergence as proof the category is real, then differentiate on the threat model.

Schema discovery: one shape vs. a typed set of shapes

agent-native's per-action Zod schema is a single chokepoint, so its schema discovery is uniform by construction — there is only ever one shape. RS2 instead models three conversation shapes, each carrying the schema natural to it: entity/store (the resource schema — e.g. a data mount's dataset schema, inlined into OpenAPI bound to {dataset}/{key}, identical to what the runtime enforces on write), query/view (params + output), and action (inputSchema/outputSchema, covering pipelines, code: services via a deploy manifest, and wrappers). As of the discovery-completion work, every mount now carries a discoverable schema appropriate to its pattern, and the OpenAPI document is fully self-contained (no $ref left to resolve by a second fetch).

So the honest claim is "schema-advertised == schema-enforced, no drift, across all service types" — with the footnote that RS2's uniformity lives at the pattern layer (every mount declares pattern + facets; the pattern tells a consumer which schema shape to expect), not at the single-schema layer. This is a deliberate trade, not a deficiency: agent-native gets one-shape simplicity but forces a CRUD store into the RPC-action mold, losing native store semantics (ETags, ranges, listings, conditional writes) unless each is re-built as an action; RS2 keeps those semantics for free at the cost of a consumer understanding ~3 patterns. (Residual non-uniformity: the agent-surface document still represents an entity's schema by reference (schemaUrlPattern) rather than inlined, and key names vary by kind — harmonizing these would make /agent-surface as self-contained as OpenAPI; minor, optional.)


Long-form narrative (page / essay structure)

  1. The hook (why now): agents write code; you can't run unreviewed code; RS2 makes the sandbox the default and removes the audit.
  2. The one idea: everything is a function on an HTTP message; one contract for services, code, pipelines, queries.
  3. The mechanism that makes it real: sub-10µs dispatch, capability default-deny, per-tenant containment — with the benchmark numbers as the credibility anchor.
  4. The payoff for builders: content, structured data, automation pipelines with idempotency/retries, and custom logic on real npm SDKs — from the same parts, with a generic UI on top. No three-tool stack.
  5. The payoff for agents: agent-consumable by construction (well-known surface, no schema drift, declared effects, safe retries); agents extend infrastructure (loadable adapters speaking raw Postgres/Mongo/Redis as JS bundles) without recompiling the host. The UI is the live demonstration.
  6. Honest boundaries: scope, not gaps (below).

Roadmap & honest boundaries

State these plainly — it builds trust and inoculates against "but it's not really X" reactions:

  • Pre-1.0, single-binary / stateless scale-out; no hosted control plane yet; embedding API explicitly 0.x.
  • Visual pipeline builder — planned, and a small lift. Pipelines are already a typed spec stored in a spec store and authored over the same store contract the UI speaks. A node/arc canvas is one more editor over a data shape the system already validates and round-trips; the pipeline modes map directly onto nodes and edges, and ?$plan introspection can drive live graph validation/preview. Framed correctly, the n8n-style visual builder isn't a competitor's moat — it's another editor tab over an existing typed surface.
  • UI configuration into the instruction plane — completes the unified repo. Move view/layout/pipeline-graph config out of the SPA's env and into the tenant's instruction plane, so the whole application is one source of truth.

What not to claim

  • Don't call it a "genuinely new web framework" — name the precedents (Cloudflare Workers, Spin, Camel, n8n) yourself and say what's different (one contract + agent-consumability + embeddable Rust crate). Pre-empting the gotcha beats getting hit with it.
  • Don't say "it is a CMS / it is n8n." Say "you build the CMS, the automation layer, and the glue out of the same parts."
  • Keep the containment benchmarks prominent — the whole pitch rests on the sandbox actually being trustworthy.
  • Don't claim sole authorship of "agent-native" — Builder.io owns that flag too. Position RS2 as the safe-execution runtime layer beneath an agent-native app framework, and differentiate on the sandbox / threat model.
  • Don't overclaim schema uniformity (agent-native is genuinely more uniform via one action shape). Claim what's true and stronger for a resource model: complete schema coverage with no drift, uniform at the pattern layer.