Python http.server can't do SPA routing and Caddy was forwarding
/turnstone/* paths that the static server couldn't resolve.
- app/rest.py: mount web/dist/assets as StaticFiles; add SPA catch-all
route that serves index.html for any unmatched path
- manage.sh: start/stop/status simplified to single process on :8534;
remove UI_PORT / UI_PID_FILE; drop http.server invocation
- Caddyfile: replace split API/:8534 + SPA/:8535 block with a single
strip_prefix + reverse_proxy to :8534
Add plex_eae_failure pattern to default.yaml targeting the EasyAudioEncoder
crash signature (EAE timeout + I/O error pair, 5s cadence). Pattern fires
when EAE's WAV handoff files stop appearing in the pms temp directory.
Add watch_plex.py: tail-based watchdog that counts EAE timeout events and
auto-restarts plexmediaserver after N consecutive hits (default 3, ~15s of
failure). Includes cooldown, dry-run mode, and a systemd unit template.
Ingest pipeline (journald / Caddy / Docker-wrapped formats) with
per-source state tracking (repeat dedup, out-of-order detection),
named pattern tagging at ingest time, and idempotent SHA1-keyed writes.
FTS5 search layer with porter stemmer, severity/source/pattern/time
filters, and BM25 ranking. MCP server (FastMCP stdio) with three tools:
search_logs, diagnose, list_log_sources — compatible with both
Claude Code and Copilot CLI.
WAL mode enabled on all connections. FTS index auto-built after ingest.
MCP configs included for Claude Code (.mcp.json) and Copilot CLI
(.github/copilot/mcp.json).