Step-3 deliverable from the #careful run. Captures the fork target verification (mclogs MIT-licensed, active, PHP 8.5 floor, MongoDB storage, already integrates Aternos's codex stack), the Composer dep plan (indifferentketchup/codex via Gitea VCS pinned to v0.1.0), the multi-file/session model decision (option iii — session-as-entity wrapping N files, with mclogs single-pastes degenerating to sessions-of-size-1), the UI changes (file-type tabs, redaction toggle gated on Step 4), the API surface (session-aware new endpoints plus legacy /api/1/log routes preserved for back-compat), a directional string/branding inventory at file-level (line-precise inventory deferred until the fork is cloned and grep-able), the migration strategy (keep legacy routes, strip aternos/codex-* and Sherlock and Aternos\Mclogs namespace), and open questions including the codex Redactor decision deferred to Step 4. No iblogs code is written by this commit. The fork, rename, and rewire happen in a follow-up session after design approval.
18 KiB
iblogs bootstrap design
Written 2026-05-01. Scope: design only. No iblogs code is written by this document; the actual fork, rename, and rewire happen in a follow-up session after this design is approved.
Summary
iblogs is a Project-Zomboid-first log triage service forked from aternosorg/mclogs. It consumes indifferentketchup/codex (pinned at v0.1.0) for log detection, parsing, and analysis, replacing mclogs's aternos/codex-minecraft / aternos/codex-hytale / aternos/sherlock dependency stack. The data model gains a session entity that wraps the multiple files Project Zomboid produces per server session (eleven file types per session), while mclogs's existing single-paste paths remain alive as legacy routes that map to "session of size 1."
(a) Fork target verification
| Check | Value |
|---|---|
| Upstream | github.com/aternosorg/mclogs |
| Default branch | main |
| License | MIT (SPDX MIT) — compatible with indifferentketchup/codex's MIT |
| Last push | 2026-03-30 (active; ~30 days ago) |
| Last update | 2026-04-26 |
| Archived | no |
| Stars / open issues | 290 / 2 |
| PHP requirement | >=8.5, plus ext-frankenphp, ext-mongodb, ext-uri, ext-zlib, ext-mbstring, ext-json |
| Storage | MongoDB |
| Existing codex dep | yes — aternos/codex-minecraft ^5.0.1 and aternos/codex-hytale ^2.0 |
Verdict: GO. License is compatible. Project is actively maintained. No archival or licensing blockers. The fact that mclogs already integrates Aternos's codex stack tells us the fork's swap surface is well-defined: replace those Composer deps and the codex-facing call sites in src/Api/Action/AnalyseLogAction.php / src/Api/Action/LogInsightsAction.php / src/Api/Response/CodexLogResponse.php / src/Detective.php / src/Log.php.
The PHP >=8.5 floor is stricter than codex's >=8.4 — iblogs inherits the stricter constraint, which is fine. The ext-frankenphp requirement means iblogs runs on the FrankenPHP runtime rather than vanilla PHP-FPM; preserving this is the path of least resistance.
aternos/sherlock (MIT, "PHP library to apply minecraft mappings to log files") is Minecraft-specific (Mojang obfuscation maps). It is not needed for PZ and gets dropped. If iblogs ever adds Minecraft support, it can come back.
(b) Repo plan
Primary remote: Gitea at git.indifferentketchup.com:2222. Fork as indifferentketchup/iblogs. SSH clone URL: ssh://git@git.indifferentketchup.com:2222/indifferentketchup/iblogs.git. Match the codex repo's existing Gitea setup.
GitHub mirror: Push-only secondary, configured via Gitea's Mirror feature (Repo Settings → Mirror Settings → Push Mirror). Same pattern any team using Gitea-as-primary uses for visibility.
Composer dep on codex. iblogs's composer.json gains a repositories entry of type vcs pointing at the codex Gitea URL (ssh://git@git.indifferentketchup.com:2222/indifferentketchup/ik-codex.git), and a require entry for indifferentketchup/codex pinned to exactly 0.1.0. The exact pin is preferred over ^0.1.0 for early-version (0.x) releases where minor bumps may carry breaking changes.
Removed deps: aternos/codex-minecraft, aternos/codex-hytale, aternos/sherlock. The first two are replaced by indifferentketchup/codex (which covers Project Zomboid and ships detective stubs for Minecraft / Hytale / SevenDaysToDie that iblogs will not use in v0.1). The third (Sherlock) is Minecraft-mapping-specific and not relevant to PZ.
Package name. aternos/mclogs becomes indifferentketchup/iblogs. Composer name and the PSR-4 namespace move together: Aternos\Mclogs\ → IndifferentKetchup\Iblogs\.
(c) Multi-file / session paste model
Project Zomboid produces eleven log files per server session. The data model needs to accommodate this without breaking mclogs's existing single-paste consumers.
Option (i) — 1 file = 1 paste, sibling-link via shared session_id
- Pros: minimal schema change. Reuse mclogs's existing
Logper file. Sibling discovery is asession_idindex. - Cons: no atomic ingest (zip becomes N independent uploads). Session views require runtime joins.
session_idpropagation through upload UX is fiddly (URL param? cookie? hidden form field?). - Effort: low.
Option (ii) — zip upload explodes server-side into N linked pastes
- Pros: atomic ingest. One endpoint for whole-session upload. Maps cleanly to PZ's natural zip-of-logs deliverable.
- Cons: zip-only ingest is restrictive (no single-file paste UX for users with just
DebugLog-server.txt). Server-side zip extraction is attack surface (zip bombs, path traversal). Doubles upload paths if single-file is also supported. - Effort: medium.
Option (iii) — session entity wraps N file entities (1:N relation)
- Pros: rich session model. Single URL for the whole session; child URLs per file. PZ's eleven-file natural session maps cleanly. mclogs's single-paste maps to "session of size 1," so the model degenerates gracefully into legacy behaviour. Session-level metadata (server name, date range, total size) becomes first-class.
- Cons: most schema migration. Two URL types in routing. More concepts in the API.
- Effort: medium-high.
Recommendation: option (iii)
PZ's natural unit IS a session — the server emits all eleven files per restart, ZIP-bundled in production. Single-file uploads (the mclogs default UX) become "session of size 1" with no special-case code; the legacy /api/1/log routes return a paste that happens to belong to a singleton session. Cross-file analysis (e.g. correlating a ServerExceptionProblem from DebugLog-server.txt with a ConnectionFailureProblem from user.txt) is unlocked because both files share a session_id. The 1:N model is the only one that supports cross-file analysers in any future Phase B.4-equivalent on iblogs's side.
(d) UI changes
Primary nav: file-type tabs. Within a session, eleven tabs (one per PZ file type) with a count badge (e.g. DebugLog (6,998 lines), chat (115)). Clicking a tab loads that file's content + analysis. Tab order: DebugLog-server first (most useful for triage), then admin, user, chat, item, map, perk, pvp, ClientActionLog, cmd, BurdJournals.
Secondary nav: session index sidebar. Lists the user's recent sessions (cookie-driven, like mclogs's history). Less primary than tabs.
Default view. /session/{id} lands on the DebugLog-server tab by default — that file is what admins want to see when something is broken.
Redaction toggle. Per-session checkbox in the toolbar: "Redact PII". Behaviour depends on Step 4 (codex Redactor) status:
- If Redactor ships first: toggle invokes
ProjectZomboidRedactor::redact()on the rendered file content client-side or server-side (decision for the implementation pass). - If Redactor is still deferred: toggle is hidden in v0.1 of iblogs. Upload-time PII filtering still happens via the ported
Filterchain (seesrc/Filter/*upstream —IPv4Filter,IPv6Filter,AccessTokenFilter,UsernameFilter).
Branding. Drop the "Built for Minecraft & Hytale" tagline and visual cues. Replace mclo.gs brand references with whatever short-domain iblogs uses (open question — see (h)). Color palette decision is open; mclogs's green accent (#5cb85c in example.config.json) is fine to keep or change.
(e) API surface
Iblogs exposes a session-oriented API on top of the recommended (iii) model, plus the legacy mclogs paths kept alive.
| Path | Method | Purpose |
|---|---|---|
/api/session |
POST | Create a session by uploading one zip OR multiple file fields. Returns session_id plus a list of {type, paste_id} for each contained file. |
/api/session/{id} |
GET | Return session metadata + array of contained pastes ({type, paste_id, line_count, size_bytes}). |
/api/session/{id}/file/{type} |
GET | Return one file's content and its codex analysis result. {type} is one of the eleven PZ file-type tokens (server, chat, clientaction, cmd, item, map, perk, pvp, admin, user, burdjournals). |
/api/paste/{id} |
GET | Single-paste back-compat. Returns content + analysis for any paste (whether part of a multi-file session or a singleton). |
/api/1/log |
POST | Legacy mclogs path — kept alive. Internally creates a singleton session under the hood and returns the existing-shape mclogs response. |
/api/1/log/{id} |
GET | Legacy mclogs path — kept alive. Same as /api/paste/{id} with the legacy response shape. |
The legacy paths preserve mclogs's API contract for any third-party clients that already integrate with mclo.gs or self-hosted mclogs instances. Upgrading clients to the session-aware API is opt-in.
(f) String / branding inventory
Producing exact path:line references requires the cloned working copy of the fork. This section gives directional pointers from the fetched-but-not-cloned upstream tree at aternosorg/mclogs:main. The actual line-precise inventory belongs in a follow-up commit on the iblogs side, after the fork exists and can be grepped.
Composer / package metadata — file composer.json upstream (no local clone, line refs not yet known):
"name": "aternos/mclogs"→"indifferentketchup/iblogs""description": "Paste, share and analyse Minecraft logs"→ describe iblogs scope (PZ-first, server-log triage)"authors"block (currentlyMatthias Neid <matthias@aternos.org>) → replace withindifferentketchupauthorrequireblock:- drop
aternos/codex-minecraft - drop
aternos/codex-hytale - drop
aternos/sherlock - add
indifferentketchup/codexpinned to0.1.0
- drop
autoload.psr-4mapping"Aternos\\Mclogs\\": "src/"→"IndifferentKetchup\\Iblogs\\": "src/"- new top-level
repositoriesarray entry of typevcspointing at the codex Gitea URL
Namespace bulk substitution — every PHP file under src/ (which is roughly 50+ files based on the upstream tree). The pattern mirrors the codex rename in commit 66a2fcc: bulk Aternos\Mclogs → IndifferentKetchup\Iblogs across namespace, use, fully-qualified refs, and PHPDoc tags. Done as one logical commit on the iblogs side per the codex-side precedent.
Codex API call sites — the files mclogs uses to integrate Aternos's codex stack, all under src/:
src/Detective.php— likely a wrapper aroundaternos/codex-minecraft's Detective. Swap toIndifferentKetchup\Codex\Detective\ProjectZomboid\ProjectZomboidDetective(or wrap multiple game detectives if iblogs ever supports more games).src/Log.php— likely a wrapper. Re-point to codex'sLoghierarchy.src/Api/Action/AnalyseLogAction.php— theanalyseendpoint. Update to call codex'sAnalysableLog::analyse()with the new analyser surface.src/Api/Action/LogInsightsAction.php— insights endpoint.src/Api/Response/CodexLogResponse.php— response shape; verify field-by-field againstIndifferentKetchup\Codex\Analysis\AnalysisInterface::jsonSerialize().src/Api/Action/CreateLogAction.php— log creation; integration with codex'sDetective::detect().src/Api/Action/RawLogAction.php,src/Api/Action/LogInfoAction.php— verify these don't depend on Minecraft-specific codex behaviour.
Frontend templates and assets — file paths only, exact branding strings discovered post-clone:
web/frontend/start.php— landing page; "Paste, share and analyse Minecraft logs" hero copy lives here.web/frontend/api-docs.php— API documentation page.web/frontend/parts/header.php,parts/footer.php,parts/head.php— site title, meta tags, footer links to legal info.web/frontend/log.php— log view template (probably hardcodes the syntax-highlighting language token — needs to handle multiple PZ file types).web/frontend/404.php— error page copy.web/public/css/mclogs.css— file is renamed toiblogs.cssand CSS class names referencingmclogsare renamed.web/public/js/start.js,web/public/js/log.js— likely contain text constants and referencemclogs.cssfilename.web/public/img/logo-icon.svg,logo.svg,favicon.ico— replaced with iblogs assets.
Configuration — file example.config.json:
- database name
mclogs→iblogs - abuse contact
abuse@aternos.org→ iblogs contact (open question — see (h)) - imprint and privacy policy links currently point at
aternos.gmbh→ iblogs equivalents mclo.gsbrand reference in the frontend styling section → new iblogs short-domain (open question)- worker request limit, ID length, TTL — review for iblogs-appropriate values; PZ sessions are larger than mclogs single pastes so size and line limits may need raising.
Docker / deployment — files Dockerfile, docker/Caddyfile, docker/compose.production.yaml, docker/mclogs.ini:
- Image label maintainer references
- Caddyfile likely hardcodes
mclo.gshostname for TLS certificates → replace with iblogs hostname - Compose service name
mclogs→iblogs - File
docker/mclogs.iniis renamed and its contents updated
LICENSE file — per MIT requirements, the original Aternos copyright line stays byte-for-byte unchanged. iblogs's LICENSE preserves the upstream copyright header. This mirrors codex's handling of its own upstream LICENSE.
README.md — full rewrite. Title, description, install line, links to upstream codex repo, scope statement (PZ-first, server-log triage). Drop Minecraft / Hytale framing entirely.
Filter classes for PZ-specific PII — upstream's filter chain (src/Filter/IPv4Filter.php, IPv6Filter.php, AccessTokenFilter.php, UsernameFilter.php) handles Minecraft-style PII (server access tokens, Minecraft-pattern usernames). For PZ, iblogs may need new filters: SteamIdFilter, WorldCoordinateFilter, and a PZ-aware username filter (Steam usernames look different from Minecraft ones). These are net-new code, not branding renames.
(g) Migration
Keep mclogs's existing single-paste API routes alive as legacy. Two reasons:
- mclogs has live API consumers calling
POST /api/1/logandGET /api/1/log/{id}againstmclo.gsand self-hosted instances. Iblogs's primary value is PZ support, not breaking compat with the broader mclogs ecosystem. - Under model option (iii), legacy single pastes are naturally "sessions of size 1." Zero extra schema work to support legacy routes — they just internally create singleton sessions.
Strip: aternos/codex-minecraft, aternos/codex-hytale, aternos/sherlock Composer deps; the Aternos\Mclogs\ namespace; mclogs-specific branding strings; the mclo.gs hostname hardcodes; Minecraft-mapping deobfuscation code paths.
Preserve: the upstream Filter chain (it solves real problems — IP redaction, access tokens, usernames); the FrankenPHP runtime; MongoDB storage layer; the cookie-based session-history UX; the Caddy fronting.
(h) Open questions
aternos/sherlocklicense confirmation — verified MIT (this design doc fetched the metadata) but iblogs is dropping it. No issue.ext-frankenphpkeep / replace decision — recommend keep for v0.1 (path of least resistance). Migrating to vanilla nginx+php-fpm is its own project and can come later.- Branding decisions:
- Site name:
iblogs(lowercase) seems chosen given the project mentionindifferentketchup/iblogs. Confirm. - Tagline: needs writing. "Project Zomboid server log triage" is honest; longer-form copy is open.
- Short-domain: mclogs uses
mclo.gs. Is there an iblogs equivalent (iblo.gs?ib.gs?)? Affects Caddyfile, frontend assets, and docs links. - Accent / palette: keep mclogs green (
#5cb85c) or pick a different colour?
- Site name:
- Database choice: keep MongoDB or migrate to PostgreSQL / SQLite? Migrating away from Mongo is a significant project; recommend keep for v0.1.
- API URL versioning: mclogs uses
/api/1/. Stay with/api/1/for legacy paths (compat) and add/api/session/...for new endpoints (no version prefix), or use/api/v2/session/...? Recommend the former — minimum surface change. - Session-ID generation: mclogs uses 7-character IDs. For iblogs sessions of N files, pick (a) one session-ID + N independent paste-IDs (richer URLs) or (b) single ID per paste with a sibling
session_idfield (simpler). Affects URL shape. - The codex Redactor utility. Iblogs's redaction toggle (section d) depends on whether Step 4 (Redactor implementation) ships before or after iblogs scaffolding. Decision deferred to user (Step 4 of the careful run).
- PZ-specific filter classes (
SteamIdFilter,WorldCoordinateFilter, etc.) — net-new work for iblogs. Could lift the regex shapes fromdocs/superpowers/specs/2026-04-30-redactor-design.md(they're the same PII categories). Implementation order: iblogs likely wants these for its upload-time filter chain regardless of whether the codexRedactorships. - Multi-game support trajectory. v0.1 of iblogs is PZ-first. If Minecraft / Hytale / SevenDaysToDie support is on the roadmap, iblogs's Detective wiring needs to be a multi-game dispatcher (not just
ProjectZomboidDetective). Codex provides the per-game detectives separately; iblogs would compose them. Out of scope for v0.1. - The exact line-precise branding inventory (every file:line ref of
Minecraft/Hytale/MC/mc/mclogs/mclo.gs/Aternos). This document gives file-level pointers; the line-precise version is produced as a separate work item once the fork is cloned and grep-able.
Pointers
- Codex package consumed:
indifferentketchup/codexv0.1.0, tag SHA8a89550(annotated tag) pointing at commit52ff8cb. - Codex Redactor design (deferred):
docs/superpowers/specs/2026-04-30-redactor-design.md. - Codex CHANGELOG:
CHANGELOG.mdin this repo. - Upstream mclogs:
https://github.com/aternosorg/mclogs(MIT,maindefault branch, last push 2026-03-30).