# Engram Scripts & Optimization Tools

This directory contains deployment automation, onboarding wizards, and memory optimization tools for Engram on Jetson Orin Nano.

## Quick Reference

| Script | Purpose | Runtime | Who Runs It |
|--------|---------|---------|-------------|
| `interview.py` | Consumer onboarding wizard (discovers Jetson, collects credentials, sets up headless) | ~10 min | User (on Hub laptop) |
| `optimize-jetson-memory.sh` | Disables GNOME + unnecessary services, creates ramdisk, saves ~1.2GB RAM | ~5 min | User (on Jetson, after fresh OS install) |
| `discover_nodes.py` | Mesh discovery script (finds Jetson nodes in Tailscale network) | <1 sec | Internal use |
| `mesh_handshake.py` | Authenticates Jetson to mesh network | <5 sec | setup.sh (on Hub) |
| `deploy_to_node.sh` | Transfers Engram code to Jetson via SSH | ~3 min | setup.sh (on Hub) |

---

## ⚡ Memory Optimization (Critical for NemoClaw)

**Start here if you have a fresh Jetson Orin Nano:**

```bash
# After Jetson OS installs (first boot from fresh image):
cd ~/engram
sudo bash scripts/optimize-jetson-memory.sh
sudo reboot

# After reboot:
free -h
# Expected: 4-5GB available (vs 2-3GB before optimization)
```

**What it does:**
- Disables GNOME desktop (saves ~1.0-1.2GB)
- Disables unnecessary services: cups, bluetooth, avahi-daemon, ModemManager (saves ~0.3GB)
- Creates 1GB ramdisk for crash protection
- Adds ramdisk to /etc/fstab (persistent across reboots)
- Verifies swap configuration (recommends 32GB if not present)

**Why this matters:**
- NemoClaw needs 2.4GB for sandbox + agents
- GNOME desktop alone consumes 900MB-1.2GB
- Without optimization: ~2-3GB free (risky)
- With optimization: ~4-5GB free (safe, headroom for 3-5 agents)

**See:** `optimize-jetson-memory.sh` for full details.

---

# Engram Consumer Onboarding Wizard - Master Guide

This is the **Engram Consumer Onboarding Wizard**—a guided setup flow that takes you from plugging in a Jetson Orin Nano via USB-C to a fully operational, headless AI node in ~10 minutes.

The wizard is **not** a fleet manager. It's designed for a single user with a single Jetson to get up and running with minimal friction.

---

## 🚀 Quick Start (3 Steps)

1. **Connect your Jetson via USB-C** to your laptop
2. **Run the wizard:**
   ```bash
   cd ~/engram
   python3 scripts/interview.py
   ```
3. **Answer the prompts** (type `help` if stuck on any step)

The wizard will:
- ✅ Discover your Jetson (USB-C bridge scan)
- ✅ Check internet connectivity (pre-flight)
- ✅ Collect your Master Key (email)
- ✅ Validate your Nvidia, Tailscale, and Matrix credentials
- ✅ Support enterprise proxies/VPN if needed
- ✅ Optimize the system for headless operation (~1GB RAM recovered)
- ✅ Boot it into high-performance mode

**Total time:** ~10 minutes (mostly waiting for API validation)

---

## 📖 Philosophy: "One Device, Maximum Performance"

### Why This Approach?

Traditional fleet management tools assume you're managing many devices. The Engram Consumer Wizard assumes you're one person with one edge device who just wants it to work.

**Design principles:**

1. **Single Device Focus** — No fleet manifest, no node aliases, no "which device?" prompts. Just one device, fully optimized.

2. **Master Key Model** — One email opens all doors. Your email is your identity across:
   - **Nvidia** (AI models & inference)
   - **Tailscale** (secure mesh network)
   - **Matrix** (team chat & alerts)

3. **Headless by Default** — No GUI eating 1GB of RAM. That RAM is now available for:
   - Larger batch inferences
   - Longer context windows
   - More concurrent model loads
   - Faster inference overall

4. **Progressive Disclosure** — The wizard doesn't explain systemctl, docker, or Nvidia NIM architecture. It just:
   - Tells you what to do
   - Provides URLs
   - Validates your input
   - Moves forward

5. **Enterprise-Ready** — Proxy support, OS-specific VPN guidance, and persistent credential storage for corporate environments.

### Why Headless? (The RAM Story)

A Jetson Orin Nano has 8GB of RAM. That's your hard constraint. A full Ubuntu desktop running GNOME + GDM3 consumes:

| Component | RAM | Purpose |
|-----------|-----|---------|
| Display Server (X11/Wayland) | 200–300 MB | Renders graphics |
| GNOME Shell | 400–500 MB | Desktop environment |
| System services | 100–200 MB | DBus, Systemd, etc. |
| **Total** | **~900 MB–1.2 GB** | **13–15% of total RAM** |

**When you disable the GUI:**
- ✅ Free 1GB of RAM immediately
- ✅ That RAM is now available for your AI models
- ✅ Larger models run faster
- ✅ Batch processing is more efficient
- ✅ You can run more concurrent inferences

**When would you need a GUI?** Rarely. SSH over Tailscale is faster and more convenient.

### Why Master Key (Email)?

Instead of managing separate credentials for Nvidia, Tailscale, and Matrix, you use one email:

- **One identity** — Single sign-on across all services
- **Easier to remember** — Your email is already your identity everywhere
- **Portable** — If you move to another device, same email = instant access
- **Secure** — 2FA on your email secures all downstream services

---

## 👶 Onboarding for New Users: Step-by-Step

### Prerequisites

You need:
- **One Jetson Orin Nano** (8GB RAM)
- **USB-C cable** (to your laptop)
- **Your Gmail account** (or any email with OAuth support)
- **Internet access** on your laptop

### Step 0: Physical Setup

1. **Connect USB-C cable** from Jetson to your laptop
2. **Power on the Jetson** (wait ~30 seconds for boot)
3. **Open terminal** on your laptop
4. **Navigate to engram:**
   ```bash
   cd ~/engram
   ```

### Step 1: Run the Wizard

```bash
python3 scripts/interview.py
```

The wizard will automatically:
- Scan for your Jetson on the USB-C bridge (192.168.55.1)
- Check if your laptop has internet access
- Guide you through seven stages of onboarding

### Step 2: Respond to Prompts

The wizard will ask for:

1. **Master Email** — Your Gmail or email address
2. **Nvidia API Key** — Generated from https://docs.nvidia.com/cloud/nvidia-cloud-services/nim/api/
3. **Tailscale Auth Key** — Generated from https://login.tailscale.com/admin/settings/keys
4. **Matrix Access Token** — Generated from https://app.element.io

**Stuck on any prompt?** Type `help` or `?` to get:
- Text explanation of what you need
- Direct link to where to get it
- Optional YouTube video (opens in browser)

### Step 3: Understand the 7 Stages

| Stage | What Happens | Time |
|-------|--------------|------|
| **1: Device Discovery** | Wizard finds your Jetson | 30 sec |
| **1B: Internet Check** | Verifies your laptop has internet | 3 sec |
| **1C: Proxy (if needed)** | Enterprise proxy/VPN setup (optional) | 2 min |
| **2: Master Key** | You enter your email | 30 sec |
| **3: Nvidia Setup** | You provide Nvidia API key + validation | 2 min |
| **4: Tailscale** | You provide Tailscale auth key | 30 sec |
| **5: Matrix** | You provide Matrix token + validation | 2 min |
| **5B: Proxy Save** | Save proxy for future (optional) | 30 sec |
| **6: Save Config** | Wizard writes credentials.json | 1 sec |
| **7: Headless** | Disable GUI, enable headless, report RAM win | 1 min |
| **8: Security Hardening** | Firewall (UFW) + brute-force protection (fail2ban) | 2 min |
| **Final** | Success message, next steps | — |

### Step 4: Your Node is Ready

After ~10 minutes, you'll see:

```
🎉 YOUR ENGRAM NODE IS READY!
✓ All credentials validated and saved
✓ System optimized for high-performance inference
✓ Headless mode enabled (you can unplug the monitor)
✓ Security hardened with firewall & brute-force protection
```

You can now:
- **Unplug the monitor** (not needed anymore)
- **Unplug the USB keyboard** (SSH will be your interface)
- **Keep USB-C connected** (provides power + network bridge + emergency access)
- **Access remotely** via Tailscale (encrypted mesh network, primary method)
- **Emergency access** via USB-C bridge if Tailscale unavailable

---

## 💻 Help System: The Integrated Guide

### How to Use Help

On **any prompt**, type `help` or `?` to get:

1. **Text explanation** — What this credential does and why you need it
2. **Setup steps** — How to get the credential from the service
3. **YouTube tutorial** (optional) — A video showing the process visually

**Example:**

```
→ Paste your Tailscale Auth Key: help

╔══ Tailscale Auth Key: Mesh Network ══╗

Tailscale creates a private, encrypted mesh network:
  • Connect devices securely (laptop ↔ Jetson)
  • No port forwarding or firewall complexity
  • Remote access from anywhere

Quick setup:
  1. Go to: https://login.tailscale.com/admin/settings/keys
  ... [more steps] ...

→ Opening video tutorial in your browser...

→ Paste your Tailscale Auth Key: [now you can paste]
```

### Available Help Contexts

| Prompt | Type `help` for | YouTube Link |
|--------|-----------------|------|
| Email | Master Key setup | PLACEHOLDER_EMAIL_SETUP |
| Nvidia API | NIM inference brain | PLACEHOLDER_NVIDIA_API |
| Tailscale Key | Mesh networking | PLACEHOLDER_TAILSCALE |
| Matrix Token | Team coordination | PLACEHOLDER_MATRIX |

---

## 🏢 Enterprise Troubleshooting: Proxies & VPNs

### When You Need a Proxy

If your organization requires internet traffic to route through a corporate proxy or VPN, the wizard offers integrated support.

### Proxy Setup Flow

When the wizard cannot reach the internet, you'll see:

```
⚠️  NETWORK CONNECTIVITY WARNING
═════════════════════════════════

Options:
  [R]etry: Check connectivity again
  [P]roxy: Configure proxy/VPN settings
  [S]kip:  Continue without API validation

Note: Enterprise/VPN users should try [P]roxy option.
```

**Choose [P]roxy to:**

1. **View OS-specific VPN guidance** — Detailed steps for Windows, macOS, or Linux
2. **Configure proxy manually** — Enter your proxy URL and optional credentials
3. **Test the proxy** — Wizard validates connectivity through the proxy
4. **Save for future use** — Proxy settings can be persisted to `credentials.json`

### Proxy URL Formats

| Format | Example | Notes |
|--------|---------|-------|
| **No auth** | `http://proxy.corp.com:8080` | Basic proxy with no credentials |
| **With auth** | `http://user:pass@proxy.corp.com:8080` | Embedded credentials |
| **HTTPS** | `https://proxy.corp.com:8443` | Secure proxy connection |

**Best practice:** Use the interactive prompt. The wizard will URL-encode credentials automatically.

### OS-Specific Internet Connection Sharing

#### 🪟 Windows: Enable Internet Connection Sharing (ICS)

1. **Find your internet interface:**
   - Settings → Network & internet → More network options
   - Click "Change adapter options"

2. **Enable sharing:**
   - Right-click your internet connection (WiFi/Ethernet)
   - Properties → Sharing tab
   - ✓ Check "Allow other network users to connect through this computer's Internet connection"
   - Select USB Ethernet adapter from dropdown
   - Click OK

3. **Verify:**
   - Open Command Prompt: `ipconfig /all`
   - Look for USB Ethernet adapter with IP `192.168.55.x`

4. **Using with VPN:**
   - Connect to your VPN first
   - Then configure proxy in wizard
   - Proxy will tunnel through VPN

#### 🍎 macOS: Enable Internet Sharing

1. **Open System Preferences:**
   - System Preferences → Sharing
   - Left panel → "Internet Sharing"

2. **Configure:**
   - "Share your connection from:" Select your internet interface (WiFi, Ethernet, etc.)
   - "To computers using:" Select USB Ethernet (or other USB interface)
   - Check the "Internet Sharing" checkbox

3. **Verify:**
   - Terminal: `ifconfig | grep -A5 "USB"`
   - Look for `inet 192.168.55.x`

4. **Using with VPN:**
   - Connect to your VPN first (System Preferences → Network → VPN)
   - Then configure proxy in wizard
   - VPN will auto-route traffic

#### 🐧 Linux: Enable IP Forwarding & NAT

1. **Enable IP forwarding:**
   ```bash
   sudo sysctl -w net.ipv4.ip_forward=1
   ```

2. **Find your internet interface:**
   ```bash
   ip route | grep default | awk '{print $5}'
   # Example output: wlan0, eth0, etc.
   ```

3. **Enable NAT (replace wlan0 with your interface):**
   ```bash
   sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
   ```

4. **Verify:**
   ```bash
   ip addr show
   # Look for your USB interface with 192.168.55.x
   ```

5. **Using with VPN:**
   - Ensure VPN connection is active first (OpenVPN, WireGuard, etc.)
   - Then configure proxy in wizard
   - VPN will handle routing automatically

### Split Tunneling: Bypass VPN for Initial Setup

If you have a VPN that blocks your Jetson setup but you still need internet for the proxy validation:

#### Windows Split Tunneling

- OpenVPN: Edit `.ovpn` config, add: `pull-filter ignore "redirect-gateway"`
- Cisco AnyConnect: Check "Split Tunneling" in settings, add `192.168.55.0/24`

#### macOS Split Tunneling

- Check your VPN client for "Split Tunneling" option
- Enable local network access for `192.168.55.0/24`

#### Linux Split Tunneling (OpenVPN)

- Edit your `.ovpn` config file
- Add: `route 192.168.55.0 255.255.255.0 vpn_gateway`
- This routes Jetson traffic directly (not through VPN)

### Troubleshooting Proxy Issues

| Problem | Cause | Fix |
|---------|-------|-----|
| "Invalid proxy URL" | Wrong format | Use `http://proxy.com:8080` (include port) |
| "Proxy test failed" | Credentials wrong | Re-enter username/password |
| "Still no internet after proxy" | Wrong proxy address | Double-check with your IT team |
| "401 Unauthorized" | Credentials not accepted | Try domain format: `CORP\jdoe` instead of `jdoe` |
| "Firewall blocked" | Corporate firewall | IT team may need to whitelist Nvidia/Matrix API endpoints |

### Persisting Proxy Settings

After successful proxy configuration, you'll be asked:

```
Save proxy settings for future use by your AI models? (y/n): y
✓ Proxy settings will be saved to credentials.json
```

If you choose "yes," proxy settings are stored in `~/engram/credentials.json`:

```json
{
  "enterprise": {
    "proxy_url": "http://proxy.corp.com:3128",
    "proxy_username": "jdoe",
    "proxy_password": "...",
    "note": "Used for API validation and model deployment"
  }
}
```

---

## 🛟 The Lifeboat: Getting Your GUI Back

If you ever need a graphical desktop:

### Quick Toggle

After headless mode is enabled, two helper scripts are created:

```bash
# Stop desktop (recover RAM):
desktop-off

# Start desktop again:
desktop-on
```

Both require `sudo` and will prompt for your password.

### Manual Revert

If the helper scripts aren't available:

```bash
# Set graphical boot:
sudo systemctl set-default graphical.target

# Start the display manager:
sudo systemctl start gdm3  # (or lightdm, sddm, etc.)

# Reboot to see GUI at next boot:
sudo reboot
```

### Why You Might Want GUI

- **Visual debugging** of a GPU issue
- **Nvidia tools** that require a display
- **Initial setup** of some drivers

**Recommendation:** Set GUI back to headless once you're done:

```bash
sudo systemctl set-default multi-user.target
```

---

## 📋 Credential Storage: credentials.json

Your wizard-generated credentials are saved in `~/engram/credentials.json`:

```json
{
  "master_account": {
    "email": "user@gmail.com",
    "nvidia_api_key": "nvapi-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "tailscale_key": "tskey-auth-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "matrix_access_token": "syt_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "status": "provisioned"
  },
  "node": {
    "alias": "engram-primary",
    "mission": "local-ai-inference",
    "ip": "192.168.55.1",
    "status": "operational"
  },
  "enterprise": {
    "proxy_url": "http://proxy.corp.com:3128",
    "proxy_username": "jdoe",
    "proxy_password": "SecurePassword123",
    "note": "These proxy settings are used for API validation and can be applied to model deployment"
  }
}
```

**Security note:** This file is **not encrypted**. Treat it like a password file:
- Don't commit to git
- Don't share with others
- Keep it private

Consider encrypting it:

```bash
gpg --symmetric ~/engram/credentials.json
rm ~/engram/credentials.json  # Remove plain text
```

---

## 🔍 Verification Checklist

After running the wizard, verify everything worked:

```bash
# 1. Credentials file exists and is valid JSON
cat ~/engram/credentials.json | python3 -m json.tool

# 2. Node is offline (no GUI running)
systemctl get-default
# Should output: multi-user.target

# 3. Display manager is stopped
systemctl is-active gdm3
# Should output: inactive

# 4. RAM was recovered
free -h
# Compare before/after values

# 5. Helper scripts exist
ls -l /usr/local/bin/desktop-*
# Should show both scripts as executable
```

---

## ❓ Common Questions

### Q: Can I use this with multiple Jetson units?

**A:** Not yet. The consumer wizard is designed for one device. For multiple units, use the legacy fleet-manager approach (coming in a future release).

### Q: Is my email stored securely?

**A:** Credentials are saved in `~/engram/credentials.json` (plain text). Treat it like a password file—keep it private. Consider encrypting it with GPG.

### Q: What if I accidentally unplug the USB cable?

**A:** Nothing bad happens. Your credentials are saved on your laptop. Just plug it back in and the wizard will detect existing credentials and ask if you want to update them.

### Q: Can I use a custom domain email instead of Gmail?

**A:** Yes. As long as the email can receive OAuth logins and works with Nvidia, Tailscale, and Matrix, it should work.

### Q: The wizard timed out. Can I resume?

**A:** The wizard saves your credentials as you progress. If it timed out, fix the issue and run the wizard again. It will detect existing credentials and allow you to update them.

### Q: How do I reset/uninstall?

**A:** Remove your credentials file:

```bash
rm ~/engram/credentials.json
```

Then run the wizard again. It will start fresh.

### Q: Can I access the Jetson from another laptop?

**A:** Yes! That's what Tailscale is for. Once your node is on the Tailscale mesh, you can SSH into it from any device on the same mesh:

```bash
ssh user@engram-primary  # Via Tailscale
```

---

## 📚 Next Steps After Onboarding

### 1. Accessing Your Node Remotely

Once the wizard completes, your node is:
- ✅ Running headless (no GUI)
- ✅ Connected to Tailscale mesh
- ✅ Ready for remote access

From your laptop:

```bash
# Access via Tailscale:
ssh user@engram-primary

# Or directly (if you know the IP):
ssh user@192.168.55.1
```

### 2. Deploying an AI Model

Once you have local access:

```bash
# Example: Run Nvidia NIM for Llama 2
export NVIDIA_API_KEY="your-nvidia-key"

docker run -it --gpus all \
  -e NVIDIA_API_KEY=$NVIDIA_API_KEY \
  nvcr.io/nim/nvidia/llama2-70b-chat:latest
```

### 3. Monitoring via Matrix

Your node can send alerts to your Matrix room:

```bash
# Example: Alert script
curl -X POST https://matrix.example.com/_matrix/client/r0/rooms/!roomid/send/m.room.message \
  -H "Authorization: Bearer YOUR_MATRIX_TOKEN" \
  -d '{"msgtype":"m.text","body":"Node healthy, inference ready"}'
```

---

## 🛡️ Security Hardening & Network Access (Stage 8)

### Security Philosophy: "Hidden From Public Internet"

After your node is configured, the wizard applies comprehensive security hardening to ensure your Jetson is:

- **Unreachable from the public internet** — Firewall blocks all unsolicited inbound traffic
- **Protected against brute-force attacks** — fail2ban monitors SSH for intrusion attempts
- **Always accessible via Tailscale** — Encrypted mesh network provides secure remote access
- **Never bricked** — USB-C bridge provides an emergency "maintenance hatch" for recovery

### The Maintenance Hatch: Emergency Access via USB-C

If something goes wrong—Tailscale stops working, SSH is unreachable, the system becomes unresponsive—you still have an emergency access path:

**The USB-C bridge (192.168.55.1) remains always open.**

This is your "maintenance hatch." It allows you to:
- SSH directly into the Jetson from your laptop via the USB-C bridge
- Diagnose network issues
- Recover from accidental firewall misconfigurations
- Re-enable Tailscale if it crashes

**Example: Emergency SSH via USB-C bridge:**

```bash
# From your laptop (connected via USB-C):
ssh user@192.168.55.1

# Or if that fails, you can even access the display output:
sudo screen /dev/ttyUSB0 115200  # Serial console fallback
```

### The Hive Mind Door: Primary Access via Tailscale

Once the system is up, **Tailscale is your primary access method:**

```bash
# Add your Jetson to your Tailscale network
tailscale up --authkey tskey-auth-XXXXX

# On your laptop, SSH via Tailscale mesh:
ssh user@engram-primary.your-tailnet-name.ts.net
```

**Why Tailscale is better than direct SSH:**
- ✅ No port forwarding (no fiddling with routers)
- ✅ End-to-end encryption (no man-in-the-middle)
- ✅ Works from anywhere (home, office, coffee shop)
- ✅ Simple DNS names (no need to remember IPs)
- ✅ No need to expose SSH to the public internet

### Firewall Rules (UFW)

The wizard configures UFW with these rules:

| Rule | Purpose | Status |
|------|---------|--------|
| **Default: Deny Incoming** | Block all unsolicited traffic | ✅ Active |
| **Default: Allow Outgoing** | Let your node reach services | ✅ Active |
| **USB-C Bridge (l4tbr0)** | Emergency access via 192.168.55.0/24 | ✅ Open |
| **Tailscale Interface** | Encrypted mesh network traffic | ✅ Open |
| **SSH Port 22** | Remote shell access (via Tailscale) | ✅ Open |

### Brute-Force Protection (fail2ban)

The wizard installs and enables fail2ban to watch for:
- Repeated SSH login failures
- Suspicious connection attempts
- Distributed attack patterns

If someone tries to brute-force your SSH password, they'll be **automatically blocked** after 5 failed attempts (default).

### Emergency Recovery: If Firewall Locks You Out

If something goes wrong and you're locked out, **you can always access via USB-C:**

```bash
# From your laptop (with USB-C connected):
ssh user@192.168.55.1

# Then disable UFW to troubleshoot:
sudo ufw disable

# Re-run the wizard or manually re-configure:
python3 ~/engram/scripts/interview.py
```

**Key point:** The USB-C bridge is **always accessible**, even if UFW or Tailscale fails.

---

## 🎬 Summary

The Engram Consumer Onboarding Wizard gets you from zero to a running, **hardened** AI edge node in ~10-12 minutes:

1. **Plug in USB-C** — Discover your Jetson
2. **Run wizard** — Eight guided stages
3. **Answer prompts** — Master email + API keys
4. **Get optimized** — Headless mode enabled, RAM freed
5. **Get hardened** — Firewall + brute-force protection enabled
6. **Go remote** — Unplug the monitor, use Tailscale (or USB-C as fallback)

**Your Jetson is now a high-performance, security-hardened AI inference engine, optimized for production, ready to run your models.**

**Access methods:**
- 🔒 **Primary:** Tailscale mesh network (encrypted, firewall-friendly, works from anywhere)
- 🚪 **Emergency:** USB-C bridge (192.168.55.1) — always available for recovery

🚀 Happy inferencing!
