# Phase 2 Deployment Guide - Granular Task Instructions **Project**: Tractatus AI Safety Framework **Domain**: agenticgovernance.digital **VPS**: vps-7f023e40.vps.ovh.net (OVHCloud) **Created**: 2025-10-07 **Status**: ACTIVE DEPLOYMENT --- ## Table of Contents 1. [Week 0: Pre-Deployment Preparation](#week-0-pre-deployment-preparation) 2. [Week 1: Infrastructure Setup](#week-1-infrastructure-setup) 3. [Week 2: Application Deployment](#week-2-application-deployment) 4. [Week 3: Security Hardening](#week-3-security-hardening) 5. [Week 4: Monitoring & Testing](#week-4-monitoring--testing) 6. [Week 5-8: AI Features](#week-5-8-ai-features) 7. [Week 9-12: Soft Launch](#week-9-12-soft-launch) 8. [Emergency Procedures](#emergency-procedures) --- ## Week 0: Pre-Deployment Preparation ### Day 0.1: OVHCloud VPS Assessment **Current VPS**: vps-7f023e40.vps.ovh.net **Tasks**: 1. [ ] **Check VPS specifications** in OVHCloud control panel: - CPU cores (need 2+) - RAM (need 4GB+) - Disk space (need 80GB+) - Bandwidth allocation - Current OS (Ubuntu 22.04 LTS preferred) 2. [ ] **Verify VPS location**: - Confirm datacenter region (Singapore/Australia preferred) - Check latency to target users 3. [ ] **Check current VPS state**: - Is it a fresh install or has existing services? - Any data to backup before proceeding? - Current SSH access method (password or key?) **Commands to Run** (if you have SSH access): ```bash # Check OS version cat /etc/os-release # Check system resources free -h # RAM df -h # Disk space nproc # CPU cores ip addr show # Network interfaces systemctl list-units # Running services ``` **Decision Points**: - [ ] Fresh install or clean existing VPS? - [ ] Keep existing OS or reinstall Ubuntu 22.04 LTS? --- ### Day 0.2: Generate Secrets **Tasks**: 1. [ ] **Generate JWT Secret**: ```bash # On your local machine openssl rand -base64 48 ``` - Copy output (64 characters) - Store in password manager (1Password, Bitwarden, etc.) - Label: "Tractatus JWT_SECRET (Production)" 2. [ ] **Generate MongoDB Password**: ```bash openssl rand -base64 32 ``` - Copy output (44 characters) - Store in password manager - Label: "Tractatus MongoDB tractatus_user password" 3. [ ] **Generate MongoDB Root Password**: ```bash openssl rand -base64 32 ``` - Store in password manager - Label: "Tractatus MongoDB root password" 4. [ ] **Generate SSH Key Pair** (for Tractatus deployments): ```bash ssh-keygen -t ed25519 -C "tractatus-deploy@agenticgovernance.digital" -f ~/.ssh/tractatus_deploy ``` - Private key: `~/.ssh/tractatus_deploy` (keep secure) - Public key: `~/.ssh/tractatus_deploy.pub` (will add to VPS) **Security Checklist**: - [ ] All secrets stored in password manager (never in Git) - [ ] SSH private key has passphrase - [ ] Backup of password manager vault --- ### Day 0.3: DNS Preparation **Tasks**: 1. [ ] **Access OVHCloud DNS Management**: - Navigate to: Domains → agenticgovernance.digital → DNS Zone - Familiarize with interface 2. [ ] **Get VPS IP Address** from OVHCloud: - VPS Dashboard → vps-7f023e40.vps.ovh.net → IP Addresses - Note IPv4 address: `___.___.___.___ ` - Note IPv6 address (if available): `____:____:____:____` 3. [ ] **Prepare DNS Records** (don't configure yet, just prepare): ``` Type | Name | Value | TTL ------|------|-------------------|----- A | @ | | 300 (5 min for testing) A | www | | 300 AAAA | @ | | 300 (if available) AAAA | www | | 300 (if available) ``` **Note**: We'll configure DNS in Week 1 after server is ready. --- ### Day 0.4: Local Repository Preparation **Tasks**: 1. [ ] **Create production branch**: ```bash cd /home/theflow/projects/tractatus git checkout -b production git push -u origin production git checkout main ``` 2. [ ] **Create .env.production template**: ```bash cat > .env.production << 'EOF' # Tractatus Production Environment NODE_ENV=production PORT=9000 # Application APP_NAME=Tractatus APP_DOMAIN=agenticgovernance.digital APP_URL=https://agenticgovernance.digital # MongoDB MONGODB_URI=mongodb://tractatus_user:@localhost:27017/tractatus_prod?authSource=tractatus_prod MONGODB_PORT=27017 MONGODB_DATABASE=tractatus_prod # JWT JWT_SECRET= JWT_EXPIRY=7d # Claude API (Week 5+) CLAUDE_API_KEY= CLAUDE_MODEL=claude-sonnet-4-5-20250929 # Admin ADMIN_EMAIL=admin@agenticgovernance.digital # Security SESSION_SECRET= COOKIE_SECURE=true COOKIE_SAMESITE=strict EOF ``` 3. [ ] **Add .env.production to .gitignore**: ```bash echo ".env.production" >> .gitignore git add .gitignore git commit -m "chore: add .env.production to gitignore" ``` 4. [ ] **Test production build locally**: ```bash NODE_ENV=production npm start # Verify app starts without errors # Ctrl+C to stop ``` --- ## Week 1: Infrastructure Setup ### Day 1.1: Initial VPS Access & User Setup **Tasks**: 1. [ ] **Access VPS via SSH** (OVHCloud provides root access): ```bash ssh root@vps-7f023e40.vps.ovh.net # Or use IP: ssh root@ ``` 2. [ ] **Update system packages**: ```bash apt update && apt upgrade -y ``` 3. [ ] **Create non-root user**: ```bash adduser tractatus # Set password (use password manager to generate & store) # Full name: Tractatus Application # Leave other fields blank (press Enter) # Add to sudo group usermod -aG sudo tractatus ``` 4. [ ] **Set up SSH key authentication** for tractatus user: ```bash # Still as root mkdir -p /home/tractatus/.ssh chmod 700 /home/tractatus/.ssh # Copy your SSH public key (from Day 0.2) # On your LOCAL machine, copy the public key: cat ~/.ssh/tractatus_deploy.pub # Back on VPS, paste it: nano /home/tractatus/.ssh/authorized_keys # Paste the public key, save (Ctrl+O, Enter, Ctrl+X) chmod 600 /home/tractatus/.ssh/authorized_keys chown -R tractatus:tractatus /home/tractatus/.ssh ``` 5. [ ] **Test SSH access** as tractatus user: ```bash # From your LOCAL machine (new terminal): ssh -i ~/.ssh/tractatus_deploy tractatus@vps-7f023e04.vps.ovh.net # If successful, you should see tractatus@vps-7f023e40:~$ ``` 6. [ ] **Configure sudo without password** (for deployment automation): ```bash # On VPS, as root: visudo # Add this line at the end: tractatus ALL=(ALL) NOPASSWD:ALL # Save and exit (Ctrl+O, Enter, Ctrl+X if nano, or :wq if vim) ``` --- ### Day 1.2: Firewall & SSH Hardening **Tasks**: 1. [ ] **Install UFW (Uncomplicated Firewall)**: ```bash # As tractatus user on VPS: sudo apt install ufw -y ``` 2. [ ] **Configure UFW rules** (CRITICAL - don't lock yourself out): ```bash # Allow SSH from your current IP (safer) # Get your IP: curl ifconfig.me sudo ufw allow from to any port 22 # Or allow SSH from anywhere (less secure but more flexible): sudo ufw allow 22/tcp # Allow HTTP and HTTPS sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Check rules before enabling sudo ufw show added ``` 3. [ ] **Enable UFW**: ```bash sudo ufw enable # Type 'y' to confirm # Verify status sudo ufw status verbose ``` 4. [ ] **Harden SSH configuration**: ```bash sudo nano /etc/ssh/sshd_config # Find and modify these lines: PermitRootLogin no # Disable root login PasswordAuthentication no # Disable password auth PubkeyAuthentication yes # Enable key-based auth Port 22 # Keep default (or change to custom) MaxAuthTries 3 # Limit authentication attempts ClientAliveInterval 300 # Timeout idle sessions (5 min) ClientAliveCountMax 2 # Max missed keepalives # Save and exit ``` 5. [ ] **Restart SSH service**: ```bash sudo systemctl restart sshd # Verify SSH is still working (open NEW terminal, don't close current one): ssh -i ~/.ssh/tractatus_deploy tractatus@vps-7f023e40.vps.ovh.net ``` 6. [ ] **Install Fail2ban**: ```bash sudo apt install fail2ban -y # Create local configuration sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local # Edit configuration sudo nano /etc/fail2ban/jail.local # Find [sshd] section and modify: [sshd] enabled = true port = 22 maxretry = 3 bantime = 3600 findtime = 600 # Save and exit ``` 7. [ ] **Start Fail2ban**: ```bash sudo systemctl enable fail2ban sudo systemctl start fail2ban sudo fail2ban-client status sshd ``` --- ### Day 1.3: Install Node.js & Dependencies **Tasks**: 1. [ ] **Install Node.js 18 LTS** (via NodeSource): ```bash # Download and run NodeSource setup script curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - # Install Node.js sudo apt install nodejs -y # Verify installation node --version # Should show v18.x.x npm --version # Should show 9.x.x or 10.x.x ``` 2. [ ] **Install build tools** (needed for some npm packages): ```bash sudo apt install build-essential -y ``` 3. [ ] **Install Git**: ```bash sudo apt install git -y git --version ``` 4. [ ] **Install PM2** (process manager for Node.js): ```bash sudo npm install -g pm2 pm2 --version ``` 5. [ ] **Configure PM2 to start on boot**: ```bash pm2 startup systemd -u tractatus --hp /home/tractatus # Copy and run the command PM2 outputs (starts with 'sudo env PATH=...') ``` --- ### Day 1.4: Install & Configure MongoDB **Tasks**: 1. [ ] **Import MongoDB GPG key**: ```bash curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \ sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor ``` 2. [ ] **Add MongoDB repository**: ```bash echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \ sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list ``` 3. [ ] **Install MongoDB**: ```bash sudo apt update sudo apt install mongodb-org -y ``` 4. [ ] **Start MongoDB**: ```bash sudo systemctl start mongod sudo systemctl enable mongod sudo systemctl status mongod ``` 5. [ ] **Create MongoDB admin user**: ```bash mongosh # In MongoDB shell: use admin db.createUser({ user: "admin", pwd: "", roles: ["root"] }) # Exit MongoDB shell exit ``` 6. [ ] **Enable MongoDB authentication**: ```bash sudo nano /etc/mongod.conf # Find the security section and modify: security: authorization: enabled # Save and exit ``` 7. [ ] **Restart MongoDB**: ```bash sudo systemctl restart mongod ``` 8. [ ] **Create Tractatus database and user**: ```bash mongosh -u admin -p --authenticationDatabase admin # In MongoDB shell (enter admin password when prompted): use tractatus_prod db.createUser({ user: "tractatus_user", pwd: "", roles: [ { role: "readWrite", db: "tractatus_prod" }, { role: "dbAdmin", db: "tractatus_prod" } ] }) # Test authentication exit mongosh -u tractatus_user -p --authenticationDatabase tractatus_prod tractatus_prod # Enter tractatus_user password when prompted # If successful, you'll see tractatus_prod> prompt exit ``` --- ### Day 1.5: Install & Configure Nginx **Tasks**: 1. [ ] **Install Nginx**: ```bash sudo apt install nginx -y # Verify installation nginx -v sudo systemctl status nginx ``` 2. [ ] **Configure Nginx for Tractatus** (HTTP only, SSL in Day 1.6): ```bash sudo nano /etc/nginx/sites-available/tractatus # Paste this configuration: ``` ```nginx # Tractatus Production - HTTP Only (SSL will be added) server { listen 80; listen [::]:80; server_name agenticgovernance.digital www.agenticgovernance.digital; # Temporary: Redirect to show "Coming Soon" location / { return 200 'Tractatus Framework - Deploying...'; add_header Content-Type text/plain; } } ``` 3. [ ] **Enable the site**: ```bash sudo ln -s /etc/nginx/sites-available/tractatus /etc/nginx/sites-enabled/ # Remove default site sudo rm /etc/nginx/sites-enabled/default # Test configuration sudo nginx -t # Reload Nginx sudo systemctl reload nginx ``` 4. [ ] **Test Nginx** (from your local machine): ```bash # If DNS is configured: curl http://agenticgovernance.digital # Or use VPS IP: curl http:// # Should see: "Tractatus Framework - Deploying..." ``` --- ### Day 1.6: Configure DNS **Tasks**: 1. [ ] **Get VPS IP address**: ```bash # On VPS: ip addr show | grep 'inet ' # Note the public IPv4 (not 127.0.0.1) ``` 2. [ ] **Configure DNS in OVHCloud**: - Navigate to: Domains → agenticgovernance.digital → DNS Zone - Click "Add an entry" **Add A record**: - Type: A - Subdomain: (leave empty for @) - Target: - TTL: 300 (5 minutes for testing) **Add A record for www**: - Type: A - Subdomain: www - Target: - TTL: 300 3. [ ] **Wait for DNS propagation** (5-30 minutes): ```bash # From your LOCAL machine: dig agenticgovernance.digital +short # Should return VPS IP dig www.agenticgovernance.digital +short # Should return VPS IP # Or use: nslookup agenticgovernance.digital ``` 4. [ ] **Test DNS** with browser: - Visit: http://agenticgovernance.digital - Should see: "Tractatus Framework - Deploying..." --- ### Day 1.7: Install SSL/TLS with Let's Encrypt **Tasks**: 1. [ ] **Install Certbot**: ```bash sudo apt install certbot python3-certbot-nginx -y ``` 2. [ ] **Obtain SSL certificate**: ```bash sudo certbot --nginx -d agenticgovernance.digital -d www.agenticgovernance.digital # Follow prompts: # - Email: admin@agenticgovernance.digital # - Agree to Terms of Service: Yes (Y) # - Share email with EFF: Your choice (Y/N) # - Redirect HTTP to HTTPS: Yes (2) ``` 3. [ ] **Test SSL certificate**: - Visit: https://agenticgovernance.digital - Should see: "Tractatus Framework - Deploying..." (now HTTPS) - Check for padlock icon in browser 4. [ ] **Test auto-renewal**: ```bash sudo certbot renew --dry-run # Should complete without errors ``` 5. [ ] **Verify Nginx configuration**: ```bash sudo cat /etc/nginx/sites-available/tractatus # Should now include SSL configuration added by Certbot ``` --- ## Week 2: Application Deployment ### Day 2.1: Clone Repository & Setup **Tasks**: 1. [ ] **Create application directory**: ```bash # On VPS as tractatus user: sudo mkdir -p /var/www/tractatus sudo chown tractatus:tractatus /var/www/tractatus cd /var/www/tractatus ``` 2. [ ] **Clone repository**: ```bash # Option A: HTTPS (simpler, but need GitHub token for private repos) git clone https://github.com//tractatus.git . # Option B: SSH (requires SSH key setup on GitHub) # First, generate SSH key on VPS: ssh-keygen -t ed25519 -C "vps@agenticgovernance.digital" -f ~/.ssh/github_tractatus cat ~/.ssh/github_tractatus.pub # Add public key to GitHub: Settings → SSH Keys → New SSH Key git clone git@github.com:/tractatus.git . ``` 3. [ ] **Checkout production branch**: ```bash git checkout production git pull origin production ``` 4. [ ] **Install dependencies**: ```bash npm ci --production # Use 'ci' instead of 'install' for reproducible builds ``` --- ### Day 2.2: Configure Environment **Tasks**: 1. [ ] **Create production .env file**: ```bash nano /var/www/tractatus/.env # Paste (with secrets from Day 0.2): NODE_ENV=production PORT=9000 APP_NAME=Tractatus APP_DOMAIN=agenticgovernance.digital APP_URL=https://agenticgovernance.digital MONGODB_URI=mongodb://tractatus_user:@localhost:27017/tractatus_prod?authSource=tractatus_prod MONGODB_PORT=27017 MONGODB_DATABASE=tractatus_prod JWT_SECRET= JWT_EXPIRY=7d ADMIN_EMAIL=admin@agenticgovernance.digital SESSION_SECRET= COOKIE_SECURE=true COOKIE_SAMESITE=strict # Save and exit ``` 2. [ ] **Secure .env file**: ```bash chmod 600 /var/www/tractatus/.env chown tractatus:tractatus /var/www/tractatus/.env ``` 3. [ ] **Initialize MongoDB** (seed collections): ```bash cd /var/www/tractatus node scripts/init-db.js ``` 4. [ ] **Create admin user**: ```bash node scripts/seed-admin.js # Note the admin credentials output ``` --- ### Day 2.3: Configure Nginx Reverse Proxy **Tasks**: 1. [ ] **Update Nginx configuration**: ```bash sudo nano /etc/nginx/sites-available/tractatus ``` Replace with: ```nginx # Tractatus Production - Full Configuration upstream tractatus_backend { server 127.0.0.1:9000; keepalive 64; } # Redirect www to non-www server { listen 80; listen [::]:80; listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.agenticgovernance.digital; ssl_certificate /etc/letsencrypt/live/agenticgovernance.digital/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/agenticgovernance.digital/privkey.pem; return 301 https://agenticgovernance.digital$request_uri; } # Main server block server { listen 80; listen [::]:80; server_name agenticgovernance.digital; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name agenticgovernance.digital; # SSL Configuration ssl_certificate /etc/letsencrypt/live/agenticgovernance.digital/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/agenticgovernance.digital/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # Security Headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; # Content Security Policy add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';" always; # Root and index root /var/www/tractatus/public; index index.html; # Logging access_log /var/log/nginx/tractatus-access.log; error_log /var/log/nginx/tractatus-error.log; # Static files location /css { alias /var/www/tractatus/public/css; expires 1y; add_header Cache-Control "public, immutable"; } location /js { alias /var/www/tractatus/public/js; expires 1y; add_header Cache-Control "public, immutable"; } location /images { alias /var/www/tractatus/public/images; expires 1y; add_header Cache-Control "public, immutable"; } # Proxy to Node.js application location / { try_files $uri $uri/ @proxy; } location @proxy { proxy_pass http://tractatus_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; proxy_read_timeout 90; } # Health check endpoint location /health { proxy_pass http://tractatus_backend/health; access_log off; } } ``` 2. [ ] **Test Nginx configuration**: ```bash sudo nginx -t ``` 3. [ ] **Reload Nginx**: ```bash sudo systemctl reload nginx ``` --- ### Day 2.4: Start Application with PM2 **Tasks**: 1. [ ] **Create PM2 ecosystem file**: ```bash nano /var/www/tractatus/ecosystem.config.js ``` ```javascript module.exports = { apps: [{ name: 'tractatus', script: './src/server.js', instances: 2, exec_mode: 'cluster', env: { NODE_ENV: 'production' }, error_file: '/var/www/tractatus/logs/pm2-error.log', out_file: '/var/www/tractatus/logs/pm2-out.log', log_date_format: 'YYYY-MM-DD HH:mm:ss Z', max_memory_restart: '500M', autorestart: true, watch: false }] }; ``` 2. [ ] **Create logs directory**: ```bash mkdir -p /var/www/tractatus/logs ``` 3. [ ] **Start application**: ```bash cd /var/www/tractatus pm2 start ecosystem.config.js # Check status pm2 status # View logs pm2 logs tractatus --lines 50 ``` 4. [ ] **Save PM2 configuration**: ```bash pm2 save ``` 5. [ ] **Test application**: ```bash # Local test curl http://localhost:9000/health # Public test curl https://agenticgovernance.digital/health ``` 6. [ ] **Open browser and test**: - Visit: https://agenticgovernance.digital - Should see Tractatus homepage - Test navigation (Researcher, Implementer, Advocate paths) - Test demos (27027 incident, classification, boundary) --- ## Week 3: Security Hardening ### Day 3.1: Automated Security Updates **Tasks**: 1. [ ] **Install unattended-upgrades**: ```bash sudo apt install unattended-upgrades -y ``` 2. [ ] **Configure automatic updates**: ```bash sudo dpkg-reconfigure -plow unattended-upgrades # Select "Yes" to enable ``` 3. [ ] **Verify configuration**: ```bash sudo cat /etc/apt/apt.conf.d/20auto-upgrades # Should show: # APT::Periodic::Update-Package-Lists "1"; # APT::Periodic::Unattended-Upgrade "1"; ``` --- ### Day 3.2: Implement Rate Limiting **Tasks**: 1. [ ] **Configure Nginx rate limiting**: ```bash sudo nano /etc/nginx/nginx.conf # In http block, add: http { # ... existing config ... # Rate limiting zones limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=auth:10m rate=3r/m; # ... rest of config ... } ``` 2. [ ] **Apply rate limits in site config**: ```bash sudo nano /etc/nginx/sites-available/tractatus # Add to server block: # Rate limiting location /auth { limit_req zone=auth burst=5; proxy_pass http://tractatus_backend; # ... other proxy settings ... } location /api { limit_req zone=api burst=10 nodelay; proxy_pass http://tractatus_backend; # ... other proxy settings ... } location / { limit_req zone=general burst=20 nodelay; # ... existing config ... } ``` 3. [ ] **Test and reload**: ```bash sudo nginx -t sudo systemctl reload nginx ``` --- ### Day 3.3: Setup Automated Backups **Tasks**: 1. [ ] **Create backup script**: ```bash sudo nano /usr/local/bin/tractatus-backup.sh ``` ```bash #!/bin/bash # Tractatus MongoDB Backup Script BACKUP_DIR="/var/backups/tractatus" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="tractatus_backup_${DATE}.gz" RETENTION_DAYS=7 # Create backup directory mkdir -p $BACKUP_DIR # Dump MongoDB database mongodump --uri="mongodb://tractatus_user:@localhost:27017/tractatus_prod?authSource=tractatus_prod" \ --gzip --archive="${BACKUP_DIR}/${BACKUP_FILE}" # Remove old backups find $BACKUP_DIR -name "tractatus_backup_*.gz" -mtime +${RETENTION_DAYS} -delete # Log result echo "[$(date)] Backup completed: ${BACKUP_FILE}" >> /var/log/tractatus-backup.log ``` 2. [ ] **Make script executable**: ```bash sudo chmod +x /usr/local/bin/tractatus-backup.sh ``` 3. [ ] **Test backup script**: ```bash sudo /usr/local/bin/tractatus-backup.sh ls -lh /var/backups/tractatus/ ``` 4. [ ] **Schedule daily backups with cron**: ```bash sudo crontab -e # Add this line (runs daily at 2 AM): 0 2 * * * /usr/local/bin/tractatus-backup.sh ``` --- ### Day 3.4: Configure Fail2ban for Nginx **Tasks**: 1. [ ] **Create Nginx jail**: ```bash sudo nano /etc/fail2ban/jail.local # Add: [nginx-http-auth] enabled = true port = http,https logpath = /var/log/nginx/tractatus-error.log [nginx-limit-req] enabled = true port = http,https logpath = /var/log/nginx/tractatus-error.log findtime = 600 maxretry = 10 ``` 2. [ ] **Restart Fail2ban**: ```bash sudo systemctl restart fail2ban sudo fail2ban-client status ``` --- ## Week 4: Monitoring & Testing ### Day 4.1: Setup Error Monitoring (Sentry) **Tasks**: 1. [ ] **Create Sentry account** at sentry.io (free tier) 2. [ ] **Create new project**: - Platform: Node.js - Project name: tractatus-production 3. [ ] **Get DSN** (Data Source Name) from Sentry dashboard 4. [ ] **Install Sentry SDK**: ```bash cd /var/www/tractatus npm install @sentry/node --save ``` 5. [ ] **Add Sentry DSN to .env**: ```bash nano /var/www/tractatus/.env # Add: SENTRY_DSN= ``` 6. [ ] **Initialize Sentry in application**: ```bash nano /var/www/tractatus/src/server.js # Add at the top (after require statements): const Sentry = require('@sentry/node'); if (process.env.SENTRY_DSN) { Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV, tracesSampleRate: 0.1, // 10% of transactions }); } # Add Sentry error handler middleware (before other error handlers): app.use(Sentry.Handlers.errorHandler()); ``` 7. [ ] **Restart application**: ```bash pm2 restart tractatus ``` 8. [ ] **Test error tracking**: - Visit Sentry dashboard - Trigger a test error on the site - Verify error appears in Sentry --- ### Day 4.2: Setup Uptime Monitoring **Tasks**: 1. [ ] **Create UptimeRobot account** at uptimerobot.com (free tier) 2. [ ] **Add monitor**: - Monitor Type: HTTPS - Friendly Name: Tractatus Production - URL: https://agenticgovernance.digital/health - Monitoring Interval: 5 minutes 3. [ ] **Configure alerts**: - Email: admin@agenticgovernance.digital - Alert when: Down - Send notification: Immediately 4. [ ] **Test monitor**: - Stop PM2: `pm2 stop tractatus` - Wait for alert (5 minutes) - Restart: `pm2 start tractatus` - Verify "UP" notification --- ### Day 4.3: Performance Testing **Tasks**: 1. [ ] **Test Core Web Vitals**: - Visit: https://pagespeed.web.dev/ - Enter: https://agenticgovernance.digital - Run test for Mobile and Desktop - Target scores: >90 for all metrics 2. [ ] **Run Lighthouse audit** (Chrome DevTools): - Open Chrome DevTools (F12) - Lighthouse tab - Run audit (Desktop) - Check: Performance, Accessibility, Best Practices, SEO - Target: All >90 3. [ ] **Load testing with Apache Bench**: ```bash # On local machine: ab -n 1000 -c 10 https://agenticgovernance.digital/ # Should handle 1000 requests with 10 concurrent without errors ``` 4. [ ] **Check response times**: ```bash curl -w "@-" -o /dev/null -s https://agenticgovernance.digital/ <<'EOF' time_namelookup: %{time_namelookup}s\n time_connect: %{time_connect}s\n time_appconnect: %{time_appconnect}s\n time_pretransfer: %{time_pretransfer}s\n time_redirect: %{time_redirect}s\n time_starttransfer: %{time_starttransfer}s\n ----------\n time_total: %{time_total}s\n EOF # Target: time_total < 2.5s ``` --- ### Day 4.4: Security Audit **Tasks**: 1. [ ] **Run SSL Labs test**: - Visit: https://www.ssllabs.com/ssltest/ - Enter: agenticgovernance.digital - Target: A or A+ rating 2. [ ] **Check security headers**: - Visit: https://securityheaders.com/ - Enter: https://agenticgovernance.digital - Target: A or A+ rating 3. [ ] **Scan for vulnerabilities**: ```bash # On VPS: sudo apt install lynis -y sudo lynis audit system # Review warnings in: /var/log/lynis-report.dat ``` 4. [ ] **Check npm dependencies**: ```bash cd /var/www/tractatus npm audit # Fix any high/critical vulnerabilities: npm audit fix ``` --- ## Week 5-8: AI Features ### Week 5: Claude API Integration **Tasks**: 1. [ ] **Create Anthropic account** and obtain production API key 2. [ ] **Add Claude API key to .env**: ```bash nano /var/www/tractatus/.env # Add: CLAUDE_API_KEY= CLAUDE_MODEL=claude-sonnet-4-5-20250929 CLAUDE_MAX_TOKENS=4096 ``` 3. [ ] **Install Claude SDK**: ```bash cd /var/www/tractatus npm install @anthropic-ai/sdk --save ``` 4. [ ] **Deploy updated code**: ```bash git pull origin production npm install pm2 restart tractatus ``` 5. [ ] **Test Claude integration**: - Test blog topic suggestion endpoint - Monitor API usage in Anthropic dashboard - Verify rate limiting is working --- ### Week 6-7: Implement AI Features **Reference**: See PHASE-2-ROADMAP.md for detailed AI feature specifications **Tasks**: 1. [ ] **Blog Curation System**: - Implement topic suggestion API - Implement outline generation API - Create human approval workflow - Test end-to-end 2. [ ] **Media Inquiry Triage**: - Implement classification API - Implement draft response generator - Create moderation queue - Test all priority levels 3. [ ] **Case Study Portal**: - Implement submission form - Implement relevance analysis API - Create moderation workflow - Test publication pipeline --- ## Week 9-12: Soft Launch ### Week 9: Pre-Launch Testing **Tasks**: 1. [ ] **End-to-end testing** of all features 2. [ ] **Governance compliance audit** (verify TRA-OPS-* policies) 3. [ ] **User acceptance testing** (internal) 4. [ ] **Performance optimization** 5. [ ] **Final security review** --- ### Week 10: Soft Launch Preparation **Tasks**: 1. [ ] **Finalize invitation list** (20-50 users) 2. [ ] **Prepare email templates** (use PHASE-2-EMAIL-TEMPLATES.md) 3. [ ] **Create feedback survey** (Google Form or TypeForm) 4. [ ] **Set up analytics** (Plausible or privacy-respecting alternative) --- ### Week 11: Send Invitations **Tasks**: 1. [ ] **Send invitations** (personalized, BCC all recipients) 2. [ ] **Monitor responses** and platform usage 3. [ ] **Respond to inquiries** within SLAs 4. [ ] **Collect feedback** via survey --- ### Week 12: Iteration & Analysis **Tasks**: 1. [ ] **Analyze feedback** (quantitative + qualitative) 2. [ ] **Implement improvements** based on user input 3. [ ] **Prepare summary report** for Phase 2 completion 4. [ ] **Decision**: Proceed to Phase 3 (Public Launch) or extend soft launch --- ## Emergency Procedures ### Application Down ```bash # Check PM2 status pm2 status # View logs pm2 logs tractatus --lines 100 # Restart application pm2 restart tractatus # If persistent issues, check MongoDB sudo systemctl status mongod # Check Nginx sudo systemctl status nginx sudo nginx -t ``` --- ### Database Issues ```bash # Check MongoDB status sudo systemctl status mongod # View MongoDB logs sudo tail -f /var/log/mongodb/mongod.log # Restart MongoDB sudo systemctl restart mongod # Restore from backup mongorestore --uri="mongodb://tractatus_user:@localhost:27017/tractatus_prod?authSource=tractatus_prod" \ --gzip --archive=/var/backups/tractatus/tractatus_backup_YYYYMMDD_HHMMSS.gz ``` --- ### Server Compromised ```bash # Immediate actions: # 1. Take server offline sudo ufw deny 80/tcp sudo ufw deny 443/tcp # 2. Kill application pm2 stop all # 3. Review access logs sudo tail -n 1000 /var/log/nginx/tractatus-access.log sudo tail -n 1000 /var/log/auth.log # 4. Check for unauthorized users sudo cat /etc/passwd # 5. Review Fail2ban status sudo fail2ban-client status # 6. Contact OVHCloud support if needed ``` --- ### SSL Certificate Expiry ```bash # Check certificate expiry sudo certbot certificates # Renew manually sudo certbot renew # Test auto-renewal sudo certbot renew --dry-run # Reload Nginx sudo systemctl reload nginx ``` --- ## Rollback Procedures ### Rollback Application ```bash # Stop current version pm2 stop tractatus # Checkout previous version cd /var/www/tractatus git log --oneline -10 # Find commit hash git checkout # Reinstall dependencies npm ci --production # Restart pm2 start ecosystem.config.js pm2 save ``` --- ### Rollback Database ```bash # List available backups ls -lh /var/backups/tractatus/ # Restore specific backup mongorestore --uri="mongodb://tractatus_user:@localhost:27017/tractatus_prod?authSource=tractatus_prod" \ --drop \ --gzip --archive=/var/backups/tractatus/tractatus_backup_YYYYMMDD_HHMMSS.gz ``` --- ## Maintenance Schedule ### Daily - [ ] Check uptime monitoring (automated) - [ ] Review error logs (Sentry) - [ ] Monitor API usage (Anthropic dashboard) ### Weekly - [ ] Review Nginx access logs - [ ] Check disk space: `df -h` - [ ] Review PM2 logs - [ ] Check for security updates: `sudo apt update && sudo apt list --upgradable` ### Monthly - [ ] Review all backups (test restore) - [ ] Analyze analytics data - [ ] Review TRA-OPS-* compliance - [ ] Update dependencies: `npm outdated` ### Quarterly - [ ] Full security audit - [ ] Performance optimization review - [ ] Governance document review (TRA-OPS-*) - [ ] SSL certificate renewal check --- ## Useful Commands Reference ### PM2 ```bash pm2 status # Show all processes pm2 logs tractatus # View logs pm2 restart tractatus # Restart app pm2 reload tractatus # Zero-downtime reload pm2 stop tractatus # Stop app pm2 delete tractatus # Remove from PM2 pm2 monit # Monitor resources pm2 save # Save current config ``` ### Nginx ```bash sudo nginx -t # Test configuration sudo systemctl reload nginx # Reload (no downtime) sudo systemctl restart nginx # Restart (brief downtime) sudo systemctl status nginx # Check status sudo tail -f /var/log/nginx/tractatus-error.log # Watch errors ``` ### MongoDB ```bash sudo systemctl status mongod # Check status sudo systemctl restart mongod # Restart mongosh -u tractatus_user -p --authenticationDatabase tractatus_prod tractatus_prod # Connect ``` ### Git ```bash git status # Check working tree git pull origin production # Update code git log --oneline -10 # View recent commits git checkout # Rollback to commit ``` ### System ```bash df -h # Disk usage free -h # Memory usage top # CPU/process monitor sudo ufw status # Firewall status sudo fail2ban-client status # Fail2ban status ``` --- ## Document Status **Created**: 2025-10-07 **Last Updated**: 2025-10-07 **Status**: ACTIVE - Ready for deployment **Next Review**: After Week 4 completion --- **End of Deployment Guide**