# DEPLOYMENT PLAN - PART 2

**Continuation from DEPLOYMENT-PLAN-PART-1.md**

---

## PHASE 4: CONFIGURE DIFY

**Estimated time:** 45 minutes

### Step 4.1: Access Dify Setup Page

**Action:** Open browser to https://codex.firefrostgaming.com

**Expected:** Dify installation wizard

**If fails:** Check TROUBLESHOOTING.md

---

### Step 4.2: Create Admin Account

**On the Dify setup page:**

1. **Email:** Enter Michael's email (e.g., michael@firefrostgaming.com)
2. **Password:** Create strong password (save it in password manager)
3. **Name:** Michael Krause
4. **Click:** "Create Account"

**⚠️ SAVE CREDENTIALS:** Store in password manager immediately

**Expected:** Account created, redirected to Dify dashboard

---

### Step 4.3: Skip Initial Tutorial (Optional)

**If Dify shows tutorial:**
- Click "Skip" or go through it quickly
- We'll configure manually

---

### Step 4.4: Configure Ollama Model Provider

**In Dify dashboard:**

1. Click **"Settings"** (gear icon, top right)
2. Click **"Model Providers"** in left sidebar
3. Click **"+ Add Model Provider"**
4. Select **"Ollama"**

**Configuration:**
- **Name:** Ollama (TX1)
- **Base URL:** `http://host.docker.internal:11434`
- **API Key:** (leave blank - Ollama doesn't need one)

5. Click **"Save"**

**Expected:** Ollama provider added successfully

---

### Step 4.5: Test Ollama Connection

**In Model Providers:**

1. Find Ollama provider
2. Click **"Test Connection"**

**Expected:** Green checkmark "Connection successful"

**If fails:**
- Verify Ollama is running on host: `curl http://localhost:11434/api/version`
- Check Docker extra_hosts configuration
- Review logs: `docker-compose logs dify-api`

---

### Step 4.6: Add Ollama Models

**In Ollama provider settings:**

1. Click **"Add Model"**
2. **Model name:** `llama3.3:70b`
3. **Display name:** Llama 3.3 70B (Main Reasoning)
4. **Type:** Chat
5. Click **"Save"**

**Repeat for second model:**
1. Click **"Add Model"**
2. **Model name:** `qwen2.5-coder:7b`
3. **Display name:** Qwen 2.5 Coder 7B (Fast Agent)
4. **Type:** Chat
5. Click **"Save"**

**Expected:** Both models available in Dify

---

### Step 4.7: Create First Workspace (Firefrost Admin)

**In Dify dashboard:**

1. Click workspace name dropdown (top left)
2. Click **"+ Create Workspace"**
3. **Name:** Firefrost Admin
4. **Description:** Full access to all Firefrost repositories
5. Click **"Create"**

**Expected:** New workspace created and active

---

### Step 4.8: Create Second Workspace (Pokerole HQ)

**Repeat workspace creation:**

1. Click workspace dropdown
2. Click **"+ Create Workspace"**
3. **Name:** Pokerole HQ
4. **Description:** Access to Pokerole project only
5. Click **"Create"**

**Expected:** Second workspace created

**Switch back to Firefrost Admin workspace for next steps**

---

### Step 4.9: Create First Knowledge Base (Main)

**In Firefrost Admin workspace:**

1. Click **"Knowledge"** in left sidebar
2. Click **"+ Create Knowledge Base"**
3. **Name:** Firefrost Operations Manual
4. **Description:** Complete operations documentation
5. **Embedding Model:** text-embedding-3-small (or available model)
6. **Vector Store:** Qdrant
7. **Retrieval Mode:** High Quality
8. Click **"Create"**

**Expected:** Knowledge base created

**⚠️ COPY THE DATASET ID from URL:**
```
https://codex.firefrostgaming.com/datasets/abc123-def456-...
                                              ^^^^^^^^^^^^
                                              This is your dataset ID
```

**Save to .env file:**
```bash
nano /opt/firefrost-codex/.env
# Update this line:
DIFY_DATASET_ID_MAIN=abc123-def456-ghi789
```

---

### Step 4.10: Create Second Knowledge Base (Pokerole)

**Switch to Pokerole HQ workspace:**

1. Click workspace dropdown → Pokerole HQ

**Create knowledge base:**

1. Click **"Knowledge"**
2. Click **"+ Create Knowledge Base"**
3. **Name:** Pokerole Project
4. **Description:** Pokerole campaign documentation
5. **Embedding Model:** text-embedding-3-small
6. **Vector Store:** Qdrant
7. **Retrieval Mode:** High Quality
8. Click **"Create"**

**⚠️ COPY THE DATASET ID and save to .env:**
```bash
DIFY_DATASET_ID_POKEROLE=xyz789-abc123-...
```

**Switch back to Firefrost Admin workspace**

---

### Step 4.11: Get Dify API Key

**In Dify settings:**

1. Click **"Settings"** (gear icon)
2. Click **"API Keys"** in left sidebar
3. Click **"+ Create API Key"**
4. **Name:** n8n Integration
5. **Permissions:** Full Access
6. Click **"Create"**

**⚠️ COPY THE API KEY IMMEDIATELY (shown only once)**

**Save to .env file:**
```bash
nano /opt/firefrost-codex/.env
# Update this line:
DIFY_API_KEY=sk-your-actual-api-key-here
```

**Save and exit**

---

### Step 4.12: Test Knowledge Base Creation

**In Firefrost Operations Manual knowledge base:**

1. Click **"Add Document"**
2. Click **"Text"**
3. Paste a test paragraph (any text)
4. Click **"Save and Process"**

**Expected:** Document processes and shows in knowledge base

**If fails:**
- Check Qdrant connection
- Review logs: `docker-compose logs dify-worker`

**Delete test document after verification**

---

## PHASE 5: SETUP N8N WORKFLOWS

**Estimated time:** 90 minutes

### Step 5.1: Access n8n

**Action:** Open browser to https://n8n.firefrostgaming.com

**Expected:** n8n setup page

---

### Step 5.2: Create n8n Owner Account

**On n8n setup page:**

1. **Email:** michael@firefrostgaming.com
2. **Password:** Create strong password (save in password manager)
3. **First name:** Michael
4. **Last name:** Krause
5. Click **"Create Account"**

**Expected:** Account created, redirected to n8n dashboard

---

### Step 5.3: Create Credentials - Gitea SSH

**In n8n:**

1. Click **"Credentials"** in top menu
2. Click **"Add Credential"**
3. Search for **"SSH"**
4. **Name:** Gitea SSH Key
5. **Host:** git.firefrostgaming.com
6. **Port:** 22
7. **Username:** git

**Private Key:**
```bash
# On TX1, copy your SSH private key
cat ~/.ssh/id_ed25519_gitea
```

Copy the entire key (including BEGIN and END lines) into n8n

8. Click **"Save"**

**Expected:** Credential saved

---

### Step 5.4: Create Credentials - Discord Webhooks

**Create first webhook credential:**

1. Click **"Add Credential"**
2. Search for **"HTTP Header Auth"**
3. **Name:** Discord Codex Alerts
4. **Name:** Content-Type
5. **Value:** application/json

**We'll use webhook URLs directly in workflows (no auth needed)**

---

### Step 5.5: Create Credentials - Dify API

**Create Dify API credential:**

1. Click **"Add Credential"**
2. Search for **"HTTP Header Auth"**
3. **Name:** Dify API Key
4. **Header Name:** Authorization
5. **Header Value:** Bearer YOUR_DIFY_API_KEY_HERE

(Replace with actual API key from Step 4.11)

6. Click **"Save"**

---

### Step 5.6: Create Workflow 1 - Git Sync

**In n8n dashboard:**

1. Click **"Workflows"**
2. Click **"+ Add Workflow"**
3. **Name:** Firefrost Git Sync

**Add Schedule Trigger:**
1. Click **"+"** to add first node
2. Search for **"Schedule Trigger"**
3. **Trigger Interval:** Every 1 hour
4. Click **"Save"**

**Add Execute Command Node - Git Pull:**
1. Click **"+"** after Schedule node
2. Search for **"Execute Command"**
3. **Command:** 
```bash
cd /data/git-repos/main && git pull origin main
```
4. Click **"Save"**

**Add Code Node - Filter Archives:**
1. Click **"+"** after Execute Command
2. Search for **"Code"**
3. **Mode:** Run Once for Each Item
4. **JavaScript Code:**

```javascript
const filePath = $json.path; 

// Check if path contains 'archive' directory
const isArchived = filePath.split('/').some(segment => 
    segment.toLowerCase() === 'archive'
);

return {
    ...$json,
    metadata: {
        status: isArchived ? "archived" : "current",
        last_sync: new Date().toISOString(),
        firefrost_repo: "main"
    }
};
```

5. Click **"Save"**

**Add HTTP Request Node - Send to Dify:**
1. Click **"+"** after Code node
2. Search for **"HTTP Request"**
3. **Method:** POST
4. **URL:** `http://dify-api:5001/v1/datasets/{{$env.DIFY_DATASET_ID_MAIN}}/document/create-by-text`
5. **Authentication:** Use Dify API credential
6. **Body Content Type:** JSON
7. **Body:**

```json
{
  "name": "{{$json.name}}",
  "text": "{{$json.content}}",
  "indexing_technique": "high_quality",
  "process_rule": {
    "mode": "automatic"
  }
}
```

8. Click **"Save"**

**Add Discord Notification (Success):**
1. Click **"+"** after HTTP Request
2. Search for **"HTTP Request"**
3. **Method:** POST
4. **URL:** (Your Discord webhook for #codex-alerts)
5. **Body Content Type:** JSON
6. **Body:**

```json
{
  "embeds": [{
    "title": "✅ Codex Knowledge Updated",
    "description": "The library has been refreshed with the latest files from Git.",
    "color": 3066993,
    "fields": [
      { "name": "Files Synced", "value": "{{$json.fileCount}} documents", "inline": true },
      { "name": "Repository", "value": "firefrost-main", "inline": true }
    ],
    "footer": { "text": "System: n8n-sync-worker | Node: TX1-Dallas" },
    "timestamp": "{{$now.toISO()}}"
  }]
}
```

7. Click **"Save"**

**Save entire workflow:** Click **"Save"** in top right

**Activate workflow:** Toggle switch to ON

---

### Step 5.7: Create Workflow 2 - Git Write-Back

**Create new workflow:**

1. Click **"+ Add Workflow"**
2. **Name:** Firefrost Git Write-Back

**Add Webhook Trigger:**
1. Add **"Webhook"** node
2. **HTTP Method:** POST
3. **Path:** git-update
4. **Response Mode:** Respond Immediately
5. Click **"Save"**

**⚠️ COPY WEBHOOK URL** (will be used in Dify tool definition)

**Add Code Node - Validation:**
1. Add **"Code"** node after Webhook
2. **JavaScript Code:**

```javascript
const filePath = $json.body.file_path;
const content = $json.body.new_content;
const user = $json.body.user || "Unknown";

// Protected directories
const protectedPaths = ['/security', '/infra', '/backups', '.env', 'docker-compose.yml'];
const isProtected = protectedPaths.some(p => filePath.startsWith(p) || filePath.includes(p));

// Markdown validation
const hasMarkdown = content.includes('#') || content.includes('**') || content.length > 5;

if (isProtected) {
    throw new Error(`ACCESS DENIED: ${filePath} is a protected system file.`);
}

if (!hasMarkdown || content.trim() === "") {
    throw new Error("VALIDATION FAILED: Content must be valid non-empty Markdown.");
}

return {
    file_path: filePath,
    content: content,
    user: user,
    reason: $json.body.reason || "AI Update",
    validated: true
};
```

3. Click **"Save"**

**Add Execute Command Node - Git Commit:**
1. Add **"Execute Command"** node
2. **Command:**

```bash
cd /data/git-repos/main
git checkout ai-proposals 2>/dev/null || git checkout -b ai-proposals
echo "{{$json.content}}" > "{{$json.file_path}}"
git add "{{$json.file_path}}"
git commit -m "AI Update: {{$json.reason}} (by {{$json.user}})"
git push origin ai-proposals
```

3. Click **"Save"**

**Add Discord Notification - Proposal Ready:**
1. Add **"HTTP Request"** node
2. **Method:** POST
3. **URL:** (Discord webhook for #codex-alerts)
4. **Body:**

```json
{
  "content": "🔔 **New Codex Proposal Ready**",
  "embeds": [{
    "title": "Proposal: {{$json.reason}}",
    "description": "User: **{{$json.user}}**\nFile: `{{$json.file_path}}`",
    "color": 3447003,
    "footer": { "text": "Branch: ai-proposals" }
  }],
  "components": [
    {
      "type": 1,
      "components": [
        {
          "type": 2,
          "label": "Approve & Merge",
          "style": 3,
          "custom_id": "approve_{{$json.commit_hash}}"
        },
        {
          "type": 2,
          "label": "Reject",
          "style": 4,
          "custom_id": "reject_{{$json.commit_hash}}"
        }
      ]
    }
  ]
}
```

4. Click **"Save"**

**Add Error Handler - On Failure:**
1. Add new path from Validation node (error output)
2. Add **"HTTP Request"** node
3. **Method:** POST
4. **URL:** (Discord webhook for #codex-alerts)
5. **Body:**

```json
{
  "embeds": [{
    "title": "⚠️ Access Restricted",
    "description": "Sorry **{{$json.user}}**, I can't modify that specific file.",
    "color": 15105570,
    "fields": [
      { "name": "File", "value": "`{{$json.file_path}}`", "inline": false },
      { "name": "Reason", "value": "This is a core system file. Only Michael can edit this during Chronicler sessions.", "inline": false }
    ],
    "footer": { "text": "Security Policy: FIREWALL_PROTECTION_V1" }
  }]
}
```

6. Click **"Save"**

**Save workflow and activate**

---

### Step 5.8: Create Workflow 3 - One-Click Approval

**Create new workflow:**

1. **Name:** Firefrost Approval Handler

**Add Webhook Trigger:**
1. Add **"Webhook"** node
2. **HTTP Method:** POST
3. **Path:** discord-interaction
4. **Response Mode:** Respond Immediately

**Add IF Node - Check User:**
1. Add **"IF"** node
2. **Condition:**

```
{{$json.body.member.user.id}} === "{{$env.MICHAEL_DISCORD_ID}}"
```

3. **True path:** Continue to merge
4. **False path:** Send "Unauthorized" message

**Add Execute Command - Merge:**
1. Add **"Execute Command"** on True path
2. **Command:**

```bash
cd /data/git-repos/main
git tag backup-before-ai-$(date +%s)
git checkout main
git merge ai-proposals --no-ff -m "AI Merge approved by Michael"
git push origin main
git branch -D ai-proposals
git checkout -b ai-proposals
git push origin ai-proposals --force
```

3. Click **"Save"**

**Add HTTP Request - Re-index Dify:**
1. Add **"HTTP Request"** node
2. **Method:** POST
3. **URL:** `http://dify-api:5001/v1/datasets/{{$env.DIFY_DATASET_ID_MAIN}}/sync`
4. **Authentication:** Use Dify API credential

**Add Discord Success Notification:**
1. Add **"HTTP Request"** node
2. Send success message to #codex-alerts

**Save and activate workflow**

---

### Step 5.9: Test Git Sync Workflow

**Manual test:**

1. Open "Firefrost Git Sync" workflow
2. Click **"Execute Workflow"** button
3. Wait for execution to complete

**Expected:** All nodes complete successfully (green checkmarks)

**If fails:**
- Check error messages in each node
- Verify Git repository exists at /data/git-repos/main
- Check credentials

---

### Step 5.10: Initialize Git Repository

**On TX1:**

```bash
cd /opt/firefrost-codex/git-repos
git clone git@git.firefrostgaming.com:firefrost-gaming/firefrost-operations-manual.git main
cd main
git checkout -b ai-proposals
git push -u origin ai-proposals
```

**Verify:**
```bash
git branch -a
```

**Expected:** Shows main and ai-proposals branches

---

## PHASE 6: CONFIGURE DIFY TOOLS

**Estimated time:** 30 minutes

### Step 6.1: Create update_codex Tool in Dify

**In Dify (Firefrost Admin workspace):**

1. Click **"Tools"** in left sidebar
2. Click **"+ Create Tool"**
3. **Type:** Custom API
4. **Name:** update_codex
5. **Description:** Updates a document in the knowledge base and commits changes to Git.

**Configuration:**

**Endpoint:**
- **Method:** POST
- **URL:** https://n8n.firefrostgaming.com/webhook/git-update
- **Headers:** Content-Type: application/json

**Parameters:**
```json
{
  "type": "object",
  "properties": {
    "file_path": {
      "type": "string",
      "description": "Relative path to the file (e.g., rules/moderation.md)"
    },
    "new_content": {
      "type": "string",
      "description": "Full updated content in Markdown format"
    },
    "reason": {
      "type": "string",
      "description": "Brief explanation for the change"
    }
  },
  "required": ["file_path", "new_content", "reason"]
}
```

6. Click **"Save"**

**Expected:** Tool created and available in Dify

---

### Step 6.2: Create Chat Application

**In Dify:**

1. Click **"Studio"** in left sidebar
2. Click **"+ Create App"**
3. **Type:** Chatbot
4. **Name:** Firefrost Codex
5. **Icon:** Choose appropriate icon
6. Click **"Create"**

**Configure App:**

1. **Model:** llama3.3:70b
2. **System Prompt:**

```
You are the Firefrost Codex, an AI assistant for the Firefrost Gaming community.

You have access to the complete Firefrost operations manual and can help users with:
- Finding information about servers, configurations, and procedures
- Answering questions about Firefrost policies and guidelines
- Helping staff update documentation (with approval)

When updating documents:
- Use the update_codex tool
- Provide clear reasons for changes
- Changes will be reviewed before going live

Be helpful, accurate, and refer to the knowledge base for current information.
```

3. **Knowledge Base:** Select "Firefrost Operations Manual"
4. **Tools:** Enable "update_codex"
5. **Temperature:** 0.7
6. **Max Tokens:** 4000

7. Click **"Save"**

---

### Step 6.3: Test Chat Application

**In Dify app:**

1. Click **"Preview"** button
2. Ask test question: "What are the current Tier 0 tasks?"

**Expected:** AI responds with current tasks (NOT archived tasks)

**If returns archived tasks:** Knowledge base needs proper indexing, review Git sync

---

### Step 6.4: Publish Chat Application

**In Dify app:**

1. Click **"Publish"** button
2. **Access:** Authenticated users only
3. Click **"Confirm"**

**Expected:** App published and accessible to users

---

## PHASE 7: USER ONBOARDING

**Estimated time:** 30 minutes

### Step 7.1: Invite Meg to Dify

**In Dify settings:**

1. Click **"Settings"** → **"Members"**
2. Click **"+ Invite Member"**
3. **Email:** meg@firefrostgaming.com (or actual email)
4. **Role:** Admin
5. **Workspaces:** Firefrost Admin
6. Click **"Send Invite"**

**⚠️ Copy invite link** (email may not work without SMTP)

**Send link to Meg via Discord**

---

### Step 7.2: Invite Holly to Dify

**Repeat for Holly:**

1. **Email:** holly@example.com
2. **Role:** Member
3. **Workspaces:** Pokerole HQ ONLY
4. Click **"Send Invite"**

**Send invite link to Holly via Discord**

---

### Step 7.3: Verify Meg's Access

**After Meg creates account:**

1. Verify she can access Firefrost Admin workspace
2. Verify she can chat with Codex
3. Test query: "What servers does Firefrost operate?"

**Expected:** Correct answer with current server list

---

### Step 7.4: Verify Holly's Access

**After Holly creates account:**

1. Verify she can ONLY access Pokerole HQ workspace
2. Verify she CANNOT see Firefrost infrastructure docs
3. Test query about Pokerole content

**Expected:** Only sees Pokerole knowledge base

---

### Step 7.5: Train on Update Workflow

**Show Meg and Holly:**

1. How to request document updates via chat
2. Example: "Update the recruitment doc to add applicant: John Smith"
3. Explain approval process (Michael reviews via Discord)
4. Show them notification in Discord when change is ready

**Document this in user guide**

---

## PHASE 8: MONITORING SETUP

**Estimated time:** 20 minutes

### Step 8.1: Add Dify to Uptime Kuma

**In Uptime Kuma:**

1. Click **"+ Add New Monitor"**
2. **Monitor Type:** HTTP(s)
3. **Friendly Name:** Firefrost Codex (Dify)
4. **URL:** https://codex.firefrostgaming.com
5. **Heartbeat Interval:** 60 seconds
6. **Retry Interval:** 60 seconds
7. **Accepted Status Codes:** 200-299
8. Click **"Save"**

---

### Step 8.2: Add n8n to Uptime Kuma

**Create second monitor:**

1. **Friendly Name:** Firefrost n8n
2. **URL:** https://n8n.firefrostgaming.com/healthz
3. **Heartbeat Interval:** 60 seconds
4. Click **"Save"**

---

### Step 8.3: Add Qdrant to Uptime Kuma

**Create third monitor:**

1. **Friendly Name:** Firefrost Qdrant
2. **URL:** http://38.68.14.26:6333/
3. **Heartbeat Interval:** 60 seconds
4. Click **"Save"**

---

### Step 8.4: Configure Critical Alerts

**In Uptime Kuma:**

1. Click **"Settings"** → **"Notifications"**
2. Add Discord webhook for critical alerts
3. Configure to notify on service down (15+ minutes)

---

## PHASE 9: TESTING AND VERIFICATION

**Estimated time:** 60 minutes

### Step 9.1: Query Accuracy Test

**Test current vs archived docs:**

**Query 1:** "What are current Tier 0 tasks?"
**Expected:** Whitelist Manager, NC1 Cleanup, Staff Recruitment
**NOT Expected:** Initial Server Setup, Network Configuration

**Query 2:** "What servers does Firefrost operate?"
**Expected:** Command Center, Billing, Panel, Ghost, TX1, NC1 (with IPs)

**Query 3:** "What was accomplished in recent Codex session?"
**Expected:** Deployer's work (Phase 1 deployment, etc.)

**If ANY test fails:** Git sync issue, re-run sync workflow

---

### Step 9.2: Update Workflow Test

**As Meg in Dify:**

1. Send message: "Update docs/test.md with content: This is a test update"
2. Verify AI calls update_codex tool
3. Check Discord for proposal notification
4. Verify proposal has Approve/Reject buttons

**As Michael in Discord:**

5. Click "Approve & Merge" button
6. Wait 30 seconds
7. Verify Discord shows success message
8. Check Git for commit in main branch

**Verify file updated:**
```bash
cd /opt/firefrost-codex/git-repos/main
cat docs/test.md
```

**Expected:** File contains "This is a test update"

---

### Step 9.3: Protected File Test

**As Meg:**

1. Send: "Update .env file to change password"
2. Verify AI attempts but validation blocks it
3. Check Discord for "Access Restricted" message

**Expected:** Update blocked, clear error message

---

### Step 9.4: RBAC Test

**As Holly:**

1. Try to access Firefrost Admin workspace
2. Expected: BLOCKED (no access)
3. Ask question about Firefrost infrastructure
4. Expected: "I don't have access to that information"

**As Meg:**

1. Ask same infrastructure question
2. Expected: Correct answer (she has access)

---

### Step 9.5: Self-Healing Test

**Simulate Dify crash:**

```bash
docker-compose restart dify-api
```

**Monitor:**

1. Uptime Kuma shows service down
2. Docker auto-restarts service (within 60 seconds)
3. Service comes back online
4. No manual intervention needed

**Expected:** Service recovers automatically

---

### Step 9.6: Git Failure Test

**Simulate Git unreachable:**

```bash
# Temporarily block Git access
sudo iptables -A OUTPUT -d git.firefrostgaming.com -j DROP
```

**Test update workflow:**

1. Meg requests update
2. n8n attempts commit
3. Fails (Git unreachable)
4. Update queued for retry
5. Discord shows "Update queued, will retry"

**Restore Git access:**

```bash
sudo iptables -D OUTPUT -d git.firefrostgaming.com -j DROP
```

**Verify:**
- Pending updates auto-process
- Changes commit successfully
- User notified

---

## PHASE 10: BACKUP AUTOMATION

**Estimated time:** 30 minutes

### Step 10.1: Create Backup Script

**On TX1:**

```bash
nano /opt/firefrost_backup.sh
```

**Paste complete backup script:**

```bash
#!/bin/bash
# Firefrost Codex Backup Script

# Variables
TIMESTAMP=$(date +"%Y%m%d_%H%M")
BACKUP_DIR="/tmp/codex_backup_$TIMESTAMP"
COMPOSE_DIR="/opt/firefrost-codex"

# Create temp directory
mkdir -p "$BACKUP_DIR"

# Dump PostgreSQL database
docker exec -t $(docker ps -qf "name=db") pg_dumpall -c -U postgres > "$BACKUP_DIR/dify_postgres.sql"

# Copy configuration files
cp "$COMPOSE_DIR/docker-compose.yml" "$BACKUP_DIR/"
cp "$COMPOSE_DIR/.env" "$BACKUP_DIR/"
cp -r "$COMPOSE_DIR/volumes/n8n" "$BACKUP_DIR/n8n_data"

# Copy Nginx configs
cp /etc/nginx/sites-available/firefrost-codex.conf "$BACKUP_DIR/"

# Compress
tar -czf "/opt/firefrost_codex_$TIMESTAMP.tar.gz" -C /tmp "codex_backup_$TIMESTAMP"

# Transfer to Command Center
rsync -avz -e "ssh -p 22" "/opt/firefrost_codex_$TIMESTAMP.tar.gz" root@63.143.34.217:/root/backups/firefrost-codex/

# Cleanup
rm -rf "$BACKUP_DIR"
find /opt/ -name "firefrost_codex_*.tar.gz" -mtime +7 -exec rm {} \;

echo "Backup completed: firefrost_codex_$TIMESTAMP.tar.gz"
```

**Save and exit**

---

### Step 10.2: Make Script Executable

```bash
chmod +x /opt/firefrost_backup.sh
```

---

### Step 10.3: Test Backup Script

```bash
/opt/firefrost_backup.sh
```

**Expected:**
- Backup creates successfully
- Transfers to Command Center
- Shows completion message

**Verify on Command Center:**

```bash
ls -lh /root/backups/firefrost-codex/
```

**Expected:** Backup file present

---

### Step 10.4: Schedule Daily Backups

```bash
crontab -e
```

**Add this line:**

```cron
0 4 * * * /opt/firefrost_backup.sh >> /var/log/firefrost-backup.log 2>&1
```

**Save and exit**

**This runs backup daily at 4:00 AM**

---

### Step 10.5: Test Backup Restore

**On TX1 (in test environment):**

```bash
# Extract latest backup
cd /tmp
tar -xzf /opt/firefrost_codex_*.tar.gz
cd codex_backup_*/

# Test database restore
docker run --name test-postgres -e POSTGRES_PASSWORD=test -d postgres:15-alpine
cat dify_postgres.sql | docker exec -i test-postgres psql -U postgres

# Verify no errors
docker logs test-postgres

# Cleanup
docker rm -f test-postgres
```

**Expected:** Database restores without fatal errors

---

## PHASE 11: FINAL CLEANUP

**Estimated time:** 15 minutes

### Step 11.1: Remove AnythingLLM Completely

```bash
cd /opt/anythingllm
docker-compose down -v
cd ..
rm -rf anythingllm
```

**Verify removed:**

```bash
docker ps -a | grep anything
```

**Expected:** No output

---

### Step 11.2: Clean Docker Images

```bash
docker image prune -a
```

**Removes unused Docker images**

---

### Step 11.3: Update tasks.md

**In operations manual:**

```bash
nano docs/core/tasks.md
```

**Mark Task #9 (Firefrost Codex) as COMPLETE:**

```markdown
### 9. Firefrost Codex - AI Assistant
**Status:** ✅ COMPLETE
**Completed:** February 22, 2026
**Deployed by:** The Chronicler #21
```

**Save and commit**

---

### Step 11.4: Document Completion

**Create completion record:**

```bash
cd /firefrost-operations-manual
nano docs/sessions/2026-02-22-CODEX-DEPLOYMENT-COMPLETE.md
```

**Document:**
- Deployment date
- Who deployed (Chronicler #21)
- Final configuration
- Test results
- Any issues encountered
- Lessons learned

**Commit to Git**

---

### Step 11.5: Final Verification Checklist

Run through complete checklist in VERIFICATION.md

**All tests must pass before marking complete**

---

## 🎉 DEPLOYMENT COMPLETE

**If you've reached this point:**

✅ Firefrost Knowledge Engine is LIVE  
✅ Meg and Holly can work independently  
✅ Michael has approval control via Discord  
✅ System self-heals common failures  
✅ Backups run automatically  
✅ Monitoring is active  

**Congratulations! The system is ready for production use.**

---

**Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️

**Next:** Review VERIFICATION.md for comprehensive testing procedures

