indifferentketchup 409de16003 docs: add Redactor implementation plan
Forward-looking plan on the redactor branch covering all eight design
questions called out in the careful-protocol kickoff: render-time
filter (raw is canonical), standalone string utility (not a Printer
decorator), regex-based detection with lexical anchors per PII
category, per-category placeholder replacement matching synthetic
fixture conventions, thin generic interface plus per-game
implementation under src/Util/ProjectZomboid/, hybrid fixture strategy
(unit-level synthetic plus integration against existing PZ fixtures).

Branch off master aec835e. backup/pre-redactor tag pins start.
No code is written by this commit. Implementation pass kicks off
separately after plan review.
2026-05-01 14:28:44 +00:00
2026-04-30 22:43:44 +00:00
2026-04-30 22:43:44 +00:00

IndifferentKetchup Codex

Generic PHP log parsing and analysis framework. Reads a log file, detects which log type it is, parses entries (including multi-line records like Java stack traces), runs the type-specific analysers, and returns structured Information and Problem insights with attached Solutions where applicable.

Originally a fork of aternos/codex; the framework is intentionally game-agnostic. The reference implementation in this tree is Project Zomboid server logs.

Install

composer require indifferentketchup/codex

Requires PHP >=8.4. No third-party runtime dependencies.

Quick start

Given a Project Zomboid DebugLog-server.txt:

<?php
require __DIR__ . '/vendor/autoload.php';

use IndifferentKetchup\Codex\Detective\ProjectZomboid\ProjectZomboidDetective;
use IndifferentKetchup\Codex\Log\File\PathLogFile;

$detective = new ProjectZomboidDetective();
$detective->setLogFile(new PathLogFile('2026-04-30_14-00_DebugLog-server.txt'));

$log = $detective->detect();
$log->parse();
$analysis = $log->analyse();

echo $log->getTitle(), "\n\n";

foreach ($analysis->getInformation() as $info) {
    echo "[INFO] ", $info->getMessage(), "\n";
}

foreach ($analysis->getProblems() as $problem) {
    echo "[PROBLEM] ", $problem->getMessage(), "\n";
    foreach ($problem->getSolutions() as $solution) {
        echo "          -> ", $solution->getMessage(), "\n";
    }
}

For a session with mod issues and a server-side exception, output looks roughly like:

Project Zomboid Debug Server Log

[INFO] Engine version: 42.16.3 (build <hash>, <build date>)
[INFO] Mod loaded: <mod_id>
[INFO] Mod loaded: <other_mod_id>
[PROBLEM] Required mod "<missing>" not found.
          -> Subscribe to mod "<missing>" or remove its ID from the Mods= line in serverconfig.ini.
[PROBLEM] Exception thrown: java.nio.file.NoSuchFileException

If the log content arrives without a filesystem path (clipboard paste, web upload, stream), use StringLogFile or StreamLogFile instead of PathLogFile. The detective falls back to content signatures when the filename hint is absent.

Architecture

LogFile → Log → parse() → Entry[] of Line[] → analyse() → Analysis of Insight[]
                                                          └── Information | Problem(+Solutions)
  • Detective ranks candidate Log subclasses by running each candidate's static getDetectors() and picking the highest-scoring result. Each game ships its own <Game>Detective that pre-registers its log classes.
  • PatternParser is regex-driven; lines that don't match the entry-start regex append to the previous Entry, which is how multi-line records (Java stack traces, indented warnings) are kept intact.
  • Analysers come in two flavours: configured PatternAnalyser instances for per-entry pattern matching, and custom subclasses of Analyser for cross-entry logic (pairing events, sliding-window thresholds, snapshot comparisons).
  • Insights are either Information (label + value) or Problem (with attached Solutions). Equal insights coalesce via a counter, so repeated patterns don't produce duplicate output.

Patterns live as plain string constants under src/Pattern/<Game>/ — there is no PatternInterface. Each game adds files under src/<Component>/<Game>/ (components-outer, game-suffixed). Full extension guide and conventions in CLAUDE.md.

Game support

Game State
Project Zomboid Full: 11 log subclasses across all the file types a server emits; analysers covering engine version, mod loading, server exceptions, PvP combat, admin audit, connection failures, item duplication, skill progression anomalies
Minecraft Stub only — MinecraftDetective skeleton, no log subclasses yet
Hytale Stub only
Seven Days To Die Stub only

The framework itself is generic — adding a new game means writing the same shape of files Project Zomboid demonstrates, not modifying anything in src/{Analyser,Analysis,Detective,Log,Parser,Printer,Pattern}/ outside the new game's subdirectory.

Developing

composer test runs the suite. PHP and Composer are not required on the host — invocations wrap in the official composer:latest Docker image (PHP 8.5). See CLAUDE.md for the wrapped command, file layout, and the workflow conventions used in this repo.

Source

https://git.indifferentketchup.com/indifferentketchup/ik-codex

License

MIT — see LICENSE.

Description
No description provided
Readme MIT 476 KiB
Languages
PHP 79.3%
Python 20.4%
Shell 0.3%