diff --git a/README.md b/README.md
index 3f30318..c4ff3cd 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,152 @@
# ReactiveScript
-Codename for a language that carries Solid 2.0's reactive semantics as language
-semantics: equations by default, writes confined to imperative scope, ownership
-and async (pending, holds, lanes) as things the compiler checks rather than the
-runtime warns about.
+A small language for reactive UIs that carries
+[Solid](https://github.com/solidjs/solid) 2.0's reactive semantics as
+*language* semantics, and checks them before your code runs. Files are `.rx`;
+they compile to plain Solid 2.0.
> **Status:** early design work. The spec, its scenarios and the reference
> implementation change often, and nothing here is released. See
> [CONTRIBUTING.md](CONTRIBUTING.md) to run the suite or propose a change.
-This repository is the **spec** and its **reference implementation**. The
-production compiler is a separate Rust crate over Solid's own
-`solidjs-compiler` (`spec/11-compiler.md`): ReactiveScript parses, checks
-and lowers to an Oxc AST; Solid's compiler lowers the JSX. `ref/` is its
-conformance suite, run on Solid's `next` branch built from source.
+## Why
-## Layout
+In Solid you already write UIs as derivations over signals. Most of what goes
+wrong is a *shape* mistake: writing to something that should be derived,
+writing during a computation, reading async data with no loading or error
+boundary above it, leaking a value past the owner that created it. Solid's
+dev runtime warns about many of these when they happen. ReactiveScript makes
+them things the compiler refuses, the way Rust refuses a borrow, so the
+program that runs is one where those mistakes cannot happen
+([spec/08](spec/08-constraints.md), [spec/99](spec/99-diagnostics.md)).
+
+The checks are static only. A `.rx` program compiles to ordinary Solid 2.0
+code and adds nothing at run time beyond what Solid does
+([spec/11](spec/11-compiler.md)).
+
+It is also meant to be easy for an AI to write correctly. The rules are
+small and explicit, and each checker error names the rule it enforces and usually the fix. We
+test that directly: fresh agents given only the spec wrote the apps in
+[`examples/ai`](examples/ai) and [`examples/ai2`](examples/ai2) cold and
+predicted 70 of 71 frames of their behaviour before running them
+([examples/README.md](examples/README.md)).
+
+## A taste
+
+Three kinds of names do all the work:
+
+- `source x := 0` is state. Only a source can be written, with `:=`.
+- `y = x * 2` is an **equation**: it is always true, and recomputes when
+ what it reads changes (E-1).
+- Writes happen only in imperative scope: an event handler or an `action`
+ (W-1, W-2).
+
+```rx
+export default component Counter() {
+ source count := 0
+ double = count * 2
+
+
+}
+```
+
+Write to the equation instead, `double := 4`, and the checker refuses it:
+
+```
+counter.rx:5: error WRITE_TO_NON_SOURCE [W-1] double is an equation: only sources are written (W-1)
+```
+
+Async is an `await` in an equation. The compiler tracks that the value can be
+pending and can fail, so it asks you to say what to show in both cases:
+
+```rx
+import pure { fetchUser } from "./api" // `pure`: safe to call from an equation (R-io-4)
+
+export default component Profile() {
+ source id := 1
+ user = await fetchUser(id) // re-asked whenever `id` changes
+
+
+
+ {errored fallback(e) {
Couldn't load: {e.message}
} {
+ {loading fallback {
Loading…
} {
+
{user.name}
+ }}
+ }}
+
+}
+```
+
+Leave out the `errored` boundary and it does not compile:
+
+```
+profile.rx:10: error UNHANDLED_FAILURE [R-f-5] a reader of user.name (in ) can fail with Error and no catch or errored boundary above it discharges Error — wrap it in `errored fallback(e) { … } { … }`, or catch it: `… catch (e) => …`
+```
+
+Beyond this the language has structured stores with per-path writes
+([spec/06](spec/06-stores.md)), optimistic updates and held values while new
+data loads ([spec/05](spec/05-holds.md)), modules that own their state and
+export actions to change it ([spec/09](spec/09-modules.md)), streamed SSR with
+hydration ([spec/10](spec/10-server.md)), `server fn` for code that runs on
+the server ([spec/12](spec/12-server-functions.md)), scoped `