From 1c6160008f3fd2953189b2530d16b31b06c70943 Mon Sep 17 00:00:00 2001
From: Orellius <42762368+Orellius@users.noreply.github.com>
Date: Wed, 26 Aug 2026 06:57:50 +0300
Subject: [PATCH] readme: rewrite it against the tree it describes
The old one described a host that was deleted. Its whole feature section was
headed "The Tauri host (crates/termisu)", a crate that has not existed since
2026-08-11, and one line said the Swift host was the one that got deleted,
which is exactly backwards. It also pointed at scripts/smoke-termisu.sh, which
died with that crate, at a binary that is gone, and at two docs that are not
there.
Everything from v0.32.0 to v0.47.0 was missing: the rename, the collapsible
dock, the achromatic chrome, the scrolling rows, the COLORTERM fix, the work
states, the attention bell, emoji as glyphs, local-first gating, port blocks.
Numbers re-measured against the tree rather than carried over: 822 tests over
nine crates, 223 corpus cases, 15 headless smokes, 241 resolved dependencies,
28 and 61 exports, 373 pinned esctest passes (the figure carried in my notes
said 391 and the pin file holds 373).
Three figures that were rendered for earlier slices and never used are in now:
the three dock states, emoji as monochrome engravings, and the bell wash.
---
README.md | 567 +++++++++++++++--------
docs/images/dock-states-20260826.png | Bin 0 -> 26658 bytes
docs/images/emoji-as-glyphs-20260826.png | Bin 0 -> 58085 bytes
docs/images/visual-bell-20260826.png | Bin 0 -> 46451 bytes
4 files changed, 362 insertions(+), 205 deletions(-)
create mode 100644 docs/images/dock-states-20260826.png
create mode 100644 docs/images/emoji-as-glyphs-20260826.png
create mode 100644 docs/images/visual-bell-20260826.png
diff --git a/README.md b/README.md
index 2fe0b4ba..2efe92fb 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,8 @@
+
+

@@ -25,72 +27,27 @@ Details and the Unicode conformance numbers: Bidir
---
-## Four agents, four worktrees, four port blocks
+## Six things you will not find in another terminal
+
+1. **Bidirectional text that is actually correct**, at 91,707 of 91,707 Unicode conformance
+ cases, with Hebrew and Arabic drawn rather than reordered into blank cells. The logical
+ order stays in the core and the visual order lives in the renderer, so selecting the
+ character you see gives you the character you meant.
+2. **Correctness measured against another team's implementation**, not against itself. Every
+ build feeds 223 byte streams to this engine and to the real `libghostty-vt` and compares
+ the two grids cell by cell. Seventeen cases are pinned to *disagree*, so the harness can be
+ seen to detect difference at all.
+3. **A stable port block per workspace.** Four agents in four worktrees stop fighting over
+ port 3000, and the block is derived from the path so it never moves.
+4. **A dock that says which agent needs you**, from explicit signals only. Working, done,
+ error, and a fifth state that means *stopped and waiting*, raised by the bell.
+5. **No network path, and it is gated rather than promised.** One test reads the resolved
+ dependency graph, another proves the review panel's webview cannot leave its local
+ document.
+6. **Every gate here has been watched go red.** A test that has never failed is not evidence,
+ and the list of real defects that rule caught is further down this page.
-Git worktrees are the standard answer to running agents in parallel, and the number that
-keeps appearing is four to eight per developer. The isolation works for files and does
-nothing for anything that is not a file. Every dev server defaults to 3000. Agent A starts
-one, agent B dies on `EADDRINUSE`, and agent B reports a broken build that is not broken.
-
-The formula everyone hand-rolls is `PORT = BASE + INDEX * 10 + OFFSET`, plus a script that
-rewrites a `.env` per tree, and it does not survive being moved to CI.
-
-Termisu hands the base down. Every pane's child gets:
-
-```sh
-TERMISU_PORT_BASE # the first port of this workspace's block, 20000..39990
-TERMISU_PORT_SPAN # how many ports the block holds, 10
-```
-
-```jsonc
-// vite.config.js
-const base = Number(process.env.TERMISU_PORT_BASE ?? 3000)
-export default { server: { port: base }, preview: { port: base + 1 } }
-```
-
-**Derived from the workspace path, never handed out in sequence.** A base assigned in
-launch order moves whenever the panes open in a different order, and then a bookmark, a
-proxy rule and a database URL all rot. The same worktree is the same block forever and on
-every machine, with no state kept anywhere. A worktree reached through a symlink is the
-same workspace, which matters on macOS where `/tmp` is a symlink to `/private/tmp`.
-
-**`PORT` itself is deliberately not set.** Silently moving a dev server off the port its
-operator typed is a bigger surprise than a variable nothing reads yet.
-
-**It is a hash, so collisions are possible and the number is written down rather than
-implied.** With N workspaces the chance any two share a block is about
-`1 - exp(-N(N-1)/2/2000)`: 0.3% at four worktrees, 1.4% at eight. Removing that entirely
-would need a registry file, which is state on disk that has to be cleaned up and is wrong
-the moment a worktree moves.
-
-## No account, no telemetry, no network
-
-Termisu never talks to a server. Not to check a licence, not to phone an analytics
-endpoint, not to see whether there is an update. There is nothing to sign in to, there is
-no telemetry to turn off, and the whole thing runs with the wifi off.
-
-That is a fairly ordinary thing to claim and a fairly common thing to be wrong about, so
-it is gated rather than asserted:
-
-- **`crates/host/tests/no_network.rs`** reads the resolved dependency graph out of
- `Cargo.lock` and fails if anything in it can open a socket. This is the way the claim
- would actually break: nobody writes `TcpStream::connect` in a terminal on purpose, but a
- convenience crate arrives for an unrelated reason and drags an async runtime and a TLS
- stack in behind it. 241 crates resolve today and none of them are networked.
-- **`--smoke-offline`** covers the one part that could: the review panel is a `WKWebView`,
- so WebKit is linked into the process whether we like it or not. What makes the claim
- true anyway is `PanelNavigation`, which permits exactly one navigation - the local
- document the panel was handed - and refuses every other scheme, path and navigation
- type. A remote URL carrying that same path is refused too, which is a case a mutant
- found rather than a case anyone thought of.
-
-Two things that are honestly NOT covered by either gate. The shell you run inside Termisu
-is your shell and can do whatever you tell it to; the terminal does not police its child.
-And macOS itself may talk to Apple about a signed binary the first time it runs one, which
-is Gatekeeper, not us.
-
-**The licence is AGPL-3.0**, so this is checkable rather than a promise. The audit is
-`grep`, and the two gates above run on every build.
+---
## Why this exists
@@ -112,12 +69,7 @@ through with regular expressions. If you own the terminal, you do not guess: the
its working directory and its git branch are already sitting in cells, typed, because your own
parser put them there.
-So the terminal came first. **The workbench is the goal and it is not built** - there is no session
-map, no canvas, nothing that shows you what several agents are doing at once. What exists on top of
-the engine today is a window with panes, plus a module that can launch an agent CLI into one. The
-richer surface lives in the Swift host, which is a wrapper around the same engine and is where the
-tabs, palette, blocks and worktrees actually are. Read the feature list below as two hosts over one
-core, not as a product.
+So the terminal came first, and the surface on top of it is growing from the engine outward.
## Written from zero
@@ -126,12 +78,13 @@ where the seams were without teaching me why any of it worked. So I archived it
again from an empty directory on 2026-07-28.
The parser, the grid, scrollback, reflow, the pty, the renderer, bidi, shaping, the C ABI and
-the app are all written for this project. The one piece not written here is the escape-sequence
-tokenizer, a vendored fork of [vte](https://github.com/alacritty/vte), kept in-tree with its
-licences and one addition of our own.
+the app are all written for this project: 54,000 lines of Rust and 9,000 of Swift. The one piece
+not written here is the escape-sequence tokenizer, a vendored fork of
+[vte](https://github.com/alacritty/vte), kept in-tree with its licences and one addition of our
+own.
-**No Ghostty code ships here.** The app binary contains zero of its symbols and links zero of
-its libraries, which is checkable with `nm` and `otool`.
+**No Ghostty code ships here.** The app binary contains zero of its symbols and links zero of its
+libraries, which is checkable with `nm` and `otool`.
The history carries no personal data either, and that is checkable rather than asserted. Every
commit is authored by one GitHub noreply identity, no commit message names an account, and the
@@ -147,11 +100,6 @@ which exist because OSC 7 reports a `file://` URI and the corpus has to pin what
with one. Home-relative paths appear too, and they are this program's own: `~/.termisu/config.toml`
and the `~/.ruuah` fallback it still reads.
-The commits were rewritten once, on 2026-08-07, to remove an email address and two paths into a
-private machine before the repository was made public. Nothing else moved: the tree hash at HEAD
-is byte-identical either side of that rewrite, and all 305 commits and 28 tags survived with
-their messages, dates and ordering intact.
-
## How it is checked, and against what
Ghostty did not disappear from the project. It became the instrument.
@@ -189,14 +137,33 @@ version and watched go red. That is not a slogan; it is what found:
- a selection that outlived the pane it was made in and underflowed the renderer, found by splitting panes in the live window until it died
- every Arabic letter drawn in its isolated form, invisible to a suite whose other scripts have only one form per letter
- a pty shutdown that could deadlock forever, which had been hanging a test for at least a day without ever going red
+- every pane telling its child the terminal had no truecolor, which drew one agent's mascot in the wrong colour for fourteen days
+- two of the three spinner glyphs missing from the work-state table, so the dock announced *done* while an agent was still working
+
+### Vacuous passes are the enemy, not failures
+
+A gate that cannot fail is worse than no gate, because it is read as evidence. Four found and
+fixed in this repository, each one the same shape:
+
+- **A constant folded into both sides of a comparison.** A dock-width assertion compared a delta
+ against the very constant under test, so setting that constant to a wrong value passed. Absolute
+ bounds now, never deltas against the thing being measured.
+- **A shape signature that read only the root layer.** An invisible state dot with a live
+ sublayer still scored as a distinct shape. A shape gate counts geometry; only ink says whether
+ anything can be seen.
+- **A distinct-value count that an anti-aliased edge satisfied on its own.** Counting ink levels
+ could not tell a monochrome engraving from a filled silhouette, because an emoji bitmap's edge
+ supplies 123 levels by itself. The metric is where the ink piles up now: 0.023 against 0.251.
+- **A pty helper that matched the first marker on screen**, so a second question returned the
+ first answer. It failed loudly on one test and passed *silently* on another, where "the stale
+ value was not reported" was satisfied by re-reading the value being compared against.
### A hang is worse than a failure
-The last of those is worth its own note, because it is the shape of defect this project is
-least protected against. `Host::shutdown` stopped the pty pump before killing the child, and
-the pump is the only reader of the pty master; a child exiting with a controlling terminal
-blocks in the kernel until its output queue drains, so it could never finish exiting and the
-parent waited on it forever. **The reader has to outlive the child.**
+`Host::shutdown` stopped the pty pump before killing the child, and the pump is the only reader
+of the pty master; a child exiting with a controlling terminal blocks in the kernel until its
+output queue drains, so it could never finish exiting and the parent waited on it forever.
+**The reader has to outlive the child.**
Nothing went red. Cargo simply never returned. One instance was found still running seven and
a half hours after it started, holding its child processes, with two more beside it, while
@@ -205,7 +172,7 @@ every suite run that looked green ran alongside them.
What named it was a discriminating pair rather than a theory: 120 rounds of spawn-then-shutdown
with a **silent** child pass in 0.74s, and the same loop with a child that prints **one line**
first hangs within 40. A third attempt at a deterministic repro, using a large piped write,
-did **not** reproduce, and that was evidence too - the pipeline was slow to start, so the child
+did **not** reproduce, and that was evidence too: the pipeline was slow to start, so the child
was killed before writing anything.
Two consequences, and the second matters more. The kill happens first now, so the pump keeps
@@ -218,10 +185,9 @@ counts as a gate at all.
Two tests here were green locally and red on a shared CI runner, for reasons that had nothing
to do with the code. A synchronized-output test split its batch 60ms apart and was measured
-against a 150ms anti-stuck budget - a 2.5x margin, which is no margin at all on a machine
-somebody else is using, so the budget correctly published a half-drawn frame and a test about
-the gate failed for the wrong reason. A seqlock test required the reader to land at least one
-accepted read inside a fixed 400ms window, which a two-core runner cannot promise.
+against a 150ms anti-stuck budget, a 2.5x margin that is no margin at all on a machine somebody
+else is using. A seqlock test required the reader to land at least one accepted read inside a
+fixed 400ms window, which a two-core runner cannot promise.
Neither was a real defect and neither was harmless: a gate that reports on how loaded the
machine is teaches you to ignore it. The budget became a per-test setting so the gate test and
@@ -229,17 +195,41 @@ the budget test each set the value their own claim needs, and the liveness windo
while nothing has been accepted rather than failing. The workload, the race and the invariant
are untouched in both.
+### The gates
+
+Five exit-code gates run before anything merges.
+
| gate | what it proves |
|---|---|
-| `cargo test --workspace` | 713 tests: units, pixels, concurrency, C-surface round trips |
-| `termisu-vt-difftest` | 223 corpus cases, every verdict met, 17 of them pinned to disagree |
-| `esctest2` | 391 pinned passes of 568, both directions: a regression fails, so does an unpromoted pass |
-| `scripts/smoke-termisu.sh` | 26 host invariants about what AppKit, WebKit, the IPC and the child processes actually did, with no screen required |
-| export check | 28 + 56 C symbols present in the shipped archives: our own `termisu_vt_*` surface and the `ghostty_*` drop-in, each verified by name |
-| header parity | `include/termisu_vt.h` compiled against C static assertions generated from Rust's own `size_of` and `offset_of!`, with a control that proves a false assertion fails |
-
-The screenshots above were taken with `cargo run -p termisu-vt-render --example screenshot`, which
-runs a command in a real pty and renders the result with this terminal's own CPU backend. A
+| `cargo test --workspace` | **822 tests**: units, pixels, concurrency, C-surface round trips, live-pty contracts |
+| `cargo run -p termisu-vt-difftest` | **223 corpus cases**, every verdict met, 17 of them pinned to disagree |
+| `./scripts/build-lib.sh` | **28** `termisu_vt_*` C symbols present in `libtermisu-vt.a`, verified by name |
+| `./scripts/build-host.sh` | **61** symbols in `libtermisu-vt-host.a`: the ABI plus the embedder surface |
+| `./scripts/build-swift.sh` | **15 headless smokes**: what AppKit, WebKit, the bridge and the child processes actually did, with no screen required |
+
+Two more run by hand, because neither belongs in a loop:
+
+| suite | result |
+|---|---|
+| `esctest2`, through our own pty | **373 pinned passes of 568**, both directions: a regression fails, and so does an unpromoted pass |
+| `./scripts/agent-live-tap.sh` | starts a real authenticated agent, so no automated gate may run it |
+
+Where the 822 live:
+
+| crate | tests | what it covers |
+|---|---|---|
+| `core` | 190 | the parser and the grid: a pure state machine, no I/O and no clock |
+| `render` | 164 | glyphs, atlas, bidi drawing, shaping, both backends byte-equal |
+| `host` | 158 | the embedder surface, agent launching, and live-pty contracts |
+| `frame` | 79 | the seqlock frame channel and Unicode bidi conformance |
+| `ghostty` | 67 | differential encoders: keyboard and mouse, against the reference |
+| `pty` | 54 | the pty, and `esctest2` through it |
+| `snapshot` | 39 | the typed grid other layers read |
+| `vte` | 31 | the vendored tokenizer plus our APC addition |
+| `abi` | 16 | header parity, against C static assertions generated from Rust's own layout |
+
+The screenshots on this page were taken with `cargo run -p termisu-vt-render --example screenshot`,
+which runs a command in a real pty and renders the result with this terminal's own CPU backend. A
picture of some other terminal agreeing with our numbers would not be the claim being made.
## Bidirectional text
@@ -271,15 +261,10 @@ column right-to-left where it is Hebrew or Arabic, and note what does **not** mo
| Arabic | `مرحبا بالعالم` | joined, right-to-left, each letter in its contextual form |
| Persian | `سلام دنیا` | same, and `پ چ ژ گ` resolve through the same stack |
-Three of those are the cases a plausible implementation gets wrong. **`42` stays `42`** - reversing
-the run wholesale yields `24`, and it reads as perfectly normal until somebody types a port number
-backwards. **The code keeps its direction** while the string inside it reorders. **The box drawing
-stays in columns 0, 4 and 8**, because whole-line reordering across a table moves the frame
-relative to the text it encloses.
-
-Arabic and Persian go through the same reordering as Hebrew - the algorithm is script agnostic -
-and additionally through the shaper, because they are cursive: a contiguous run in one cursive
-script is shaped as a run so each letter takes its initial, medial, final or isolated form.
+Arabic and Persian go through the same reordering as Hebrew, because the algorithm is script
+agnostic, and additionally through the shaper, because they are cursive: a contiguous run in one
+cursive script is shaped as a run so each letter takes its initial, medial, final or isolated
+form.
Render any of them yourself. The example runs a command in a real pty and draws the result with
this terminal's own CPU backend, so it needs no window and no display:
@@ -312,17 +297,17 @@ a vendoring accident fails loudly instead of quietly measuring less.
reference-vs-property form it uses needs its own harness. Stated rather than counted, because a
number nothing computes is not evidence.
-The suite caught a genuine bug on its first run: the
-fast path that skipped the algorithm for plain text ignored the base direction, and under an RTL
-base even a row of neutrals resolves to level 1 and reverses.
+The suite caught a genuine bug on its first run: the fast path that skipped the algorithm for
+plain text ignored the base direction, and under an RTL base even a row of neutrals resolves to
+level 1 and reverses.
### Where it lives, and why that is the whole design
**Bidi is in the renderer and never in the core.** Reordering in the core would break cursor
addressing, because a cursor-addressed TUI has no mapping for where its cursor went after a
reorder. It would also make every RTL line diverge from the differential oracle by construction,
-deleting the only correctness signal this project has. Slice 5.5 landed reordering with the
-corpus untouched at 78/78, which is that separation demonstrated rather than asserted.
+deleting the only correctness signal this project has. Reordering landed with the corpus
+untouched, which is that separation demonstrated rather than asserted.
### Fonts, and what each script needs
@@ -334,7 +319,7 @@ stack rather than by the reordering.
| Latin, box drawing, powerline, Nerd icons | **JetBrains Mono NF** (SIL OFL 1.1) | ships inside the app; leads, so the cell box is its advance |
| geometric shapes | Menlo | ships with macOS; 96/96 where the lead is 43/96 |
| Hebrew | **Cousine** (SIL OFL 1.1) | ships inside the app; monospaced, GPOS attaches niqqud to its base, marks carry zero advance so a pointed cluster stays one cell |
-| Arabic, Persian | **Kawkab Mono** (SIL OFL 1.1) | ships inside the app; covers both blocks and joins correctly. It does **not** fix the grid - see below |
+| Arabic, Persian | **Kawkab Mono** (SIL OFL 1.1) | ships inside the app; covers both blocks and joins correctly |
| Arabic fallback | SF Arabic, Geeza Pro | ship with macOS, so Arabic and Persian render on a bare machine |
The three bundled faces ship inside `Termisu.app`; `assets/fonts/README.md` records why each one
@@ -343,20 +328,13 @@ is there and what it is licensed under. They were `~/Library/Fonts` lookups desc
step nobody performs on a fresh machine. A user-installed copy still wins, so an operator who
has their own build of a bundled family keeps it.
-Until 2026-08-07 the stack was `Menlo -> Miriam Mono CLM -> Arial Hebrew` - Menlo led and Miriam
-was the Hebrew face until 2026-08-25 - and none of the three carries
-the Arabic block, so every Arabic and Persian codepoint drew as a **blank cell** while the bidi
-algorithm reordered them perfectly. Correct algorithm, empty row, no error anywhere. It was found
-by rendering the sheet above across three scripts and looking at it, not by a test, and
-`arabic_and_persian_resolve_somewhere_in_the_stack` is that omission turned into one.
+Until 2026-08-07 the stack was `Menlo -> Miriam Mono CLM -> Arial Hebrew`, and none of the three
+carries the Arabic block, so every Arabic and Persian codepoint drew as a **blank cell** while the
+bidi algorithm reordered them perfectly. Correct algorithm, empty row, no error anywhere. It was
+found by rendering the sheet above across three scripts and looking at it, not by a test.
-Coverage alone was not the fix. Adding a face stopped the blank cells and left Arabic sitting off
-the grid, so `a_monospaced_arabic_face_outranks_the_proportional_ones` pins the ordering and
-checks that the monospaced face is the one which actually answers rather than merely the one
-listed first.
-
-**And a monospaced face is still not enough**, which this file claimed otherwise for a day.
-Installing one does not put Arabic on the grid. Measured at 32px against a 19px cell:
+**A monospaced face is not enough**, which this file claimed otherwise for a day. Measured at
+32px against a 19px cell:
| codepoint | face that answers | advance |
|---|---|---|
@@ -364,8 +342,8 @@ Installing one does not put Arabic on the grid. Measured at 32px against a 19px
| `א` | Miriam Mono CLM, the Hebrew face at the time; Cousine advances identically | 19.20px |
| `ب` | **Kawkab Mono** | **22.40px** |
-Monospaced is a property of a face on its own - uniform advance within itself. A terminal grid
-needs something else entirely: an advance equal to the **primary** face's, and no font ships
+Monospaced is a property of a face on its own: uniform advance within itself. A terminal grid
+needs something else entirely, an advance equal to the **primary** face's, and no font ships
promising that. Miriam Mono matching Menlo to 0.07px is luck rather than design, and it is the
whole reason Hebrew never showed this symptom and Arabic always did: a letter overhanging its
cell, and because a run paints in logical order, on a right-to-left row that spill lands on a cell
@@ -373,10 +351,10 @@ already painted and never cleared. An empty space beside an Arabic letter kept 5
its neighbour.
**Fixed 2026-08-08.** Each fallback face is rasterised and shaped at a size whose advance fits one
-cell - `32 * 19 / 22.46 = 27.07px` for Kawkab. Uniform scaling, so letter shapes are preserved,
-which is what separates it from the two alternatives that were rejected on measurement: scaling a
-run horizontally distorts the letters, and clipping each glyph to its cell cuts exactly the
-strokes that make cursive readable.
+cell: `32 * 19 / 22.46 = 27.07px` for Kawkab. Uniform scaling, so letter shapes are preserved,
+which is what separates it from the two alternatives rejected on measurement. Scaling a run
+horizontally distorts the letters; clipping each glyph to its cell cuts exactly the strokes that
+make cursive readable.
Before, three letters where each one's overhang pushes the next along and the last is clipped:
@@ -387,15 +365,7 @@ After, the same bytes through the same renderer:

Both are native-resolution crops of the same region, magnified with point sampling so no pixel is
-invented. Three exemptions keep the scaling where it belongs: the primary face defines the cell so
-it is never scaled; a face already inside the cell is left alone rather than nudged by fractions;
-and a full-em face is left alone because **an emoji spans two cells**, so its advance is correctly
-wider than one and fitting it to one would shrink every emoji in the terminal.
-
-The test that proves it was a characterisation pin asserting the defect, and was **promoted** to
-asserting zero - the promotion is the evidence, exactly as with a corpus case marked `diff`. Full
-record, including the four mutants killed and the two that survived, in
-[`docs/BACKLOG-2026.md`](docs/BACKLOG-2026.md).
+invented.
**Arabic letters take their contextual forms.** A contiguous run of cells in one cursive script
is shaped as a run, so each letter resolves to its initial, medial, final or isolated glyph, and
@@ -410,16 +380,13 @@ After, the same bytes through the same renderer, one variable changed:

-Both are this terminal's own CPU backend, which is byte-identical to the GPU one by
-specification, captured with `cargo run -p termisu-vt-render --example screenshot` and therefore
-needing no window and no display. The Hebrew and the Latin are unchanged between them, which is
-the control: a change that moved those would be a change to something other than joining.
+The Hebrew and the Latin are unchanged between them, which is the control: a change that moved
+those would be a change to something other than joining.
Until 2026-08-08 this rendered as isolated forms, and the note here blamed terminal grids. That
was wrong. Shaping was gated on a cluster having more than one codepoint, so a lone Arabic letter
-never reached the shaper at all and got the charmap's nominal glyph, which is the isolated form -
-a bug in this renderer, not a property every terminal shares. The diagnosis is kept in
-[`docs/plans/2026-08-07-arabic-joining.md`](docs/plans/2026-08-07-arabic-joining.md).
+never reached the shaper at all and got the charmap's nominal glyph, which is the isolated form:
+a bug in this renderer, not a property every terminal shares.
Hebrew coverage is pinned across the classes that appear in real text rather than one letter:
base letters, final forms, niqqud, the dagesh GSUB composes into its base, and punctuation.
@@ -432,14 +399,130 @@ fall back to the isolated forms drawn before. Wrong in a known way beats overlap
**Joining strokes do not always meet**, because each glyph is positioned in its own cell rather
than at the previous glyph's advance. The letters are in their correct joined forms, which is the
-part that makes Arabic readable. That is the real grid limit, and it is much smaller than the one
-this section used to claim.
+part that makes Arabic readable. That is the real grid limit.
+
+## Running agents in parallel
+
+The second reason this project exists. Everything here is built on explicit signals from the
+child, never on guessing at a byte stream.
+
+### A stable port block per workspace
+
+Git worktrees are the standard answer to running agents in parallel, and the number that keeps
+appearing is four to eight per developer. The isolation works for files and does nothing for
+anything that is not a file. Every dev server defaults to 3000: agent A starts one, agent B dies
+on `EADDRINUSE`, and agent B reports a broken build that is not broken.
+
+The formula everyone hand-rolls is `PORT = BASE + INDEX * 10 + OFFSET`, plus a script that
+rewrites a `.env` per tree, and it does not survive being moved to CI.
+
+Termisu hands the base down. Every pane's child gets:
+
+```sh
+TERMISU_PORT_BASE # the first port of this workspace's block, 20000..39990
+TERMISU_PORT_SPAN # how many ports the block holds, 10
+```
+
+```js
+// vite.config.js
+const base = Number(process.env.TERMISU_PORT_BASE ?? 3000)
+export default { server: { port: base }, preview: { port: base + 1 } }
+```
+
+**Derived from the workspace path, never handed out in sequence.** A base assigned in launch
+order moves whenever the panes open in a different order, and then a bookmark, a proxy rule and
+a database URL all rot. The same worktree is the same block forever and on every machine, with no
+state kept anywhere. A worktree reached through a symlink is the same workspace, which matters on
+macOS where `/tmp` is a symlink to `/private/tmp`.
+
+**`PORT` itself is deliberately not set.** Silently moving a dev server off the port its operator
+typed is a bigger surprise than a variable nothing reads yet.
+
+**It is a hash, so collisions are possible and the number is written down rather than implied.**
+With N workspaces the chance any two share a block is about `1 - exp(-N(N-1)/2/2000)`: 0.3% at
+four worktrees, 1.4% at eight. Removing that entirely would need a registry file, which is state
+on disk that has to be cleaned up and is wrong the moment a worktree moves.
+
+The hash took three measured attempts, and the spread gate is the only reason that was visible.
+Sibling worktrees differ in their **last** byte, which is the adversarial input for a cheap hash:
+
+| derivation | distinct blocks out of 64 |
+|---|---|
+| FNV-1a, `hash % BLOCKS` | 54 (a fair hash gives 63) |
+| FNV-1a, high half | 3 |
+| FNV-1a + `fmix64` + multiply-shift | **64** |
+
+Neither slice of the raw hash was good. The fix was an avalanche step, not a different set of
+bits.
+
+### The dock knows which agent needs you
+
+
+
+Rendered offscreen by --shot-sidebar: expanded, collapsed to its
+28pt rail, and parked mid-scroll at fourteen sessions.
+
+Five work states, and every one of them comes from something the child actually said:
+
+| state | shape | signal |
+|---|---|---|
+| idle | nothing | |
+| working | filled circle | a spinner glyph in the `OSC 0` title, or `OSC 9;4` progress |
+| done | hollow ring | the spinner stopped |
+| error | filled square | `OSC 9;4` state 2 |
+| **attention** | **a bar** | **`BEL`**: the session has stopped and cannot continue without you |
+
+**Attention is sticky.** A bell means stopped, so everything arriving afterwards is the program
+repainting rather than you answering. A spinner glyph one frame later must not erase it, and
+neither may a progress report. Only focusing that pane clears it.
+
+**The states are shapes, not colours.** The whole chrome is achromatic by law, one file with
+eight levels of `NSColor(white:)`, so a hue is not expressible. Three brightnesses of one circle
+read as one circle at three distances, especially on a 28pt rail.
+
+**There is no "waiting on you" signal to read, and that was measured rather than assumed.** With
+one agent CLI frozen on its own permission prompt, unable to proceed without a keystroke, it
+emitted no title, no bell and no `OSC 9;4`. The only escape sequence on the wire was a
+background-colour query. Across a full session, all ten `BEL` bytes were `OSC 0` string
+terminators and not one was a real bell. So the terminal cannot infer the block, the child has to
+say it, and `\a` is the one gesture every CLI already has.
+
+**A bell washes the pane, it does not chime.** `NSSound.beep()` was the answer until 2026-08-26,
+and the system chime says something needs you while saying nothing about *which* pane, which is
+useless the moment two agents are running.
-**Arabic glyphs overhang their cell**, because the faces that ship with macOS are proportional -
-beh advances 22.4px against a 19px cell. Whether the overhang survives depends on paint order, so
-in a right-to-left run an empty space beside a letter carries its neighbour's ink: measured
-2026-08-08, 50 pixels of it. Recorded in
-[`docs/BACKLOG-2026.md`](docs/BACKLOG-2026.md); installing Kawkab Mono avoids it entirely.
+
+
+Above quiet, below ringing. Measured rather than eyeballed, because a 140ms
+fade cannot be caught by hand: 142.8 mean brightness against 134.1.
+
+## No account, no telemetry, no network
+
+Termisu never talks to a server. Not to check a licence, not to phone an analytics endpoint, not
+to see whether there is an update. There is nothing to sign in to, there is no telemetry to turn
+off, and the whole thing runs with the wifi off.
+
+That is a fairly ordinary thing to claim and a fairly common thing to be wrong about, so it is
+gated rather than asserted:
+
+- **`crates/host/tests/no_network.rs`** reads the resolved dependency graph out of `Cargo.lock`
+ and fails if anything in it can open a socket. This is the way the claim would actually break:
+ nobody writes `TcpStream::connect` in a terminal on purpose, but a convenience crate arrives
+ for an unrelated reason and drags an async runtime and a TLS stack in behind it. 241 crates
+ resolve today and none of them are networked.
+- **`--smoke-offline`** covers the one part that could: the review panel is a `WKWebView`, so
+ WebKit is linked into the process whether we like it or not. What makes the claim true anyway
+ is `PanelNavigation`, which permits exactly one navigation, the local document the panel was
+ handed, and refuses every other scheme, path and navigation type. A remote URL carrying that
+ same path is refused too, which is a case a mutant found rather than a case anyone thought of.
+
+Two things that are honestly **not** covered by either gate. The shell you run inside Termisu is
+your shell and can do whatever you tell it to; the terminal does not police its child. And macOS
+itself may talk to Apple about a signed binary the first time it runs one, which is Gatekeeper,
+not us.
+
+**The licence is AGPL-3.0**, so this is checkable rather than a promise. The audit is `grep`, and
+the two gates above run on every build.
## How it compares
@@ -469,19 +552,44 @@ I have not audited the others, and I would rather leave a cell empty than fill i
## Architecture
-Three rules, enforced by crate boundaries rather than by convention.
+Four rules, enforced by crate boundaries rather than by convention.
+
+1. **The core is a pure, deterministic state machine.** Bytes in, grid mutations out. No pty, no
+ GPU, no clock, no I/O. That is what makes headless CI and differential testing possible at
+ all, and I/O lives in exactly one crate which is not the core.
+2. **Bidi lives in the renderer, never in the core.** Reordering there would break cursor
+ addressing and delete the differential signal at the same time.
+3. **No terminal bytes in a webview.** Not pixels, not keystrokes, not frames. Document-shaped
+ panels get a browser engine; the terminal surface never does. Renting `xterm.js` would mean
+ running a second VT parser in front of ours, which would make every test here measure code
+ nothing calls.
+4. **A policy a gate cannot reach is a policy that has never been asserted.** Four have been
+ pulled out of live objects for exactly this reason, after one of them turned out to be wrong
+ in a way nothing could see: `LastPaneOutcome`, `WorkStateRule`, `ChromeTransition` and
+ `PanelNavigation`.
-1. **The core is a pure, deterministic state machine.** Bytes in, grid mutations out. No pty, no GPU, no clock, no I/O. That is what makes headless CI and differential testing possible at all, and I/O lives in exactly one crate which is not the core.
-2. **No terminal bytes in the webview.** Not pixels, not keystrokes, not frames. The chrome strip is a browser engine drawing documents. Renting `xterm.js` would mean running a second VT parser in front of ours, which would make every test here measure code nothing calls.
-3. **One wgpu surface for all panes.** Pane count is a Rust-side fact. If the webview needs to know it, the design is wrong.
+```
+crates/vte the vendored tokenizer, plus APC dispatch
+crates/core the parser and the grid. No I/O, no clock
+crates/snapshot the typed grid every other layer reads
+crates/frame the seqlock frame channel, and bidi reordering
+crates/render glyphs, atlas, shaping, CPU and wgpu backends
+crates/pty the only crate that touches the operating system
+crates/abi the C surface: libtermisu-vt.a, the libghostty-vt drop-in
+crates/abi-types the C layouts, pinned byte for byte against the real library
+crates/difftest the differential harness and its oracle
+crates/host the embedder surface: panes, agents, worktrees, launch
+crates/markdown pipe tables laid out as box drawing. Built, wired to nothing yet
+swift/ the macOS app: window, chrome, panels, input
+```
## Features
-**Terminal core**
+### Terminal core
-- Full VT parsing on a vendored [vte](https://github.com/alacritty/vte) fork (one addition: APC dispatch)
+- Full VT parsing on a vendored [vte](https://github.com/alacritty/vte) fork, one addition: APC dispatch
- True colour; styled underlines, single / double / curly / dotted / dashed, with SGR 58 underline colour
-- OSC 8 hyperlinks whose stamps survive scroll and resize; OSC 52 clipboard write; OSC 9 and OSC 777 notifications; bell
+- OSC 8 hyperlinks whose stamps survive scroll and resize; OSC 52 clipboard write; OSC 9 and OSC 777 notifications; `BEL`
- OSC 7 working directory, stored exactly as reported, including two rules the reference implementation's own source gets wrong
- OSC 133 semantic regions (prompt, input, output), the rails everything else rides
- DSR / DA / DECRQM query replies through the pty, so programs that probe get real answers
@@ -493,80 +601,127 @@ Three rules, enforced by crate boundaries rather than by convention.
- Grapheme clusters from day one; wide glyphs and spacer tails; VS16 emoji presentation
- Paged scrollback with an exact row budget
-**Rendering**
+### Rendering
- Glyph atlas with damage-driven redraw; a CPU reference backend and a wgpu compute backend, byte-equal to each other by specification
-- Colour emoji (sbix), synthesized block mosaics, per-glyph font fallback
-- **Bidi in the renderer**: UBA reordering at 91,707 of 91,707 BidiCharacterTest cases, mirrored brackets in RTL runs, niqqud placed by GPOS shaping. In the renderer and never in the core, because reordering there would break cursor addressing
+- **Bidi in the renderer**: UBA reordering at 91,707 of 91,707 `BidiCharacterTest` cases, mirrored brackets in RTL runs, niqqud placed by GPOS shaping
+- Per-glyph font fallback, with each fallback face scaled so its advance fits the cell the primary face defines
+- Synthesized block mosaics
- Font ligatures behind a substitution guard, so a non-ligating font renders byte-identically with the feature on or off
- Selection drawn as a tint blended over the finished row rather than as a cell background, which would be erased by the next cell's
-**Input**
+#### Emoji are glyphs, not stickers
-- Kitty keyboard protocol: the full flag stack, CSI-u encoding, `modifyOtherKeys`, byte-compared against the reference encoder across 135,216 cases with zero divergent
-- SGR mouse (1000 / 1002 / 1003 / 1006) plus alternate scroll, against a ~65k-case differential matrix; the wheel routes by mode to report, arrow keys, or viewport
-- Chords match physical keys, so a Hebrew layout keeps every one of them
+
+
+A coloured sticker is not a terminal glyph. The artwork's own colours are dropped and it is
+painted in the cell's foreground, down the same blit path as a letter. Dropping the face instead
+was rejected: the codepoint still occupies its cells, so a removed face leaves a hole the line
+reflows around.
-**The Tauri host** (`crates/termisu`) - a window with panes. Not a workbench yet: nothing here shows
-you several agents at once, which is the whole point of the word and the reason it is not used.
+- Alpha alone is a filled silhouette, so the artwork's **luminance** carves the interior. It is
+ stretched across the glyph's own range first, because emoji are authored against white and an
+ unstretched mask reads as mud.
+- A floor on every opaque pixel, so a black heart does not vanish on a dark ground.
+- Rec.709 in integers, so the CPU and GPU backends still receive byte-identical pixels.
+- **Every emoji is one size**: a square of one cell advance, sitting on the text baseline.
+ Measured at 16px, cell 10x22: `M` inks 8x12, `x` inks 8x9, an emoji is 10x10, and all three
+ share a bottom edge. The grid never moves, because a `VS16` cluster stays one cell wide, which
+ the corpus pins against the reference.
+- **Known limit**: the polarity assumes ink is lighter than ground, true of every scheme shipped
+ today. On a light theme an emoji reads as a negative.
-- One window opening with one pane, split right with cmd+D, with a real gutter between panes and a rule drawn into it in the same render pass. Splitting stops before a pane becomes too narrow to use rather than continuing until something breaks
-- A pane whose child has exited closes itself and gives its width back to the survivors; the last one closing closes the window
-- Click-drag, double-click and triple-click selection, cmd+A, cmd+C. cmd+C is conditional on purpose: with nothing selected it falls through to the child as `^C` and can still interrupt a command. Shift takes the pointer back from a child that has captured the mouse
-- cmd+V bracketed paste, cmd+= / cmd+- / cmd+0 live zoom across every pane, cmd+click hyperlinks
+### Input
+
+- Kitty keyboard protocol: the full flag stack, CSI-u encoding, `modifyOtherKeys`, byte-compared against the reference encoder across **135,216 cases** with zero divergent
+- SGR mouse (1000 / 1002 / 1003 / 1006) plus alternate scroll, against a ~65k-case differential matrix; the wheel routes by mode to report, arrow keys, or viewport
+- **Chords match physical key codes, never characters**, so a Hebrew layout keeps every one of them. This is also why the pane cannot be SwiftUI: `KeyPress` carries a `KeyEquivalent`, which is a character
+
+### The app
+
+macOS, AppKit, one window. The reasoning is written down in
+[`docs/decisions/2026-08-25-appkit-not-swiftui.md`](docs/decisions/2026-08-25-appkit-not-swiftui.md);
+the short version is the keyCode line above, plus the geometry gates, which are assertable only
+because the layout types exist apart from the views.
+
+- **One bar, and it starts shut.** A collapsible dock down the right-hand side of the window, listing every session with the directory and branch it is in. `cmd+B` toggles it, on the physical key, which is free in a terminal because readline and every TUI reach for `ctrl+B`
+- **It collapses to a 28pt rail rather than to nothing.** A sidebar that collapses to zero has a state you can enter and not leave, and a chord is no way out for anyone who has not been told the chord exists. The non-idle state dots stack down the rail, so closing it does not hide which agent is working
+- **The dock scrolls**, so no session is unreachable. It used to stop building rows past a capacity limit, silently, with no scrollbar and no ellipsis
+- **The chrome takes the terminal's own background** and paints only white at an alpha over it. When themes land, one file is where they plug in
+- **Closing the last tab opens a shell, it does not quit.** `cmd+W` says close this tab; answering it by quitting is the app deciding you meant `cmd+Q`. A child that exited on its own still terminates, because `exit` and `logout` are the universal "done with this terminal" gesture
+- Splits with a real gutter, a pane whose child exited closing itself and giving its width back, and splitting that stops before a pane becomes too narrow to use
+- Click-drag, double-click and triple-click selection, `cmd+A`, `cmd+C`. `cmd+C` is conditional on purpose: with nothing selected it falls through to the child as `^C` and can still interrupt a command
+- `cmd+V` bracketed paste, `cmd+=` / `cmd+-` / `cmd+0` live zoom across every pane, `cmd+click` hyperlinks
+- A `cmd+K` command palette, OSC 133 block navigation with a gutter, git worktree workspaces, and an SSH host list read from your own `ssh_config`
- Agent launcher: ten agent CLIs with the fields that actually differ, a PATH probe that measures availability rather than trusting a table, spawn-observe-retry with counted backoff, and a guard that refuses an auto-approve bypass rather than stripping it
- `~/.termisu/config.toml`: font size, family, ligatures, shell, themes, auto-direction, and `reports`, off by default because it lets a program read back what is on your screen
-**There was a second host, in Swift, and it was deleted on 2026-08-08.** It carried tabs, a
-cmd+K palette with TOML workflows, fish-style autosuggestions, OSC 133 blocks and git-worktree
-workspaces, and it was kept for a long time as the parity target the Tauri port was measured
-against - a port with no reference is a rewrite with extra steps. It went once the Tauri host
-could produce an app on its own, because a reference nobody builds is a liability rather than a
-reference. `git log -- swift/` still has all of it.
-
## Status
Working as a terminal, and in daily use on macOS, Apple Silicon. Pre-1.0, no stability promises.
-**What it is not: a workbench.** There is no session map, no canvas, no way to see what several
-agents are doing at once. The host is a window with panes and an agent launcher. The engine is
-the part that is finished. The surface that would earn the word "workbench" is planned in
-`docs/plans/` and not started.
+**What is finished is the engine.** The core, the renderer, the pty, the C ABI and the
+differential harness are the parts this project is about, and they are done to the standard the
+gates describe.
-Linux is compiled on every push (`cargo check -p termisu` on ubuntu-latest) and is otherwise
-UNRUN: the GTK key and clipboard paths exist and no key has ever been pressed on a real Linux
-machine. Windows is a separate slice and is not started - there is no POSIX pty there, so the pty
-crate needs ConPTY.
+**What is not built is a workbench.** There is no session map, no canvas, no way to see what
+several agents are doing at once beyond the dock. The review panel renders documents and is
+**read only**: editing from it needs a conflict model, undo, save semantics and an answer for the
+agent editing the same file in the same second, and none of those is a diff viewer. Sessions do
+not yet outlive the window, which is the one reason people stay on `tmux`.
+
+**The GUI layer is deliberately uncovered by the differential harness** and its debt is declared
+per slice rather than hidden. Features landing there close as `untested - needs your eyes` unless
+a picture was taken.
+
+Linux is compiled on every push (`cargo check`) and is otherwise **unrun**: the key and clipboard
+paths exist and no key has ever been pressed on a real Linux machine. Windows is not started;
+there is no POSIX pty there, so the pty crate needs ConPTY.
## Building
-Requires Rust 1.93 or newer.
+Requires Rust 1.93 or newer, and Xcode for the app.
```sh
git clone https://github.com/Orellius/termisu.git
cd termisu
-cargo run -q -p termisu --bin termisu # run it
+./scripts/build-app.sh # assemble, sign and install to ~/Applications
+```
+
+`build-app.sh` is the only supported install path. It takes the version from `git describe`, so
+tag before you build. It also needs GNU `timeout` (`brew install coreutils`) and `librsvg`
+(`brew install librsvg`) for the icon, and it fails loudly rather than shipping something wrong
+if either is missing.
+
+The gates:
+
+```sh
+cargo test --workspace # 822 tests
+cargo run -p termisu-vt-difftest # 223 corpus cases, against libghostty-vt
+./scripts/build-lib.sh # libtermisu-vt.a (the drop-in ABI, 28 exports)
+./scripts/build-host.sh # libtermisu-vt-host.a (ABI plus embedder, 61 exports)
+./scripts/build-swift.sh # the host, then 15 headless smokes
```
The rest:
```sh
-cargo test --workspace # the gate: every test green
-cargo run -p termisu-vt-difftest # the corpus, measured against libghostty-vt
-./scripts/smoke-termisu.sh # host gate: no window, no synthesized input
-./scripts/build-lib.sh # libtermisu-vt.a (the drop-in ABI)
-./scripts/build-host.sh # libtermisu-vt-host.a (ABI plus embedder surface)
-./scripts/build-app.sh # assemble, sign and install the app
-sh scripts/demo-features.sh # the one-screen feature tour, inside the terminal
+sh scripts/demo-features.sh # the one-screen feature tour, inside the terminal
+./scripts/make-signing-identity.sh # a stable local signing identity, once per machine
```
Running the differential harness additionally needs a Ghostty checkout to build its oracle from,
-pointed at by `TERMISU_VT_ORACLE_SRC`. See [CONTRIBUTING.md](CONTRIBUTING.md) for that and the rest
-of the development setup.
+pointed at by `TERMISU_VT_ORACLE_SRC`. See [CONTRIBUTING.md](CONTRIBUTING.md) for that and the
+rest of the development setup.
+
+**On signing.** `codesign -s -` makes the designated requirement a bare hash of the code, so every
+rebuild is a *different application* to macOS and it re-asks for every permission.
+`make-signing-identity.sh` creates a stable local identity and fixes that. It is not Developer ID
+and it is not notarization, which is what a public release would need.
## The names
-- **Termisu** is the product: the app in `crates/termisu`.
+- **Termisu** is the product: the macOS app, built from `swift/` over the engine.
- **`termisu-vt`** is the engine, and it keeps its name. The VT core, pty, renderers and C ABI are
the part somebody else could embed, so the crates carry the engine's name while the repository
carries the product's.
@@ -574,6 +729,8 @@ of the development setup.
`libghostty-vt`, meant to sit behind somebody else's GUI, then grew its own window, renderer,
panes and agent launcher. The ABI promise is still real and still tested: you can link
`libtermisu-vt.a` where `libghostty-vt` was expected.
+- The product was **Mind2t** until 2026-08-25 (terminal plus tiramisu) and the repository was
+ **ruuah-vt** until 2026-08-06. GitHub redirects the old URLs.
## Contributing
@@ -599,5 +756,5 @@ derivation rather than transcription.
- [Ghostty](https://ghostty.org) (MIT), the reference implementation this engine is measured against at test time, and the origin of the ABI.
- [vte](https://github.com/alacritty/vte), the tokenizer this project vendors and extends.
- [esctest2](https://github.com/ThomasDickey/esctest2) (GPL-2.0, test time only), the conformance suite run against our own pty.
-- [Cousine](https://github.com/googlefonts/cousine), the Hebrew face, and [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) via [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts), the lead.
+- [Cousine](https://github.com/googlefonts/cousine), the Hebrew face, [Kawkab Mono](https://makkuk.com/kawkab-mono/), the Arabic face, and [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) via [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts), the lead.
- [Culmus](https://culmus.sourceforge.io), for Miriam Mono CLM. It was the Hebrew face until 2026-08-25 and is still the GPOS control the mark-placement tests are measured against.
diff --git a/docs/images/dock-states-20260826.png b/docs/images/dock-states-20260826.png
new file mode 100644
index 0000000000000000000000000000000000000000..1bdbfc3cfd3b47111279c9a6d1c045b26a936423
GIT binary patch
literal 26658
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
Z%Ng}I8GbGsi=NeEL^07X+;bw}{{a$Y#)AL=
literal 0
HcmV?d00001
diff --git a/docs/images/emoji-as-glyphs-20260826.png b/docs/images/emoji-as-glyphs-20260826.png
new file mode 100644
index 0000000000000000000000000000000000000000..a605964a4558557eeb89e8c34420b24762dbf0d8
GIT binary patch
literal 58085
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