3 Commits
Author SHA1 Message Date
mattlqxandClaude Code 95e7317b81 feat: log aggregation — the machine ships its logs to Loki
The gameplay logs sat on /dump on the machine, readable only over SSH. Now
they land in Loki for query and tail:

- k8s/loki/loki.yaml: Loki 3.4.4 monolithic on the home cluster's monitoring
  namespace — filesystem storage on CephFS, 30-day retention, traefik ingress
  at loki.k8s-home.lqx.net with a cert-manager cert, Grafana datasource
  auto-registered via the sidecar. reject_old_samples_max_age is a year:
  the machines backfill their history on first ship.
- shipper/: logshipper, a ~300-line static Go service for the machine. Tails
  /dump/mode.log and /dump/switch.log, batches, pushes to Loki's push API.
  Per-file offsets are saved only after a successful push (down Loki =
  retry-then-catch-up, never loss); first run starts at each file's end,
  SHIP_FROM_START=1 ships history; truncation is noticed. Lines keep their
  own RFC 3339 stamp as the Loki timestamp; unstamped lines (the boot
  banner) inherit the next stamped line's, so a stream never starts at
  "now" and jumps back. After a backfill it calls /flush — old entries are
  invisible in the ingester's head until they reach the store (found the
  hard way: Loki answers 204 to an old entry on a new stream and then never
  serves it). Labels: job=pinball, machine, source, game (from the boot
  line). /etc/init.d/log_shipper runs it at boot.

Deployed: Loki is live and verified (query through the ingress). The shipper
is verified end-to-end against the cluster from this Mac; the machine was
unreachable at deploy time — the README has the install commands.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 18:48:25 -04:00
mattlqxandClaude Code 539bab3bdc feat: multi-game port selection — the machine says which game it is on
The runtime tried one port file (game.port) and refused it if the game's
words did not match. Now it tries every *.port in /usr/local/padmode/ports
and /dump/ports (then the single files, the old layout), resetting the port
tables between candidates, and keeps the first whose core sites verify: a
wrong candidate hooks nothing, so trying it is safe, and the port that
verifies names the game (pm_game/pm_version).

The switch log's buttons and names come from the port's switch lines now —
the baked-in King Kong button list and switch_names.inc are gone (the port
lines carry the same ids and names, so King Kong's switch.log is unchanged).

Boot log: each refused candidate says its path and the game/version it
declares; no candidates at all says so; a game update whose port is not
deployed logs the refusal and runs stock.

tests/test_multi_game.py lifts the new code verbatim and compiles it for the
host: selection among candidates, table reset between them, the getdents64
*.port scan (it caught an inverted suffix test and an off-by-one), and the
port-driven switch log. The address-dependent tests need a Linux host (the
port's site addresses are 32 bits; darwin arm64 maps nothing below 4 GiB).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 15:38:45 -04:00
mattlqxandClaude Code abc881f913 feat: add passive GAMELOG event logger for Spike 2 King Kong LE 0.97
Snapshot of the stern-event-agent work (as of 2026-10-12):

- gamelog.c: passive PAD mode logging bus events (game/ball/bonus/tilt),
  all named shots and all-players' scores to /dump/mode.log
- pad_mode_runtime.c: the SDK runtime + a GAMELOG section (passive
  stock-mode and award watching, gl_award_seq()/gl_last_award_id()),
  a per-edge switch logger to /dump/switch.log (switch_names.inc), and
  a passive Insider Connected gate; docs/runtime-patch.diff shows the
  exact changes vs the upstream runtime
- event_probe.c / event_read.py: event-bus measurement tooling for
  identifying bus event ids on another game
- ports/king_kong_le-0.97.port: 121 verified sites, 55 named shots, 6
  bus events (emulator-proven by the SDK repo authors)

Deployed and verified on the machine: events, shots, stock modes and
awards. The /dump/switch.log feature is implemented but NOT yet
deployed or verified, and the extra-ball award id (default 13) is
unconfirmed. See README.md for build/install/log usage and unfinished
work.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-12 13:57:12 -04:00