Scaffold Lumbridge architecture and research plan

This commit is contained in:
2026-08-31 14:37:49 -07:00
commit 8971ddcf58
19 changed files with 840 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
# Architecture
## Recommended shape
Lumbridge should be two cooperating Rust processes:
```text
native desktop UI
| local authenticated IPC
Lumbridge session runtime
|-- PTYs and process trees
|-- ACP clients and adapters
|-- repositories and worktrees
|-- usage/event ledger
`-- secret-store handles
```
Separating the UI from the session runtime lets terminals survive renderer
restarts, permits a future headless/SSH mode, and gives persistence one owner.
The first development build may run both in one process, but boundaries and IPC
messages should be real from the beginning.
## Planned crates
- `lumbridge-core`: IDs, commands, events, errors, capability and usage types.
- `lumbridge-runtime`: session ownership, supervision, recovery, IPC server.
- `lumbridge-pty`: portable PTY and process-tree adapters.
- `lumbridge-terminal`: VT parsing, scrollback, selection, search, render model.
- `lumbridge-acp`: ACP client, capability negotiation, transcript normalization.
- `lumbridge-harness`: manifests, launch profiles, hooks, PTY fallback adapters.
- `lumbridge-provider`: BYOK providers and provider-neutral usage records.
- `lumbridge-storage`: SQLite migrations, event log, snapshots, retention.
- `lumbridge-secrets`: Keychain/libsecret adapters and redaction.
- `lumbridge-git`: repositories, worktrees, diffs, status, conflict state.
- `lumbridge-ui`: native desktop state and rendering.
- `lumbridge`: installable application entry point.
Only `lumbridge-core` and the entry point exist in the scaffold. New crates are
added after their architecture spike passes.
## Terminal path
The runtime owns PTYs, child process groups, resize signals, input ordering, and
raw output. The terminal engine turns output into immutable render snapshots and
bounded deltas for the UI. Scrollback is chunked and persisted separately from
the live screen to prevent large agent transcripts from blocking input.
We should evaluate, not blindly copy, WezTerm, Zellij, RMUX, tmux, and cmux. The
first spike must compare a reusable terminal crate with a small first-party layer.
Correctness cases include alternate screen, bracketed paste, OSC 8 links, Kitty
keyboard/graphics negotiation, Unicode width, IME, mouse modes, shell integration,
and simultaneous automation plus human input.
## UI decision gate
Do not lock the project to a webview or to Zed's private implementation details
before a measured spike. Compare:
1. GPUI for a Zed-like native model and excellent text-heavy interaction.
2. Iced/wgpu plus a dedicated terminal renderer for stable Rust portability.
3. Tauri only as a delivery-speed baseline, not the assumed winner.
The winner must render six busy panes smoothly, keep input latency low, support
IME/accessibility, package on macOS and both Linux targets, and avoid a license
or upstream-stability trap.
## Harness integration
Each harness is described by a versioned manifest: executable discovery, launch
arguments, environment allowlist, resume semantics, status/usage probes, ACP
command when available, and hook installation rules.
ACP is preferred because it provides structured prompts, plans, tool calls,
permissions, content blocks, and session lifecycle. A supervised PTY is always
available because terminal fidelity and arbitrary CLI compatibility are product
requirements. Harness-specific adapters translate both paths into the same event
model without pretending a PTY has capabilities it cannot prove.
## Usage model
Usage is an append-only observation stream, not a mutable percentage field.
Observations include account profile, provider, harness, model, units, time
window, reset time, provenance, confidence, and source timestamp. Projections are
derived views that can be recomputed as forecasting improves.
Subscription balance is provider-specific and sometimes unavailable. BYOK calls
usually expose token counts but cost still depends on cached tokens, reasoning,
tool calls, and current pricing. Adapters normalize facts without erasing their
source or uncertainty.
## Persistence
SQLite in WAL mode stores metadata, commands/events, normalized usage, and small
snapshots. Large scrollback chunks and binary attachments use content-addressed
files. A write-ahead event is committed before an external mutation is reported
as accepted. Startup replays incomplete operations and reconciles live children.
## Security
- macOS secrets: Keychain; Linux secrets: Secret Service/libsecret, with an
explicit encrypted-file fallback only if the user enables it.
- Never pass keys in process arguments. Prefer inherited file descriptors or a
minimal child environment when a harness requires environment variables.
- IPC is local, authenticated, permission-restricted, and version-negotiated.
- Transcript and crash-report redaction happens before persistence or export.
- Repository trust, harness approval mode, and sandbox mode are visible per pane.
- Remote control and plugins are out of scope until a capability/permission model
exists.
## Platform adapters
Shared contracts cover PTY, process tree, notifications, secret store, paths,
autostart, updater, and packaging. macOS uses `forkpty`/process groups and native
Keychain. Ubuntu and Omarchy use Unix PTYs, cgroups/systemd scopes when available,
and Secret Service. Omarchy is treated as Arch Linux, not as a separate kernel.