3.3 KiB
3.3 KiB
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/504mapping
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
<serverRoot>/mods - Enables via filename convention
- Soft delete moves to
<serverRoot>/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)
{
"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:
curl -sS -D headers.txt -o body.txt ...
API Error Mapping Refinement
"mod already exists"should return409(currently502)
Next Steps
- Reproduce and resolve response corruption issue
- Tighten API error mapping (
409for duplicate) - Wire install endpoint to portal UI
- Begin file browser (see
OPEN_THREADS.md)