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:
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.
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 andelevateis the explicit opt-in. - Secrets the agent can't exfiltrate — built and tested. The host owns every
I/O edge (
HttpOutand the socket capability are host-implemented choke points) and now injects credentials the guest never sees. A grant carries aninjectref — either"infra:<name>"(the operator supplies the whole strategy + secret ininfras.json) or an inline strategy drawing on a granted tenantsecret:<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 thehttpOutgrant path and in a no-codeproxyservice (fixed-target forward-with-auth). Proven bytests/credential_inject.rsandtests/proxy.rs, which assert the secret is absent from both the guestctxandGET /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
httpOutgrant has itshostsallowlist, andproxyfixes thetarget("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:
- 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.) - 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.)
- 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.)
- 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)
- The hook (why now): agents write code; you can't run unreviewed code; RS2 makes the sandbox the default and removes the audit.
- The one idea: everything is a function on an HTTP message; one contract for services, code, pipelines, queries.
- The mechanism that makes it real: sub-10µs dispatch, capability default-deny, per-tenant containment — with the benchmark numbers as the credibility anchor.
- 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.
- 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.
- 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
?$planintrospection 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.