docs: four directories, and a rule for when a thing leaves the roadmap

docs/ was ten files where a plan, a description, a guide and a bug report all
sat next to each other. It is now architecture/ (what SchOS is), plan/ (what it
will be), guides/ (how to work on it) and history/ (why it is like this), with
an index that states the one rule holding it together: when something is
finished it moves from plan/ to architecture/ and is rewritten as a description
of the thing rather than a record of building it.

A ticked checkbox says the work happened. It does not say what the work
*produced*, and six months later the checkbox is all that is left. The network
stack proved the point: finished, verified end to end, and for a month the only
description of it anywhere was a checkbox four levels of indentation deep.

So roadmap.md went from 534 lines to 181 -- nothing deleted, the done work
graduated. Seven subsystems that were finished and undescribed now have
descriptions: boot, kernel, syscalls, filesystem, networking, graphics, usb,
init. Every one ends with "What it does not do", which is the section that pays;
a document listing only strengths is marketing, and the reader who needs it most
is the one about to trip over a limitation nobody wrote down.

schfs.md still opened with "phases 1 through 3 1/2 are done, phase 4 is next"
long after all five had landed. It is a description now, with the phase record
and the hard-won bugs moved to history/.

Three corrections found on the way, all load-bearing:

  * projects/schcom/README.md claimed SCM_RIGHTS was done. There is no
    sendmsg/recvmsg in the kernel at all, and an entire GUI plan rested on it.
  * The root README said "No TCP/IP" months after the stack landed.
  * history/kernel.md sec.7 was marked "in progress" on a problem that process
    groups solved.

Also adds plan/1.0.md, which draws a finish line so the open list stops being
infinite, and marks schwm/ and schde/ superseded: in Wayland the compositor is
the window manager, so that split dissolves rather than being abandoned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
Nexoniarz 2026-09-12 17:13:35 +02:00
commit 57aff40228
59 changed files with 3981 additions and 1124 deletions

167
docs/plan/wayland.md Normal file
View file

@ -0,0 +1,167 @@
# The GUI becomes Wayland
Schcom survives and changes its wire format. SchWM and SchDE are deleted. What
follows is why that is not a retreat, and what it costs.
Blocked on [foundations.md](foundations.md), items 1–4.
---
## What is deleted
`projects/schwm/` and `projects/schde/`. Both are README-only; no code is lost.
### SchWM is not abandoned — Wayland dissolves it
In X11 the window manager is a separate privileged client because X11 puts
compositing in the server and policy nowhere. **Wayland's central decision is
that the compositor *is* the window manager**: there is no protocol by which a
second process places another's windows, and every attempt to add one has been a
private extension.
So the argument in `projects/schwm/README.md` —
> *"Compositing is mechanical and must never stall: it runs every frame and a
> mistake there is a frozen screen. Window management is policy, full of special
> cases and personal taste, and it changes constantly."*
— is a real and correct observation **about X11**, which Wayland answers a
different way. It stays worth honouring, but as a **module boundary inside
Schcom**, not a process boundary: policy in its own file behind its own
interface. Do not keep it in its own process, because the protocol to talk to it
does not exist.
### SchDE is re-sited rather than deleted
A panel, a launcher and a wallpaper are ordinary Wayland clients using
`wlr-layer-shell` — MIT, an XML file, no dependency. They need no directory of
their own until one of them is written.
### `projects/schinst/` stays
Its GUI was the part tied to SchWM, and that part becomes a Wayland client.
Everything else in it — the `.sip` format, `mksip`, the apply path, the
installation environment — is untouched by any of this, and remains the
best-specified unstarted work in the tree.
---
## What survives
**Schcom stays, and keeps its name.** It already owns the display, allocates and
owns client buffers, implements surface/attach/commit, routes input from
`/dev/input/eventN`, composites multiple clients bottom-to-top, and cleans up
after clients that die.
Its own README says the protocol is deliberately Wayland-shaped — surfaces rather
than windows, buffers attached and made visible only on commit, the compositor
telling clients when to draw. That was the right call and this is where it is
cashed in: **what changes is the wire format and the buffer handle, not the
architecture.**
---
## What has to exist first
Items 1–4 of [foundations.md](foundations.md), and the first three are absolute —
libwayland does not start without them.
The sharpest is descriptor passing. `wl_shm_create_pool` passes a **file
descriptor**, and there is no path in the protocol that passes an integer
instead. `struct schcom_surface`'s `handle_kind` field was written precisely so
that switching would be a new value rather than a protocol break, and it cannot
help: *our* protocol is the flexible one.
---
## Port libwayland. Do not port Weston.
**libwayland is the small piece**: a wire protocol, an object map, and an event
loop, needing `libffi` and — for the build-time scanner, on the host only —
`libexpat`. A real port, but a bounded one.
**Weston is the trap.** It arrives welded to `libinput`, `udev`, `libdrm`,
`logind`-shaped seat management and a GL renderer, and porting it means porting
Linux's device management first and finding the compositor somewhere underneath.
This is precisely the lesson already recorded twice in this tree — about
FreeBSD's `sys/dev/usb` (100k lines welded to newbus) and about FreeBSD's
`sys/netinet` (not a library; reaches into mbufs, epoch, netisr, VNET and uma).
> The tree has learned this twice. It should not pay to learn it a third time.
So **Schcom links `libwayland-server` and remains ours.** Input comes from
`/dev/input/eventN`, which already works, rather than from libinput. Output goes
through `display_ops`, which already exists.
### Software rendering first, and probably for a long time
`pixman` for composition, `wl_shm` for buffers. Mesa means EGL means `dlopen`
means a dynamic loader, and that is a large kernel project that does not have to
be on this path. Static binaries are enough to reach a working desktop; keep it
that way until something concrete demands otherwise.
### One sharp edge
`wl_keyboard` hands the client **a keymap as an XKB text blob over a file
descriptor**. A compositor cannot avoid xkbcommon by having simpler opinions
about keyboards — the protocol requires the blob.
The cheap route is one precompiled keymap string shipped in the binary, with
xkbcommon and `xkeyboard-config` deferred until more than one layout is wanted.
---
## Licensing
Checked before anything is fetched — the standing rule is that the licence goes
in `NOTICE` **before** the file is committed, not after.
| | |
|---|---|
| wayland, wayland-protocols | MIT |
| `wlr-layer-shell` | MIT |
| pixman | MIT |
| libffi | MIT |
| libxkbcommon | MIT |
| xkeyboard-config | MIT |
All Apache-2.0 compatible, all needing only a `NOTICE` entry. **Nothing here
carries the GPL problem that governs drivers**, which is a pleasant change and
worth noticing: the Wayland ecosystem is permissively licensed almost throughout,
and that is a genuine argument for it beyond any technical one.
---
## Milestones
| | |
|---|---|
| **W0** | [foundations.md](foundations.md) items 1–4, with the combined test that passes a descriptor *and* shares a `memfd` *and* binds a socket at a real path. |
| **W1** | libwayland builds and installs into the sysroot. `wayland-scanner` runs on the host. |
| **W2** | Schcom serves `wl_compositor`, `wl_shm`, `wl_surface`, `xdg_shell`. A client draws one window. |
| **W3** | `wl_seat`: keyboard and pointer, from the evdev path that exists. |
| **W4** | Two clients, focus, stacking, move and resize. **This is where SchWM's policy lives, as a file.** |
| **W5** | `wlr-layer-shell`, and a panel. This is SchDE's first pixel. |
Every milestone from W2 on is asserted **from the host, by pixel**, the way
`schcom-test` already does. The compositor's own report that it composited
something proves nothing.
---
## What it will still not do
- **No hardware acceleration.** Software rendering only, until dynamic linking
and Mesa, neither of which is on this plan.
- **No XWayland**, so no X11 clients, ever, unless someone ports it.
- **No mode setting.** Resolution stays whatever the loader asked for — see
[hybrid.md](hybrid.md), where the GPU driver's eviction is also where a modeset
API would arrive.
- **No damage tracking beyond "repaint everything"**, no multiple outputs, no
subsurfaces. Schcom's README already lists these; they are additions rather
than rewrites, which is the reason for committing to the surface/commit model
now.
- **One keyboard layout**, until xkbcommon is ported.
- **No clipboard, no drag and drop, no screen capture protocol**, none of which
W0–W5 touches.