# Echidna Deployment Guide
**Familiar v1.3.9 — GJL Nonprofit Operations**

This guide covers deploying and onboarding Echidna for staff use.
It assumes a fresh Linux server or Raspberry Pi 4/5 with internet access.

---

## Architecture Overview

Echidna runs as a systemd service. Staff interact via Telegram.
All data is stored locally under `/var/lib/familiar` (Pi install)
or `~/.familiar` (manual install). Nothing leaves the server except
LLM API calls to Anthropic and Google Workspace API calls.

```
Staff Telegram ──► Bot Token ──► Echidna (systemd) ──► Claude API
                                      │
                                      ├── Gmail API  (triage, send)
                                      ├── Google Calendar API
                                      ├── Google Drive API
                                      └── ~/.familiar/  (sessions, memory, audit)
```

---

## 1. Server Setup (first time only)

### Raspberry Pi (recommended)

```bash
curl -fsSL https://raw.githubusercontent.com/you/familiar/main/scripts/install-pi.sh \
  | bash -s -- --nonprofit --channel telegram
```

The `--nonprofit` flag loads the correct skill set:
email, calendar, triage, gdrive, tasks, nonprofit, knowledge, proactive.

### Linux server (manual)

```bash
# Unzip the release
unzip familiar-v1.3.8.zip && cd familiar

# Install
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# Copy and edit env file
cp env.sample ~/.familiar/.env
nano ~/.familiar/.env
```

---

## 2. Environment Configuration

Edit `~/.familiar/.env`. Minimum required fields:

```bash
# LLM
ANTHROPIC_API_KEY=sk-ant-...

# Telegram bot (get from @BotFather — /newbot)
TELEGRAM_BOT_TOKEN=1234567890:AAE...

# Your Telegram user ID (get from @userinfobot)
OWNER_TELEGRAM_ID=123456789

# Email (if using IMAP/SMTP instead of Gmail API)
# EMAIL_ADDRESS=exec@gjl.org
# EMAIL_PASSWORD=xxxx-xxxx-xxxx-xxxx   # App Password
```

Leave everything else commented out for now.
Google Workspace credentials are set up separately in Step 4.

---

## 3. Start the Service

### Systemd (Pi / Linux server)

```bash
sudo systemctl enable familiar
sudo systemctl start familiar
sudo systemctl status familiar   # should show "active (running)"
```

### Manual (foreground, for testing)

```bash
cd familiar
./run.sh
# or
python -m familiar --telegram
```

---

## 4. Google Workspace Setup (one-time per deployment)

Run the guided wizard. This replaces all manual OAuth steps:

```bash
python -m familiar --setup-google
```

The wizard will:
1. Check that required Python packages are installed
2. Find or prompt for your `credentials.json` from Google Cloud Console
3. Catch the most common mistake (Web app vs Desktop app credentials)
4. Walk through enabling Calendar, Gmail, Drive, and Contacts APIs
5. Open the OAuth authorization URL in your browser (or print it for SSH)
6. Create and immediately delete a test doc to verify write access
7. Report exactly which Familiar skills are now unlocked

**Getting `credentials.json`:**
1. Go to [console.cloud.google.com](https://console.cloud.google.com)
2. Create a project → APIs & Services → Credentials
3. Create OAuth client ID → **Desktop app** (not Web application)
4. Download the JSON file → save as `~/.familiar/data/google_credentials.json`
5. Add your email as a test user under OAuth consent screen

If you hit an error, the wizard tells you exactly what to fix and where.

---

## 5. Preauth Staff Telegram IDs

This must happen **before** a staff member's first message.
Without preauth, they hit the STRANGER trust level and can't use email or calendar tools.

**How to find a Telegram user ID:**
Ask the staff member to message [@userinfobot](https://t.me/userinfobot) on Telegram.
It replies with their numeric user ID (e.g. `987654321`).

**Grant access** — send this in the Telegram bot as the owner:

```
grant 987654321 staff
```

Or by email if they've signed into Telegram with it:

```
grant sarah@gjl.org staff
```

**Roles:**
- `staff` — full access to email, calendar, Drive, triage, tasks (recommended for all staff)
- `readonly` — can read and search, cannot send or create
- `admin` — same as staff plus session management and audit tools

**List current preauth:**
```
list preauth
```

**Revoke:**
```
revoke 987654321
```

---

## 6. Staff Onboarding Workflow

Walk each staff member through this their first session.

### First message
Staff send any message to the bot. If preauth is set, they get `TRUSTED` access immediately.
If they get "I can't help with that yet", check that preauth was applied.

### Run a triage
```
triage my inbox
```
Echidna fetches the last 3 days of unread email, categorizes by:
Campaign, Trans Pride, GJL Operations, Staff, Board, Coalitions, Donors, Grants, Media, Volunteers.
Priority flags: 🔴 urgent, 🟡 needs action, ⚪ FYI.

### Follow up on a specific email
After triage, emails are numbered. No need to repeat sender or subject:
```
read #3
reply to #4 saying I'll follow up by end of week
show me all the Board emails
```

### Calendar
```
what's on my calendar this week
schedule a call with the team Wednesday at 2pm for 1 hour
```

### Drive
```
create a doc called "Q1 Donor Report" with a summary of this quarter's campaigns
add a section about the gala to that doc
```

### Confirmation flow
Any write action (sending email, creating calendar events, Drive writes) shows a preview first.
Staff tap **✅ Confirm** or **❌ Cancel** before anything is executed.

---

## 7. Day-to-Day Operations

### Checking logs
```bash
sudo journalctl -u familiar -f          # live logs
sudo journalctl -u familiar --since today   # today's logs
```

### Restarting after config changes
```bash
sudo systemctl restart familiar
```

### Updating
```bash
cd familiar
unzip -o familiar-v1.x.x.zip
sudo systemctl restart familiar
```

### Backups
Echidna backs up automatically at 3am if enabled in config:
```yaml
backup:
  enabled: true
  path: /var/backups/echidna
  retention_days: 30
```

Manual backup:
```
create a backup
```

### Audit log
```
show audit log
```
Returns the last 50 actions with timestamps and user attribution.

---

## 8. Troubleshooting

**Bot doesn't respond**
```bash
sudo systemctl status familiar
sudo journalctl -u familiar -n 50
```

**"I can't help with that yet"**
Staff member is at STRANGER trust level. Run `grant <telegram_id> staff` as owner.

**Google skills not working**
Re-run `python -m familiar --setup-google`. Check which services are authorized at stage 8.

**Triage shows wrong categories**
Categories are hardcoded for GJL in `skills/triage/skill.py`.
Edit `CATEGORIES` and `CATEGORY_KEYWORDS` to adjust.

**Email sends without confirmation / confirmation never appears**
Check Telegram bot token is valid. If using Signal or Teams,
confirmations are text-based — staff reply Y or N.

**"Triage list is older than 4 hours"**
Run `triage my inbox` again. Context expires after 4 hours for freshness.

---

## 9. Security Notes

- Session data, memory, and audit logs are encrypted at rest when `FAMILIAR_ENCRYPTION_KEY` is set.
  Generate a key: `python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"`
- OAuth tokens are stored in `~/.familiar/data/google_token*.json`. Permissions should be `600`.
- The bot owner (OWNER_TELEGRAM_ID) has admin-level trust automatically.
- All write actions require explicit confirmation — no email is sent, no event created without staff approval.
- Audit log records every tool execution with timestamp, user ID, and action.

---

## 10. Reference — Skill Capabilities by Role

| Skill | readonly | staff | admin |
|-------|----------|-------|-------|
| triage inbox | ✅ | ✅ | ✅ |
| read email | ✅ | ✅ | ✅ |
| reply / send email | ❌ | ✅ | ✅ |
| calendar (read) | ✅ | ✅ | ✅ |
| calendar (create/edit) | ❌ | ✅ | ✅ |
| Google Drive (read) | ✅ | ✅ | ✅ |
| Google Drive (create/edit) | ❌ | ✅ | ✅ |
| tasks | ✅ | ✅ | ✅ |
| nonprofit tools | ✅ | ✅ | ✅ |
| session management | ❌ | ❌ | ✅ |
| audit log | ❌ | ❌ | ✅ |
| grant/revoke access | ❌ | ❌ | ✅ (owner only) |
