From cce6007679189596fc866e80499dd73dafb4c6bb Mon Sep 17 00:00:00 2001 From: jester Date: Mon, 2 Mar 2026 00:02:10 +0000 Subject: [PATCH] remove incorrectly dated file (replaced by 2026-02-28) --- ...2026-02-23-modrinth-install-integration.md | 154 ------------------ 1 file changed, 154 deletions(-) delete mode 100644 SESSION_LOG/2026-02-23-modrinth-install-integration.md diff --git a/SESSION_LOG/2026-02-23-modrinth-install-integration.md b/SESSION_LOG/2026-02-23-modrinth-install-integration.md deleted file mode 100644 index 8fe2a37..0000000 --- a/SESSION_LOG/2026-02-23-modrinth-install-integration.md +++ /dev/null @@ -1,154 +0,0 @@ -# 2026-02-23 — Modrinth Install + Full Mod Lifecycle - -**Type:** Foundational Architecture + Implementation -**Status:** Full mod lifecycle complete, file browser next - ---- - -## Completed - -### API - -Implemented full mod lifecycle routes: - -``` -GET /api/game/mods/search?q=&vmid= -GET /api/game/servers/:id/mods -POST /api/game/servers/:id/mods/install -PATCH /api/game/servers/:id/mods/:modId -DELETE /api/game/servers/:id/mods/:modId -``` - -All routes: -- `requireAuth` -- Enforce container ownership -- Enforce `ctype === "game"` -- Forward to agent with timeout + `502`/`504` mapping - -### Resolver - -- Loader normalization fixed (`neoforge` / `fabric` / `forge` / `quilt`) -- `.jar`-only enforcement -- Host allowlist: `cdn.modrinth.com` -- Publish-date safe sorting -- SHA512 preferred (fallback to SHA1) - -### Agent - -Mod install flow: - -- Accepts direct Modrinth artifact URL -- Validates: - - HTTPS only - - Allowed host (`cdn.modrinth.com`, `artifacts.zerolaghub.com`) - - Max size 200MB - - SHA256 hash -- Writes to `/mods` -- Enables via filename convention -- Soft delete moves to `/mods-removed` -- Enable/disable via rename: `.jar` ↔ `.jar.disabled` - -### Frontend - -- Mod search drawer implemented -- Installed mods panel implemented -- Installed flag merged into search results (heuristic matching) -- Install button functional -- Enable / disable functional -- Delete functional -- Toast notifications added - ---- - -## Current System Behavior - -Filesystem is source of truth. - -No database persistence for: -- Mod install history -- Modrinth project ID mapping - -Installed matching is heuristic based on: -- Slug -- Filename -- Name - -Soft delete retains file permanently in `/mods-removed`. No retention policy implemented (intentional). - ---- - -## Known Architectural Tradeoffs - -- No deterministic Modrinth project ID persistence yet -- Installed detection is best-effort heuristic -- No install queue -- No auto-update logic - ---- - -## Security Controls In Place - -**Agent level:** -- HTTPS-only downloads -- Host allowlist enforcement -- Redirect limit (max 3) -- 200MB hard cap -- SHA256 verification -- Filename sanitization (`[a-zA-Z0-9._+-]` — `+` added for Modrinth filenames) -- Duplicate prevention -- Ownership enforcement (`minecraft:minecraft`) -- Temp file cleanup on failure -- Controlled mod directory write path -- Cache invalidation after every mutation - -**API level:** -- Auth + ownership enforcement -- VMID validation -- Timeout protection with `AbortController` -- Resolver filtering (loader + version + stability) -- Correct payload contract to agent - ---- - -## Payload Contract (API → Agent) - -```json -{ - "source": "modrinth", - "download_url": "...", - "filename": "...", - "sha512": "..." -} -``` - -Engine metadata format (corrected this session): - -``` -engineType = "neoforge" (not "minecraft") -engineVersion = "1.21.4" (not "neoforge-1.21.4") -``` - ---- - -## Remaining Issues - -### Response Corruption (Needs Verification) - -One early `curl` output appeared corrupted. Reproduce before wiring portal: - -```bash -curl -sS -D headers.txt -o body.txt ... -``` - -### API Error Mapping Refinement - -- `"mod already exists"` should return `409` (currently `502`) - ---- - -## Next Steps - -1. Reproduce and resolve response corruption issue -2. Tighten API error mapping (`409` for duplicate) -3. Wire install endpoint to portal UI -4. Begin file browser (see `OPEN_THREADS.md`)