refactor(t-paliad-151): extract Paliadin interface; rename PaliadinService → LocalPaliadinService

Phase B step 1 of the Tailscale-SSH route to mRiver. Splits the existing
local-tmux PoC into a Paliadin interface with two implementations; the
remote-SSH backend lands in a follow-up commit (paliadin_remote.go).

Surface:
- Paliadin interface — RunTurn, ResetSession, ListRecentTurns, Stats,
  IsOwner. The handler at internal/handlers/paliadin.go now talks to
  this instead of the concrete struct.
- paliadinDB — embedded base type carrying the audit-table I/O
  (insertTurnRow, completeTurn, markTurnError, markTurnAbandonedOrError)
  plus the read-side queries (IsOwner, ListRecentTurns, Stats). Both
  Local and Remote impls inherit these by embedding paliadinDB so the
  remote path doesn't have to duplicate any DB code.
- LocalPaliadinService — the renamed PoC backend. Identical behaviour
  to the previous PaliadinService; only the type name and method
  receivers change. Method receivers split: tmux-specific operations
  (RunTurn, ResetSession, ensurePane, sendToPane, pollForResponse, etc.)
  stay on *LocalPaliadinService; DB-only operations promote to
  *paliadinDB.

Wiring:
- internal/handlers/handlers.go — Paliadin field becomes the interface
  type; Register() unchanged.
- cmd/server/main.go — calls NewLocalPaliadinService instead of
  NewPaliadinService. The remote-vs-local switch on PALIADIN_REMOTE_HOST
  lands in B5.

Tests in paliadin_test.go all green — they test package-level functions
(splitTrailer, countChips, approxTokenCount, sanitiseForTmux,
PaliadinOwnerEmail) and don't touch the renamed struct. No behaviour
change on the local-tmux path.

Refs m/paliad#12
This commit is contained in:
m
2026-05-08 02:14:12 +02:00
parent f62bf9f8fb
commit 56a3dc961e
4 changed files with 75 additions and 48 deletions

View File

@@ -69,10 +69,12 @@ type Services struct {
Pin *services.PinService
CardLayout *services.CardLayoutService
// Paliadin is wired only when PALIADIN_ENABLED=true at boot
// (PoC; m's laptop only). On prod it stays nil and all /paliadin*
// routes 404 because Register() skips registering them.
Paliadin *services.PaliadinService
// Paliadin is wired when DATABASE_URL is set. The concrete backend
// is picked in cmd/server/main.go based on PALIADIN_REMOTE_HOST
// (remote → mRiver via SSH) or local tmux availability. Stays nil
// without DATABASE_URL; in that case the per-request handler gate
// 404s anyway.
Paliadin services.Paliadin
}
func Register(mux *http.ServeMux, client *auth.Client, giteaAPIToken string, svc *Services) {