ruvnet-kb-first 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +674 -0
- package/SKILL.md +740 -0
- package/bin/kb-first.js +123 -0
- package/install/init-project.sh +435 -0
- package/install/install-global.sh +257 -0
- package/install/kb-first-autodetect.sh +108 -0
- package/install/kb-first-command.md +80 -0
- package/install/kb-first-skill.md +262 -0
- package/package.json +87 -0
- package/phases/00-assessment.md +529 -0
- package/phases/01-storage.md +194 -0
- package/phases/01.5-hooks-setup.md +521 -0
- package/phases/02-kb-creation.md +413 -0
- package/phases/03-persistence.md +125 -0
- package/phases/04-visualization.md +170 -0
- package/phases/05-integration.md +114 -0
- package/phases/06-scaffold.md +130 -0
- package/phases/07-build.md +493 -0
- package/phases/08-verification.md +597 -0
- package/phases/09-security.md +512 -0
- package/phases/10-documentation.md +613 -0
- package/phases/11-deployment.md +670 -0
- package/phases/testing.md +713 -0
- package/scripts/1.5-hooks-verify.sh +252 -0
- package/scripts/8.1-code-scan.sh +58 -0
- package/scripts/8.2-import-check.sh +42 -0
- package/scripts/8.3-source-returns.sh +52 -0
- package/scripts/8.4-startup-verify.sh +65 -0
- package/scripts/8.5-fallback-check.sh +63 -0
- package/scripts/8.6-attribution.sh +56 -0
- package/scripts/8.7-confidence.sh +56 -0
- package/scripts/8.8-gap-logging.sh +70 -0
- package/scripts/9-security-audit.sh +202 -0
- package/scripts/init-project.sh +395 -0
- package/scripts/verify-enforcement.sh +167 -0
- package/src/commands/hooks.js +361 -0
- package/src/commands/init.js +315 -0
- package/src/commands/phase.js +372 -0
- package/src/commands/score.js +380 -0
- package/src/commands/status.js +193 -0
- package/src/commands/verify.js +286 -0
- package/src/index.js +56 -0
- package/src/mcp-server.js +412 -0
- package/templates/attention-router.ts +534 -0
- package/templates/code-analysis.ts +683 -0
- package/templates/federated-kb-learner.ts +649 -0
- package/templates/gnn-engine.ts +1091 -0
- package/templates/intentions.md +277 -0
- package/templates/kb-client.ts +905 -0
- package/templates/schema.sql +303 -0
- package/templates/sona-config.ts +312 -0
|
@@ -0,0 +1,670 @@
|
|
|
1
|
+
# Phase 11: Deployment Planning
|
|
2
|
+
|
|
3
|
+
Updated: 2026-01-02 00:25:00 EST | Version 1.0.0
|
|
4
|
+
Created: 2026-01-02 00:25:00 EST
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
Plan and execute production deployment with public access. This phase covers infrastructure setup, deployment automation, monitoring, and go-live procedures.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- Phase 10 complete (documentation and versioning ready)
|
|
15
|
+
- Security audit passed (Phase 9)
|
|
16
|
+
- All tests passing
|
|
17
|
+
- Domain name acquired (if applicable)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Why Deployment Planning Matters
|
|
22
|
+
|
|
23
|
+
A great application with poor deployment:
|
|
24
|
+
- Is unreliable and frustrating for users
|
|
25
|
+
- Costs more to operate than necessary
|
|
26
|
+
- Is difficult to update and maintain
|
|
27
|
+
- Creates security vulnerabilities
|
|
28
|
+
|
|
29
|
+
**Deploy right the first time. It's cheaper than fixing production issues.**
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Sub-Phases
|
|
34
|
+
|
|
35
|
+
| Sub-Phase | Name | Purpose |
|
|
36
|
+
|-----------|------|---------|
|
|
37
|
+
| 11.1 | Infrastructure Selection | Choose hosting platform |
|
|
38
|
+
| 11.2 | Environment Configuration | Production environment setup |
|
|
39
|
+
| 11.3 | CI/CD Pipeline | Automated deployment |
|
|
40
|
+
| 11.4 | Database Migration | Production DB setup |
|
|
41
|
+
| 11.5 | Monitoring & Alerting | Observability setup |
|
|
42
|
+
| 11.6 | Go-Live Checklist | Final verification |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 11.1 Infrastructure Selection
|
|
47
|
+
|
|
48
|
+
### Platform Options
|
|
49
|
+
|
|
50
|
+
| Platform | Best For | KB-First Considerations |
|
|
51
|
+
|----------|----------|-------------------------|
|
|
52
|
+
| **Railway** | Quick deployment, good DX | PostgreSQL add-on, auto-scaling |
|
|
53
|
+
| **Vercel** | Frontend + serverless | Need separate DB hosting |
|
|
54
|
+
| **Fly.io** | Global edge deployment | PostgreSQL included |
|
|
55
|
+
| **AWS/GCP/Azure** | Enterprise, full control | More setup, more flexibility |
|
|
56
|
+
| **Docker + VPS** | Cost control, simplicity | Manual scaling |
|
|
57
|
+
|
|
58
|
+
### Recommended: Railway
|
|
59
|
+
|
|
60
|
+
For KB-First applications, Railway is recommended because:
|
|
61
|
+
- Native PostgreSQL with pgvector support
|
|
62
|
+
- Simple deployment from git
|
|
63
|
+
- Automatic HTTPS
|
|
64
|
+
- Easy environment variable management
|
|
65
|
+
- Reasonable pricing
|
|
66
|
+
|
|
67
|
+
### Infrastructure Checklist
|
|
68
|
+
|
|
69
|
+
| Component | Requirement | Notes |
|
|
70
|
+
|-----------|-------------|-------|
|
|
71
|
+
| Compute | 1+ vCPU, 1GB+ RAM | Scale based on load |
|
|
72
|
+
| Database | PostgreSQL 15+ with pgvector | Persistent storage |
|
|
73
|
+
| CDN | Optional | For static assets |
|
|
74
|
+
| Domain | Custom domain | Required for production |
|
|
75
|
+
| SSL | HTTPS required | Usually automatic |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 11.2 Environment Configuration
|
|
80
|
+
|
|
81
|
+
### Production Environment Variables
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Required
|
|
85
|
+
DATABASE_URL=postgres://user:pass@host:5432/dbname?sslmode=require
|
|
86
|
+
NODE_ENV=production
|
|
87
|
+
PORT=3000
|
|
88
|
+
|
|
89
|
+
# Authentication
|
|
90
|
+
JWT_SECRET=<random-256-bit-hex>
|
|
91
|
+
JWT_EXPIRY=1h
|
|
92
|
+
REFRESH_TOKEN_EXPIRY=7d
|
|
93
|
+
|
|
94
|
+
# Security
|
|
95
|
+
ALLOWED_ORIGINS=https://yourdomain.com
|
|
96
|
+
RATE_LIMIT_WINDOW_MS=900000
|
|
97
|
+
RATE_LIMIT_MAX=100
|
|
98
|
+
|
|
99
|
+
# KB Configuration
|
|
100
|
+
KB_DEFAULT_NAMESPACE=production
|
|
101
|
+
KB_GAP_LOGGING=true
|
|
102
|
+
KB_MIN_CONFIDENCE=0.5
|
|
103
|
+
|
|
104
|
+
# Monitoring (optional but recommended)
|
|
105
|
+
SENTRY_DSN=https://...@sentry.io/...
|
|
106
|
+
LOG_LEVEL=info
|
|
107
|
+
|
|
108
|
+
# External Services (if applicable)
|
|
109
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
110
|
+
OPENAI_API_KEY=sk-...
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Environment File Template
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Create .env.production.template (commit this)
|
|
117
|
+
DATABASE_URL=
|
|
118
|
+
NODE_ENV=production
|
|
119
|
+
PORT=3000
|
|
120
|
+
JWT_SECRET=
|
|
121
|
+
ALLOWED_ORIGINS=
|
|
122
|
+
KB_DEFAULT_NAMESPACE=production
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Secrets Management
|
|
126
|
+
|
|
127
|
+
| Secret | Storage Method |
|
|
128
|
+
|--------|----------------|
|
|
129
|
+
| DATABASE_URL | Platform secrets (Railway, Vercel, etc.) |
|
|
130
|
+
| JWT_SECRET | Platform secrets |
|
|
131
|
+
| API Keys | Platform secrets |
|
|
132
|
+
|
|
133
|
+
**Never commit secrets to git. Use platform-provided secrets management.**
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 11.3 CI/CD Pipeline
|
|
138
|
+
|
|
139
|
+
### GitHub Actions Workflow
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
# .github/workflows/deploy.yml
|
|
143
|
+
name: Deploy to Production
|
|
144
|
+
|
|
145
|
+
on:
|
|
146
|
+
push:
|
|
147
|
+
branches: [main]
|
|
148
|
+
workflow_dispatch:
|
|
149
|
+
|
|
150
|
+
env:
|
|
151
|
+
NODE_VERSION: '20'
|
|
152
|
+
|
|
153
|
+
jobs:
|
|
154
|
+
test:
|
|
155
|
+
runs-on: ubuntu-latest
|
|
156
|
+
steps:
|
|
157
|
+
- uses: actions/checkout@v4
|
|
158
|
+
|
|
159
|
+
- name: Setup Node.js
|
|
160
|
+
uses: actions/setup-node@v4
|
|
161
|
+
with:
|
|
162
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
163
|
+
cache: 'npm'
|
|
164
|
+
|
|
165
|
+
- name: Install dependencies
|
|
166
|
+
run: npm ci
|
|
167
|
+
|
|
168
|
+
- name: Run tests
|
|
169
|
+
run: npm test
|
|
170
|
+
|
|
171
|
+
- name: Run security audit
|
|
172
|
+
run: npm audit --audit-level=high
|
|
173
|
+
|
|
174
|
+
security:
|
|
175
|
+
runs-on: ubuntu-latest
|
|
176
|
+
needs: test
|
|
177
|
+
steps:
|
|
178
|
+
- uses: actions/checkout@v4
|
|
179
|
+
|
|
180
|
+
- name: Run security checks
|
|
181
|
+
run: |
|
|
182
|
+
chmod +x scripts/9.*.sh
|
|
183
|
+
./scripts/9.3-sql-injection.sh
|
|
184
|
+
./scripts/9.5-secrets-scan.sh
|
|
185
|
+
|
|
186
|
+
kb-verify:
|
|
187
|
+
runs-on: ubuntu-latest
|
|
188
|
+
needs: test
|
|
189
|
+
steps:
|
|
190
|
+
- uses: actions/checkout@v4
|
|
191
|
+
|
|
192
|
+
- name: Run KB verification
|
|
193
|
+
run: |
|
|
194
|
+
chmod +x scripts/8.*.sh
|
|
195
|
+
./scripts/8.1-code-scan.sh
|
|
196
|
+
./scripts/8.2-import-check.sh
|
|
197
|
+
|
|
198
|
+
deploy:
|
|
199
|
+
runs-on: ubuntu-latest
|
|
200
|
+
needs: [test, security, kb-verify]
|
|
201
|
+
if: github.ref == 'refs/heads/main'
|
|
202
|
+
steps:
|
|
203
|
+
- uses: actions/checkout@v4
|
|
204
|
+
|
|
205
|
+
# Railway deployment
|
|
206
|
+
- name: Deploy to Railway
|
|
207
|
+
uses: bervProject/railway-deploy@main
|
|
208
|
+
with:
|
|
209
|
+
railway_token: ${{ secrets.RAILWAY_TOKEN }}
|
|
210
|
+
service: ${{ secrets.RAILWAY_SERVICE }}
|
|
211
|
+
|
|
212
|
+
# Or Vercel deployment
|
|
213
|
+
# - name: Deploy to Vercel
|
|
214
|
+
# uses: amondnet/vercel-action@v25
|
|
215
|
+
# with:
|
|
216
|
+
# vercel-token: ${{ secrets.VERCEL_TOKEN }}
|
|
217
|
+
# vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
|
|
218
|
+
# vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
|
|
219
|
+
# vercel-args: '--prod'
|
|
220
|
+
|
|
221
|
+
- name: Verify deployment
|
|
222
|
+
run: |
|
|
223
|
+
sleep 30
|
|
224
|
+
curl -f https://yourdomain.com/health || exit 1
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Deployment Verification
|
|
228
|
+
|
|
229
|
+
After each deployment, verify:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
#!/bin/bash
|
|
233
|
+
# scripts/verify-deployment.sh
|
|
234
|
+
|
|
235
|
+
DOMAIN=${1:-"https://yourdomain.com"}
|
|
236
|
+
|
|
237
|
+
echo "Verifying deployment at $DOMAIN"
|
|
238
|
+
|
|
239
|
+
# Health check
|
|
240
|
+
echo -n "Health check: "
|
|
241
|
+
if curl -sf "$DOMAIN/health" > /dev/null; then
|
|
242
|
+
echo "✅ PASS"
|
|
243
|
+
else
|
|
244
|
+
echo "❌ FAIL"
|
|
245
|
+
exit 1
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
# DB connectivity
|
|
249
|
+
echo -n "Database: "
|
|
250
|
+
HEALTH=$(curl -sf "$DOMAIN/health/db")
|
|
251
|
+
if echo "$HEALTH" | grep -q "ok"; then
|
|
252
|
+
echo "✅ PASS"
|
|
253
|
+
else
|
|
254
|
+
echo "❌ FAIL"
|
|
255
|
+
exit 1
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
# KB accessible
|
|
259
|
+
echo -n "KB: "
|
|
260
|
+
KB_HEALTH=$(curl -sf "$DOMAIN/health/kb")
|
|
261
|
+
if echo "$KB_HEALTH" | grep -q "ok"; then
|
|
262
|
+
echo "✅ PASS"
|
|
263
|
+
else
|
|
264
|
+
echo "❌ FAIL"
|
|
265
|
+
exit 1
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
echo ""
|
|
269
|
+
echo "Deployment verified successfully!"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 11.4 Database Migration
|
|
275
|
+
|
|
276
|
+
### Production Database Setup
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# 1. Create production database
|
|
280
|
+
# (Usually done through platform UI)
|
|
281
|
+
|
|
282
|
+
# 2. Run migrations
|
|
283
|
+
npm run migrate:production
|
|
284
|
+
|
|
285
|
+
# 3. Verify schema
|
|
286
|
+
psql $DATABASE_URL -c "\dt kb_*"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Migration Script
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// src/db/migrate.ts
|
|
293
|
+
import { Pool } from 'pg';
|
|
294
|
+
import fs from 'fs';
|
|
295
|
+
import path from 'path';
|
|
296
|
+
|
|
297
|
+
async function migrate() {
|
|
298
|
+
const pool = new Pool({
|
|
299
|
+
connectionString: process.env.DATABASE_URL,
|
|
300
|
+
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
// Create migrations table
|
|
305
|
+
await pool.query(`
|
|
306
|
+
CREATE TABLE IF NOT EXISTS migrations (
|
|
307
|
+
id SERIAL PRIMARY KEY,
|
|
308
|
+
name TEXT NOT NULL UNIQUE,
|
|
309
|
+
applied_at TIMESTAMPTZ DEFAULT NOW()
|
|
310
|
+
)
|
|
311
|
+
`);
|
|
312
|
+
|
|
313
|
+
// Get applied migrations
|
|
314
|
+
const { rows: applied } = await pool.query('SELECT name FROM migrations');
|
|
315
|
+
const appliedSet = new Set(applied.map(r => r.name));
|
|
316
|
+
|
|
317
|
+
// Get migration files
|
|
318
|
+
const migrationsDir = path.join(__dirname, 'migrations');
|
|
319
|
+
const files = fs.readdirSync(migrationsDir).sort();
|
|
320
|
+
|
|
321
|
+
for (const file of files) {
|
|
322
|
+
if (appliedSet.has(file)) continue;
|
|
323
|
+
|
|
324
|
+
console.log(`Applying migration: ${file}`);
|
|
325
|
+
const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf-8');
|
|
326
|
+
|
|
327
|
+
await pool.query('BEGIN');
|
|
328
|
+
try {
|
|
329
|
+
await pool.query(sql);
|
|
330
|
+
await pool.query('INSERT INTO migrations (name) VALUES ($1)', [file]);
|
|
331
|
+
await pool.query('COMMIT');
|
|
332
|
+
console.log(` ✅ Applied: ${file}`);
|
|
333
|
+
} catch (err) {
|
|
334
|
+
await pool.query('ROLLBACK');
|
|
335
|
+
throw err;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
console.log('All migrations applied successfully');
|
|
340
|
+
} finally {
|
|
341
|
+
await pool.end();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
migrate().catch(console.error);
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### KB Data Migration
|
|
349
|
+
|
|
350
|
+
If migrating KB data from development to production:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# Export from development
|
|
354
|
+
pg_dump $DEV_DATABASE_URL -t kb_nodes -t kb_gaps --data-only > kb_data.sql
|
|
355
|
+
|
|
356
|
+
# Import to production
|
|
357
|
+
psql $PROD_DATABASE_URL < kb_data.sql
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## 11.5 Monitoring & Alerting
|
|
363
|
+
|
|
364
|
+
### Health Endpoints
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
// src/api/health.ts
|
|
368
|
+
import { Router } from 'express';
|
|
369
|
+
import { pool } from '../db';
|
|
370
|
+
import { kb } from '../kb';
|
|
371
|
+
|
|
372
|
+
const router = Router();
|
|
373
|
+
|
|
374
|
+
// Basic health
|
|
375
|
+
router.get('/health', (req, res) => {
|
|
376
|
+
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// Database health
|
|
380
|
+
router.get('/health/db', async (req, res) => {
|
|
381
|
+
try {
|
|
382
|
+
await pool.query('SELECT 1');
|
|
383
|
+
res.json({ status: 'ok', database: 'connected' });
|
|
384
|
+
} catch (err) {
|
|
385
|
+
res.status(503).json({ status: 'error', database: 'disconnected' });
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// KB health
|
|
390
|
+
router.get('/health/kb', async (req, res) => {
|
|
391
|
+
try {
|
|
392
|
+
const result = await kb.verifyConnection();
|
|
393
|
+
if (result) {
|
|
394
|
+
const { rows } = await pool.query('SELECT COUNT(*) FROM kb_nodes');
|
|
395
|
+
res.json({
|
|
396
|
+
status: 'ok',
|
|
397
|
+
kb: 'connected',
|
|
398
|
+
nodeCount: parseInt(rows[0].count)
|
|
399
|
+
});
|
|
400
|
+
} else {
|
|
401
|
+
res.status(503).json({ status: 'error', kb: 'unavailable' });
|
|
402
|
+
}
|
|
403
|
+
} catch (err) {
|
|
404
|
+
res.status(503).json({ status: 'error', kb: 'error' });
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
export default router;
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Logging
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
// src/lib/logger.ts
|
|
415
|
+
import pino from 'pino';
|
|
416
|
+
|
|
417
|
+
export const logger = pino({
|
|
418
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
419
|
+
transport: process.env.NODE_ENV === 'development'
|
|
420
|
+
? { target: 'pino-pretty' }
|
|
421
|
+
: undefined,
|
|
422
|
+
redact: ['password', 'token', 'authorization', 'cookie']
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Usage
|
|
426
|
+
logger.info({ query, results: results.length }, 'KB search completed');
|
|
427
|
+
logger.error({ err, query }, 'KB search failed');
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Metrics (Prometheus)
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
// src/lib/metrics.ts
|
|
434
|
+
import promClient from 'prom-client';
|
|
435
|
+
|
|
436
|
+
// Enable default metrics
|
|
437
|
+
promClient.collectDefaultMetrics();
|
|
438
|
+
|
|
439
|
+
// Custom metrics
|
|
440
|
+
export const kbSearchDuration = new promClient.Histogram({
|
|
441
|
+
name: 'kb_search_duration_seconds',
|
|
442
|
+
help: 'Duration of KB searches',
|
|
443
|
+
buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5]
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
export const kbGapTotal = new promClient.Counter({
|
|
447
|
+
name: 'kb_gap_total',
|
|
448
|
+
help: 'Total number of KB gaps detected'
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
export const kbNodeCount = new promClient.Gauge({
|
|
452
|
+
name: 'kb_node_count',
|
|
453
|
+
help: 'Current number of KB nodes'
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Metrics endpoint
|
|
457
|
+
router.get('/metrics', async (req, res) => {
|
|
458
|
+
res.set('Content-Type', promClient.register.contentType);
|
|
459
|
+
res.end(await promClient.register.metrics());
|
|
460
|
+
});
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Alerting Rules
|
|
464
|
+
|
|
465
|
+
| Metric | Threshold | Severity | Action |
|
|
466
|
+
|--------|-----------|----------|--------|
|
|
467
|
+
| Health check fails | 3 consecutive | Critical | Page on-call |
|
|
468
|
+
| Response time > 2s | 5 min avg | Warning | Investigate |
|
|
469
|
+
| Error rate > 1% | 5 min avg | Warning | Investigate |
|
|
470
|
+
| KB gaps > 100/day | Daily | Info | Review gaps |
|
|
471
|
+
| DB connections > 80% | Current | Warning | Scale DB |
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## 11.6 Go-Live Checklist
|
|
476
|
+
|
|
477
|
+
### Pre-Launch (24 hours before)
|
|
478
|
+
|
|
479
|
+
- [ ] All tests passing in production environment
|
|
480
|
+
- [ ] Database migrations applied
|
|
481
|
+
- [ ] KB data verified (node count, search working)
|
|
482
|
+
- [ ] SSL certificate valid
|
|
483
|
+
- [ ] DNS configured correctly
|
|
484
|
+
- [ ] Monitoring dashboards set up
|
|
485
|
+
- [ ] Alerting configured and tested
|
|
486
|
+
- [ ] Rollback plan documented
|
|
487
|
+
- [ ] Team notified of launch time
|
|
488
|
+
|
|
489
|
+
### Launch Day
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
#!/bin/bash
|
|
493
|
+
# scripts/go-live.sh
|
|
494
|
+
|
|
495
|
+
echo "=== Go-Live Checklist ==="
|
|
496
|
+
echo ""
|
|
497
|
+
|
|
498
|
+
# 1. Verify production environment
|
|
499
|
+
echo "1. Checking production environment..."
|
|
500
|
+
./scripts/verify-deployment.sh https://yourdomain.com
|
|
501
|
+
if [ $? -ne 0 ]; then
|
|
502
|
+
echo "❌ Deployment verification failed"
|
|
503
|
+
exit 1
|
|
504
|
+
fi
|
|
505
|
+
|
|
506
|
+
# 2. Run smoke tests
|
|
507
|
+
echo ""
|
|
508
|
+
echo "2. Running smoke tests..."
|
|
509
|
+
npm run test:smoke
|
|
510
|
+
if [ $? -ne 0 ]; then
|
|
511
|
+
echo "❌ Smoke tests failed"
|
|
512
|
+
exit 1
|
|
513
|
+
fi
|
|
514
|
+
|
|
515
|
+
# 3. Verify KB
|
|
516
|
+
echo ""
|
|
517
|
+
echo "3. Verifying KB..."
|
|
518
|
+
curl -s https://yourdomain.com/api/search -X POST \
|
|
519
|
+
-H "Content-Type: application/json" \
|
|
520
|
+
-d '{"query": "test query", "limit": 1}' | jq .
|
|
521
|
+
|
|
522
|
+
# 4. Check monitoring
|
|
523
|
+
echo ""
|
|
524
|
+
echo "4. Verify monitoring is receiving data..."
|
|
525
|
+
echo " - Check Prometheus/Grafana dashboards"
|
|
526
|
+
echo " - Verify alerts are configured"
|
|
527
|
+
|
|
528
|
+
# 5. Final confirmation
|
|
529
|
+
echo ""
|
|
530
|
+
echo "================================================"
|
|
531
|
+
echo "Pre-launch checks complete!"
|
|
532
|
+
echo ""
|
|
533
|
+
echo "To go live:"
|
|
534
|
+
echo " 1. Update DNS to point to production"
|
|
535
|
+
echo " 2. Remove any maintenance page"
|
|
536
|
+
echo " 3. Announce launch"
|
|
537
|
+
echo ""
|
|
538
|
+
echo "Post-launch:"
|
|
539
|
+
echo " - Monitor dashboards for 30 minutes"
|
|
540
|
+
echo " - Check error rates"
|
|
541
|
+
echo " - Verify user access"
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Post-Launch (First 24 hours)
|
|
545
|
+
|
|
546
|
+
- [ ] Monitor error rates
|
|
547
|
+
- [ ] Monitor response times
|
|
548
|
+
- [ ] Check KB search quality
|
|
549
|
+
- [ ] Review first user feedback
|
|
550
|
+
- [ ] Document any issues encountered
|
|
551
|
+
- [ ] Celebrate! 🎉
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
## Rollback Procedure
|
|
556
|
+
|
|
557
|
+
If issues are discovered after launch:
|
|
558
|
+
|
|
559
|
+
### Quick Rollback (< 5 minutes)
|
|
560
|
+
|
|
561
|
+
```bash
|
|
562
|
+
# 1. Revert to previous deployment
|
|
563
|
+
railway rollback # or equivalent for your platform
|
|
564
|
+
|
|
565
|
+
# 2. Verify rollback
|
|
566
|
+
./scripts/verify-deployment.sh https://yourdomain.com
|
|
567
|
+
|
|
568
|
+
# 3. Notify team
|
|
569
|
+
echo "Rollback completed at $(date)"
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Database Rollback
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
# If DB changes need reverting
|
|
576
|
+
# (Requires pre-migration backup)
|
|
577
|
+
|
|
578
|
+
# 1. Stop application
|
|
579
|
+
railway stop
|
|
580
|
+
|
|
581
|
+
# 2. Restore database
|
|
582
|
+
psql $DATABASE_URL < backup_before_migration.sql
|
|
583
|
+
|
|
584
|
+
# 3. Deploy previous version
|
|
585
|
+
git revert HEAD
|
|
586
|
+
git push
|
|
587
|
+
|
|
588
|
+
# 4. Restart and verify
|
|
589
|
+
railway restart
|
|
590
|
+
./scripts/verify-deployment.sh
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
## Public Access Configuration
|
|
596
|
+
|
|
597
|
+
### Custom Domain Setup
|
|
598
|
+
|
|
599
|
+
1. **DNS Configuration**
|
|
600
|
+
```
|
|
601
|
+
Type: CNAME
|
|
602
|
+
Name: app (or @)
|
|
603
|
+
Value: [platform-provided-domain]
|
|
604
|
+
TTL: 300
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
2. **SSL Certificate**
|
|
608
|
+
- Most platforms auto-provision Let's Encrypt
|
|
609
|
+
- Verify HTTPS works before going live
|
|
610
|
+
|
|
611
|
+
3. **Security Headers**
|
|
612
|
+
```typescript
|
|
613
|
+
app.use(helmet({
|
|
614
|
+
contentSecurityPolicy: {
|
|
615
|
+
directives: {
|
|
616
|
+
defaultSrc: ["'self'"],
|
|
617
|
+
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
618
|
+
scriptSrc: ["'self'"],
|
|
619
|
+
imgSrc: ["'self'", "data:", "https:"],
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
hsts: {
|
|
623
|
+
maxAge: 31536000,
|
|
624
|
+
includeSubDomains: true,
|
|
625
|
+
preload: true
|
|
626
|
+
}
|
|
627
|
+
}));
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## Quality Gate Checklist
|
|
633
|
+
|
|
634
|
+
Before going live, verify:
|
|
635
|
+
|
|
636
|
+
- [ ] Infrastructure provisioned and configured
|
|
637
|
+
- [ ] All environment variables set
|
|
638
|
+
- [ ] CI/CD pipeline working
|
|
639
|
+
- [ ] Database migrated with production data
|
|
640
|
+
- [ ] Monitoring and alerting configured
|
|
641
|
+
- [ ] Health endpoints responding
|
|
642
|
+
- [ ] SSL/HTTPS working
|
|
643
|
+
- [ ] Custom domain configured
|
|
644
|
+
- [ ] Go-live checklist completed
|
|
645
|
+
- [ ] Rollback procedure documented and tested
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
649
|
+
## Exit Criteria
|
|
650
|
+
|
|
651
|
+
Application is deployed to production with:
|
|
652
|
+
- Public access via custom domain
|
|
653
|
+
- Monitoring and alerting active
|
|
654
|
+
- Rollback procedure ready
|
|
655
|
+
- Team trained on operations
|
|
656
|
+
|
|
657
|
+
**The application is now live! 🚀**
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Post-Launch Operations
|
|
662
|
+
|
|
663
|
+
After launch, establish ongoing processes:
|
|
664
|
+
|
|
665
|
+
1. **Daily**: Check dashboards, review errors
|
|
666
|
+
2. **Weekly**: Review KB gaps, update knowledge
|
|
667
|
+
3. **Monthly**: Security updates, dependency updates
|
|
668
|
+
4. **Quarterly**: Performance review, capacity planning
|
|
669
|
+
|
|
670
|
+
See the Operator Guide (Phase 10.5) for detailed procedures.
|