diff --git a/docs/implementation/trinity-console-2-implementation-guide.md b/docs/implementation/trinity-console-2-implementation-guide.md
new file mode 100644
index 0000000..aabc26f
--- /dev/null
+++ b/docs/implementation/trinity-console-2-implementation-guide.md
@@ -0,0 +1,1776 @@
+# Trinity Console 2.0 — Complete Implementation Guide
+
+**Version:** 1.0
+**Created:** April 5, 2026
+**Authors:** Michael (The Wizard), Claude (Chronicler #61), Gemini (Architectural Partner)
+**Purpose:** Cold-start handoff document — any AI or developer can implement Trinity Console 2.0 from this single document.
+
+---
+
+## Table of Contents
+
+1. [Project Overview](#1-project-overview)
+2. [Architecture Decisions](#2-architecture-decisions)
+3. [Complete File Structure](#3-complete-file-structure)
+4. [Database Migrations](#4-database-migrations)
+5. [Core Engine Code](#5-core-engine-code)
+6. [RBAC System Code](#6-rbac-system-code)
+7. [Feature Flags Code](#7-feature-flags-code)
+8. [Authentication System](#8-authentication-system)
+9. [Branding & Design System](#9-branding--design-system)
+10. [Example Module (Dashboard)](#10-example-module-dashboard)
+11. [Deployment Infrastructure](#11-deployment-infrastructure)
+12. [Implementation Checklist](#12-implementation-checklist)
+13. [Migration from Arbiter 3.5](#13-migration-from-arbiter-35)
+
+---
+
+## 1. Project Overview
+
+### What is Trinity Console 2.0?
+
+Trinity Console is the admin panel for Firefrost Gaming, a subscription-based modded Minecraft server community. Version 2.0 is a complete architectural rewrite from a monolithic Express app to a modular plugin-based system.
+
+### The Trinity (Users)
+
+| Name | Role | Username | Default Permission Set |
+|------|------|----------|------------------------|
+| Michael | The Wizard (Owner) | Frostystyle | Admin (full access) |
+| Meg | The Emissary (Community) | Gingerfury | Community (player management) |
+| Holly | The Catalyst (Builder) | unicorn20089 | Builder (server/infrastructure) |
+
+### Key Characteristics
+
+- **Stack:** Node.js 20, Express, HTMX, Tailwind CSS, PostgreSQL, EJS
+- **Auth:** Discord OAuth (only Trinity staff can access)
+- **Design:** Dark theme with Firefrost branding (Fire/Frost/Arcane colors)
+- **Deployment:** Hybrid (Dev VPS for development, Command Center for production)
+
+### Brand Colors
+
+| Name | Hex | CSS Variable | Usage |
+|------|-----|--------------|-------|
+| Fire | `#FF6B35` | `fire` | Fire path, energy, CTAs |
+| Frost | `#4ECDC4` | `frost` | Frost path, calm, info |
+| Arcane | `#A855F7` | `arcane` | Trinity/founder elements |
+| Gold | `#FFD700` | `gold` | Highlights, achievements |
+| Void (Dark) | `#0F0F1E` | `void` | Backgrounds |
+| Void Surface | `#16162C` | `void-surface` | Cards, panels |
+| Void Hover | `#1D1D3A` | `void-hover` | Hover states |
+| Void Border | `#2A2A4A` | `void-border` | Dividers |
+
+---
+
+## 2. Architecture Decisions
+
+### Module System
+
+- **12 consolidated modules** (not 35 thin ones)
+- **Discovery:** `fs.readdirSync` on startup scans `src/modules/`
+- **Load order:** Topological sort based on dependencies, fatal on circular deps
+- **Hot reload:** Skip — nodemon restart is acceptable
+- **Communication:** Shared DB pool + EventEmitter (`core.events.emit`)
+
+### Modules List
+
+| # | Module ID | Name | Contains |
+|---|-----------|------|----------|
+| 1 | dashboard | Dashboard | Overview, stats, quick actions |
+| 2 | players | Players | Subscribers, bans, support, community notes, grace period, role audit |
+| 3 | servers | Servers & Scheduling | Game servers, scheduler, whitelist sync |
+| 4 | infrastructure | Infrastructure | Server inventory, services, domains, backups |
+| 5 | financials | Financials | MRR/ARR, transactions, projections, expenses |
+| 6 | tasks | Tasks | Work tracking, assignments, blockers, comments |
+| 7 | docs | Docs | Ops manual editing via Gitea API, handoffs |
+| 8 | team | Team | Staff roster, availability, calendar |
+| 9 | marketing | Marketing | Social embeds/webhooks, announcements, assets |
+| 10 | chroniclers | Chroniclers | Lineage tracking, memorials, portraits, Codex status |
+| 11 | system | System | Modules mgmt, permissions, users, audit log, settings, feature flags, About page |
+| 12 | health | Health | Uptime Kuma webhook integration, deadman's switch alerts |
+
+### RBAC (Role-Based Access Control)
+
+- **Model:** Roles + Direct Overrides (Option C)
+- **Resolution:** Overrides → Role → Default Deny
+- **Wildcards:** Store `tasks.*` as literal, resolve in middleware
+
+### Versioning
+
+- **Platform:** Trinity Console 2.0
+- **Migrated modules:** Start at 1.0.0
+- **New modules:** Start at 0.1.0 until stable
+
+### Deployment Strategy (Strangler Fig)
+
+1. Develop on Dev VPS (64.50.188.128)
+2. Connect to Command Center's PostgreSQL (63.143.34.217)
+3. Migrate one module at a time
+4. Old routes coexist with new until verified
+5. Promote to Command Center when stable
+6. Dev VPS becomes permanent staging
+
+---
+
+## 3. Complete File Structure
+
+```
+/opt/trinity-console/
+├── ecosystem.config.js # PM2 configuration
+├── package.json
+├── .env # Environment variables
+├── tailwind.config.js # Tailwind with Firefrost colors
+│
+├── migrations/ # Core database migrations (run manually first)
+│ ├── 001_rbac_tables.sql
+│ ├── 002_feature_flags.sql
+│ └── 003_auth_users.sql
+│
+├── public/
+│ └── css/
+│ └── output.css # Compiled Tailwind
+│
+├── views/
+│ └── layout.ejs # Master layout with sidebar
+│
+└── src/
+ ├── index.js # Main entry point
+ ├── db.js # PostgreSQL pool
+ │
+ ├── core/
+ │ ├── boot.js # System initialization orchestrator
+ │ │
+ │ ├── auth/
+ │ │ ├── routes.js # Login, logout, profile routes
+ │ │ ├── strategy.js # Discord OAuth strategy
+ │ │ ├── middleware.js # requireActiveUser (gatekeeper)
+ │ │ ├── webhook.js # Discord webhook for pending users
+ │ │ └── views/
+ │ │ ├── login.ejs
+ │ │ ├── profile.ejs
+ │ │ ├── pending.ejs
+ │ │ └── rejected.ejs
+ │ │
+ │ ├── database/
+ │ │ └── migrations.js # Per-module migration runner
+ │ │
+ │ ├── events/
+ │ │ └── index.js # EventEmitter registry
+ │ │
+ │ ├── features/
+ │ │ ├── index.js # Feature flag cache
+ │ │ ├── middleware.js # requireFeature()
+ │ │ └── routes.js # Toggle API
+ │ │
+ │ ├── modules/
+ │ │ ├── loader.js # fs.readdirSync + topological sort
+ │ │ ├── registry.js # In-memory module store
+ │ │ └── routes.js # Dynamic route mounting
+ │ │
+ │ ├── navigation/
+ │ │ └── index.js # Permission-filtered sidebar builder
+ │ │
+ │ └── permissions/
+ │ ├── middleware.js # requirePermission()
+ │ ├── resolver.js # fetchUserPermissions() + hasPermission()
+ │ ├── routes.js # RBAC API endpoints
+ │ └── sync.js # Upsert permissions from module.json
+ │
+ └── modules/
+ ├── dashboard/
+ │ ├── module.json
+ │ ├── routes.js
+ │ ├── api.js
+ │ ├── events.js
+ │ ├── views/
+ │ │ └── index.ejs
+ │ └── migrations/
+ │ └── 001_dashboard_stats.sql
+ │
+ ├── system/
+ │ ├── module.json
+ │ ├── routes.js
+ │ └── views/
+ │ ├── index.ejs
+ │ ├── users.ejs
+ │ ├── permissions.ejs
+ │ └── about.ejs
+ │
+ ├── servers/
+ │ ├── module.json
+ │ ├── routes.js
+ │ └── views/
+ │ ├── index.ejs
+ │ └── scheduler.ejs
+ │
+ └── [other modules follow same pattern]
+```
+
+---
+
+## 4. Database Migrations
+
+**CRITICAL:** Run these manually via psql BEFORE first boot to avoid migration failures.
+
+### `migrations/001_rbac_tables.sql`
+
+```sql
+-- 1. Roles Table
+CREATE TABLE IF NOT EXISTS roles (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(50) UNIQUE NOT NULL,
+ description TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 2. Permissions Table
+CREATE TABLE IF NOT EXISTS permissions (
+ permission_key VARCHAR(100) PRIMARY KEY,
+ module_id VARCHAR(50) NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ description TEXT,
+ is_active BOOLEAN DEFAULT TRUE,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 3. Role Permissions Table
+CREATE TABLE IF NOT EXISTS role_permissions (
+ role_id INT REFERENCES roles(id) ON DELETE CASCADE,
+ permission_key VARCHAR(100) REFERENCES permissions(permission_key) ON DELETE CASCADE,
+ PRIMARY KEY (role_id, permission_key)
+);
+
+-- 4. User Roles Table
+CREATE TABLE IF NOT EXISTS user_roles (
+ user_id VARCHAR(50) PRIMARY KEY,
+ role_id INT REFERENCES roles(id) ON DELETE CASCADE,
+ assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ assigned_by VARCHAR(50)
+);
+
+-- 5. User Permission Overrides Table
+CREATE TABLE IF NOT EXISTS user_permission_overrides (
+ user_id VARCHAR(50) NOT NULL,
+ permission_key VARCHAR(100) REFERENCES permissions(permission_key) ON DELETE CASCADE,
+ is_granted BOOLEAN NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ created_by VARCHAR(50),
+ PRIMARY KEY (user_id, permission_key)
+);
+
+-- 6. Core System Migrations Table
+CREATE TABLE IF NOT EXISTS core_migrations (
+ id SERIAL PRIMARY KEY,
+ module_id VARCHAR(50) NOT NULL,
+ migration_file VARCHAR(255) NOT NULL,
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ UNIQUE(module_id, migration_file)
+);
+
+-- Indexes
+CREATE INDEX IF NOT EXISTS idx_user_overrides ON user_permission_overrides(user_id);
+CREATE INDEX IF NOT EXISTS idx_role_permissions ON role_permissions(role_id);
+CREATE INDEX IF NOT EXISTS idx_active_permissions ON permissions(is_active);
+
+-- Seed Roles
+INSERT INTO roles (name, description) VALUES
+('Admin', 'Full system access (The Wizard)'),
+('Community', 'Player management and support (The Emissary)'),
+('Builder', 'Server and infrastructure management (The Catalyst)')
+ON CONFLICT (name) DO NOTHING;
+```
+
+### `migrations/002_feature_flags.sql`
+
+```sql
+CREATE TABLE IF NOT EXISTS feature_flags (
+ key VARCHAR(100) PRIMARY KEY,
+ is_enabled BOOLEAN NOT NULL DEFAULT FALSE,
+ description TEXT,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_by VARCHAR(50)
+);
+```
+
+### `migrations/003_auth_users.sql`
+
+```sql
+-- 1. Create the Users table
+CREATE TABLE IF NOT EXISTS users (
+ discord_id VARCHAR(50) PRIMARY KEY,
+ username VARCHAR(100) NOT NULL,
+ avatar VARCHAR(255),
+ status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'approved', 'rejected'
+ last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 2. Seed the Founders (Replace with actual Discord IDs!)
+INSERT INTO users (discord_id, username, status) VALUES
+('MICHAELS_DISCORD_ID', 'Frostystyle', 'approved'),
+('MEGS_DISCORD_ID', 'Gingerfury', 'approved'),
+('HOLLYS_DISCORD_ID', 'unicorn20089', 'approved')
+ON CONFLICT (discord_id) DO UPDATE SET status = 'approved';
+
+-- 3. Auto-assign roles to founders
+INSERT INTO user_roles (user_id, role_id, assigned_by)
+SELECT 'MICHAELS_DISCORD_ID', id, 'SYSTEM' FROM roles WHERE name = 'Admin'
+ON CONFLICT (user_id) DO NOTHING;
+
+INSERT INTO user_roles (user_id, role_id, assigned_by)
+SELECT 'MEGS_DISCORD_ID', id, 'SYSTEM' FROM roles WHERE name = 'Community'
+ON CONFLICT (user_id) DO NOTHING;
+
+INSERT INTO user_roles (user_id, role_id, assigned_by)
+SELECT 'HOLLYS_DISCORD_ID', id, 'SYSTEM' FROM roles WHERE name = 'Builder'
+ON CONFLICT (user_id) DO NOTHING;
+```
+
+---
+
+## 5. Core Engine Code
+
+### `src/core/boot.js`
+
+```javascript
+const path = require('path');
+const { loadModules } = require('./modules/loader');
+const registry = require('./modules/registry');
+const { runModuleMigrations } = require('./database/migrations');
+const { mountModuleRoutes } = require('./modules/routes');
+const { loadModuleEvents } = require('./events');
+const { syncPermissions } = require('./permissions/sync');
+const { refreshCache: refreshFeatureCache } = require('./features');
+
+async function bootSystem(app, pool) {
+ console.log('[Boot] Initializing Trinity Console 2.0...');
+
+ // 1. Load Modules
+ const modulesPath = path.join(__dirname, '../modules');
+ const modules = loadModules(modulesPath);
+ console.log(`[Boot] Discovered ${modules.length} modules`);
+
+ // 2. Register, Migrate, Mount
+ for (const mod of modules) {
+ registry.register(mod);
+ await runModuleMigrations(pool, mod);
+ mountModuleRoutes(app, mod);
+ loadModuleEvents(mod);
+ await syncPermissions(pool, mod);
+ }
+
+ // 3. Load Feature Flags
+ await refreshFeatureCache(pool);
+
+ console.log('[Boot] Trinity Console 2.0 ready.');
+}
+
+module.exports = { bootSystem };
+```
+
+### `src/core/modules/registry.js`
+
+```javascript
+const modules = new Map();
+
+module.exports = {
+ register: (moduleConfig) => {
+ modules.set(moduleConfig.id, moduleConfig);
+ },
+ getModule: (id) => modules.get(id),
+ getAllModules: () => Array.from(modules.values()),
+ isModuleEnabled: (id) => modules.has(id)
+};
+```
+
+### `src/core/modules/loader.js`
+
+```javascript
+const fs = require('fs');
+const path = require('path');
+
+function loadModules(modulesPath) {
+ if (!fs.existsSync(modulesPath)) return [];
+
+ const folders = fs.readdirSync(modulesPath, { withFileTypes: true })
+ .filter(dirent => dirent.isDirectory())
+ .map(dirent => dirent.name);
+
+ const loadedModules = [];
+
+ for (const folder of folders) {
+ const configPath = path.join(modulesPath, folder, 'module.json');
+ if (fs.existsSync(configPath)) {
+ try {
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
+ config.dirPath = path.join(modulesPath, folder);
+ loadedModules.push(config);
+ } catch (err) {
+ console.error(`[Core] Failed to parse module.json for ${folder}:`, err.message);
+ }
+ }
+ }
+
+ return topologicalSort(loadedModules);
+}
+
+function topologicalSort(modules) {
+ const sorted = [];
+ const visited = new Set();
+ const visiting = new Set();
+ const moduleMap = new Map(modules.map(m => [m.id, m]));
+
+ function visit(moduleId) {
+ if (visiting.has(moduleId)) {
+ throw new Error(`[Core] Fatal: Circular dependency detected involving module '${moduleId}'`);
+ }
+ if (visited.has(moduleId)) return;
+
+ visiting.add(moduleId);
+ const mod = moduleMap.get(moduleId);
+
+ if (mod && mod.dependencies) {
+ for (const dep of Object.keys(mod.dependencies)) {
+ if (!moduleMap.has(dep)) {
+ console.warn(`[Core] Warning: Module '${moduleId}' depends on missing module '${dep}'`);
+ continue;
+ }
+ visit(dep);
+ }
+ }
+
+ visiting.delete(moduleId);
+ visited.add(moduleId);
+ if (mod) sorted.push(mod);
+ }
+
+ for (const mod of modules) {
+ visit(mod.id);
+ }
+
+ return sorted;
+}
+
+module.exports = { loadModules };
+```
+
+### `src/core/modules/routes.js`
+
+```javascript
+const path = require('path');
+const fs = require('fs');
+
+function mountModuleRoutes(app, moduleConfig) {
+ const routesPath = path.join(moduleConfig.dirPath, 'routes.js');
+ if (fs.existsSync(routesPath)) {
+ const router = require(routesPath);
+ const prefix = moduleConfig.routes || `/${moduleConfig.id}`;
+ app.use(prefix, router);
+ console.log(`[Routes] Mounted ${moduleConfig.id} at ${prefix}`);
+ }
+}
+
+module.exports = { mountModuleRoutes };
+```
+
+### `src/core/database/migrations.js`
+
+```javascript
+const fs = require('fs');
+const path = require('path');
+
+async function runModuleMigrations(pool, moduleConfig) {
+ const migrationsDir = path.join(moduleConfig.dirPath, 'migrations');
+ if (!fs.existsSync(migrationsDir)) return;
+
+ const files = fs.readdirSync(migrationsDir)
+ .filter(f => f.endsWith('.sql'))
+ .sort();
+
+ for (const file of files) {
+ const checkRes = await pool.query(
+ 'SELECT 1 FROM core_migrations WHERE module_id = $1 AND migration_file = $2',
+ [moduleConfig.id, file]
+ );
+
+ if (checkRes.rowCount === 0) {
+ console.log(`[Migrations] Applying ${moduleConfig.id}/${file}...`);
+ const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf8');
+
+ const client = await pool.connect();
+ try {
+ await client.query('BEGIN');
+ await client.query(sql);
+ await client.query(
+ 'INSERT INTO core_migrations (module_id, migration_file) VALUES ($1, $2)',
+ [moduleConfig.id, file]
+ );
+ await client.query('COMMIT');
+ } catch (err) {
+ await client.query('ROLLBACK');
+ throw new Error(`Migration failed: ${moduleConfig.id}/${file} - ${err.message}`);
+ } finally {
+ client.release();
+ }
+ }
+ }
+}
+
+module.exports = { runModuleMigrations };
+```
+
+### `src/core/events/index.js`
+
+```javascript
+const EventEmitter = require('events');
+const fs = require('fs');
+const path = require('path');
+
+class CoreEvents extends EventEmitter {}
+const coreEmitter = new CoreEvents();
+
+function loadModuleEvents(moduleConfig) {
+ const eventsPath = path.join(moduleConfig.dirPath, 'events.js');
+ if (fs.existsSync(eventsPath)) {
+ const registerEvents = require(eventsPath);
+ registerEvents(coreEmitter);
+ console.log(`[Events] Registered events for ${moduleConfig.id}`);
+ }
+}
+
+module.exports = {
+ emitter: coreEmitter,
+ loadModuleEvents
+};
+```
+
+### `src/core/navigation/index.js`
+
+```javascript
+const registry = require('../modules/registry');
+
+function buildNavigation(userPermissions) {
+ const modules = registry.getAllModules();
+ const navStructure = {};
+
+ modules.forEach(mod => {
+ if (!mod.nav) return;
+
+ // Check if user has at least one permission for this module
+ const modulePermKeys = (mod.permissions || []).map(p => p.key);
+ const hasAccess = modulePermKeys.length === 0 ||
+ modulePermKeys.some(key =>
+ userPermissions.includes(key) ||
+ userPermissions.includes(`${mod.id}.*`)
+ );
+
+ if (!hasAccess) return;
+
+ const section = mod.nav.section || 'General';
+ if (!navStructure[section]) {
+ navStructure[section] = [];
+ }
+
+ navStructure[section].push({
+ id: mod.id,
+ name: mod.name,
+ icon: mod.icon || 'circle',
+ path: mod.routes || `/${mod.id}`,
+ position: mod.nav.position || 99,
+ badge: mod.nav.badge || null
+ });
+ });
+
+ // Sort each section by position
+ Object.keys(navStructure).forEach(section => {
+ navStructure[section].sort((a, b) => a.position - b.position);
+ });
+
+ return navStructure;
+}
+
+module.exports = { buildNavigation };
+```
+
+---
+
+## 6. RBAC System Code
+
+### `src/core/permissions/resolver.js`
+
+```javascript
+async function fetchUserPermissions(pool, userId) {
+ // 1. Get role-based permissions
+ const roleRes = await pool.query(`
+ SELECT p.permission_key
+ FROM user_roles ur
+ JOIN role_permissions rp ON ur.role_id = rp.role_id
+ JOIN permissions p ON rp.permission_key = p.permission_key
+ WHERE ur.user_id = $1 AND p.is_active = TRUE
+ `, [userId]);
+
+ const rolePermissions = roleRes.rows.map(r => r.permission_key);
+
+ // 2. Get direct overrides
+ const overrideRes = await pool.query(`
+ SELECT permission_key, is_granted
+ FROM user_permission_overrides
+ WHERE user_id = $1
+ `, [userId]);
+
+ const overrides = {};
+ overrideRes.rows.forEach(r => {
+ overrides[r.permission_key] = r.is_granted;
+ });
+
+ // 3. Apply overrides to role permissions
+ const finalPermissions = new Set(rolePermissions);
+
+ Object.entries(overrides).forEach(([key, granted]) => {
+ if (granted) {
+ finalPermissions.add(key);
+ } else {
+ finalPermissions.delete(key);
+ }
+ });
+
+ return Array.from(finalPermissions);
+}
+
+function hasPermission(userPermissions, requiredKey) {
+ if (userPermissions.includes(requiredKey)) return true;
+
+ // Check for wildcard (e.g., tasks.* grants tasks.edit)
+ const modulePart = requiredKey.split('.')[0];
+ if (userPermissions.includes(`${modulePart}.*`)) return true;
+
+ return false;
+}
+
+module.exports = { fetchUserPermissions, hasPermission };
+```
+
+### `src/core/permissions/middleware.js`
+
+```javascript
+const { hasPermission } = require('./resolver');
+
+function requirePermission(permissionKey) {
+ return (req, res, next) => {
+ if (!req.user || !req.userPermissions) {
+ return res.redirect('/auth/login');
+ }
+
+ if (hasPermission(req.userPermissions, permissionKey)) {
+ return next();
+ }
+
+ const isHtmx = req.headers['hx-request'] === 'true';
+ if (isHtmx) {
+ return res.status(403).send(`
+
+ Access Denied: You do not have permission to access this resource.
+
+ `);
+ }
+
+ return res.status(403).render('errors/403', {
+ message: `Permission required: ${permissionKey}`
+ });
+ };
+}
+
+module.exports = { requirePermission };
+```
+
+### `src/core/permissions/sync.js`
+
+```javascript
+async function syncPermissions(pool, moduleConfig) {
+ if (!moduleConfig.permissions || moduleConfig.permissions.length === 0) return;
+
+ for (const perm of moduleConfig.permissions) {
+ await pool.query(`
+ INSERT INTO permissions (permission_key, module_id, name, description, is_active)
+ VALUES ($1, $2, $3, $4, TRUE)
+ ON CONFLICT (permission_key) DO UPDATE SET
+ name = EXCLUDED.name,
+ description = EXCLUDED.description,
+ is_active = TRUE
+ `, [perm.key, moduleConfig.id, perm.name, perm.description || '']);
+ }
+
+ console.log(`[Permissions] Synced ${moduleConfig.permissions.length} permissions for ${moduleConfig.id}`);
+}
+
+module.exports = { syncPermissions };
+```
+
+### `src/core/permissions/routes.js`
+
+```javascript
+const express = require('express');
+const router = express.Router();
+const db = require('../../db');
+const { requirePermission } = require('./middleware');
+
+// All routes require system.permissions.manage
+router.use(requirePermission('system.permissions.manage'));
+
+// Get all roles
+router.get('/api/roles', async (req, res) => {
+ const { rows } = await db.query('SELECT * FROM roles ORDER BY id');
+ res.json(rows);
+});
+
+// Get permissions for a role
+router.get('/api/roles/:id/permissions', async (req, res) => {
+ const { rows } = await db.query(
+ 'SELECT permission_key FROM role_permissions WHERE role_id = $1',
+ [req.params.id]
+ );
+ res.json(rows.map(r => r.permission_key));
+});
+
+// Assign permission to role
+router.post('/api/roles/:id/permissions', async (req, res) => {
+ const { permission_key } = req.body;
+ await db.query(
+ 'INSERT INTO role_permissions (role_id, permission_key) VALUES ($1, $2) ON CONFLICT DO NOTHING',
+ [req.params.id, permission_key]
+ );
+ res.sendStatus(201);
+});
+
+// Remove permission from role
+router.delete('/api/roles/:id/permissions/:key', async (req, res) => {
+ await db.query(
+ 'DELETE FROM role_permissions WHERE role_id = $1 AND permission_key = $2',
+ [req.params.id, req.params.key]
+ );
+ res.sendStatus(200);
+});
+
+// Get all users with roles
+router.get('/api/users', async (req, res) => {
+ const { rows } = await db.query(`
+ SELECT u.discord_id, u.username, u.avatar, u.status, r.name as role_name
+ FROM users u
+ LEFT JOIN user_roles ur ON u.discord_id = ur.user_id
+ LEFT JOIN roles r ON ur.role_id = r.id
+ ORDER BY u.username
+ `);
+ res.json(rows);
+});
+
+// Assign role to user
+router.post('/api/users/:id/role', async (req, res) => {
+ const { role_id } = req.body;
+ await db.query(`
+ INSERT INTO user_roles (user_id, role_id, assigned_by)
+ VALUES ($1, $2, $3)
+ ON CONFLICT (user_id) DO UPDATE SET role_id = EXCLUDED.role_id, assigned_by = EXCLUDED.assigned_by
+ `, [req.params.id, role_id, req.user.discord_id]);
+ res.sendStatus(200);
+});
+
+// Approve user
+router.post('/api/users/:id/approve', async (req, res) => {
+ await db.query(
+ 'UPDATE users SET status = $1 WHERE discord_id = $2',
+ ['approved', req.params.id]
+ );
+ res.sendStatus(200);
+});
+
+// Get user overrides
+router.get('/api/users/:id/overrides', async (req, res) => {
+ const { rows } = await db.query(
+ 'SELECT permission_key, is_granted FROM user_permission_overrides WHERE user_id = $1',
+ [req.params.id]
+ );
+ res.json(rows);
+});
+
+// Add user override
+router.post('/api/users/:id/overrides', async (req, res) => {
+ const { permission_key, is_granted } = req.body;
+ await db.query(`
+ INSERT INTO user_permission_overrides (user_id, permission_key, is_granted, created_by)
+ VALUES ($1, $2, $3, $4)
+ ON CONFLICT (user_id, permission_key) DO UPDATE SET is_granted = EXCLUDED.is_granted
+ `, [req.params.id, permission_key, is_granted, req.user.discord_id]);
+ res.sendStatus(201);
+});
+
+// Remove user override
+router.delete('/api/users/:id/overrides/:key', async (req, res) => {
+ await db.query(
+ 'DELETE FROM user_permission_overrides WHERE user_id = $1 AND permission_key = $2',
+ [req.params.id, req.params.key]
+ );
+ res.sendStatus(200);
+});
+
+module.exports = router;
+```
+
+---
+
+## 7. Feature Flags Code
+
+### `src/core/features/index.js`
+
+```javascript
+let featureCache = {};
+
+async function refreshCache(pool) {
+ try {
+ const { rows } = await pool.query('SELECT key, is_enabled FROM feature_flags');
+ const newCache = {};
+ rows.forEach(r => { newCache[r.key] = r.is_enabled; });
+ featureCache = newCache;
+ console.log('[Features] Feature flag cache refreshed.');
+ } catch (err) {
+ console.error('[Features] Failed to refresh cache:', err);
+ }
+}
+
+function isEnabled(key) {
+ return !!featureCache[key];
+}
+
+async function setFlag(pool, key, enabled, updatedBy) {
+ await pool.query(`
+ INSERT INTO feature_flags (key, is_enabled, updated_by, updated_at)
+ VALUES ($1, $2, $3, CURRENT_TIMESTAMP)
+ ON CONFLICT (key) DO UPDATE SET
+ is_enabled = EXCLUDED.is_enabled,
+ updated_by = EXCLUDED.updated_by,
+ updated_at = CURRENT_TIMESTAMP
+ `, [key, enabled, updatedBy]);
+ await refreshCache(pool);
+}
+
+module.exports = { refreshCache, isEnabled, setFlag };
+```
+
+### `src/core/features/middleware.js`
+
+```javascript
+const { isEnabled } = require('./index');
+
+function requireFeature(featureKey) {
+ return (req, res, next) => {
+ if (isEnabled(featureKey)) {
+ return next();
+ }
+
+ const isHtmx = req.headers['hx-request'] === 'true';
+ const msg = `Feature '${featureKey}' is currently disabled.`;
+
+ if (isHtmx) {
+ return res.status(503).send(`
+
+ Service Unavailable: ${msg}
+
+ `);
+ }
+
+ return res.status(503).render('errors/503', { message: msg });
+ };
+}
+
+module.exports = { requireFeature };
+```
+
+### `src/core/features/routes.js`
+
+```javascript
+const express = require('express');
+const router = express.Router();
+const db = require('../../db');
+const { requirePermission } = require('../permissions/middleware');
+const { setFlag } = require('./index');
+
+router.use(requirePermission('system.features.manage'));
+
+router.get('/api/features', async (req, res) => {
+ const { rows } = await db.query('SELECT * FROM feature_flags ORDER BY key');
+ res.json(rows);
+});
+
+router.post('/api/features/:key', async (req, res) => {
+ const { is_enabled } = req.body;
+ await setFlag(db, req.params.key, is_enabled, req.user.discord_id);
+ res.sendStatus(200);
+});
+
+module.exports = router;
+```
+
+---
+
+## 8. Authentication System
+
+### `src/core/auth/webhook.js`
+
+```javascript
+async function notifyAdminOfPendingUser(user) {
+ const webhookUrl = process.env.DISCORD_ADMIN_WEBHOOK_URL;
+ if (!webhookUrl) return;
+
+ const payload = {
+ embeds: [{
+ title: "🔐 New Trinity Console Access Request",
+ description: `**${user.username}** has logged in via Discord and is waiting for authorization.`,
+ color: 16739381, // Fire orange
+ thumbnail: {
+ url: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`
+ },
+ fields: [
+ { name: "Discord ID", value: `\`${user.id}\``, inline: true }
+ ],
+ url: `https://trinity.firefrostgaming.com/system/users`
+ }]
+ };
+
+ try {
+ await fetch(webhookUrl, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(payload)
+ });
+ } catch (err) {
+ console.error('[Auth] Failed to send Discord webhook alert:', err);
+ }
+}
+
+module.exports = { notifyAdminOfPendingUser };
+```
+
+### `src/core/auth/strategy.js`
+
+```javascript
+const db = require('../../db');
+const { notifyAdminOfPendingUser } = require('./webhook');
+
+async function verifyDiscordLogin(accessToken, refreshToken, profile, done) {
+ const { id, username, avatar } = profile;
+
+ try {
+ const result = await db.query(`
+ INSERT INTO users (discord_id, username, avatar, last_login)
+ VALUES ($1, $2, $3, CURRENT_TIMESTAMP)
+ ON CONFLICT (discord_id) DO UPDATE
+ SET username = EXCLUDED.username,
+ avatar = EXCLUDED.avatar,
+ last_login = CURRENT_TIMESTAMP
+ RETURNING status, (xmax = 0) AS is_new_user;
+ `, [id, username, avatar]);
+
+ const dbUser = result.rows[0];
+
+ const sessionUser = {
+ id: id,
+ discord_id: id,
+ username: username,
+ avatar: avatar,
+ status: dbUser.status
+ };
+
+ if (dbUser.is_new_user && dbUser.status === 'pending') {
+ await notifyAdminOfPendingUser(sessionUser);
+ }
+
+ return done(null, sessionUser);
+ } catch (err) {
+ console.error('[Auth Error]', err);
+ return done(err, null);
+ }
+}
+
+module.exports = { verifyDiscordLogin };
+```
+
+### `src/core/auth/middleware.js`
+
+```javascript
+function requireActiveUser(req, res, next) {
+ if (!req.user) {
+ return res.redirect('/auth/login');
+ }
+
+ if (req.user.status === 'pending') {
+ if (req.headers['hx-request'] === 'true') {
+ return res.status(403).send(`
+
+ Account pending authorization.
+
+ `);
+ }
+ return res.render('../src/core/auth/views/pending', { layout: false, user: req.user });
+ }
+
+ if (req.user.status === 'rejected') {
+ return res.render('../src/core/auth/views/rejected', { layout: false });
+ }
+
+ next();
+}
+
+module.exports = { requireActiveUser };
+```
+
+### `src/core/auth/routes.js`
+
+```javascript
+const express = require('express');
+const router = express.Router();
+const db = require('../../db');
+
+router.get('/auth/login', (req, res) => {
+ if (req.user) return res.redirect('/dashboard');
+ res.render('../src/core/auth/views/login', { layout: false });
+});
+
+router.get('/auth/logout', (req, res) => {
+ req.session.destroy((err) => {
+ if (err) console.error('Session destruction error:', err);
+ res.redirect('/auth/login?loggedOut=true');
+ });
+});
+
+router.get('/profile', async (req, res) => {
+ if (!req.user) return res.redirect('/auth/login');
+
+ try {
+ const roleRes = await db.query(`
+ SELECT r.name
+ FROM user_roles ur
+ JOIN roles r ON ur.role_id = r.id
+ WHERE ur.user_id = $1`,
+ [req.user.id]
+ );
+ const roleName = roleRes.rowCount > 0 ? roleRes.rows[0].name : 'Member';
+
+ const { fetchUserPermissions } = require('../permissions/resolver');
+ const permissions = await fetchUserPermissions(db, req.user.id);
+
+ res.render('../src/core/auth/views/profile', {
+ user: req.user,
+ roleName,
+ permissions: permissions.sort()
+ });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Error loading profile");
+ }
+});
+
+module.exports = router;
+```
+
+### `src/core/auth/views/login.ejs`
+
+```html
+
+
+
+
+
+ Login | Trinity Console
+
+
+
+
+
+
+
+
+
+
Trinity Console
+
Command Center for Firefrost Gaming
+
+
+
+ Sign in with Discord
+
+
+
+
+```
+
+### `src/core/auth/views/pending.ejs`
+
+```html
+
+
+
+
+
+ Access Pending | Trinity Console
+
+
+
+
+
+
+
+
+
+
+
Access Pending
+
Your Discord identity (<%= user.username %>) has been verified, but your clearance level has not yet been assigned by the Trinity.
+
+
+
STATUS: WAITING_FOR_WIZARD
+
+
+
An alert has been dispatched to the administrators. You will be able to access the console once your profile is approved.
+
+
+ Return to Login
+
+
+
+
+```
+
+### `src/core/auth/views/profile.ejs`
+
+```html
+
+
+
+
+

+
+
+
<%= user.username %>
+
+
+ Connected via Discord
+
+
+
+ <%= roleName %>
+
+
+
+
+
+
+
Active Permissions
+
These are the specific clearance levels assigned to you by the Trinity.
+
+ <% if (permissions && permissions.length > 0) { %>
+
+ <% permissions.forEach(perm => { %>
+
+ <% }) %>
+
+ <% } else { %>
+
+
No explicit permissions assigned to this profile.
+
+ <% } %>
+
+
+```
+
+---
+
+## 9. Branding & Design System
+
+### `tailwind.config.js`
+
+```javascript
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./src/**/*.{ejs,js,html}", "./views/**/*.ejs"],
+ theme: {
+ extend: {
+ colors: {
+ fire: {
+ DEFAULT: '#FF6B35',
+ hover: '#E55A2A',
+ dim: 'rgba(255, 107, 53, 0.1)'
+ },
+ frost: {
+ DEFAULT: '#4ECDC4',
+ hover: '#3EBAB1',
+ dim: 'rgba(78, 205, 196, 0.1)'
+ },
+ arcane: {
+ DEFAULT: '#A855F7',
+ hover: '#9333EA',
+ dim: 'rgba(168, 85, 247, 0.1)'
+ },
+ gold: {
+ DEFAULT: '#FFD700',
+ hover: '#E6C200',
+ dim: 'rgba(255, 215, 0, 0.1)'
+ },
+ void: {
+ DEFAULT: '#0F0F1E',
+ surface: '#16162C',
+ hover: '#1D1D3A',
+ border: '#2A2A4A'
+ }
+ },
+ fontFamily: {
+ sans: ['Inter', 'system-ui', 'sans-serif'],
+ mono: ['JetBrains Mono', 'monospace']
+ }
+ },
+ },
+ plugins: [
+ require('@tailwindcss/forms'),
+ ],
+}
+```
+
+### `views/layout.ejs`
+
+```html
+
+
+
+
+
+ Trinity Console | Firefrost
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%- body %>
+
+
+
+
+
+
+```
+
+### Component Reference
+
+**Cards:**
+```html
+
+
Card Title
+
+
+```
+
+**Buttons:**
+```html
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**Form Inputs:**
+```html
+
+
+
+
+```
+
+**Alerts:**
+```html
+
+
+
+
+
+
Success message here.
+
+```
+
+**Badges:**
+```html
+Online
+Admin
+Offline
+```
+
+---
+
+## 10. Example Module (Dashboard)
+
+### `src/modules/dashboard/module.json`
+
+```json
+{
+ "id": "dashboard",
+ "name": "Dashboard",
+ "description": "System overview and quick stats",
+ "version": "1.0.0",
+ "author": "Trinity",
+ "dependencies": {},
+ "icon": "home",
+ "nav": {
+ "section": "General",
+ "position": 1
+ },
+ "permissions": [
+ {
+ "key": "dashboard.view",
+ "name": "View Dashboard",
+ "description": "Access the main overview screen"
+ }
+ ],
+ "routes": "/dashboard"
+}
+```
+
+### `src/modules/dashboard/routes.js`
+
+```javascript
+const express = require('express');
+const router = express.Router();
+const { requirePermission } = require('../../core/permissions/middleware');
+
+router.use(requirePermission('dashboard.view'));
+
+router.get('/', (req, res) => {
+ res.render('../src/modules/dashboard/views/index', { user: req.user });
+});
+
+module.exports = router;
+```
+
+### `src/modules/dashboard/views/index.ejs`
+
+```html
+
+
+
Welcome back, <%= user.username %>
+ The Frostwall holds strong.
+
+
+
+
+
+
Servers Online
+
+
+
12 / 12
+
+
+
+
+
Active Subscribers
+
+
+
47
+
+
+
+
+
Monthly Revenue
+
+
+
$385
+
+
+
+```
+
+### `src/modules/dashboard/events.js`
+
+```javascript
+module.exports = function(coreEvents) {
+ coreEvents.on('server.status_change', (data) => {
+ console.log(`[Dashboard] Server ${data.serverId} changed to ${data.status}`);
+ });
+};
+```
+
+### `src/modules/dashboard/api.js`
+
+```javascript
+module.exports = {
+ getSystemHealthScore: async () => {
+ return 100; // Placeholder
+ }
+};
+```
+
+---
+
+## 11. Deployment Infrastructure
+
+### Server Information
+
+| Server | IP | Role |
+|--------|-----|------|
+| Dev VPS | 64.50.188.128 | Development/Staging (Trinity 2.0 development) |
+| Command Center | 63.143.34.217 | Production (PostgreSQL, Arbiter 3.5) |
+
+### Cloudflare DNS
+
+Create A Record:
+- **Name:** `trinity`
+- **Target:** `64.50.188.128`
+- **Proxy:** Gray Cloud for Certbot, then Orange Cloud
+
+### PostgreSQL Remote Access (Command Center)
+
+**Step 1:** Edit `/etc/postgresql/*/main/postgresql.conf`:
+```
+listen_addresses = '*'
+```
+
+**Step 2:** Edit `/etc/postgresql/*/main/pg_hba.conf`:
+```
+host arbiter_db arbiter 64.50.188.128/32 scram-sha-256
+```
+
+**Step 3:** Firewall:
+```bash
+sudo ufw allow from 64.50.188.128 to any port 5432
+```
+
+**Step 4:** Restart:
+```bash
+sudo systemctl restart postgresql
+```
+
+### Dev VPS Bootstrap
+
+```bash
+# System updates
+sudo apt update && sudo apt upgrade -y
+
+# Install dependencies
+sudo apt install -y nginx certbot python3-certbot-nginx curl git ufw
+
+# Firewall
+sudo ufw allow OpenSSH
+sudo ufw allow 'Nginx Full'
+sudo ufw enable
+
+# Node.js 20
+curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
+sudo apt install -y nodejs
+
+# PM2
+sudo npm install -g pm2
+```
+
+### Nginx Configuration
+
+Create `/etc/nginx/sites-available/trinity`:
+```nginx
+server {
+ listen 80;
+ server_name trinity.firefrostgaming.com;
+
+ location / {
+ proxy_pass http://localhost:3001;
+ 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;
+ }
+}
+```
+
+Enable:
+```bash
+sudo ln -s /etc/nginx/sites-available/trinity /etc/nginx/sites-enabled/
+sudo nginx -t
+sudo systemctl restart nginx
+```
+
+### SSL Certificate
+
+```bash
+sudo certbot --nginx -d trinity.firefrostgaming.com
+```
+
+### PM2 Configuration
+
+Create `ecosystem.config.js`:
+```javascript
+module.exports = {
+ apps: [{
+ name: "trinity-console",
+ script: "./src/index.js",
+ watch: false,
+ max_memory_restart: "1G",
+ env: {
+ NODE_ENV: "production",
+ PORT: 3001
+ }
+ }]
+};
+```
+
+### Environment Variables (`.env`)
+
+```env
+# Database (Command Center)
+DB_USER=arbiter
+DB_HOST=63.143.34.217
+DB_NAME=arbiter_db
+DB_PASSWORD=FireFrost2026!Arbiter
+DB_PORT=5432
+
+# Discord
+DISCORD_CLIENT_ID=1330262498058670162
+DISCORD_CLIENT_SECRET=[from Vaultwarden]
+DISCORD_BOT_TOKEN=[from Vaultwarden]
+DISCORD_GUILD_ID=1286373938067198003
+DISCORD_ADMIN_WEBHOOK_URL=[create webhook in admin channel]
+
+# Stripe
+STRIPE_SECRET_KEY=[from Vaultwarden]
+STRIPE_WEBHOOK_SECRET=[from Vaultwarden]
+
+# Session
+SESSION_SECRET=[from Vaultwarden]
+
+# Pterodactyl
+PTERO_CLIENT_KEY=ptlc_NDkYX6yPPBHZacPmViFWtl4AvopzgxNcnHoQTOOtQEl
+
+# App
+PORT=3001
+NODE_ENV=production
+BASE_URL=https://trinity.firefrostgaming.com
+```
+
+---
+
+## 12. Implementation Checklist
+
+### Phase 0: Infrastructure Setup
+
+- [ ] Create Cloudflare A record for `trinity` → 64.50.188.128
+- [ ] Update Command Center PostgreSQL for remote access
+- [ ] Open UFW port 5432 for Dev VPS IP
+- [ ] Bootstrap Dev VPS (Node, PM2, Nginx, Certbot)
+- [ ] Run Certbot for SSL
+
+### Phase 1: Core Foundation
+
+- [ ] Run 001_rbac_tables.sql manually on Command Center
+- [ ] Run 002_feature_flags.sql manually
+- [ ] Run 003_auth_users.sql manually (with real Discord IDs)
+- [ ] Create project structure on Dev VPS
+- [ ] Implement `src/db.js`
+- [ ] Implement `src/core/boot.js`
+- [ ] Implement `src/core/modules/` (registry, loader, routes)
+- [ ] Implement `src/core/events/index.js`
+- [ ] Implement `src/core/navigation/index.js`
+- [ ] Create `tailwind.config.js` and compile CSS
+- [ ] Create `views/layout.ejs`
+- [ ] Test boot sequence
+
+### Phase 2: RBAC & Auth
+
+- [ ] Implement `src/core/permissions/` (resolver, middleware, sync, routes)
+- [ ] Implement `src/core/auth/` (strategy, middleware, webhook, routes, views)
+- [ ] Configure Passport Discord strategy
+- [ ] Test Discord OAuth flow
+- [ ] Test pending user flow
+- [ ] Test founder auto-approval
+
+### Phase 3: First Modules
+
+- [ ] Create Dashboard module
+- [ ] Create System module (with About page)
+- [ ] Test navigation building
+- [ ] Test permission enforcement
+
+### Phase 4: Migration (Strangler Fig)
+
+- [ ] Migrate Servers module (includes Scheduler)
+- [ ] Migrate Players module
+- [ ] Migrate Financials module
+- [ ] Build Tasks module (new)
+- [ ] Continue with remaining modules
+
+---
+
+## 13. Migration from Arbiter 3.5
+
+### Current Arbiter Structure
+
+```
+/opt/arbiter-3.0/src/
+├── routes/admin/
+│ ├── dashboard.js
+│ ├── players.js
+│ ├── servers.js
+│ ├── scheduler.js
+│ └── financials.js
+└── views/admin/
+ ├── dashboard.ejs
+ ├── players.ejs
+ └── ...
+```
+
+### Migration Steps Per Module
+
+1. **Create module folder:** `src/modules/{name}/`
+2. **Create module.json** with permissions
+3. **Move routes:** Copy from `routes/admin/{name}.js` → `src/modules/{name}/routes.js`
+4. **Update imports:** Change `../../views/admin/` → `./views/`
+5. **Move views:** Copy from `views/admin/{name}.ejs` → `src/modules/{name}/views/`
+6. **Add permission checks:** Wrap routes with `requirePermission()`
+7. **Test in isolation**
+8. **Remove old routes** once verified
+
+### Servers Module Example
+
+**`src/modules/servers/module.json`:**
+```json
+{
+ "id": "servers",
+ "name": "Servers & Scheduling",
+ "description": "Game server status, whitelist sync, and restart automation",
+ "version": "1.0.0",
+ "author": "Trinity",
+ "dependencies": {},
+ "icon": "server",
+ "nav": {
+ "section": "Infrastructure",
+ "position": 1
+ },
+ "permissions": [
+ {
+ "key": "servers.view",
+ "name": "View Servers",
+ "description": "See server matrix and status"
+ },
+ {
+ "key": "servers.manage",
+ "name": "Manage Servers",
+ "description": "Sync whitelists and toggle maintenance mode"
+ },
+ {
+ "key": "servers.scheduler",
+ "name": "Manage Scheduler",
+ "description": "Deploy global restart schedules and nuke conflicts"
+ }
+ ],
+ "routes": "/servers"
+}
+```
+
+---
+
+## Emergency Contacts
+
+If Claude is unavailable:
+
+1. **Gemini** — Knows the entire architecture (paste this doc for context)
+2. **GPT-4o** — Can implement from this guide
+3. **New Claude session** — Start fresh with this document
+
+---
+
+## Document History
+
+| Version | Date | Author | Changes |
+|---------|------|--------|---------|
+| 1.0 | 2026-04-05 | Claude (Chronicler #61) | Initial creation from 7 Gemini consultation rounds |
+
+---
+
+**Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️