The Evaluation Rubric

Score yourself honestly. This rubric is for you; a generous self-assessment costs you the only thing it could have given.

Scoring: 0 = absent · 1 = attempted · 2 = works · 3 = works and I can explain every part.

The only score that matters is 3. A 2 means you have a program; a 3 means you have understanding, which was the point.


Part 1: Unix Process and Terminal Semantics (Section 1)

#Criterion0123
1.1A PTY pair allocated with raw syscalls, no PTY crate
1.2The child's session, controlling terminal, and fds set up correctly
1.3The complete spawn syscall list, in order, with each one's failure mode, from memory
1.4termios raw mode with restore on every exit path including panic
1.5A single poll loop over stdin, master, and signals
1.6Async-signal-safe signal handling (one write in the handler)
1.7SIGWINCH → TIOCGWINSZ → TIOCSWINSZ, verified with vim and top
1.8SIGCHLD → waitpid(WNOHANG) in a loop; exit code propagated
1.9Linux EIO vs. macOS EOF handled explicitly, with a comment naming both
1.10Partial writes handled; a 100 KB paste arrives intact
1.11All seven Section 1 experiments performed, with written predictions
1.12Job control explained: sessions, groups, foreground group, tcsetpgrp, SIGHUP

Section 1 total: ___ / 36


Part 2: The Terminal Core (Section 2)

#Criterion0123
2.1A real VT state machine with every state, not if chains
2.2The split-input property holds at chunk sizes 1, 2, 3, 7, 13, ∞ over the whole corpus
2.3UTF-8 decoding inside Ground, with incomplete sequences buffered
2.4Parameters, intermediates, and OSC payloads all bounded
2.5A fuzz target run ≥10 minutes clean, corpus committed
2.6Pending wrap implemented and explicitly tested
2.7Scroll regions, with sub-region scrolls excluded from scrollback
2.8The alternate screen, with no scrollback, enforced structurally
2.9Erase honoring the current background color
2.10SGR: all attributes, 16/256/truecolor, both semicolon and colon forms
2.11Wide characters with the spacer invariant, property-tested
2.12Combining marks absorbing, bounded, leading-mark case handled
2.13OSC: title (sanitized), hyperlinks (interned, scheme-checked), clipboard (policy)
2.14Terminal replies queued, not written; rate-limited
2.15Damage tracking, including the two-row cursor rule
2.16≥10 golden cases with checked-in snapshots

Section 2 total: ___ / 48


Part 3: The Graphical Frontend (Section 3)

#Criterion0123
3.1A window with a working shell; vim, top, and yes all behave
3.2Correct font metrics; you can state ascent/descent/gap/advance for your font
3.3The baseline rule; no clipped descenders
3.4A glyph atlas with a measured hit rate >99%
3.5Damage tracking with a printable dirty-row count
3.6Idle CPU ~0%, verified with top
3.7yes does not freeze the UI (read/render decoupled)
3.8Resize in the correct order, with HiDPI handled
3.9Every key in the encoding table implemented and unit-tested
3.10DECCKM honored, including the modified-arrow asymmetry
3.11Bracketed paste with envelope-escape protection
3.12Mouse reporting with the Shift bypass and 1-based coordinates
3.13Selection with wrapped-line joining and no trailing padding
3.14All modes reset on every exit path

Section 3 total: ___ / 42


Part 4: The Multiplexer (Section 4)

#Criterion0123
4.1N sessions, all read and parsed, input to the active one only
4.2A layout tree with exact tiling, property-tested over 1,000 trees
4.3Per-pane resize in the correct order, with the no-op guard
4.4Compositing with borders, junctions, and a status line
4.5A correctly daemonized server (double fork, setsid, SIGPIPE ignored)
4.6A socket in a per-user directory, 0700, ownership verified, stale sockets reclaimed
4.7A framed protocol with a version handshake and round-trip tests
4.8kill -9 on the client leaves shells running, proven with ps
4.9Panes read and parsed with zero clients attached
4.10Attach repaints from state, verified with the alt-screen case
4.11A documented multi-client resize policy, with the zero-client rule
4.12Two clients rendering and typing; a stalled client blocks nobody
4.13The prefix key parsed client-side, with the literal escape
4.14cargo tree -p terminal-mux shows no GUI crates

Section 4 total: ___ / 42


Part 5: Architecture (Section 5)

#Criterion0123
5.1The boundary audit passing, in CI
5.2terminal-protocol and terminal-core build for wasm32
5.3#![deny(missing_docs)] with the docs actually written
5.4Four consumers of one unmodified core
5.5The forty-line headless simulator
5.6Configuration passed down, never a global
5.7Platform behavior as configuration, not cfg
5.8A boundary-defense document with "known tensions"
5.9Every pub item justifiable in one sentence
5.10(Optional) A C ABI with a CI-tested C example

Section 5 total: ___ / 30


Part 6: Testing and Observability

#Criterion0123
6.1Unit tests: normal, boundary, and degenerate for every sequence
6.2Property tests over five structural invariants
6.3The four required PTY integration tests
6.4Golden tests with the UPDATE_GOLDEN discipline documented
6.5Differential tests against vte, with divergences documented
6.6Fuzz targets including the chunking-equivalence assertion
6.7terminal-debugger with all nine capabilities
6.8Debug channels: switchable, cheap when off, never to the debugged terminal
6.9Record/replay, with the bytewise mode
6.10The compatibility matrix for eleven programs
6.11The test suite runs in under ten seconds

Section 6 total: ___ / 33


Part 7: Understanding (The Part That Matters)

Scored by explanation, not by code. Answer out loud, from memory, to someone else.

#Criterion0123
7.1Define TTY, PTY, line discipline, emulator, shell, and multiplexer without using each other
7.2Trace one keystroke through all fifteen layers of the mux path
7.3Explain who echoes, and prove it in one command
7.4Explain Ctrl+C: the byte, the flag, the signal, the exact recipients
7.5Explain why tmux keeps shells alive, in one sentence
7.6Explain why a mux server contains a terminal emulator
7.7Explain pending wrap and its visible bug
7.8Explain why UTF-8 decoding belongs inside the parser's ground state
7.9Explain why repaint-from-state beats replay, with the alt-screen case
7.10Defend every crate boundary with the capability it protects
7.11Explain what breaks with pipes instead of a PTY — ten concrete differences
7.12Who owns the terminal screen? One sentence, and defend it

Section 7 total: ___ / 36


Part 8: The Write-Up

#Criterion0123
8.1Scope stated honestly, including what does not work
8.2Architecture explained well enough to predict where a bug lives
8.3The hardest bug: a case where your model was wrong, not a typo
8.4Four design decisions with alternatives, criteria, and costs
8.5"What I would do differently", specific and actionable
8.6Real measurements, with the method stated
8.7"What I still do not understand", named honestly

Section 8 total: ___ / 21


The Total

   Section 1  Unix semantics        ___ / 36
   Section 2  Terminal core         ___ / 48
   Section 3  Graphical frontend    ___ / 42
   Section 4  Multiplexer           ___ / 42
   Section 5  Architecture          ___ / 30
   Section 6  Testing & tooling     ___ / 33
   Section 7  Understanding         ___ / 36
   Section 8  Write-up              ___ / 21
   ─────────────────────────────────────────
   TOTAL                            ___ / 288
RangeMeaning
250–288You could contribute meaningfully to Alacritty, WezTerm, Ghostty, or zellij tomorrow.
200–249You understand terminals better than most people who work on them. Find the gaps in Section 7 and close them.
150–199You built it and it works. The understanding is uneven — re-read the chapters behind your lowest scores.
100–149You have a working program and a partial model. Redo the experiments; that is where the gap is.
< 100You skipped the experiments, or you used a crate you were told not to use. Both are recoverable; go back.

The Weighting, Explained

Section 7 is worth as much as Section 1. That is deliberate.

You can build a working terminal by copying code. You cannot explain one without having understood it. The rubric is weighted so that a beautiful implementation you cannot explain scores lower than a rougher one you can — because the second engineer can fix it at 3 a.m. and the first cannot.

Learning Priority #10 was:

Build enough of each part manually that I can explain it without relying on abstractions I do not understand.

Section 7 is that priority, scored.


Honest Self-Assessment: A Method

Scoring yourself is hard. Two techniques that make it less so:

1. The explanation test. For every criterion you want to score 3, explain it out loud to someone who does not know terminals — or to a recording. If you hesitate, hedge, or say "it just works," it is a 2.

2. The modification test. For every criterion you want to score 3, name a change to that component and estimate how long it would take. If you cannot estimate, you do not understand it well enough to score 3.

   "Add DECSCUSR (cursor shape) support."           → 20 minutes. I know where.  ✓ 3
   "Change the Cell representation to interned."    → I would have to go and look. 2
   "Make resize reflow instead of truncate."        → No idea where to start.      1

A Note on Scoring Zero

A zero on an optional criterion (the C ABI, GPU rendering) is fine and expected. A zero on a required one is information: it tells you exactly which chapter to re-read and which experiment to redo.

The rubric is not a grade. It is a map of what you know, and its only purpose is to point at the parts you do not.


Return to the capstone, or to the introduction to re-answer the twelve questions.