Files
Claude 3542afbe28 feat: Add YAML frontmatter to all 57 task READMEs
Phase 1 of task management consolidation (per Gemini consultation).

Added standardized frontmatter with:
- status: open | blocked | complete
- priority: P1 | P2 | P3 | P4
- owner: Michael | Meg | Holly
- created: YYYY-MM-DD

Final counts:
- 39 open tasks
- 17 complete tasks
- 1 blocked task

Metadata extracted from existing inline markdown and audit results.
Ready for Phase 2: 11ty mobile index generation.

Chronicler #69
2026-04-08 14:21:41 +00:00
..

status, priority, owner, created
status priority owner created
complete P1 Michael 2026-03-31

Task #90: Arbiter 2.x - Unified Access Manager

Status: OPEN
Priority: Tier 1 - Soft Launch Blocker
Estimated Time: 20-30 hours (5 phases)
Created: March 31, 2026
Architecture Validated By: Gemini AI


Overview

Complete rewrite merging Arbiter (Discord role management) + Whitelist Manager (server access control) into single Node.js application with PostgreSQL backend.

Goal: Subscription-driven Minecraft server whitelist access - user subscribes → links Minecraft account → automatically whitelisted on all servers.


  • Implementation Guide: IMPLEMENTATION-GUIDE.md (complete technical spec with code examples)
  • Architecture Decision: ../../reference/gemini-consultations/2026-03-31-arbiter-whitelist-architecture.md
  • Implementation Details: ../../reference/gemini-consultations/2026-03-31-arbiter-implementation-details.md
  • Main Task: ../../core/tasks.md#90

The Flow

  1. User subscribes via Paymenter (any tier, even $1 Awakened)
  2. Paymenter webhook → Arbiter assigns Discord role
  3. User runs /link <minecraft_username> in Discord
  4. Arbiter validates via Mojang API, gets UUID
  5. Stores in PostgreSQL: discord_id, minecraft_username, minecraft_uuid
  6. Master whitelist auto-syncs to all whitelisted servers
  7. User can now join any Minecraft server

Why Rewrite?

Current Whitelist Manager is broken:

  • Hardcoded server name keywords (fails when servers change)
  • WebSocket console commands (unreliable, returns "UNKNOWN")
  • No subscription integration
  • No master whitelist concept
  • Manual-only operation

Current Arbiter doesn't:

  • Store Minecraft usernames
  • Communicate with Whitelist Manager
  • Handle subscription-driven whitelist access

Architecture Decisions

All validated by Gemini AI consultation (March 31, 2026):

Single unified app - Arbiter 2.x replaces both services
PostgreSQL - Concurrent write safety at 500-user scale
Discord /link slash command - Mojang API validation
Pterodactyl File Management API - Replaces WebSocket console
Hybrid sync - Event-driven push + hourly cron reconciliation
UUIDs with dashes - Minecraft 1.8+ requirement


Implementation Phases

Phase 1: Database Migration

  • Provision PostgreSQL 15+
  • Execute schema creation
  • Apply indexes for 500-user scale
  • Migrate legacy SQLite data

Phase 2: Core Functions

  • pg connection pool
  • Mojang API validation + UUID formatting
  • Pterodactyl Application API (auto-discovery)
  • Pterodactyl Client API (file write, commands)

Phase 3: Discord Integration

  • /link slash command registration
  • UUID validation flow
  • Auto-DM new subscribers
  • Paymenter webhook updates

Phase 4: Sync System

  • Event-driven immediate sync
  • node-cron hourly reconciliation
  • Sequential batch processing
  • Sync logging to database

Phase 5: Admin Panel

  • server_sync_log dashboard
  • Manual "Force Sync" trigger
  • Linked accounts view
  • Production deployment

Critical Gotchas

From Gemini consultation - these will break production if missed:

  1. Content-Type: text/plain for Panel file write (NOT application/json)
  2. Mojang UUIDs without dashes, Minecraft needs WITH dashes
  3. HTTP 412 = server offline, NOT an error (file saved for next boot)
  4. Sequential processing prevents Panel API rate limiting
  5. Application API for discovery, Client API for file operations

Database Schema

CREATE TABLE users (
    discord_id VARCHAR(255) PRIMARY KEY,
    minecraft_username VARCHAR(255) UNIQUE,
    minecraft_uuid VARCHAR(255) UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE subscriptions (
    id SERIAL PRIMARY KEY,
    discord_id VARCHAR(255) REFERENCES users(discord_id),
    tier_level INT NOT NULL,
    status VARCHAR(50) NOT NULL, -- active, grace_period, cancelled
    stripe_customer_id VARCHAR(255)
);

CREATE TABLE server_sync_log (
    server_identifier VARCHAR(50) PRIMARY KEY,
    last_successful_sync TIMESTAMP,
    last_error TEXT,
    is_online BOOLEAN DEFAULT true
);

CREATE INDEX idx_users_discord_id ON users(discord_id);
CREATE INDEX idx_subscriptions_status ON subscriptions(status);

Success Criteria

  • User subscribes → links account → auto-whitelisted within 5 minutes
  • Master whitelist = database (single source of truth)
  • All servers sync from master (hourly reconciliation)
  • Server discovery is automatic (no hardcoded names)
  • Works reliably for remote RV operations
  • Handles 500 subscribers by September 2027

What Gets Retired

Once Arbiter 2.x is deployed:

  • Old Whitelist Manager (Python Flask on Billing VPS)
  • Old Arbiter 1.x (if not already migrated)
  • Update all documentation to reference unified system

Dependencies

  • PostgreSQL 15+
  • Node.js 20 LTS
  • Pterodactyl Panel v1.12.1 (Client + Application API keys)
  • Mojang API (public, no auth)
  • Discord Bot with slash command permissions

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