From 6fde2d49ffe0b7ea9a4eb432480efdd047ae4547 Mon Sep 17 00:00:00 2001 From: indifferentketchup Date: Fri, 1 May 2026 13:03:48 +0000 Subject: [PATCH] docs: add iblogs bootstrap design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../2026-05-01-iblogs-bootstrap-design.md | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-01-iblogs-bootstrap-design.md diff --git a/docs/superpowers/specs/2026-05-01-iblogs-bootstrap-design.md b/docs/superpowers/specs/2026-05-01-iblogs-bootstrap-design.md new file mode 100644 index 0000000..d88cd79 --- /dev/null +++ b/docs/superpowers/specs/2026-05-01-iblogs-bootstrap-design.md @@ -0,0 +1,186 @@ +# 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 `Log` per file. Sibling discovery is a `session_id` index. +- **Cons:** no atomic ingest (zip becomes N independent uploads). Session views require runtime joins. `session_id` propagation 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 `Filter` chain (see `src/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 `grep`ped. + +**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 (currently `Matthias Neid `) → replace with `indifferentketchup` author +- `require` block: + - drop `aternos/codex-minecraft` + - drop `aternos/codex-hytale` + - drop `aternos/sherlock` + - add `indifferentketchup/codex` pinned to `0.1.0` +- `autoload.psr-4` mapping `"Aternos\\Mclogs\\": "src/"` → `"IndifferentKetchup\\Iblogs\\": "src/"` +- new top-level `repositories` array entry of type `vcs` pointing 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 around `aternos/codex-minecraft`'s Detective. Swap to `IndifferentKetchup\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's `Log` hierarchy. +- `src/Api/Action/AnalyseLogAction.php` — the `analyse` endpoint. Update to call codex's `AnalysableLog::analyse()` with the new analyser surface. +- `src/Api/Action/LogInsightsAction.php` — insights endpoint. +- `src/Api/Response/CodexLogResponse.php` — response shape; verify field-by-field against `IndifferentKetchup\Codex\Analysis\AnalysisInterface::jsonSerialize()`. +- `src/Api/Action/CreateLogAction.php` — log creation; integration with codex's `Detective::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** to `iblogs.css` and CSS class names referencing `mclogs` are renamed. +- `web/public/js/start.js`, `web/public/js/log.js` — likely contain text constants and reference `mclogs.css` filename. +- `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.gs` brand 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.gs` hostname for TLS certificates → replace with iblogs hostname +- Compose service name `mclogs` → `iblogs` +- File `docker/mclogs.ini` is 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: +1. mclogs has live API consumers calling `POST /api/1/log` and `GET /api/1/log/{id}` against `mclo.gs` and self-hosted instances. Iblogs's primary value is PZ support, not breaking compat with the broader mclogs ecosystem. +2. 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 + +1. **`aternos/sherlock` license confirmation** — verified MIT (this design doc fetched the metadata) but iblogs is dropping it. No issue. +2. **`ext-frankenphp` keep / 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. +3. **Branding decisions:** + - Site name: `iblogs` (lowercase) seems chosen given the project mention `indifferentketchup/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? +4. **Database choice:** keep MongoDB or migrate to PostgreSQL / SQLite? Migrating away from Mongo is a significant project; recommend keep for v0.1. +5. **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. +6. **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_id` field (simpler). Affects URL shape. +7. **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).** +8. **PZ-specific filter classes** (`SteamIdFilter`, `WorldCoordinateFilter`, etc.) — net-new work for iblogs. Could lift the regex shapes from `docs/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 codex `Redactor` ships. +9. **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. +10. **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/codex` v0.1.0, tag SHA `8a89550` (annotated tag) pointing at commit `52ff8cb`. +- Codex Redactor design (deferred): `docs/superpowers/specs/2026-04-30-redactor-design.md`. +- Codex CHANGELOG: `CHANGELOG.md` in this repo. +- Upstream mclogs: `https://github.com/aternosorg/mclogs` (MIT, `main` default branch, last push 2026-03-30).