docs: add DEC-009 through DEC-015 to ADL; update header to Feb 22 v1.2

This commit is contained in:
jester 2026-02-22 18:30:13 +00:00
parent d4157cfd39
commit f651b2d5c1

View File

@ -1,7 +1,7 @@
# 🛡️ ZeroLagHub Cross-Project Tracker & Drift Prevention System
**Last Updated**: January 18, 2026
**Version**: 1.1 (Canonical Architecture Enforcement + Git Status Update)
**Last Updated**: February 22, 2026
**Version**: 1.2 (DEC-009 through DEC-015 added)
**Status**: ACTIVE - Must Be Consulted Before All Code Changes
---
@ -60,57 +60,57 @@ This document establishes **architectural boundaries** across the three major Ze
---
## 📊 The Three Systems (Canonical Ownership)
## 📋 The Three Systems (Canonical Ownership)
```
┌────────────────────────────────────────────────────────────┐
│ NODE.JS API v2 │
(Orchestration Engine) │
│ (Orchestration Engine)
│ │
│ Owns: VMID allocation, port management, DNS publishing, │
│ Velocity registration, job queue, database state │
│ │
│ Speaks To: Proxmox, Cloudflare, Technitium, Velocity, │
│ Speaks To: Proxmox, Cloudflare, Technitium, Velocity,
│ MariaDB, BullMQ, Go Agent (HTTP) │
│ │
│ Never Touches: Container filesystem, game server files, │
│ Java installation, artifact downloads
└───────────────────────────────────────────────────────────┘
│ HTTP Contract
│ POST /config, /start, /stop
│ GET /status, /health
Java installation, artifact downloads │
└───────────────────────────────────────────────────────────┘
│ HTTP Contract
│ POST /config, /start, /stop
│ GET /status, /health
┌────────────────────────────────────────────────────────────┐
│ GO AGENT │
│ (Container-Internal Manager) │
│ │
│ Owns: Server installation, Java runtime, artifact │
│ downloads, process management, READY detection, │
│ filesystem layout, verification + self-repair │
│ filesystem layout, verification + self-repair
│ │
│ Speaks To: Local filesystem, game server process, │
│ Speaks To: Local filesystem, game server process,
│ API (status updates via HTTP polling) │
│ │
│ Never Touches: Proxmox, DNS, Cloudflare, Velocity, │
│ Never Touches: Proxmox, DNS, Cloudflare, Velocity,
│ port allocation, VMID selection │
└───────────────────────────────────────────────────────────┘
│ Status Polling
│ Agent reports state
└───────────────────────────────────────────────────────────┘
│ Status Polling
│ Agent reports state
┌────────────────────────────────────────────────────────────┐
│ NEXT.JS FRONTEND │
(Customer + Admin UI) │
│ (Customer + Admin UI)
│ │
│ Owns: User interaction, form validation, display logic, │
│ client-side state, UI components │
│ │
│ Speaks To: API v2 only (REST + WebSocket when added) │
│ Speaks To: API v2 only (REST + WebSocket when added)
│ │
│ Never Touches: Proxmox, Go Agent, DNS, Velocity, │
│ Never Touches: Proxmox, Go Agent, DNS, Velocity,
│ Cloudflare, direct container access │
└────────────────────────────────────────────────────────────┘
```
@ -134,34 +134,34 @@ This document establishes **architectural boundaries** across the three major Ze
---
## 🔒 API Agent Contract (IMMUTABLE)
## 🔒 API Agent Contract (IMMUTABLE)
### **API → Agent Endpoints**
```
POST /config
├─ Payload: {
│ game: "minecraft",
│ variant: "paper",
│ version: "1.21.3",
│ ports: [25565, 25575],
│ memory: "4G",
│ motd: "Welcome to ZeroLagHub",
│ worldSettings: {...}
│ }
└─ Response: 200 OK
└─ Payload: {
game: "minecraft",
variant: "paper",
version: "1.21.3",
ports: [25565, 25575],
memory: "4G",
motd: "Welcome to ZeroLagHub",
worldSettings: {...}
}
└─ Response: 200 OK
POST /start
└─ Triggers: ensureProvisioned() → StartServer()
└─ Triggers: ensureProvisioned() → StartServer()
POST /stop
└─ Triggers: Graceful shutdown via server stop command
└─ Triggers: Graceful shutdown via server stop command
POST /restart
└─ Triggers: stop → start sequence
└─ Triggers: stop → start sequence
GET /status
└─ Response: {
└─ Response: {
state: "RUNNING" | "INSTALLING" | "FAILED",
pid: 12345,
uptime: 3600,
@ -169,7 +169,7 @@ GET /status
}
GET /health
└─ Response: {
└─ Response: {
healthy: true,
java: "/usr/lib/jvm/java-21-openjdk-amd64",
variant: "paper",
@ -205,7 +205,7 @@ Agent **NEVER**:
---
## 🖥️ Frontend API Contract (IMMUTABLE)
## 🖥️ Frontend API Contract (IMMUTABLE)
### **Frontend Allowed Endpoints**
@ -249,7 +249,7 @@ Frontend **NEVER**:
---
## 🚨 NEW: Architectural Boundary Enforcement (January 18, 2026)
## 🚀 NEW: Architectural Boundary Enforcement (January 18, 2026)
### **Critical Rule: Frontend Cannot Call Agents**
@ -460,7 +460,7 @@ async function registerVelocity(vmid, hostname, internalIP) {
---
## 🔍 Context Switching Safety Workflow
## 🔑 Context Switching Safety Workflow
### **When Moving to Node.js API Work:**
@ -513,7 +513,7 @@ async function registerVelocity(vmid, hostname, internalIP) {
---
## 🛡️ High-Risk Integration Zones (GUARDED)
## 🛑 High-Risk Integration Zones (GUARDED)
These areas have historically caused drift across sessions:
@ -559,7 +559,7 @@ These areas have historically caused drift across sessions:
---
## 📊 Architecture Decision Log (LOCKED) ⭐ NEW
## 📋 Architecture Decision Log (LOCKED) ⭐ NEW
**Purpose**: Records finalized architectural decisions that **must not be re-litigated** unless explicitly requested.
@ -662,7 +662,7 @@ These areas have historically caused drift across sessions:
---
### **DEC-008: Frontend-Agent Network Isolation (NEW - January 18, 2026)**
### **DEC-008: Frontend-Agent Network Isolation (January 18, 2026)**
**Decision**: Frontend can NEVER call agents directly
@ -682,7 +682,110 @@ These areas have historically caused drift across sessions:
---
## 📊 Canonical Architecture Anchors (ABSOLUTE)
### **DEC-009: Game-Specific API Organization (February 21, 2026)**
**Decision**: Game telemetry lives in a dedicated router (`src/routes/game.js`) mounted at `/api/game`
**Rationale**:
- Clean separation between container lifecycle (existing `/api/containers/*`) and game-runtime telemetry
- Enables per-game feature expansion without polluting the orchestration layer
- Redis-backed polling keeps game state reads fast and agent-decoupled
**Applies To**: API v2
**Status**: ✅ LOCKED
---
### **DEC-010: Engine Abstraction Timing (February 21, 2026)**
**Decision**: Design the engine interface now; implement engine classes when adding game #2
**Rationale**:
- Premature abstraction adds complexity before requirements are clear
- `engineType` + `engineVersion` DB fields added now to avoid a migration later
- Full engine class hierarchy deferred until Rust/Terraria development begins
**Applies To**: API v2, Agent
**Status**: ✅ LOCKED
---
### **DEC-011: Mod Security Model (February 21, 2026)**
**Decision**: Phase 1 = Modrinth-sourced only with hash verification; Phase 2 = user uploads with scanning
**Rationale**:
- Modrinth provides SHA-512 hashes eliminating need for local hash calculation
- Container isolation limits blast radius of any malicious mod
- ClamAV + VirusTotal scanning deferred to Phase 2 to avoid blocking launch
**Applies To**: Agent, API v2, Frontend
**Status**: ✅ LOCKED
---
### **DEC-012: Developer Mod Pipeline (February 21, 2026)**
**Decision**: Dev container → game server mod promotion is a first-class workflow
**Rationale**:
- Core to the developer-to-player revenue pipeline
- Mods developed in LXC dev containers should be installable directly to game servers
- Implementation details deferred; the architectural intent is locked
**Applies To**: Agent, API v2, Frontend
**Status**: ✅ LOCKED
---
### **DEC-013: Artifact Resolver Phase 1 Scope (February 22, 2026)**
**Decision**: `zlh-artifactd` Phase 1 is a **mod resolver only** — no local mod storage, no catalog maintenance
**Rationale**:
- Single-operator sustainability: self-hosting all mod artifacts creates unsustainable manual maintenance
- Phase 1: query Modrinth/NeoForge APIs on demand, return download URL + hash, agent fetches and verifies
- Phase 2: add caching layer based on real usage patterns
- Phase 3: full orchestrator (game jars + runtimes + mods unified)
- Learn ingestion patterns from mods before automating game jars
**Applies To**: Agent, Infrastructure
**Status**: ✅ LOCKED
---
### **DEC-014: Modrinth as Primary Mod Source (February 22, 2026)**
**Decision**: Modrinth is the canonical mod catalog; CurseForge is SFTP-only fallback
**Rationale**:
- Modrinth: open REST API (`api.modrinth.com/v2`), no API key required, SHA-512 hashes provided, 300 req/min rate limit, native NeoForge/Fabric/Forge/Quilt filter support
- CurseForge: hostile download flow (app-first, API restrictions), hostile to automation
- Modrinth hosts the majority of NeoForge mods anyway
- Users accept SFTP for non-Modrinth mods (their friction, not ours)
**Applies To**: Agent, API v2
**Status**: ✅ LOCKED
---
### **DEC-015: NeoForge Version Coverage (February 22, 2026)**
**Decision**: Support NeoForge 1.21.1, 1.21.4, and 1.21.11 at launch; skip all 1.20.x
**Rationale**:
- 1.21.1: highest mod ecosystem density (16,000+ mods), dominant NeoForge era
- 1.21.4: next significant stable adoption wave
- 1.21.11: current latest for bleeding-edge users
- 1.20.x NOT needed: NeoForge never gained traction there; existing Forge installation covers the 1.20.1 modpack ecosystem
- Gap versions (1.21.2, 1.21.5, etc.): minimal mod ecosystem, add on demand if requested
**Applies To**: Infrastructure (artifact tree), Agent
**Status**: ✅ LOCKED
---
## 📋 Canonical Architecture Anchors (ABSOLUTE)
These rules are **immutable** unless explicitly changed with full system review:
@ -724,7 +827,7 @@ These rules are **immutable** unless explicitly changed with full system review:
---
## 🛡️ Enforcement Policies (ACTIVE)
## 🚨 Enforcement Policies (ACTIVE)
When future instructions conflict with Canonical Architecture or Architecture Decision Log:
@ -766,7 +869,7 @@ D) Cancel this change?
```
### **Step 5: ARCHITECTURE DECISION LOG SPECIAL RULE**
If violation is against a **LOCKED** Architecture Decision (DEC-001 through DEC-008):
If violation is against a **LOCKED** Architecture Decision (DEC-001 through DEC-015):
**ADDITIONAL CHECK**:
```
@ -905,4 +1008,4 @@ Before every coding session with any AI:
---
🛡️ **This document prevents architectural drift. Violate at your own risk.**
🚨 **This document prevents architectural drift. Violate at your own risk.**