# 00 — What Greenfield Is and How It's Structured ## The one-paragraph summary Greenfield is a Wayland compositor that runs partly in the browser (the actual compositing and rendering, written in TypeScript against WebGL / WebCodecs / WASM) and partly on a Linux host (a Node.js process that hosts real Linux Wayland apps via `libwayland-server` and bridges their wire traffic to the browser over WebSocket). The two halves together let you display **real Linux applications** (GTK3/4, Qt, xterm, X11 apps via XWayland) inside a browser tab, as if they were native browser apps. An optional Emscripten-based SDK lets you compile separate Wayland apps to WASM and run them entirely in the browser with no Linux host required. ## Repo layout ``` greenfield/ ├── README.md # "The in-browser wayland compositor" ├── package.json # yarn 4.5.0 workspaces: libs/*, packages/*, examples/webapps/*, examples/compositor/* ├── .yarnrc.yml # nodeLinker: pnpm, global cache off ├── yarn.lock # 9368 lines ├── publish.sh # yarn workspaces foreach npm publish ├── protocol/ # Wayland XML protocol definitions (4 files) │ ├── wayland.xml # Core Wayland protocol (124KB) │ ├── xdg-shell.xml # Desktop shell protocol (48KB) │ ├── wayland-drm.xml # DRM buffer formats (8.8KB) │ └── web-bitmapbuf-unstable-v1.xml # *** Greenfield custom extension (2KB) *** ├── libs/ # 9 internal @gfld/* libraries │ ├── common/ # @gfld/common - shared client/server runtime (wire format) │ ├── client-protocol/ # @gfld/client-protocol - browser-side generated Wayland bindings │ ├── compositor-protocol/ # @gfld/compositor-protocol - Node.js-side generated Wayland bindings │ ├── client-generator/ # CLI: XML → TS browser protocol source │ ├── compositor-generator/ # CLI: XML → TS Node protocol source │ ├── compositor-proxy-generator/ # CLI: XML → TS proxy protocol source │ ├── compositor-wasm/ # pixman + xkbcommon compiled to WASM │ ├── compositor-ffmpeg-h264/ # FFmpeg n5.1.2 compiled to WASM (H.264 software fallback decoder) │ └── xtsb/ # X11/XCB TypeScript bindings (vendored) ├── packages/ # 4 user-facing @gfld/* packages │ ├── compositor/ # @gfld/compositor - browser-side Wayland compositor library (AGPL) │ ├── compositor-shell/ # @gfld/compositor-shell - Preact+Tailwind SPA shell (AGPL) *** OUT OF SCOPE *** │ ├── compositor-proxy/ # @gfld/compositor-proxy - native Wayland compositor proxy (AGPL, Linux-only) │ └── compositor-proxy-cli/ # @gfld/compositor-proxy-cli - CLI binary (AGPL, Linux-only) ├── sdk/ # Greenfield WebAssembly SDK (for browser-resident WASM apps) │ ├── README.md │ ├── build.sh # clones emsdk 3.1.60, builds 30+ sysrootlibs │ ├── sdk_env.sh # exports PKG_CONFIG_LIBDIR + PATH=toolkit/bin │ ├── toolkit/ # gfcc/gf++/gfar/gfnm wrappers around emcc + wayland-scanner + meson cross inis │ └── sysrootlibs/ # 34 build scripts for cross-compiling graphics stack (wayland, pixman, cairo, pango, gtk4, etc.) ├── examples/ │ ├── compositor/experimental-fullscreen/ # vite PWA kiosk running a single remote app │ ├── docker-compose/ # Dockerfile + applications.json + docker-compose.yml for gtk3-demo/gtk4-demo/xterm/glxgears │ ├── sdk/simple-shm/ # Weston simple-shm.c built with gfcc + wayland-scanner │ ├── sdk/weston/ # Weston clients (terminal, dnd, editor, keyboard, flower, ...) meson-built │ ├── sdk/gtk4/ # GTK4 demos meson-built to WASM │ └── webapps/ # Pure-JS browser demos: simple-shm, webgl, weston-clients (symlink), gtk4 ├── docs/ # Jekyll site (CNAME: udev.be/greenfield) │ └── pages/{components, design, future_plans, getting_started, sdk} └── docker/ # Production Dockerfile for compositor-proxy-cli ``` ## The dual-side architecture Greenfield is split into **two cooperating halves**, connected over WebSocket (or, in the future, WebTransport). Understanding this split is fundamental to everything else in this bundle. ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ BROWSER SIDE (TypeScript + WASM) │ │ │ │ ┌─────────────────────────┐ ┌──────────────────────────────────────────┐ │ │ │ @gfld/compositor-shell │ │ @gfld/compositor │ │ │ │ (Preact + Tailwind SPA)│───▶│ - Session, Compositor, Surface, Seat │ │ │ │ *** OUT OF SCOPE *** │ │ - Keyboard, Pointer, Touch, Xkb (WASM) │ │ │ └─────────────────────────┘ │ - Output (WebGL canvas) │ │ │ │ - render/ (WebGL shaders: YUV→RGB, etc.) │ │ │ ┌─────────────────────────┐ │ - desktop/ (Floating vs AlwaysFullScreen) │ │ │ │ JS/WASM webapps │───▶│ - remote/ (Channel, kcp.ts, decoders) │ │ │ │ (use @gfld/client- │ │ - browser/ (dnd, selection, input) │ │ │ │ protocol + common) │ │ │ │ │ └─────────────────────────┘ └──────────────┬──────────────┬─────────────┘ │ │ │ │ │ │ depends on ▼ ▼ │ │ ┌─────────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ @gfld/compositor│ │ @gfld/common │ │ @gfld/xtsb │ │ │ │ -protocol │ │ (Connection, │ │ (X11/XCB bindings,│ │ │ │ (Node-side │ │ wire format)│ │ used by both │ │ │ │ generated │ │ │ │ compositor+proxy)│ │ │ │ bindings) │ │ │ └──────────────────┘ │ │ └─────────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ WebSocket (TCP, perMessageDeflate=false) │ + KCP-over-WebSocket (reliable UDP, ready for WebTransport) │ + 9 endpoint paths per session ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ NATIVE SIDE (Linux, Node 18+, C) │ │ │ │ ┌──────────────────────────┐ ┌──────────────────────────────────────────┐ │ │ │ @gfld/compositor-proxy-cli│───▶│ @gfld/compositor-proxy │ │ │ │ - main.ts: http + ws │ │ - Session, SessionController │ │ │ │ WebSocketServer │ │ - NativeWaylandClientSession │ │ │ │ - forks SessionProcess │ │ - NativeWaylandCompositorSession │ │ │ │ per browser session │ │ - NativeAppContext (launch) │ │ │ │ - --bind-port=8081 │ │ - SurfaceBufferEncoding │ │ │ │ - --applications= │ │ - Channel, FrameFeedback │ │ │ │ - --encoder=x264|nvh264 │ │ - XWaylandSession │ │ │ │ - --render-device=/dev/ │ │ - kcp.ts (1100-line TypeScript impl) │ │ │ │ dri/renderD128 │ │ - wayland-server.ts (TS wrapper) │ │ │ └──────────────────────────┘ │ - io/, encoding/, protocol/ │ │ │ └──────────────┬──────────────┬─────────────┘ │ │ │ │ │ │ depends on ▼ ▼ │ │ ┌────────────────────────┐ ┌────────────────────────────────┐ │ │ │ @gfld/compositor-proxy-│ │ native/ (C, built via CMake + │ │ │ │ generator │ │ Ninja) │ │ │ │ (generates *_interface │ │ - wayland/src/addon.c │ │ │ │ and *_interceptor.js) │ │ - encoding/src/gst_frame_ │ │ │ └────────────────────────┘ │ encoder.c │ │ │ │ - poll/src/poll.c (libuv) │ │ │ │ - wayland-server/ (patched) │ │ │ │ - westfield-*.c (EGL, dmabuf, │ │ │ │ XWayland, etc.) │ │ │ └────────────────────────────────┘ │ │ │ │ Native Wayland apps (GTK3/4, Qt, xterm, X11 via XWayland) attach to the │ │ proxy as if it were a real wl_display. The proxy encodes each surface's │ │ buffer to H.264 via GStreamer (x264 software or nvh264 hardware) using │ │ zero-copy dmabuf, sends frames over WebSocket/KCP to the browser. │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ## Tech-stack table | Category | Component | Tech / Version | Role | |---|---|---|---| | **Languages** | Browser TS | TypeScript ^5.5.2 | All `@gfld/*` TS packages | | | Native C | C99 | `packages/compositor-proxy/native/` | | | Shell | bash | sdk/build.sh, toolkit wrappers | | | Python | python3 (xcbgen) | libs/xtsb protocol generation | | **Build tools** | Workspace | Yarn 4.5.0 (Berry, pnpm nodeLinker) | Monorepo workspace mgmt | | | Browser bundler | Vite ^5.3.1 | compositor-shell, examples | | | TS compiler | tsc ^5.5.2 | libs/* and packages/* build | | | Native build | CMake 3.13+ + Ninja | packages/compositor-proxy `build:native` | | | Native pkg | @vercel/pkg (Brotli) + @vercel/ncc | compositor-proxy-cli single-binary | | | Lint/format | ESLint ^8.57 + Prettier ^3.3.2 | All TS packages | | | Test | Jest ^29.7.0 + ts-jest ^29.1.5 | libs/xtsb, packages/compositor-proxy | | **WASM toolchain** | Emscripten (libs build) | emsdk 3.1.46 | libs/compositor-wasm, libs/compositor-ffmpeg-h264 | | | Emscripten (SDK build) | emsdk 3.1.60 | sdk/build.sh (sysrootlibs) | | | Meson cross | meson-gf-cross.ini (host_machine: wasm32/emscripten) | sdk/toolkit | | **Wayland / GL stack** | wayland.xml / xdg-shell.xml / wayland-drm.xml | upstream freedesktop.org | protocol/ | | | wayland-scanner | vendored at sdk/toolkit/bin/wayland-scanner | C header/codegen for native clients | | | libwayland (server) | vendored + patched at packages/compositor-proxy/native/wayland/src/wayland-server/ | native compositor server side | | | wl_drm + linux-dmabuf-unstable-v1 | implemented in native/wayland/src/wlr_*.c | zero-copy dmabuf to GStreamer | | **Custom protocol** | web-bitmapbuf-unstable-v1.xml | Greenfield extension (Erik De Rijcke, 2023) | browser JS/WASM clients wrap HTML ImageBitmap as wl_buffer via fd | | **Native GL/media runtime** | GStreamer | 1.20 (built from gitlab.freedesktop.org in docker) | H.264 encoding pipeline, plugins: base/good/bad/ugly/gl + nvcodec | | | GStreamer encoders | x264 (software), nvh264 (NVIDIA hardware), vaapih264 (Intel, experimental) | --encoder flag on compositor-proxy-cli | | | Mesa / OpenGL / EGL | libgbm1, libdrm2, libopengl0, libglvnd0, libegl1-mesa | GPU buffer mgmt + EGL rendering | | | NVIDIA | libnvidia-egl-wayland1, libnvidia-egl-gbm1 | optional HW accel | | **Browser transport** | WebSocket | ws ^8.17.1 (Node), native WebSocket (browser) | primary transport (TCP) | | | KCP | TypeScript impl (1100+ lines per side) | planned reliable UDP — future switch to WebTransport | | | WebTransport | mentioned in docs/design as future | not yet implemented | | | XWayland | xwayland package + xauth + xxd | X11 backward compat on native side | | **Browser rendering** | WebGL | WebGL1 native, `desynchronized:true` | Output.ts canvas, render/*.ts shaders | | | WebCodecs API | @types/dom-webcodecs ^0.1.11 | H.264 GPU decode in browser (preferred path) | | | WebAssembly (FFmpeg) | libs/compositor-ffmpeg-h264 (FFmpeg n5.1.2) | software fallback H.264 decode | | | WebAssembly (pixman+xkbcommon) | libs/compositor-wasm (emsdk 3.1.46) | pixel ops + XKB keymap math | | | SharedArrayBuffer + Web Workers | browser-native (COOP/COEP required) | async compositor, H.264 NAL decoder workers | | | ImageBitmap | browser-native | web-bitmapbuf-unstable-v1 backing store | | **Shell UI (out of scope)** | Preact | ^10.22.0 | compositor-shell SPA | | | Tailwind CSS | ^3.4.4 | compositor-shell styling | | | @preact/signals | ^1.2.3 | reactivity | ## Package inventory ### Browser side **`packages/compositor`** (`@gfld/compositor`, AGPL-3.0) — The browser-side Wayland compositor library. Pure TypeScript + WebGL + WebCodecs + WASM, no 3rd-party runtime deps. Exports `createCompositorSession()` and `createAppLauncher(session, 'web' | 'remote')`. Internally: `Session.ts` orchestrates, `Compositor.ts`/`Surface.ts`/`Seat.ts`/`Pointer.ts`/ `Keyboard.ts`/`Output.ts` implement Wayland semantics, `render/` holds WebGL shaders (YUV/YUVA/RGB→RGBA conversion), `desktop/` arranges surfaces (Floating vs AlwaysFullScreen), `web/` speaks to same-origin-iframe JS/WASM clients, `remote/` speaks to the native proxy (with `kcp.ts`, `websocket-events.ts`, `webcodec-buffer-decoder.ts`, `wasm-buffer-decoder.ts`, `H264NALDecoder.worker.ts`, `xwayland/`), `browser/` handles dnd/selection/ input. Output is a WebGL texture inside an HTML5 canvas. Async — a slow client never blocks another. **`libs/client-protocol`** (`@gfld/client-protocol`, MIT) — Browser-side generated Wayland protocol bindings (wayland.xml + xdg-shell.xml + web-bitmapbuf-unstable-v1.xml). Used by JS/WASM webapps via `@gfld/common` for the wire format. **`libs/compositor-protocol`** (`@gfld/compositor-protocol`, MIT) — Node-side generated Wayland protocol bindings (same 3 XMLs). Used by `@gfld/compositor` for the in-browser server-side marshalling of Wayland messages. **`libs/common`** (`@gfld/common`, MIT) — Shared client/server Wayland wire-format runtime. Two source files: `Connection.ts` (message framing + argument codec) + `index.ts`. Tiny core that both `client-protocol` and `compositor-protocol` build on. **`libs/compositor-wasm`** (`@gfld/compositor-wasm`, MIT) — pixman 0.42.2 + xkbcommon 1.5.0 compiled to WASM via emsdk 3.1.46. Exposes `src/index.ts` (`init` function). Used by `@gfld/compositor` for pixel-region math and XKB keyboard layout state. **`libs/compositor-ffmpeg-h264`** (`@gfld/compositor-ffmpeg-h264`, Apache-2.0) — FFmpeg n5.1.2 compiled to a single WASM module. TypeScript wrapper in `src/{H264Decoder.ts, H264Worker.ts, index.ts}` runs in a Web Worker. Used as the software fallback H.264 decoder when the browser lacks WebCodecs. ### Native side **`packages/compositor-proxy`** (`@gfld/compositor-proxy`, AGPL-3.0, Linux-only, Node ≥18) — Native Wayland compositor that bridges Linux apps to the browser. Has BOTH a TypeScript layer (`src/Session.ts`, `NativeWaylandClientSession.ts`, `NativeWaylandCompositorSession.ts`, `NativeAppContext.ts`, `SurfaceBufferEncoding.ts`, `XWaylandSession.ts`, `kcp.ts`, `Channel.ts`, `FrameFeedback.ts`, `wayland-server.ts`) AND a C layer (`native/`) built with `cmake -G Ninja`. The C layer produces: - `wayland-server.so` — patched libwayland-server (vendored at `native/wayland/src/wayland-server/`, with `changes.diff` and `generate_wayland_server_patch.sh`) - `westfield.so` — Greenfield's westfield-* helpers (buffer, dmabuf, egl, xwayland, fdutils) + `wlr_drm.c` + `wlr_linux_dmabuf_v1.c` + `drm-protocol.c` + `linux-dmabuf-unstable-v1-protocol.c` - `proxy-encoding.so` — GStreamer frame encoder (`gst_frame_encoder.c` + `gst_main_loop.c`) - `proxy-encoding-addon.node` + `proxy-poll-addon.node` + `wayland-server-addon.node` — Node-API addons (vendored node-api headers in `native/node-api/`) loaded by `src/addons/` - `poll.c` — epoll wrapper backed by libuv CMake deps: glib-2.0, gstreamer-1.0/app/video/gl/allocators ≥1.18, graphene-1.0, egl ≥1.5, opengl ≥3.3, libffi, gbm, libdrm. Runtime also needs libudev, mesa, NVIDIA EGL wayland/gbm drivers, xwayland. Implements `wl_drm` + `linux-dmabuf-v1` for zero-copy GPU buffer transfer to GStreamer encoder pipeline (x264 software or nvh264 hardware). Connects to browser via WebSocket; has TypeScript KCP implementation ready for the future WebTransport switch. Supports direct peer-to-peer copy-paste between two proxy instances to avoid browser round-trip. **`packages/compositor-proxy-cli`** (`@gfld/compositor-proxy-cli`, AGPL-3.0, Linux-only, Node ≥18) — CLI binary that wraps `@gfld/compositor-proxy`. `src/main.ts` runs an HTTP server + `ws` WebSocketServer on `--bind-port` (default 8081), and on first connection per `compositorSessionId` query param, `fork()`s a `SessionProcess` (src/SessionProcess.ts) — one child per active browser session. CLI args: `--applications=` (URL→executable map), `--encoder=x264|nvh264`, `--render-device=/dev/dri/renderD128`, `--base-url`, `--allow-origin`, `--bind-ip`, `--bind-port`, `--basic-auth`. The `--applications` JSON maps paths like `/gtk4-demo`, `/kwrite`, `/xterm` to executables + args + env. Packaged with `@vercel/pkg` (Brotli, target `node18-linux`) into a single static binary. **`libs/compositor-proxy-generator`** (`@gfld/compositor-proxy-generator`, MIT) — CLI that converts `protocol/{wayland,xdg-shell,wayland-drm}.xml` into TypeScript source under `packages/compositor-proxy/src/protocol/`. Used at build time only (yarn `generate` script). ### Shell side (OUT OF SCOPE for user) **`packages/compositor-shell`** (`@gfld/compositor-shell`, AGPL-3.0) — Preact + Tailwind single-page-app shell built with Vite. Depends only on `@gfld/compositor` + `preact` at runtime. Provides application launcher, keyboard config, window management UI. **Explicitly out of scope for the user** per task brief. The protocol-level integration point the user needs to know about is `UserShellApi` (see `08-app-lifecycle.md`). ### Generators (3 sibling CLIs) All three generators share the same dependency set (`camelcase`, `uppercamelcase`, `meow`, `xml2js`) and similar layout (`ProtocolParser.mjs` + `ProtocolArguments.mjs` + `index.mjs`). They consume the same `protocol/*.xml` files but emit slightly different TypeScript flavors for each side: - **`libs/client-generator`** — emits browser-side client bindings into `libs/client-protocol/src/protocol/`. - **`libs/compositor-generator`** — emits Node.js-side server bindings into `libs/compositor-protocol/src/protocol/`. - **`libs/compositor-proxy-generator`** — emits proxy-side bindings into `packages/compositor-proxy/src/protocol/`. Different file layout: `src/EndpointProtocolArguments.mjs` + `EndpointProtocolParser.mjs` + `index.mjs`. ### XWayland support **`libs/xtsb`** (`@gfld/xtsb`, MIT, repo: github.com/udevbe/xtsb) — Vendored TypeScript X11/XCB bindings. Builds from `xcbgen/ts_client.py` against 5 XCB protocol XMLs in `libs/xtsb/protocol/`: `xproto.xml`, `shape.xml`, `xfixes.xml`, `render.xml`, `composite.xml`. Dual main/module entries: `dist/main/index.node.js` (Node) + `dist/module/index.web.js` (browser). Used by BOTH `@gfld/compositor` (browser side, `packages/compositor/src/remote/xwayland/`) AND `@gfld/compositor-proxy` (native side, `src/XWaylandSession.ts`) — same TS API on both ends of the wire. On the native C side, `packages/compositor-proxy/native/wayland/src/westfield-xwayland.c` actually launches XWayland and bridges it. ### Wire between browser and native - **Transport today**: WebSocket over TCP. Browser connects to `ws(s)://:/?compositorSessionId=`. `compositor-proxy-cli` uses `ws` ^8.17.1 with `perMessageDeflate: false` (compression off for latency). The `compositorSessionId` is generated by the browser and used by the CLI to route the upgrade to the correct per-session child process. - **Transport future**: KCP-over-WebTransport (reliable UDP). The codebase already has a full TS KCP implementation in both `packages/compositor-proxy/src/kcp.ts` (~1100 lines) and `packages/compositor/src/remote/kcp.ts`. `docs/pages/design/index.md` explicitly calls out that WebSockets-over-TCP is ill-suited for real-time, that WebRTC DataChannels' SCTP congestion control is too slow, and that they're waiting for WebTransport + will pair it with KCP + forward-error-correction. - **Out-of-band data**: copy-paste between two proxy instances goes peer-to-peer (proxy → proxy) without browser round-trip, configured via `--base-url` so each proxy can advertise itself to peers. ### SDK (`sdk/`) — for browser-resident WASM apps, NOT native apps The Greenfield SDK lets you compile existing native Wayland C/C++ apps to WebAssembly and run them directly in the browser compositor (no proxy needed). Based on Emscripten 3.1.60 with three Greenfield-specific extensions: 1. `sdk/toolkit/bin/gfcc` and `gf++` — wrapper scripts around `emcc`/`em++` that inject pthread pool size, asyncify, and the unix-socket fs shim. 2. `sdk/toolkit/bin/wayland-scanner` — symlink to the natively-built wayland-scanner inside `build-sysroot/bin/wayland-scanner`, used to generate C client headers/source from xdg-shell.xml during app builds. 3. `sdk/sysrootlibs/` — 34 build scripts that cross-compile a full graphics stack (wayland, wayland-protocols, pixman, zlib, png, xml2, xkbcommon, icu, harfbuzz, freetype, fontconfig, pcre2, glib, jpeg, cairo, fribidi, tiff4, pango, gdk-pixbuf, egl-stub, glesv2-stub, epoxy-emscripten, graphene, sass, sassc, uapi-stub, upoll, cygepoll, expat, libffi; gtk4 currently broken) into `sdk/sysroot/` for static linking. `sdk/build.sh` runs everything end-to-end and writes `meson-gf-toolchain.ini` (with absolute `_SDK_DIR`). `sdk/sdk_env.sh` exports `PKG_CONFIG_LIBDIR` (pointing at `sysroot/lib/pkgconfig` + `build-sysroot/lib/pkgconfig`) and prepends `toolkit/bin` to `PATH`. Meson projects use `--cross-file toolkit/meson-gf-cross.ini --cross-file toolkit/meson-gf-toolchain.ini` (host_machine: cpu=mvp, cpu_family=wasm32, system=emscripten). **Important**: the `sdk/` is **not for native apps**. It's exclusively for **WASM apps** that run inside the browser via Emscripten. Native Linux apps on the proxy use the host's own system libraries — the Dockerfile installs them via `apt-get install libffi8 libgbm1 libgstreamer1.0-plugins-base … xwayland xauth`. ## Versioning note Every workspace package is `1.0.0-rc1`. This signals: 1. **Feature freeze for 1.0** — the architecture, protocol bindings, and public APIs are expected to be stable; no breaking changes anticipated before 1.0.0 final. 2. **Not yet production-blessed** — known issues remain (e.g. gtk4 WASM is "broken for now" per `sdk/build.sh` comment; WebTransport/KCP-over-UDP is designed but not yet active; Linux Kernel Library WASM + JuiceFS web FS are explicitly future work). 3. **Yarn Berry semantics** — `workspace:^` resolution means all `@gfld/*` deps are pinned to rc1 across the tree; if the user forks and bumps, they bump the whole tree consistently. For the user's purpose (building their own Wayland-to-HTML compositor for an Odoo 20 + JS/Python web OS), the rc1 status means they should treat Greenfield as a stable architectural reference but plan to pin to a specific commit if they fork it, since 1.0.0 final may land breaking-ish changes before the rc1 → 1.0.0 transition completes. ## License of the source The four `packages/*` (compositor, compositor-proxy, compositor-proxy-cli, compositor-shell) are **AGPL-3.0-or-later**. The lower-level `libs/*` are MIT or Apache-2.0. Anyone forking or building on the runtime packages must respect AGPL — see `11-pitfalls.md` §License for implications.