docs: replace README with current system state (upload model, provenance, console, repo usage)
This commit is contained in:
parent
ca105227c3
commit
c378881849
184
README.md
184
README.md
@ -1,74 +1,140 @@
|
||||
# zlh-grind
|
||||
# ZeroLagHub – Grind State Repository
|
||||
|
||||
Execution workspace for **ZeroLagHub (ZLH)**.
|
||||
This repository documents the current architecture, decisions, constraints, and open threads for ZeroLagHub (ZLH).
|
||||
|
||||
This repository is intentionally lightweight and is used for:
|
||||
- project handovers / "where we left off" notes
|
||||
- architecture decisions and rationale
|
||||
- system constraints and guardrails
|
||||
- scratch investigations that shouldn't live in code repos
|
||||
It is not a code repository.
|
||||
It is the authoritative design + operational alignment layer between:
|
||||
|
||||
- Portal (Next.js frontend)
|
||||
- API (Node + Express)
|
||||
- Agent (Go runtime inside containers)
|
||||
|
||||
---
|
||||
|
||||
## Latest handover (2026-02-22)
|
||||
## Current System Overview
|
||||
|
||||
### System state (high confidence)
|
||||
- **PTY-backed consoles are stable** (dev + game) and no longer depend on log tailing.
|
||||
- **Customer isolation is enforced** end-to-end (API auth → ownership checks → per-customer data).
|
||||
- **Agent update system is operational** (versioned, SHA-verified) with periodic checks.
|
||||
- **Game telemetry is now separated** behind a dedicated API router (`/api/game/*`).
|
||||
### Runtime Model
|
||||
|
||||
### What shipped since the prior handover
|
||||
Each game container has a single runtime root:
|
||||
|
||||
#### API (control plane)
|
||||
- Added `src/routes/game.js` and mounted at `/api/game`.
|
||||
- Added `GET /api/game/servers/:id/players` (reads Redis `agent:<vmid>`; returns normalized `{ vmid, playerCount, players, max, timestamp }`).
|
||||
- Extended `src/utils/agentPoller.js`:
|
||||
- polls agent `GET /game/players` for **game** containers and caches in Redis.
|
||||
- polls agent `GET /version` and `GET /agent/update/status`; derives `updateAvailable`.
|
||||
- Added `GET /api/game/servers/:id/update-status` (returns agent version + update state).
|
||||
- Provisioning persists engine metadata:
|
||||
- `engineType = "minecraft"` for game containers
|
||||
- `engineVersion` from payload
|
||||
- dev containers set both to `null`
|
||||
- Rolled back API-triggered update during provisioning (back to direct `/config` provisioning flow).
|
||||
```
|
||||
/opt/zlh/minecraft/<runtime>/<world>/
|
||||
```
|
||||
|
||||
#### Frontend (portal)
|
||||
- Game console now polls:
|
||||
- `GET /api/game/servers/:id/players`
|
||||
- `GET /api/game/servers/:id/update-status`
|
||||
- Player presence shows count + optional name list.
|
||||
- Version context displayed as `Version: X` or `Version: X -> Y`.
|
||||
- Auth behavior unchanged (all calls through `apiClient` with JWT Bearer).
|
||||
All file operations are resolved relative to this root.
|
||||
|
||||
#### Agent (runtime)
|
||||
- `GET /game/players` hardened for reliability (port/protocol fallbacks).
|
||||
- Added periodic update checks:
|
||||
- `ZLH_AGENT_UPDATE_MODE=notify|auto|off`
|
||||
- `ZLH_AGENT_UPDATE_INTERVAL` (default `30m`; first check ~10s after boot)
|
||||
- Added Phase 1 mod management endpoints:
|
||||
- `GET /game/mods`
|
||||
- `POST /game/mods/install`
|
||||
- `PATCH /game/mods/:mod_id`
|
||||
- `DELETE /game/mods/:mod_id`
|
||||
- Added `GET /metrics/process` (PID + memory via `/proc/<pid>/status`, restart_count mapped to crash count).
|
||||
- Added Minecraft readiness probe after start/restart + stop-wait-before-restart sync to reduce restart races.
|
||||
- Logging improved with `lifecycle.log` alongside `agent.log`.
|
||||
|
||||
#### Artifacts
|
||||
- Artifact tree expanded to include **NeoForge** under `.../minecraft/neoforge/<mc_version>/`.
|
||||
- Phase 1 contract: NeoForge installer filename is normalized to `neoforge-installer.jar` within the version directory.
|
||||
The agent is the only authority allowed to mutate the filesystem.
|
||||
|
||||
---
|
||||
|
||||
## Primary focus moving forward
|
||||
## File System Capabilities (Current State)
|
||||
|
||||
1. **API proxy endpoints for mods + process metrics** (to mirror agent capabilities behind auth/ownership).
|
||||
2. **Artifact catalog + ingestion workflow** (Modrinth/NeoForge local-first, approval-gated).
|
||||
3. **Frontend Mods UI** (installed mods list + enable/disable/remove + curated install; upload likely Phase 2).
|
||||
4. **Concurrent provisioning validation** (multi-user parallel create + port allocation + isolation).
|
||||
### Read
|
||||
- List
|
||||
- Stat
|
||||
- Read text files
|
||||
- Download
|
||||
- Hidden internal paths blocked (`.zlh_metadata.json`, `.zlh-shadow`)
|
||||
|
||||
See:
|
||||
- `OPEN_THREADS.md` for remaining work
|
||||
- `CONSTRAINTS.md` + `ANTI_DRIFT*.md` for guardrails
|
||||
- `SESSION_LOG.md` for a chronological ledger
|
||||
### Write
|
||||
- Full overwrite for:
|
||||
- `server.properties`
|
||||
- `config/*.toml`
|
||||
- `config/*.json`
|
||||
- `config/*.properties`
|
||||
- Shadow backup created on first modification
|
||||
- Manual revert supported
|
||||
- No automated rollback for user writes
|
||||
|
||||
### Delete (Constrained)
|
||||
Allowed only for:
|
||||
- `mods-removed/<file>`
|
||||
- `mods-uploaded/<file>`
|
||||
- `logs/<file>.log`
|
||||
- `logs/<file>.log.gz`
|
||||
|
||||
No directory deletes. No recursive deletes.
|
||||
|
||||
### Upload
|
||||
Allowed only for:
|
||||
- `mods/<file>.jar`
|
||||
- `world/datapacks/<file>.zip`
|
||||
|
||||
Uploads:
|
||||
- Are streamed (raw `http.request` piping in API)
|
||||
- Written atomically via `os.Rename()`
|
||||
- Enforced by strict allowlist
|
||||
- Do not create directories
|
||||
- Do not use staging
|
||||
- Do not use symlinks
|
||||
|
||||
---
|
||||
|
||||
## Provenance Model
|
||||
|
||||
User uploads write to `.zlh_metadata.json` at runtime root.
|
||||
|
||||
```json
|
||||
{
|
||||
"mods/sodium.jar": {
|
||||
"source": "user",
|
||||
"uploaded_at": "2026-03-01T22:37:01Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`stat` returns `"source": "user" | null`
|
||||
|
||||
No curated inference currently implemented.
|
||||
|
||||
---
|
||||
|
||||
## Upload Transport
|
||||
|
||||
```
|
||||
Browser → API → Agent
|
||||
```
|
||||
|
||||
API uses raw Node `http.request` piping:
|
||||
|
||||
```js
|
||||
req.pipe(proxyReq)
|
||||
proxyRes.pipe(res)
|
||||
```
|
||||
|
||||
No `fetch()` streaming for uploads. Upload timeout must be significantly larger than normal file operations.
|
||||
|
||||
---
|
||||
|
||||
## Console Model
|
||||
|
||||
`TerminalView` owns WebSocket lifecycle. `ServerConsole` owns policy + session gating.
|
||||
|
||||
Console reconnect is automatic. File panel does not interrupt console lifecycle.
|
||||
|
||||
---
|
||||
|
||||
## Repo Usage
|
||||
|
||||
This repo is used to:
|
||||
- Prevent architecture drift
|
||||
- Track decisions
|
||||
- Record sessions
|
||||
- Track open threads
|
||||
- Keep portal/API/agent alignment clean
|
||||
|
||||
---
|
||||
|
||||
## Update Instructions
|
||||
|
||||
When updating this repo:
|
||||
|
||||
1. Update `SESSION_LOG.md` with date-stamped entry
|
||||
2. Update `OPEN_THREADS.md` if decisions were resolved
|
||||
3. Update `CONSTRAINTS.md` if guardrails changed
|
||||
4. Keep architecture docs consistent with real code behavior
|
||||
5. Do not document future features as implemented
|
||||
|
||||
---
|
||||
|
||||
**System posture: Stable, controlled expansion phase.**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user