- spec 2026-09-01-runtime-v2-design.md: the one principle (PULL — a child is fds, the net verbs drive them; runtime-v2 adds acquisition verbs, never transport), the full surface (ids 97+: spawn/spawn_pty/ wait_dl/signal/resize, signal.on delivering the sig number, term.raw/ restore with runtime-guaranteed restore, send_fd/recv_fd/connect_unix), actor-owned lifecycle, mechanics notes, refusals by name - push transport rejected with reasons recorded (mailbox-cap collision, new delivery machinery); death-notice verb refused (a two-line fiber composes wait_dl) - five stories flip readiness: ready; fork sections rewritten as settled - graph section 6 remapped: pull broke the 1->2->3 chain — only 1->2 remains; 3, 4, 5 and the VTE grid startable alone today - board section + registry follow; linkcheck 0 broken Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit d313cdeebbe53c83b83f31f4480631568d9d0743)
47 lines
1.9 KiB
Markdown
47 lines
1.9 KiB
Markdown
---
|
|
track: runtime-v2
|
|
iteration: "2"
|
|
status: pending
|
|
readiness: ready
|
|
---
|
|
|
|
# runtime-v2 2 — PTY: a child that believes it owns a terminal
|
|
|
|
> Part of [Story — runtime-v2: the runtime beyond sockets](00-story.md).
|
|
> After [1](01-streaming-subprocess.md): a streaming child whose stdio
|
|
> is a pseudo-terminal instead of pipes. A shell run over pipes disables
|
|
> its prompt, its line editing and its job control; a multiplexer is
|
|
> pointless without them.
|
|
>
|
|
> **The problem.** Nothing can allocate a PTY pair, place the child on
|
|
> the slave side as its controlling terminal, or resize it. The
|
|
> reference reading is `.dev/reference/tmux` `spawn.c` +
|
|
> `compat/fdforkpty.c` (~450 lines of C covering five platforms; Linux
|
|
> alone is far smaller).
|
|
|
|
## Info — the forks, settled (brainstorm 2026-09-01; spec:
|
|
[`2026-09-01-runtime-v2-design.md`](../../superpowers/specs/2026-09-01-runtime-v2-design.md))
|
|
|
|
1. **Separate verb**: `proc.spawn_pty(cmd, args, cols, rows) -> ?Child`
|
|
— its own builtin id (static arity table stays static), same Child
|
|
record with `in` and `out` both the master fd, `err` nil.
|
|
2. **Resize ships HERE**: `proc.resize(id, cols, rows)` → TIOCSWINSZ on
|
|
the slot; refusal by name on a pipe child.
|
|
3. **Transport settled by iteration 1's pull decision** — the master fd
|
|
is driven by the existing net verbs, nothing new.
|
|
4. **Master raw by default, no knobs** — until a consumer asks by name.
|
|
(`openpty` may need `-lutil` — the plan verifies the link line
|
|
before assuming.)
|
|
|
|
## Acceptance sketch
|
|
|
|
- A real shell spawned on a PTY prints a PROMPT (it never does over
|
|
pipes) — asserted on the bytes.
|
|
- Resize: the child (a script reading TIOCGWINSZ) observes the new size.
|
|
- `isatty` inside the child answers yes on all three fds.
|
|
- Kill/reap/stop legs identical to 1's, PTY edition; fd count flat.
|
|
|
|
## Consumers
|
|
|
|
wmux 1 (every pane), the alacritty study's stage A (the headless
|
|
expect-clone is exactly "spawn on a PTY, script it, assert").
|