diff --git a/README.md b/README.md
index d560ade..9343f0c 100644
--- a/README.md
+++ b/README.md
@@ -4,211 +4,140 @@
-CommandRelay is a secure, bi-directional terminal control gateway for long-running coding sessions.
+CommandRelay is a production-oriented gateway for remote terminal control of long-running coding sessions.
-It lets you monitor and control home-machine terminal sessions (tmux and ghostty/cmux runtime) from remote clients, with replay, guarded input, and auditability.
+## SSH-First Architecture
-## Why This Exists
+CommandRelay is oriented around an SSH-first operating model:
-Long AI coding sessions run for hours while you are away from your main machine.
+1. Run the gateway on the machine that owns the terminal runtime.
+2. Keep runtime state in `tmux` so sessions survive client disconnects.
+3. Reach the gateway from remote clients over an SSH transport path (for example, tunnel + WebSocket) while CommandRelay enforces terminal control policy.
-CommandRelay gives you one control surface to:
+`ghostty` is an optional local terminal UI. It is not the control backend for remote lane ownership, replay, or policy enforcement.
-1. See active terminal sessions.
-2. Reattach after disconnects.
-3. Send commands safely when needed.
-4. Keep read-only mode as default.
+## Control Plane (Bi-Directional)
-## What You Get
+Web and native clients use the same v1 envelope and core flow:
-1. WebSocket event protocol with strict envelope validation.
-2. Replay-aware terminal output streaming (`streamSeq` + `attach(lastSeq)`).
-3. Guarded input flow: `enable_input` -> `input` -> `disable_input`.
-4. Kill switch and lane-ownership controls.
-5. Runtime backend multiplexer (`tmux`, `cmux`) with backend-aware pane/session routing.
-6. Proxy package ecosystem for reusable outbound proxy behavior.
+1. `list_sessions`
+2. `attach(paneId, lastSeq)`
+3. `output` stream with ordered `streamSeq` replay behavior
+4. guarded input: `enable_input` -> `input` -> `disable_input`
-## Architecture
+Safety controls:
-### Runtime Topology
+1. read-only by default
+2. explicit input enable per client
+3. global input kill switch
+4. pane writer-lane ownership arbitration
+5. message/input rate limits and max input bytes
+6. audit logging for auth/input/policy events
-```text
-Remote Client (web/iOS/android/macos)
- |
- | WS (/ws)
- v
-+-----------------------------------+
-| CommandRelay Gateway (Node/TS) |
-| - Auth / policy / limits |
-| - Replay + output stream engine |
-| - Input lane arbitration |
-+----------------+------------------+
- |
- | Runtime multiplexer
- v
- +-------------------+-------------------+
- | |
-+----+------------------+ +-----------+-----------+
-| tmux backend adapter | | cmux backend adapter |
-| pane ids: %1, %2 ... | | pane ids: surface-* |
-+-----------------------+ +-----------------------+
-```
-
-### Event Flow (Condensed)
+## Architecture Snapshot
```text
-Client -> hello/auth -> list_sessions -> attach(paneId,lastSeq)
-Server -> session_list -> output(snapshot/delta, streamSeq)
-Client -> enable_input -> input -> disable_input
-Server -> ack/error + policy_update
+Remote Web / Native Client
+ |
+ | SSH transport path + WS (/ws)
+ v
++----------------------------------------+
+| CommandRelay Gateway (Node/TS) |
+| - auth + policy |
+| - replay + stream sequencing |
+| - input lane arbitration |
++----------------------+-----------------+
+ |
+ v
+ +------------------+
+ | tmux runtime |
+ | panes: %1, %2... |
+ +------------------+
+
+Local optional UI: Ghostty (operator convenience only)
```
-### Safety State Model
+## UX Model (Operator View)
```text
-DISCONNECTED
- -> AUTHENTICATED_READ_ONLY
- -> STREAMING_READ_ONLY
- -> STREAMING_INPUT_ENABLED (explicit only)
- -> READ_ONLY (disable_input / kill switch / disconnect)
++------------------------------------------------------+
+| Session Tab: "backend-api" |
+| +--------------------------+ +----------------------+ |
+| | Pane %1 (read-only) | | Pane %2 (writer) | |
+| | replay + live output | | input explicitly on | |
+| +--------------------------+ +----------------------+ |
+| Notifications: lane conflict, input enabled, |
+| kill switch active, reconnect + replay complete |
++------------------------------------------------------+
```
-## Runtime Backends (tmux + ghostty/cmux)
+## Proxy Packages: Parallel Track
-Configure runtime backends with:
+The proxy packages (`@commandrelay/*`, `@termina/proxy-*`) are a parallel product track for outbound HTTP/proxy reuse.
-```bash
-COMMANDRELAY_RUNTIME_BACKENDS=tmux
-# or
-COMMANDRELAY_RUNTIME_BACKENDS=tmux,cmux
-```
+They are not mandatory for the core terminal-control path (`list/attach/replay/input`) and should be treated as adjacent infrastructure, not a prerequisite for SSH + tmux operation.
-Optional cmux command override:
+## Quick Start
```bash
-COMMANDRELAY_CMUX_COMMAND=/opt/homebrew/bin/cmux
+npm install
+npm run check
+npm start
```
-Notes:
-
-1. Default backend set is `tmux`.
-2. In multi-backend mode, pane IDs are backend-namespaced (`tmux:%1`, `cmux:surface-1`).
-3. Startup logs availability per backend.
-4. Startup fails only when all configured backends are unavailable in non-tmux-only mode.
-
-## Security Model
-
-CommandRelay is secure-by-default:
-
-1. Read-only mode on connect.
-2. Explicit input enable required.
-3. Global kill switch available.
-4. Per-client input rate limits and max payload limits.
-5. Pane ownership arbitration to prevent silent concurrent writers.
-6. Audit logging support for auth/input/policy events.
-
-## Quick Start
+Optional SSH startup wiring (remote profile orchestration contract):
```bash
-npm install
-npm run check
+export COMMANDRELAY_TRANSPORT_MODE=ssh
+export COMMANDRELAY_SSH_PROFILE=primary
+export COMMANDRELAY_SSH_TARGET="dev@relay-host"
+export COMMANDRELAY_SSH_COMMAND=ssh
+export COMMANDRELAY_SSH_PORT=22
+export COMMANDRELAY_SSH_CONNECT_TIMEOUT_SECONDS=8
+export COMMANDRELAY_SSH_STRICT_HOST_KEY_CHECKING=true
npm start
```
-Default endpoints:
+Current runtime data path remains the WS server (`/ws`) plus tmux runtime control.
+In `ssh` mode, the bridge runs tmux operations on the remote target over SSH after startup preflight passes.
+SSH runtime execution is non-interactive (`-T`, `BatchMode=yes`); when strict host key checking is disabled, runtime uses `UserKnownHostsFile=/dev/null` to suppress known_hosts writes.
+`ssh` mode is tmux-only: set `COMMANDRELAY_RUNTIME_BACKENDS=tmux`.
+
+Default local endpoints (current runtime path):
-1. Health: `GET http://127.0.0.1:8787/health`
-2. Web app (if enabled): `http://127.0.0.1:8787/app/`
-3. WebSocket: `ws://127.0.0.1:8787/ws`
+1. `GET http://127.0.0.1:8787/health`
+2. `http://127.0.0.1:8787/app/` (when static app hosting is enabled)
+3. `ws://127.0.0.1:8787/ws`
-## Core Environment Variables
+## Core Configuration
| Variable | Purpose |
| --- | --- |
| `COMMANDRELAY_AUTH_TOKEN` | Token auth for non-loopback binds |
-| `COMMANDRELAY_RUNTIME_BACKENDS` | Runtime backend list (`tmux,cmux`) |
-| `COMMANDRELAY_CMUX_COMMAND` | cmux executable/path override |
+| `COMMANDRELAY_RUNTIME_BACKENDS` | Runtime backends (`tmux` default, optional `tmux,cmux`). Must be `tmux` when `COMMANDRELAY_TRANSPORT_MODE=ssh`. |
+| `COMMANDRELAY_CMUX_COMMAND` | Optional `cmux` command/path override |
+| `COMMANDRELAY_TRANSPORT_MODE` | Startup transport selector (`ws` default, `ssh` enables remote tmux execution over SSH) |
+| `COMMANDRELAY_SSH_PROFILE` | SSH profile name (`primary` when unset). If set, must be non-empty and match `[A-Za-z0-9._-]+`. |
+| `COMMANDRELAY_SSH_TARGET` | SSH target (required in `ssh` mode) in `[user@]host` format, where host is `name` or bracketed IPv6 (`[2001:db8::1]`). |
+| `COMMANDRELAY_SSH_COMMAND` | SSH executable/command override used for preflight and runtime SSH execution (`ssh` default). |
+| `COMMANDRELAY_SSH_PORT` | SSH target port override (`22` default) |
+| `COMMANDRELAY_SSH_CONNECT_TIMEOUT_SECONDS` | SSH connect/runtime command timeout in seconds (`8` default, allowed `1..60`). |
+| `COMMANDRELAY_SSH_STRICT_HOST_KEY_CHECKING` | SSH strict host key checking policy (`true` default) |
| `COMMANDRELAY_INPUT_KILL_SWITCH` | Global input disable switch |
-| `COMMANDRELAY_ALLOW_INPUT_OVERRIDE` | Allow explicit pane ownership takeover |
-| `COMMANDRELAY_MAX_INPUT_BYTES` | Max input payload bytes |
+| `COMMANDRELAY_ALLOW_INPUT_OVERRIDE` | Allow/deny forced lane takeover |
+| `COMMANDRELAY_MAX_INPUT_BYTES` | Max input payload size |
| `COMMANDRELAY_MAX_MSG_PER_MIN` | Per-client message rate limit |
| `COMMANDRELAY_MAX_INPUT_PER_MIN` | Per-client input rate limit |
-| `COMMANDRELAY_STRICT_PROTOCOL_PARSING` | Strict envelope parsing toggle |
-| `COMMANDRELAY_APP_STATIC_ENABLED` | Enable/disable static web app hosting |
-| `COMMANDRELAY_APP_STATIC_DIR` | Static app root |
+| `COMMANDRELAY_STRICT_PROTOCOL_PARSING` | Strict v1 envelope parsing |
| `COMMANDRELAY_AUDIT_LOG` | Audit JSONL path |
-| `HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY`/`NO_PROXY` | Outbound proxy settings |
-
-## Protocol and Behavior
-
-Primary protocol docs:
-
-1. `docs/protocol-v1.md` (normative contract)
-2. `docs/protocol.md` (operator-facing summary)
-3. `docs/security.md` (threat model + controls)
-
-`list_sessions` behavior in multi-backend mode:
-
-1. `payload.panes[]` include backend-aware pane ids.
-2. `payload.sessions[]` are grouped by `(backendId, sessionName)` to avoid cross-backend session-name collisions.
-
-## Validation
-
-Use these for repeatable validation (not date-bound):
-
-```bash
-npm run check:root
-npm run test:root
-npm run ci:all
-```
-
-Targeted protocol/runtime checks:
-
-```bash
-node --import tsx --test src/protocol.conformance.test.ts
-node --import tsx --test src/server/ws-contract-matrix.test.ts
-node --import tsx --test src/server/bridge-server.policy.test.ts
-```
-
-## Project Structure
-
-```text
-src/
- bridge/ replay + delta streaming engine
- server/ ws/http gateway, policies, contract tests
- runtime/ runtime mux + cmux adapter
- tmux/ tmux adapter
- net/ proxy routing and agent factory adapters
-packages/
- cli-proxy/
- proxy-core/
- proxy-agent/
- proxy-fetch/
- proxy-http-client/
- proxy-undici/
-docs/
- protocol, security, operations, roadmap, proxy ecosystem
-apps/
- ios/, android/, web/
-```
-
-## Documentation Map
-
-1. `docs/README.md` - full docs index
-2. `docs/getting-started.md` - setup and runbook
-3. `docs/operations.md` - operations and runtime handling
-4. `docs/roadmap-native.md` - iOS/Android/macos/web rollout
-5. `docs/proxy-ecosystem-roadmap.md` - proxy package expansion + discovery/use strategy
-
-## Project Status
-
-The core TypeScript gateway is implemented, tested, and production-oriented for the tmux/cmux runtime path.
-Active work continues on:
+## Docs
-1. Native client parity and UX hardening.
-2. Multi-runtime and control-lane reliability.
-3. Externalized `@commandrelay` / `@termina` proxy package line, with P1 (`@termina/proxy-undici`, `@termina/cli-proxy`, `@termina/proxy-fetch`) implemented and validated.
+1. `docs/protocol-v1.md` - normative wire contract
+2. `docs/security.md` - controls and threat notes
+3. `docs/operations.md` - deployment and operator runbook
+4. `docs/roadmap-native.md` - web/native parity roadmap
+5. `docs/proxy-ecosystem-roadmap.md` - proxy package track
## License
diff --git a/docs/README.md b/docs/README.md
index 3541e12..a9b23ff 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -17,7 +17,7 @@ This folder contains project documentation for users, contributors, and operator
## Runtime Snapshot
1. Gateway runtime: TypeScript on Node.js `>=22` (`tsx` execution, `tsc --noEmit` checks).
-2. Gateway transport package: `ws`.
+2. SSH-first transport with current WS runtime path: data plane remains WebSocket (`/ws`), and `ssh` mode executes tmux runtime operations on the remote target after startup preflight passes (see `ssh-transport-contract.md` and ADR-001).
3. Outbound proxy package set: `http-proxy-agent`, `https-proxy-agent`, `socks-proxy-agent`, `pac-proxy-agent`.
4. Client ecosystem direction: iOS (Swift) first, Android (Kotlin) second, web fallback last.
@@ -33,6 +33,13 @@ Local MCP note:
5. Planner: read [Native Roadmap](roadmap-native.md) and [Execution TODO](TODO.md).
6. Release owner: read [Proxy Publish Runbook](release/proxy-publish.md) and capture outputs in weekly checkpoints.
+## Quickstart References
+
+1. [getting-started.md](getting-started.md): runtime quickstart and live environment setup.
+2. [operations.md](operations.md): operator runbook and runtime behavior details.
+3. SSH startup config keys: `COMMANDRELAY_TRANSPORT_MODE`, `COMMANDRELAY_SSH_PROFILE`, `COMMANDRELAY_SSH_TARGET`, `COMMANDRELAY_SSH_COMMAND`, `COMMANDRELAY_SSH_PORT`, `COMMANDRELAY_SSH_CONNECT_TIMEOUT_SECONDS`, `COMMANDRELAY_SSH_STRICT_HOST_KEY_CHECKING`.
+4. Tunnel helper runbook: [../scripts/ssh/README.md](../scripts/ssh/README.md).
+
## Current Execution Baselines
1. iOS protocol mock package path: `apps/ios/M0ProtocolMockClient` (`swift test`).
@@ -58,7 +65,11 @@ Local MCP note:
9. [roadmap-native.md](roadmap-native.md)
10. [macos-menu-bar-control-lane-spec.md](macos-menu-bar-control-lane-spec.md)
11. [control-lane-parity-checklist.md](control-lane-parity-checklist.md)
-12. [proxy-ecosystem-roadmap.md](proxy-ecosystem-roadmap.md)
-13. [research-next-opportunities.md](research-next-opportunities.md)
-14. [TODO.md](TODO.md)
-15. [release/proxy-publish.md](release/proxy-publish.md)
+12. [controlled-input-audit.md](controlled-input-audit.md)
+13. [proxy-ecosystem-roadmap.md](proxy-ecosystem-roadmap.md)
+14. [research-next-opportunities.md](research-next-opportunities.md)
+15. [TODO.md](TODO.md)
+16. [release/proxy-publish.md](release/proxy-publish.md)
+17. [ssh-transport-contract.md](ssh-transport-contract.md)
+18. [adr/ADR-001-ssh-first-transport.md](adr/ADR-001-ssh-first-transport.md)
+19. [architecture/host-state-authority-plan.md](architecture/host-state-authority-plan.md)
diff --git a/docs/TODO.md b/docs/TODO.md
index c5a06fa..5e3642e 100644
--- a/docs/TODO.md
+++ b/docs/TODO.md
@@ -1,297 +1,240 @@
-# CommandRelay Execution TODO (Native-First)
+# CommandRelay Execution TODO (SSH-First + Proxy Hardening)
-Last reviewed: 2026-02-26
-Owner scope: iOS first, Android second, web fallback last.
-
-## Gateway Runtime Baseline
-
-- [x] TypeScript gateway runtime on Node.js `>=22` (`tsx` entrypoint and `tsc --noEmit` checks).
-- [x] WebSocket transport baseline via `ws`.
-- [x] Proxy agent package baseline via `http-proxy-agent`, `https-proxy-agent`, `socks-proxy-agent`, and `pac-proxy-agent`.
-
-## Priority Order
-
-1. iOS Swift app (primary delivery target).
-2. Android app (feature-parity follow-up).
-3. Web fallback (minimum viable control surface).
-
-## Current Milestones
-
-## Controlled-Input Status Snapshot
-
-- [x] Gateway controlled-input runtime is implemented and test-covered (`enable_input`, `input`, `disable_input`, kill switch enforcement).
-- [x] iOS controlled-input baseline is implemented (`enable_input`, `input`, `disable_input` wiring + UX safety gate); Mac runtime validation is pending.
-
-## M0 - Gateway and Mobile Contract Baseline (Target: 2026-03-13)
-
-- [x] Freeze mobile event contract (`auth`, `list_sessions`, `attach`, `output`, `input`, `ack`, `error`).
-- [x] Define replay/ordering guarantees (`streamSeq`, reconnect with `lastSeq`).
-- [x] Finalize read-only-by-default and explicit input-enable policy.
-- [x] Add API conformance checks for protocol envelope and event types.
-- [x] Publish v1 contract doc for native clients.
-- [x] Add CI Node 22 gate for root/package typecheck + TAP test artifacts.
-- [ ] Exit criteria met:
-- [ ] iOS can consume mocked gateway events without schema drift for 7 days.
-- [x] Command input path can be disabled globally and per-session.
-
-## M1 - iOS Alpha (Read-Only Streaming) (Target: 2026-04-03)
-
-- [x] Create Swift app shell (auth, session list, pane viewer).
-- [x] Implement WebSocket connection + reconnect with backoff.
-- [x] Implement pane attach, output render, replay resume.
-- [ ] Add accessibility baseline (VoiceOver labels, dynamic type, focus order).
-- [ ] Add telemetry for connect latency, reconnect count, stream lag.
-- [ ] Exit criteria met:
-- [ ] 30-minute stable stream under flaky network simulation.
-- [ ] Crash-free rate >= 99% on TestFlight alpha cohort.
-
-## M2 - iOS Beta (Controlled Input) (Target: 2026-04-24)
-
-- [x] Implement explicit `enable_input` UX with clear risk gate.
-- [x] Implement input send/ack path with timeout/error handling.
-- [x] Add safeguards: per-command length limits, rate limit feedback, kill switch handling (`input_too_large` + `input_rate_limited` payload metadata, 2026-02-26).
-- [ ] Add audit event surfacing for sent commands.
-- [ ] Exit criteria met:
-- [ ] Read-only mode remains default on every reconnect.
-- [ ] Input commands are fully auditable by pane and timestamp.
-
-## M3 - iOS GA (Target: 2026-05-15)
-
-- [ ] Complete reliability pass (background/foreground, idle resume, token refresh).
-- [ ] Complete App Store readiness (privacy manifest, permission copy, support docs).
-- [ ] Produce on-call runbook for gateway + mobile incidents.
-- [ ] Exit criteria met:
-- [ ] 14 days beta with no Sev-1 mobile-to-gateway regression.
-- [ ] Median command round-trip latency <= 250ms on Tailscale path.
-
-## M4 - Android Alpha/Beta (Target: 2026-06-12)
-
-- [ ] Port protocol client and session UX in Kotlin (read-only first).
-- [ ] Add controlled input flow matching iOS safety model.
-- [ ] Validate device/network matrix and background limits.
-- [ ] Exit criteria met:
-- [ ] Functional parity with iOS core flows (`list`, `attach`, `replay`, guarded `input`).
-
-## M5 - Web Fallback (Last) (Target: 2026-07-03)
-
-- [ ] Build minimal responsive web console for emergency access.
-- [ ] Support auth, session list, pane attach, read-only stream.
-- [ ] Add guarded input behind explicit enable flow.
-- [ ] Keep web control lane on the same v1 envelope/event set as native clients (no web-only protocol fork).
-- [ ] Implement lane conflict UX: block send on `input_lane_conflict`, show owner context, require explicit takeover action.
-- [ ] Add takeover path using `override=true`/`takeOwnership=true` with clear operator confirmation.
-- [ ] Add multi-tab tests for single-writer lane ownership, detach/disconnect release, and takeover behavior.
-- [ ] Exit criteria met:
-- [ ] Works on modern mobile browsers as fallback only.
-- [ ] iOS + web lane handoff scenarios pass shared fixture suite without schema drift.
-
-## M6 - macOS Menu Bar + iOS/Web Parity Follow-Through (Target: 2026-07-24)
-
-- [x] Define macOS menu bar scope: quick connect, session pick, read-only attach, explicit input arm/disarm (`docs/macos-menu-bar-control-lane-spec.md`, completed 2026-02-25).
-- [x] Specify menu bar lane-state indicators (`read-only`, `input-enabled`, `lane-conflict`, `kill-switch-blocked`) (`docs/macos-menu-bar-control-lane-spec.md`, completed 2026-02-25).
-- [x] Reuse the same gateway client contract/events used by iOS/web (`hello`, `policy_update`, `ack`, `error`) in spec mapping (`docs/macos-menu-bar-control-lane-spec.md`, completed 2026-02-25).
-- [ ] Build parity matrix covering iOS/web/menu bar for connect/auth/list/attach/replay/enable/disable/input/conflict/takeover (baseline iOS/web matrix: `docs/control-lane-parity-checklist.md`).
-- [ ] Add remaining cross-client fixture cases:
- - [x] iOS writer -> web takeover (`src/server/bridge-server.policy.test.ts`, completed 2026-02-25)
- - [x] web writer -> iOS takeover (`src/server/bridge-server.policy.test.ts`, completed 2026-02-25)
- - menu bar observer -> iOS writer handoff
- - menu bar writer -> web takeover
-- [ ] Exit criteria met:
-- [ ] Menu bar flow can attach read-only and complete guarded input handoff without protocol drift.
-- [ ] iOS/web/menu bar parity checklist is fully green in weekly checkpoint artifact.
-
-## Dependencies
-
-- [x] Stable gateway protocol and auth policy.
-- [ ] Tailscale network path for low-friction private connectivity.
-- [ ] Test environments: tmux session fixtures + replay test data.
-- [ ] Apple/Google developer accounts and release pipelines.
-- [ ] Observability stack (logs, metrics, crash reporting).
-
-## Top Risks and Mitigations
-
-- [ ] Risk: protocol churn blocks native velocity.
-- [ ] Mitigation: lock v1 schema in M0; version all event changes.
-- [ ] Risk: accidental destructive remote commands.
-- [ ] Mitigation: default read-only, explicit enable input, kill switch, audit trail.
-- [ ] Risk: mobile reconnect instability on poor networks.
-- [ ] Mitigation: replay buffer tests, chaos simulation, backoff tuning.
-- [ ] Risk: app store review delays.
-- [ ] Mitigation: submit early TestFlight/Internal tracks and stage approvals.
-
-## Immediate Next Actions (Rolling)
-
-- [x] Create `v1` protocol contract tests in gateway repo.
-- [x] Build iOS spike for WebSocket connect/list/attach/output, then extend with controlled-input baseline.
-- [x] Define iOS screen map and navigation for three core flows.
-- [x] Decide telemetry schema (connect time, replay time, input ack latency).
-- [x] Implement weekly checkpoint workflow artifacts (`scripts/checkpoints/generate-weekly-checkpoint.sh` + template) and document tracking in `docs/roadmap-native.md`.
-- [x] Wire the existing proxy stack into auth/pairing/telemetry outbound clients and add integration tests for `HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY`/`NO_PROXY`.
-- [x] Draft macOS menu bar control-lane spec and state diagram (`docs/macos-menu-bar-control-lane-spec.md`, completed 2026-02-25).
-- [x] Author iOS/web parity checklist for control-lane flows and map each item to an automated/manual test (`docs/control-lane-parity-checklist.md`, completed 2026-02-25).
-- [x] Add two gateway fixture scenarios for lane conflict + explicit takeover (iOS writer -> web takeover, web writer -> iOS takeover) (`src/server/bridge-server.policy.test.ts`, completed 2026-02-25).
-- [x] Document distilled capsule-to-brief wiring (`npm run capsule:build --` -> `npm run capsule:brief --`) in operations/docs/skill guidance (`docs/operations.md`, `docs/README.md`, `skills/termina-orchestrator/SKILL.md`, completed 2026-02-26).
-- [x] Document distilled capsule-to-dispatch wiring (`npm run capsule:build --` -> `npm run capsule:brief --` -> `npm run capsule:dispatch --`) in operations/docs/skill guidance (`docs/operations.md`, `docs/README.md`, `skills/termina-orchestrator/SKILL.md`, completed 2026-02-26).
-
-## Weekly Cross-Platform Checkpoint Runbook
-
-- [x] Workflow script: `scripts/checkpoints/generate-weekly-checkpoint.sh`
-- [x] Template: `scripts/checkpoints/templates/weekly-cross-platform-checkpoint.md`
-- [x] Weekly command:
- `scripts/checkpoints/generate-weekly-checkpoint.sh --date YYYY-MM-DD --facilitator "Owner Name"`
-- [x] Weekly artifact to track in git:
- `scripts/checkpoints/runs/YYYY-MM-DD-weekly-cross-platform-checkpoint.md`
-- [ ] Post-sync tracking rule:
- checkpoint is complete only after sign-off boxes are checked and milestone decisions are mirrored in `docs/roadmap-native.md` + `docs/TODO.md`.
-
-## Mac Validation Acceptance Checklist
-
-- [ ] Node.js runtime is `v22.x` on Mac validation machine.
-- [ ] `npm run check` passes.
-- [ ] `node --import tsx --test src/protocol.conformance.test.ts` passes.
-- [ ] `node --import tsx --test src/server/ws-contract-matrix.test.ts src/server/bridge-server.policy.test.ts src/server/input-policy.test.ts` passes.
-- [ ] `node --import tsx --test src/server/startup-validation.test.ts` passes.
-- [ ] `node --import tsx --test src/control-plane/control-plane-client.test.ts src/net/proxy-agent-factory.test.ts src/net/proxy-router.test.ts` passes.
-- [ ] `cd apps/ios/M0ProtocolMockClient && swift test` passes.
-- [ ] `npm run test:ci:all` passes on Mac.
-- [ ] Live smoke (kill switch off) passes: `COMMANDRELAY_INPUT_KILL_SWITCH=off npm run start` + `npm run bench:input -- --iterations 5`.
-- [ ] Live smoke (kill switch on) blocks input: `COMMANDRELAY_INPUT_KILL_SWITCH=on npm run start` + `npm run bench:input -- --iterations 3` fails with input-disabled behavior.
-- [ ] Nightly evidence captured: TAP artifacts + swift test log + short smoke summary.
-
-## Home Pickup TODO
-
-- [ ] Copy MCP template and set absolute paths: `cp mcp.example.json .mcp.json` then edit paths.
-- [ ] Verify Chitragupta MCP starts with the workaround command from `docs/operations.md`.
-- [ ] Run full gateway test pack: `npm run check && npm test && npm run test:ci:all`.
-- [ ] Run replay-focused suites:
- - `node --import tsx --test src/bridge/bridge-engine.replay.test.ts`
- - `node --import tsx --test src/server/bridge-server.replay.e2e.test.ts`
-- [ ] Run iOS transport tests:
- - `cd apps/ios/M0ProtocolMockClient && swift test --filter M0WebSocketTransportClientTests`
- - `swift test`
-- [ ] Run Android parity module tests (requires Gradle wrapper or local Gradle):
- - `cd apps/android/M0ProtocolMockClient && ./gradlew test` (or `gradle test`)
-- [ ] Run tmux fixture harness smoke:
- - `scripts/tmux-fixtures/create-fixture.sh --session fixture_smoke --panes 2`
- - `scripts/tmux-fixtures/emit-fixture-output.sh --session fixture_smoke --profile replay --cycles 5`
- - `scripts/tmux-fixtures/teardown-fixture.sh --session fixture_smoke`
-- [ ] Run perf smoke benchmarks:
- - `npm run bench:connect -- --iterations 20`
- - `npm run bench:list -- --iterations 20`
- - `npm run bench:input -- --iterations 20`
-- [ ] If all green, open/update PR notes with:
- - replay coverage results
- - iOS/Android local test results
- - perf summary (`p50/p95/p99`)
-
-## Home-Mac Continuation Checklist
-
-### Session Bootstrap (single owner)
-
-- [ ] Confirm Node.js `v22.x` and clean install: `node -v && npm ci`.
-- [ ] Confirm local MCP wiring and Chitragupta launch command from `docs/operations.md`.
-- [ ] Start evidence log for this run (tests, perf, publish dry-run outputs).
-
-### Parallel Track A: tmux Engine Follow-up
-
-- [ ] Run replay/ordering suites:
- - `node --import tsx --test src/bridge/bridge-engine.replay.test.ts`
- - `node --import tsx --test src/server/bridge-server.replay.e2e.test.ts`
-- [ ] Run tmux fixture harness:
- - `scripts/tmux-fixtures/create-fixture.sh --session fixture_smoke --panes 2`
- - `scripts/tmux-fixtures/emit-fixture-output.sh --session fixture_smoke --profile replay --cycles 5`
- - `scripts/tmux-fixtures/teardown-fixture.sh --session fixture_smoke`
-- [ ] Run perf smoke (`connect`, `list`, `input`) with `--iterations 20`; record `p50/p95/p99`.
-- [ ] Mark tmux track complete only when replay + fixture + perf evidence is captured.
-
-### Parallel Track B: iOS Follow-up
-
-- [ ] `cd apps/ios/M0ProtocolMockClient && swift test --filter M0WebSocketTransportClientTests`.
-- [ ] `cd apps/ios/M0ProtocolMockClient && swift test`.
-- [ ] Validate controlled-input safety behavior against gateway kill-switch on/off runs.
-- [ ] Capture iOS evidence summary (pass/fail, flaky tests, retry count).
-
-### Merge Gate (both tracks)
-
-- [ ] Run full aggregate check: `npm run check && npm test && npm run test:ci:all`.
-- [ ] Update `scripts/checkpoints/runs/2026-02-25-weekly-cross-platform-checkpoint.md` with outcomes.
-- [ ] Update proxy release gate status in `docs/release/proxy-publish.md`.
-
-## Proxy Package Release Gates (for internal v0.1 prep)
-
-- [x] Gate 1: version readiness confirmed for each `@commandrelay/proxy-*` package (`@commandrelay/proxy-core@0.1.0`, `@commandrelay/proxy-agent@0.1.0`, `@commandrelay/proxy-http-client@0.1.0`).
-- [ ] Gate 2: root/package `check`, `build`, `test` all green on Mac run.
- - Batch evidence (2026-02-25): TAP green in current environment (`root 14/14`, `proxy-core 1/1`, `proxy-agent 2/2`, `proxy-http-client 1/1`).
-- [ ] Gate 3: publish workflow dry-run green with expected package selector and `dist_tag`.
- - Home Mac action: run `Publish Proxy Packages` with `mode=dry-run`, `package_selector=@commandrelay/proxy-*`, `dist_tag=latest`.
-- [ ] Gate 4: `NPM_TOKEN` + `npm-publish` environment policy verified.
- - Home Mac action: verify `NPM_TOKEN` secret, `npm-publish` reviewers, and default-branch restrictions.
-- [ ] Gate 5: release notes/changelog draft reviewed before any publish-mode trigger.
- - Home Mac action: append dry-run URL + artifact summary + go/no-go note.
-
-## Internal v0.1 Tag Plan (proposal only; do not create tags yet)
-
-- [ ] Step 1: complete tmux + iOS follow-up tracks and evidence capture.
-- [ ] Step 2: run proxy publish dry-run gate review and resolve blockers.
-- [ ] Step 3: freeze internal v0.1 candidate scope and finalize release notes draft.
-- [ ] Step 4: run final go/no-go check (tests, perf, release gates, checkpoint sign-off).
-- [ ] Step 5: if all gates stay green, prepare internal `v0.1` tag request in PR/release notes (no tag creation in this step).
-
-## Proxy Ecosystem Expansion Backlog
-
-Reference roadmap: `docs/proxy-ecosystem-roadmap.md`.
-
-- [x] Harden current package line for external use (`@commandrelay/proxy-core`, `@commandrelay/proxy-agent`, `@commandrelay/proxy-http-client`) with reusable docs/assets/examples.
-- [ ] Publish/validate adapter ecosystem package plan and naming contract (`@termina/proxy-*`).
-- [ ] P1 package wave (active):
- - [x] `@termina/cli-proxy` (`packages/cli-proxy`, diagnostics CLI + JSON/human modes + tests/docs/assets completed on 2026-02-26)
- - [x] `@termina/proxy-undici` (`packages/proxy-undici`, check/build/test + docs/assets/examples complete on 2026-02-26)
- - [x] `@termina/proxy-fetch` (`packages/proxy-fetch`, fetch adapter + JSON/timeout/size guards + tests/docs/assets completed on 2026-02-26)
-- [x] P1 exit criteria: `@termina/cli-proxy` + `@termina/proxy-fetch` both pass check/build/test and include README + NOTES + SVG branding assets.
-- [ ] P2 package wave:
+Last reviewed: 2026-02-27
+Primary strategy: SSH-first transport, tmux-first runtime, remote state owned by host.
+
+## Vision Reset (SSH-First)
+
+- CommandRelay is a host-adjacent remote operations product, not a mobile-first product.
+- SSH is the default control/data transport for production use; WebSocket remains for compatibility and controlled environments.
+- `tmux` on the remote host is the source of truth for live session state.
+- Host runtime owns replay/order state (`streamSeq`, `lastSeq`, lane ownership, audit trail); clients only render and request actions.
+- iOS, Android, web, and macOS menu bar are thin clients over one contract; no client-specific protocol forks.
+- Safety posture remains strict: read-only default, explicit input enable, lane conflict controls, global kill switch, and auditable input history.
+
+## Two-Track Plan (Run in Parallel)
+
+- Track A ships the SSH-first CommandRelay product baseline.
+- Track B hardens and productizes the `proxy-*` ecosystem used by CommandRelay and external consumers.
+- Merge/release gate: no Track A GA candidate without Track B publish/process hardening at release-ready status.
+
+## Track A: SSH-First CommandRelay Product
+
+### A1) Transport
+
+- [ ] Finalize SSH transport contract for connect/auth/list/attach/replay/input/ack/error with explicit reconnect semantics.
+- [ ] Specify host identity + trust model (host key verification mode, fingerprint surfacing, rotation handling).
+- [ ] Lock protocol compatibility matrix for SSH transport and existing WebSocket transport.
+- [ ] Add transport conformance tests covering:
+ - happy path attach + replay resume
+ - reconnect with `lastSeq`
+ - lane conflict + explicit takeover
+ - kill-switch enforcement on active lane
+
+### A2) Runtime (Host-State Ownership)
+
+- [ ] Make host runtime authoritative for session metadata, lane owner, replay offsets, and capability flags.
+- [x] Validate tmux fixture harness for deterministic replay and multi-pane ordering. Status: `done` ([tmux fixture harness runbook](../scripts/tmux-fixtures/README.md), [fixture evidence runner](../scripts/tmux-fixtures/run-fixture-evidence.ts), [2026-02-27 fixture harness evidence run](../scripts/checkpoints/runs/2026-02-27-a2-tmux-fixture-harness-evidence.md)).
+- [x] Add startup validation profile for remote host environments (Node runtime, tmux availability, permissions, env policy). Status: `done` ([startup profile checks](../src/startup/startup-profile.ts), [startup profile tests](../src/startup/startup-profile.test.ts), [remote runtime validator script](../scripts/ssh/validate-remote-runtime.sh), [runtime validator runbook](./operations.md#ssh-runtime-validator-reference), [validation checkpoint command evidence](../scripts/checkpoints/runs/2026-02-27-feat-ssh-exploration-validation-checkpoint.md#command-evidence)).
+- [x] Ensure runtime failure modes are explicit and recoverable (auth reject, transport drop, tmux session loss, stale lane owner). Status: `done` ([runtime failure classifier](../src/server/bridge-runtime-failures.ts), [bridge handler wiring](../src/server/bridge-server.ts), [bridge attach failure propagation](../src/bridge/bridge-engine.ts), [failure-mode e2e tests](../src/server/bridge-server.failure-modes.e2e.test.ts), [classifier unit tests](../src/server/bridge-runtime-failures.test.ts)).
+
+### A3) UX (Thin Clients)
+
+- [ ] Keep one interaction model across iOS/web/macOS menu bar:
+ - read-only attach by default
+ - explicit input arm/disarm
+ - lane conflict message with owner context
+ - explicit takeover confirmation
+- [ ] Complete parity checklist for connect/auth/list/attach/replay/enable/disable/input/conflict/takeover.
+- [ ] Finish accessibility baseline in active clients (labels, focus order, dynamic type, keyboard paths where applicable).
+
+### A4) Safety
+
+- [x] Controlled-input baseline exists (`enable_input`, `input`, `disable_input`, kill switch, size/rate limit payload metadata).
+- [x] Add host-side input audit log record (actor, pane, command hash/preview policy, timestamp, result) ([runtime audit writes](../src/server/bridge-server.ts), [audit timestamp envelope](../src/server/audit-log.ts), [policy audit assertions](../src/server/bridge-server.policy.test.ts), [e2e audit flow assertions](../src/server/bridge-server.e2e.test.ts)).
+- [x] Add policy tests for default read-only on reconnect, lane lease expiry, and takeover audit event ([policy tests](../src/server/bridge-server.policy.test.ts), [arbiter lease tests](../src/server/bridge-server-utils.test.ts)).
+- [x] Add operator safety runbook for kill-switch and lane lockout incidents ([runbook](./operations.md#controlled-input-safety-incident-runbook), [checkpoint evidence](../scripts/checkpoints/runs/2026-02-27-feat-ssh-exploration-validation-checkpoint.md#operator-safety-runbook-evidence)).
+
+### A5) Observability
+
+- [x] Define metrics contract and dashboards ([metrics contract v1](./observability-evidence-contract.md#metrics-contract-v1), [dashboard baseline v1](./observability-evidence-contract.md#dashboard-baseline-v1), [operations weekly flow](./operations.md#weekly-observability-baseline-and-evidence-pack)):
+ - connect latency
+ - replay lag
+ - reconnect count
+ - input ack latency
+ - lane conflict frequency
+ - kill-switch blocks
+- [x] Add structured logs for lifecycle events (connect, attach, replay resume, input enabled/disabled, takeover, policy reject) ([connect audit emit](../src/server/bridge-server.ts), [lifecycle log assertions](../src/server/bridge-server.lifecycle-logging.test.ts)).
+- [x] Replay resume/fallback behavior is implemented and currently test-covered ([bridge replay unit](../src/bridge/bridge-engine.replay.test.ts), [bridge replay e2e](../src/server/bridge-server.replay.e2e.test.ts)).
+- [x] Dedicated replay audit actions `replay_resume` and `replay_gap_snapshot_fallback` are emitted from attach flow and asserted in replay e2e coverage ([audit contract](./controlled-input-audit.md), [attach audit writes](../src/server/bridge-server.ts), [replay audit assertions](../src/server/bridge-server.replay.e2e.test.ts)).
+- [x] Set minimum evidence pack for weekly checkpoint artifacts ([minimum artifact set](./observability-evidence-contract.md#minimum-weekly-evidence-pack-v1), [command-to-evidence mapping](./observability-evidence-contract.md#command-to-evidence-mapping-v1), [operations weekly flow](./operations.md#weekly-observability-baseline-and-evidence-pack)).
+
+### A6) Release Criteria (Track A)
+
+- [ ] 7-day stability window with no Sev-1 SSH transport regressions in checkpoint evidence.
+- [ ] 30-minute flaky-network stream test passes with replay correctness.
+- [ ] Controlled input remains opt-in on every reconnect path.
+- [ ] Full parity checklist is green across active clients.
+- [ ] On-call incident/runbook document is complete and reviewed.
+
+## Track B: `proxy-*` Ecosystem Hardening and Productization
+
+### B1) Current Package Line Hardening
+
+- [x] Baseline line exists and is in active use:
+ - `@commandrelay/proxy-core`
+ - `@commandrelay/proxy-agent`
+ - `@commandrelay/proxy-http-client`
+- [ ] Complete API stability review and public surface lock for v0.1.
+- [x] Add negative tests for malformed proxy URLs, auth variants, NO_PROXY edge cases, PAC failures, and fallback behavior ([proxy factory negative + PAC suite](../src/net/proxy-agent-factory.test.ts), [proxy router malformed + NO_PROXY suite](../src/net/proxy-router.test.ts), [expected-vs-actual malformed input report](../scripts/checkpoints/runs/proxy-negative-input-report-2026-02-27.md)).
+- [x] Add interoperability matrix validation (Node fetch/undici/http(s), env var permutations, proxy chaining expectations) ([core env + routing matrix](../src/net/proxy-interoperability-matrix.test.ts), [fetch adapter matrix](../packages/proxy-fetch/test/proxy-fetch-client-env-matrix.test.ts), [undici dispatcher matrix + unsupported chaining expectations](../packages/proxy-undici/test/proxy-undici-dispatcher-factory.test.ts), [http(s) request resolver interoperability](../packages/proxy-http-client/test/request-json-proxy-agent-interoperability.test.ts)).
+
+### B2) Productization Readiness
+
+- [x] Complete docs pack per package: README usage matrix, NOTES, migration/compat notes, troubleshooting. Status: `done` ([coverage matrix](./proxy/package-docs-matrix.md)); evidence confirms all six packages now satisfy this set.
+- [x] Add runnable examples with expected output snapshots. Status: `done` ([coverage matrix](./proxy/package-docs-matrix.md)); evidence confirms all six packages now include runnable examples plus expected snapshot artifacts.
+- [x] Ensure CI gates are explicit and reproducible (`check`, `build`, `test`) at root and per package ([root scripts](../package.json), [cli-proxy scripts](../packages/cli-proxy/package.json), [proxy-core scripts](../packages/proxy-core/package.json), [proxy-agent scripts](../packages/proxy-agent/package.json), [proxy-fetch scripts](../packages/proxy-fetch/package.json), [proxy-http-client scripts](../packages/proxy-http-client/package.json), [proxy-undici scripts](../packages/proxy-undici/package.json)).
+- [ ] Confirm publish workflow dry-run path with selector and dist-tag policy. Status: `partial` ([workflow dispatch + selector/dist-tag logic](../.github/workflows/publish-proxy-packages.yml), [release runbook](./release/proxy-publish.md), [2026-02-27 local dry-run checkpoint](../scripts/checkpoints/runs/2026-02-27-proxy-publish-dry-run.md)); remaining gaps: rerun dry-run in an unblocked environment and archive successful `npm pack/publish --dry-run` artifacts.
+- [ ] Validate npm publish governance (`NPM_TOKEN`, `npm-publish` environment reviewers, branch protections). Status: `partial` ([workflow token/env guards](../.github/workflows/publish-proxy-packages.yml), [governance checklist](./release/proxy-publish.md#required-github-configuration)); remaining gaps: repository-level verification of secret presence, environment reviewers, and branch protection settings is not evidenced in-repo yet.
+
+### B3) Parallel Ecosystem Wave
+
+- [x] P1 completed:
+ - `@termina/cli-proxy`
+ - `@termina/proxy-undici`
+ - `@termina/proxy-fetch`
+- [ ] P2 hardening wave (parallelizable):
- `@termina/proxy-axios`
- `@termina/proxy-got`
- `@termina/proxy-runtime`
-- [ ] P3 exploration:
- - `@termina/proxy-ssh` (`ssh-proxy`) feasibility and threat model.
-- [ ] External compatibility checks against ecosystem dependencies/counterparts:
- - `agent-base`
- - `data-uri-to-buffer`
- - `degenerator`
- - `get-uri`
- - `http-proxy-agent`
- - `https-proxy-agent`
- - `pac-proxy-agent`
- - `pac-resolver`
- - `proxy-agent`
- - `proxy`
- - `socks-proxy-agent`
-
-## Research-Backed Next Wave (Home Pickup)
-
-Reference notes: `docs/research-next-opportunities.md`.
-
-- [ ] Cross-platform command safety contract:
- - shared `input` timeout/retry semantics for iOS, Android, macOS, and web fallback
- - shared telemetry keys for `enable_input` -> `input` -> `ack/error`
- - deterministic kill-switch and lane-conflict behavior across clients
-- [ ] Multi-session UX + handoff model:
- - session switch rules while preserving read-only default
- - explicit takeover UX with owner visibility and confirmation
- - per-pane activity/audit indicators in native clients
-- [ ] Reliability + SLO matrix:
- - reconnect success target, command RTT target, replay catch-up target
- - failover behavior when current writer disconnects mid-command
- - weekly checkpoint artifact includes SLO trend deltas
-- [ ] Proxy family hardening gates (pre external publish):
- - mandatory benchmark budgets (latency, throughput, memory/socket growth)
- - dependency/license/SBOM/vulnerability gate in release flow
- - interoperability matrix for `fetch`, `undici`, `axios`, `got`, and CLI adapters
-- [ ] Advanced transport exploration (feature-flagged):
- - evaluate QUIC/WebTransport lane for degraded-network resilience
- - compare against current WebSocket lane with controlled benchmark harness
- - adopt only if reliability and operability improve without security regression
-- [ ] Remote-control trust model upgrades:
- - short-lived pairing via QR + signed challenge response
- - step-up confirmation for risky command classes
- - immutable command audit stream export for incident review
+- [ ] P3 exploration gate:
+ - `@termina/proxy-ssh` feasibility + threat model (explicit go/no-go decision doc)
+
+### B4) Release Criteria (Track B)
+
+- [ ] Gate 1: version and changelog readiness confirmed for all release candidates.
+- [ ] Gate 2: `check/build/test` green on designated Mac validation environment.
+- [ ] Gate 3: publish dry-run green with expected selector + dist-tag.
+- [ ] Gate 4: release notes and rollback notes approved before publish-mode is allowed.
+- [ ] Gate 5: support/troubleshooting docs linked from package READMEs.
+
+## Next 2-4 Week Milestones (Execution-Ready)
+
+### Milestone W1 (2026-03-02 to 2026-03-08)
+
+- Track A goals:
+ - freeze SSH transport contract + compatibility matrix
+ - complete host-state authority spec for lane/replay ownership
+ - add first-pass SSH conformance tests
+- Track B goals:
+ - finish proxy API surface audit for v0.1 candidates
+ - close negative-test gaps for proxy env parsing/fallback
+- Acceptance criteria:
+ - [x] SSH contract/spec document merged and referenced by tests ([contract](./ssh-transport-contract.md), [matrix test](../src/server/ws-contract-matrix.test.ts)).
+ - [x] At least one automated suite exercises SSH reconnect with `lastSeq` replay ([replay e2e](../src/server/bridge-server.replay.e2e.test.ts)).
+ - [x] Proxy test report includes malformed URL + NO_PROXY + PAC failure cases with expected results ([proxy negative input report](../scripts/checkpoints/runs/proxy-negative-input-report-2026-02-27.md), [proxy factory tests](../src/net/proxy-agent-factory.test.ts), [proxy router tests](../src/net/proxy-router.test.ts)).
+
+### Milestone W2 (2026-03-09 to 2026-03-15)
+
+- Track A goals:
+ - implement host audit log events and lane/takeover policy assertions
+ - complete tmux fixture replay ordering validation
+ - advance parity checklist coverage
+- Track B goals:
+ - complete docs/examples pack for `@commandrelay/proxy-*`
+ - execute publish workflow dry-run and archive artifacts
+- Acceptance criteria:
+ - [x] Audit log records are emitted for enable/disable/input/takeover flows, and `input` records include command metadata policy fields (`commandHash`, `previewPolicy`) ([runtime audit writes](../src/server/bridge-server.ts), [e2e audit flow assertions](../src/server/bridge-server.e2e.test.ts), [policy audit assertions](../src/server/bridge-server.policy.test.ts)).
+ - [x] Replay ordering suite passes under fixture harness without manual intervention ([tmux fixture harness runbook](../scripts/tmux-fixtures/README.md), [fixture harness evidence run](../scripts/checkpoints/runs/2026-02-27-a2-tmux-fixture-harness-evidence.md), [CR-P1-002 weekly evidence lane checkpoint](../scripts/checkpoints/runs/2026-02-27-cr-p1-002-weekly-evidence-lane.md)).
+ - [ ] Dry-run artifacts contain selected package set, dist-tag, and no publish-policy blockers. Status: `partial` ([2026-02-27 proxy publish local dry-run checkpoint](../scripts/checkpoints/runs/2026-02-27-proxy-publish-dry-run.md), [CR-P1-002 weekly evidence lane checkpoint](../scripts/checkpoints/runs/2026-02-27-cr-p1-002-weekly-evidence-lane.md)); remaining gaps: selected package set + dist-tag evidence exists, but `npm pack/publish --dry-run` remains blocked by local npm cache `EACCES`.
+
+### Milestone W3 (2026-03-16 to 2026-03-22)
+
+- Track A goals:
+ - finalize observability metrics + dashboard baseline
+ - run 30-minute flaky-network soak for stream/replay behavior
+ - close critical UX parity gaps (conflict + takeover messaging)
+- Track B goals:
+ - complete P2 package scaffolds and core adapter conformance tests
+ - resolve docs/troubleshooting gaps found in dry-run review
+- Acceptance criteria:
+ - [ ] Weekly checkpoint includes metrics export and soak summary.
+ - [ ] No Sev-1/Sev-2 unresolved bugs in lane safety path.
+ - [ ] P2 packages have passing base check/build/test and minimal docs skeleton.
+
+### Milestone W4 (2026-03-23 to 2026-03-29)
+
+- Track A goals:
+ - run release-candidate gate review for SSH-first baseline
+ - publish incident/runbook docs for transport and safety operations
+- Track B goals:
+ - run final pre-release gate review for proxy line
+ - prepare release notes + rollback notes for v0.1 internal release decision
+- Acceptance criteria:
+ - [ ] Track A release criteria checklist is fully green or has explicit blocker list with owners.
+ - [ ] Track B gates 1-5 reviewed with evidence links and go/no-go status.
+ - [ ] Combined checkpoint artifact documents cross-track dependencies and release decision.
+
+## Prioritized Immediate Actions (Do Next)
+
+- Execution board: [Execution-Owned Tickets](./execution-owned-tickets.md)
+
+### P0 (Today -> next 48h)
+
+- [x] Convert this TODO into owned tickets with single owners and explicit file scope ([execution board](./execution-owned-tickets.md)).
+- [x] Land SSH transport contract doc + test plan references ([contract](./ssh-transport-contract.md), [protocol references](./protocol-v1.md#11-contract-compatibility-test-plan-references), [contract tests](../src/server/ws-contract-matrix.test.ts)).
+- [x] Start host-state authority implementation plan (lane owner + replay offsets + audit schema) ([plan](./architecture/host-state-authority-plan.md), [policy tests](../src/server/bridge-server.policy.test.ts)).
+- [x] Execute proxy negative-test expansion for malformed env/config inputs ([proxy factory tests](../src/net/proxy-agent-factory.test.ts), [proxy router tests](../src/net/proxy-router.test.ts), [expected-vs-actual report](../scripts/checkpoints/runs/proxy-negative-input-report-2026-02-27.md)).
+
+### P1 (This week)
+
+- Latest checkpoint evidence: [2026-02-27-cr-p1-002-weekly-evidence-lane.md](../scripts/checkpoints/runs/2026-02-27-cr-p1-002-weekly-evidence-lane.md), [2026-02-27-feat-ssh-exploration-validation-checkpoint.md](../scripts/checkpoints/runs/2026-02-27-feat-ssh-exploration-validation-checkpoint.md)
+
+- [x] Run and archive core validation suites:
+ - `npm run check`
+ - `npm test`
+ - `npm run test:ci:all`
+ - `node --import tsx --test src/server/ws-contract-matrix.test.ts src/server/bridge-server.policy.test.ts src/server/input-policy.test.ts`
+ - `node --import tsx --test src/control-plane/control-plane-client.test.ts src/net/proxy-agent-factory.test.ts src/net/proxy-router.test.ts`
+- [x] Validate replay resume/fallback behavior and current audit coverage for this branch (`node --import tsx --test src/bridge/bridge-engine.replay.test.ts src/server/bridge-server.replay.e2e.test.ts src/server/bridge-server.audit.test.ts`).
+- [x] Update weekly checkpoint artifact and mirror milestone decisions into roadmap docs. Status: `done` for the docs evidence lane on 2026-02-27; tracked milestone outcomes remain `partial` where execution blockers persist ([CR-P1-002 weekly evidence lane checkpoint](../scripts/checkpoints/runs/2026-02-27-cr-p1-002-weekly-evidence-lane.md), [proxy roadmap decision mirror](./proxy-ecosystem-roadmap.md#milestone-decision-mirror-2026-02-27-cr-p1-002)).
+- [x] Run publish dry-run for `@commandrelay/proxy-*` and capture artifact links ([proxy publish checkpoint](../scripts/checkpoints/runs/2026-02-27-proxy-publish-dry-run.md); local dry-run blocked by npm cache `EACCES`, blocker documented in [release runbook](./release/proxy-publish.md)).
+
+### P2 (Next 2 weeks)
+
+- [ ] Complete remaining parity matrix items including menu bar handoff cases.
+- [ ] Complete observability dashboard baseline and alert thresholds.
+- [ ] Finalize release-notes template for combined SSH-first + proxy hardening increment.
+
+## Retained Context (Still Relevant)
+
+### Completed Baselines
+
+- [x] TypeScript gateway runtime on Node.js `>=22` (`tsx` entrypoint and `tsc --noEmit` checks).
+- [x] WebSocket baseline via `ws` remains available as compatibility transport.
+- [x] Proxy agent baseline via `http-proxy-agent`, `https-proxy-agent`, `socks-proxy-agent`, `pac-proxy-agent`.
+- [x] Controlled-input runtime baseline is implemented and test-covered.
+- [x] iOS controlled-input baseline exists with safety gate wiring.
+- [x] Weekly checkpoint workflow script/template exists.
+- [x] Distilled capsule build/brief/dispatch wiring is documented.
+
+### Open Dependencies and Risks
+
+- [ ] Stable private network path for low-friction host connectivity (Tailscale or equivalent).
+- [ ] Test environments: tmux fixtures + replay data kept fresh.
+- [ ] Observability stack completion (logs, metrics, crash reporting).
+- [ ] Risk: transport/protocol churn slows clients.
+- [ ] Mitigation: versioned contract + conformance suite as release gate.
+- [ ] Risk: accidental destructive commands.
+- [ ] Mitigation: read-only default, explicit input enable, kill switch, audit trail.
+- [ ] Risk: reconnect instability under poor networks.
+- [ ] Mitigation: replay chaos tests + soak checkpoints + backoff tuning.
+
+## Key References
+
+- `docs/macos-menu-bar-control-lane-spec.md`
+- `docs/control-lane-parity-checklist.md`
+- `docs/proxy-ecosystem-roadmap.md`
+- `docs/release/proxy-publish.md`
+- `scripts/checkpoints/generate-weekly-checkpoint.sh`
+- `scripts/checkpoints/templates/weekly-cross-platform-checkpoint.md`
diff --git a/docs/adr/ADR-001-ssh-first-transport.md b/docs/adr/ADR-001-ssh-first-transport.md
new file mode 100644
index 0000000..3e2026d
--- /dev/null
+++ b/docs/adr/ADR-001-ssh-first-transport.md
@@ -0,0 +1,44 @@
+# ADR-001: SSH-First Transport
+
+## Status
+Accepted
+
+## Date
+2026-02-27
+
+## Context
+- CommandRelay needs resilient remote control across disconnects and client restarts.
+- Session durability depends on `tmux` reattach/replay semantics.
+- A WebSocket-first default increases exposed network surface and deployment variance.
+- SSH is already standard in operator environments with mature auth and host trust controls.
+
+## Decision
+- Set SSH as the default transport for CommandRelay.
+- Keep `tmux` as the persistence layer, independent of transport lifecycle.
+- Keep WebSocket available as explicit opt-in fallback for constrained environments.
+
+## Rationale
+- SSH reuses proven security controls (keys, host verification, access policy).
+- Default exposure is narrower than opening a WebSocket endpoint by default.
+- SSH attach/detach behavior aligns with `tmux` session continuity goals.
+- Operators can use existing tooling and runbooks instead of introducing new transport infrastructure.
+
+## Tradeoffs
+- SSH provisioning and key management are required.
+- Browser-only clients need a bridge or gateway for SSH workflows.
+- Some environments may see slower reconnect UX than long-lived WebSocket connections.
+
+## Consequences
+- Product UX must treat SSH auth and host trust failures as first-class paths.
+- Test coverage must include host-key checks, auth failures, reconnect, and replay.
+- Docs and operational playbooks must position WebSocket as exception flow, not baseline.
+
+## Alternatives considered
+- WebSocket-first default: rejected due to larger exposed surface and proxy/TLS drift risk.
+- Custom transport protocol: rejected due to long-term maintenance burden.
+- Dual equal default (SSH + WebSocket): rejected to avoid ambiguous guidance and split testing focus.
+
+## Rollout/rollback triggers
+- Roll out once SSH path is feature-complete for attach, replay, input guardrails, and failure handling.
+- Keep WebSocket fallback during migration for controlled cases.
+- Trigger rollback review if SSH path shows sustained reliability or security regressions that cannot be mitigated operationally.
diff --git a/docs/architecture/host-state-authority-plan.md b/docs/architecture/host-state-authority-plan.md
new file mode 100644
index 0000000..2b8d6ec
--- /dev/null
+++ b/docs/architecture/host-state-authority-plan.md
@@ -0,0 +1,172 @@
+# Host-State Authority Implementation Plan
+
+Last updated: 2026-02-27
+Status: In progress (replay behavior and replay attach-audit actions landed)
+Owner lane: host runtime (`src/server/*`, `src/bridge/*`)
+
+## Goal
+
+Make the host runtime the single authority for:
+1. Pane write-lane ownership.
+2. Replay offsets (`streamSeq`, `lastSeq`) and replay ordering.
+3. Auditable state transitions and recovery behavior.
+
+Clients remain thin: they request actions and render host decisions.
+
+## Authority Boundaries
+
+1. Host-owned state:
+ - lane owner per `paneId`
+ - pane replay state (`streamSeq`, bounded history window)
+ - attach/replay decisions
+ - authoritative audit trail
+2. Client-owned state:
+ - last rendered cursor (`lastSeq`) used only as a resume hint
+ - local UX state (`read_only`, `conflict`, `reconnecting`)
+
+## Data Model and Module Ownership
+
+## Lane Owner State (`src/server/bridge-server-utils.ts`)
+
+`PaneInputOwnershipArbiter` becomes metadata-aware:
+
+```ts
+type LaneOwnerRecord = {
+ paneId: string;
+ ownerClientId: string;
+ acquiredAtMs: number;
+ lastInputAtMs: number;
+ leaseExpiresAtMs: number;
+ takeoverCount: number;
+};
+```
+
+Rules:
+1. First allowed `input` claims lane.
+2. Owner input refreshes `lastInputAtMs` and `leaseExpiresAtMs`.
+3. Non-owner input gets `input_lane_conflict` unless explicit override is requested and allowed.
+4. `detach`, `disconnect`, and socket `close` release lane if owned by that client.
+5. Expired lease is auto-released by host before next claim attempt.
+
+Config knobs (add in `src/config.ts`):
+1. `COMMANDRELAY_INPUT_LANE_LEASE_MS` (default: `120000`).
+2. `COMMANDRELAY_INPUT_LANE_SWEEP_MS` (default: `5000`).
+
+## Replay Offset State (`src/bridge/bridge-engine.ts`)
+
+Per pane watcher tracks:
+1. `streamSeq` (host monotonic sequence).
+2. `history` (bounded, sorted by `streamSeq` on replay path).
+3. `historyStartSeq`/`historyEndSeq` derived from stored events.
+
+Attach replay algorithm:
+1. Parse `lastSeq` as optional integer cursor.
+2. Replay events where `streamSeq > lastSeq`.
+3. If replay set is empty and watcher exists, send snapshot at current `streamSeq`.
+4. If pane watcher is new, capture snapshot and start at sequence `1`.
+
+Operational guarantees:
+1. `streamSeq` is monotonic per pane watcher.
+2. Replay never emits duplicates for a single attach operation.
+3. If replay cannot be served from host history, host falls back to snapshot delivery and emits `replay_gap_snapshot_fallback` from attach flow.
+
+## Audit Schema (`src/server/audit-log.ts`)
+
+Keep JSONL storage, add normalized schema fields under `details` for compatibility:
+
+```json
+{
+ "ts": 1772179200000,
+ "action": "input_takeover",
+ "clientId": "client-b",
+ "details": {
+ "schemaVersion": 1,
+ "paneId": "%1",
+ "result": "allowed",
+ "reason": "override",
+ "ownerClientIdBefore": "client-a",
+ "ownerClientIdAfter": "client-b",
+ "streamSeq": 184,
+ "lastSeq": 176,
+ "leaseExpiresAtMs": 1772179320000
+ }
+}
+```
+
+Required actions:
+1. `attach`, `detach`, `disconnect`
+2. `enable_input`, `disable_input`
+3. `input` (allowed/denied)
+4. `input_takeover`
+5. `lane_owner_released` (detach/disconnect/lease_expired)
+6. `replay_resume` (with `lastSeq`, replayed count)
+7. `replay_gap_snapshot_fallback` (requested seq outside retained window)
+
+## Implementation Snapshot (2026-02-27)
+
+| Scope | Status | Evidence |
+| --- | --- | --- |
+| Replay resume semantics (`streamSeq > lastSeq`) | Implemented + tested | [`src/bridge/bridge-engine.ts`](../../src/bridge/bridge-engine.ts), [`src/bridge/bridge-engine.replay.test.ts`](../../src/bridge/bridge-engine.replay.test.ts), [`src/server/bridge-server.replay.e2e.test.ts`](../../src/server/bridge-server.replay.e2e.test.ts) |
+| Snapshot fallback on reconnect cursor mismatch | Implemented + tested | [`src/bridge/bridge-engine.ts`](../../src/bridge/bridge-engine.ts), [`src/server/bridge-server.replay.e2e.test.ts`](../../src/server/bridge-server.replay.e2e.test.ts) |
+| `replay_resume` audit action emission | Implemented + tested | attach path emits `replay_resume` when replay resumes from `lastSeq` ([`src/server/bridge-server.ts`](../../src/server/bridge-server.ts), [`src/server/bridge-server.replay.e2e.test.ts`](../../src/server/bridge-server.replay.e2e.test.ts)) |
+| `replay_gap_snapshot_fallback` audit action emission | Implemented + tested | attach path emits `replay_gap_snapshot_fallback` on ahead-of-stream fallback ([`src/server/bridge-server.ts`](../../src/server/bridge-server.ts), [`src/server/bridge-server.replay.e2e.test.ts`](../../src/server/bridge-server.replay.e2e.test.ts)) |
+
+## Failure and Recovery Flows
+
+| Failure | Detection | Host action | Client-visible result | Recovery |
+| --- | --- | --- | --- | --- |
+| Auth reject | invalid token | no state mutation | `auth_error` | re-authenticate |
+| Transport drop | socket close | release lane + detach panes + clear limiter state | disconnected/reconnecting UX | reconnect, `attach(lastSeq)` |
+| Stale lane owner | lease expired | auto-release before claim | previous owner loses lane silently | next writer claims or explicit takeover |
+| Replay window exceeded | `lastSeq < historyStartSeq` | snapshot fallback (attach flow also emits replay-gap fallback audit when cursor is ahead of stream) | output snapshot continuity reset | client resets local buffer baseline |
+| tmux poll failure | `capturePane` throws | emit `pane_poll_failed` | error event + degraded state | retry attach/reconnect with backoff |
+| Audit file append failure | logger write exception | warn + continue runtime path | none (internal) | operator fixes filesystem and monitors warning rate |
+
+## Rollout Phases
+
+1. Phase 0: Guardrails and flags.
+ - Add lease config parsing and default values.
+ - Add no-op telemetry counters for replay-gap and lease-expiry events.
+ - Exit: runtime boots unchanged with new flags disabled/enabled by defaults.
+2. Phase 1: Lane ownership lease authority.
+ - Extend `PaneInputOwnershipArbiter` metadata and expiry checks.
+ - Emit `lane_owner_released` audit records.
+ - Exit: ownership conflict/takeover behavior remains protocol-compatible.
+3. Phase 2: Replay offset authority hardening.
+ - Replay-gap detection and `replay_resume`/`replay_gap_snapshot_fallback` attach-audit events are landed.
+ - Preserve current `attach` + `output` wire contract.
+ - Exit: reconnect behavior unchanged for clients, with new audit observability.
+4. Phase 3: Failure/recovery enforcement.
+ - Add lease sweeper timer and deterministic close-path cleanup assertions.
+ - Validate degraded behavior for tmux poll failures and reconnect loops.
+ - Exit: no leaked lane owners after disconnect/restart simulations.
+5. Phase 4: Rollout and gate.
+ - Enable in staging, run flaky-network soak, then promote to production.
+ - Exit: all test gates green and audit schema consumed by ops tooling.
+
+## Test Plan (Release Gate)
+
+Unit:
+1. `src/server/bridge-server-utils.test.ts`:
+ - claim/refresh/release/lease-expire behaviors
+ - override + takeover transitions
+2. `src/bridge/bridge-engine.replay.test.ts`:
+ - ordered replay `streamSeq > lastSeq`
+ - replay-gap fallback when `lastSeq` predates retained history
+
+Integration:
+1. `src/server/bridge-server.policy.test.ts`:
+ - reconnect remains read-only until explicit enable
+ - stale owner expires and new owner can write
+ - takeover emits both `input` and `input_takeover` audit records
+2. `src/server/bridge-server.replay.e2e.test.ts`:
+ - disconnect/reconnect with `lastSeq`
+ - no duplicate replay on repeated reconnect
+
+Operational/soak:
+1. 30-minute flaky-network run with repeated reconnect and lane handoff.
+2. Assert:
+ - zero out-of-order `streamSeq` per pane
+ - zero duplicate replay events per reconnect
+ - no orphaned lane owners after disconnect churn
+ - replay-gap events remain below agreed SLO threshold
diff --git a/docs/brand/commandrelay-logo.svg b/docs/brand/commandrelay-logo.svg
index b27ca46..f8595e7 100644
--- a/docs/brand/commandrelay-logo.svg
+++ b/docs/brand/commandrelay-logo.svg
@@ -1,5 +1,5 @@