Files
the-nexus/docs/ADR-001-shell-boundary.md
Claude (Opus 4.6) c97364ac13
Some checks failed
Deploy Nexus / deploy (push) Failing after 5s
Staging Verification Gate / verify-staging (push) Failing after 5s
[claude] ATLAS Cockpit: operator inspector rail and session shell (#1695) (#1696)
2026-04-22 05:19:13 +00:00

85 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-001 — Shell / Terminal Boundary and Transport Model
**Status:** Accepted
**Date:** 2026-04-22
**Issue:** [#1695 — ATLAS Cockpit: operator inspector rail and session shell patterns](https://forge.alexanderwhitestone.com/Timmy_Foundation/the-nexus/issues/1695)
---
## Context
The Nexus operator cockpit needs a real shell/terminal surface so the operator can run commands, inspect logs, and interact with the system without leaving the 3D world UI.
Three transport models were evaluated:
| Option | Description |
|---|---|
| **A. Native local PTY** | `server.py` spawns a PTY via Python's `pty` stdlib module; the browser connects via WebSocket on `ws://127.0.0.1:8766/pty` |
| **B. Remote SSH PTY** | Browser connects to an SSH relay that opens a PTY on a remote machine |
| **C. Browser pseudo-terminal** | Pure JavaScript terminal emulation (e.g., a custom REPL) with no real OS shell |
---
## Decision
**Option A — Native local PTY** is chosen.
The Nexus is explicitly a **local-first** system (CLAUDE.md: "local-first training ground for Timmy"). The operator is the same person sitting at the machine. A local PTY bridged through `server.py` is:
- Architecturally consistent with the existing `server.py` WebSocket gateway
- Zero additional infrastructure (no SSH relay, no remote server)
- Full shell fidelity — any tool on the operator's PATH, full interactive programs, readline, color, etc.
- Bounded: PTY_PORT (8766) binds to `127.0.0.1` only; no external exposure
---
## Transport Detail
```
Browser (xterm.js) ←→ ws://127.0.0.1:8766/pty ←→ server.py pty_handler ←→ OS PTY ($SHELL)
```
- Each WebSocket connection gets its own `pty.openpty()` pair and subprocess.
- Input from xterm.js `onData``_ptyWs.send(data)``os.write(master_fd, data)`
- Output from PTY → `os.read(master_fd)``websocket.send(text)``_term.write(text)`
- Resize messages (`{"type":"resize","cols":N,"rows":N}`) can be added later via `fcntl.ioctl(TIOCSWINSZ)`.
---
## Why not Option B (Remote SSH PTY)?
Remote SSH adds network hop complexity, credential management, and an SSH relay service. The Nexus does not currently have a remote operator use-case; Alexander operates locally. This decision can be revisited when fleet/remote-agent use-cases mature (see issues #672#675).
---
## Why not Option C (Browser pseudo-terminal)?
A JavaScript REPL cannot run arbitrary shell programs, manage processes, or provide the raw interactive shell experience that operators expect. It would be a toy, not a tool.
---
## Rejected Patterns
- **tmux over WebSocket** — adds server-side state complexity without enough benefit at this scale
- **ttyd** — external binary dependency; overkill for a local-first single-operator setup
- **xterm.js + websocketd** — external binary dependency; `server.py` already owns the WebSocket gateway
---
## Consequences
- `server.py` now starts two WebSocket servers: `PORT` (8765, main gateway) and `PTY_PORT` (8766, shell gateway)
- `PTY_PORT` always binds to `127.0.0.1` regardless of `NEXUS_WS_HOST`
- `cockpit-inspector.js` loads xterm.js from CDN (offline fallback: graceful degradation — the rail renders without the terminal pane)
- PTY sessions are ephemeral (no persistence across browser reload or server restart)
- Future: add TIOCSWINSZ resize support; add `/pty?shell=zsh` query param selection
---
## Related
- `cockpit-inspector.js` — implements the browser side (xterm.js + WebSocket)
- `server.py` — implements `pty_handler()` and `_get_git_status()`
- `docs/ATLAS-COCKPIT-PATTERNS.md` — documents source patterns adopted
- Issues: #1695, #686, #687