aichat Phase B — paliad migration to centralized chat backend (PALIADIN_BACKEND=aichat opt-in) #38

Open
opened 2026-05-15 00:52:19 +00:00 by mAi · 1 comment
Collaborator

Context

m approved Phase B of m/mAi#207 (aichat centralized Claude-in-tmux backend) on 2026-05-15. Phase A shipped by mai/darwin on mai/darwin/issue-207-aichatinternal/aichat Go packages + binary, skill bundles for paliadin / hugo / lexie / nl-translator, response paths at /tmp/aichat/<persona>/. mai/head is merging + deploying to mRiver.

This issue is the paliad-side migration that consumes the new backend. Paliadin's Claude-in-tmux pipeline currently lives in internal/services/paliadin*.go + scripts/paliadin-shim; Phase B builds a parallel aichat_paliadin.go that calls the centralized service, gated by env PALIADIN_BACKEND=aichat (default: legacy path stays live).

Scope

New file — internal/services/aichat_paliadin.go

A thin client that speaks to the centralized aichat backend (HTTP / SSH to mRiver, exact transport per darwin's Phase A doc).

  • Implements the same interface as RemotePaliadinService (so the existing handler path can swap backends transparently).
  • Methods: Health(ctx), RunTurn(ctx, req), ResetSession(ctx, userID).
  • Session keying: per-user, matches paliad's existing pattern (paliad-paliadin-<userid8>), but the session is now a window inside the persona-shared aichat-paliadin session per m's 2026-05-13 decision.
  • Response polling: /tmp/aichat/paliadin/<turn_id>.txt (per darwin's Phase A path convention) instead of /tmp/paliadin/<turn_id>.txt.
  • JWT pass-through: the planck branch (mai/planck/paliadin-per-user-rls, parked t-paliad-156) has the JWT mint. Phase B should reuse that mint (the cancelled t-156 task notes specifically anticipated this fold-in). The JWT goes into the aichat envelope, the aichat service passes it through to Claude via the per-turn .jwt file.

Env gate

  • cmd/server/main.go reads PALIADIN_BACKEND env. Values:
    • legacy (default) — existing RemotePaliadinService path, unchanged.
    • aichat — new AichatPaliadinService path.
    • empty or other — legacy.
  • No hard cut; parallel paths exist for at least one release. m can flip back via env redeploy if anything breaks.

Skill propagation

  • The current scripts/skills/paliadin/SKILL.md + references/sql-recipes.md files MOVE to the aichat repo per m's 2026-05-13 decision ("Skill SoT: hard-move + delete in paliad+youpcorg").
  • In Phase B paliad-side: delete scripts/skills/paliadin/ + the install shim scripts/install-paliadin-skill. The aichat backend owns skill installation on mRiver.
  • VERIFY before deleting: aichat repo has the equivalent files committed and deployed.

Tests

  • Backend integration: internal/services/aichat_paliadin_test.go — assert RunTurn roundtrip with a mock aichat endpoint. Health check works. ResetSession works.
  • Backend gate test: PALIADIN_BACKEND=aichat env wires the new service; PALIADIN_BACKEND=legacy keeps the old.
  • Manual smoke: deploy with PALIADIN_BACKEND=aichat, hit /paliadin as the admin owner (PaliadinOwnerEmail per CLAUDE.md), verify response renders.

What does NOT happen in Phase B

  • No removal of RemotePaliadinService (Phase C / legacy retirement, separate slice).
  • No youpcorg migration (separate workstream, mai/head's responsibility).
  • No streaming (Phase C concern, per mai/head's heads-up).
  • No paliadin_turns table change (the existing primer system stays; aichat reads from paliad's DB via JWT-scoped access — see m/mAi#207 design §5).

Worker recommendation

Darwin (the aichat author) recommends noether or planck. Planck was fired earlier in the session, but the planck branch mai/planck/paliadin-per-user-rls is preserved on remote with the JWT mint code that Phase B needs to reuse. Either:

  • (a) Rehire planck → resume from planck's branch, integrate the JWT mint into aichat_paliadin.go, add the env gate. Preserves the t-156 work cleanly.
  • (b) Fresh coder → cherry-pick the JWT mint from planck's branch into the new aichat_paliadin file. Cleaner separation but loses planck's deeper context.

Head leans (a) since planck has the JWT context.

References

  • m/mAi#207 — aichat centralized backend (Phase A spec + darwin's design)
  • t-paliad-155 (done, 2026-05-08) — Paliadin real Claude SKILL.md + per-user tmux session keying
  • t-paliad-156 (cancelled 2026-05-13, branch preserved) — Paliadin per-user RLS JWT mint; folds into Phase B per the cancel note
  • internal/services/paliadin_remote.go — the source pattern Phase B mirrors
  • scripts/paliadin-shim — the existing transport, replaced by aichat's HTTP/SSH interface

Branch convention

mai/<worker>/aichat-phase-b — fresh from main.

## Context m approved Phase B of m/mAi#207 (aichat centralized Claude-in-tmux backend) on 2026-05-15. Phase A shipped by `mai/darwin` on `mai/darwin/issue-207-aichat` — `internal/aichat` Go packages + binary, skill bundles for paliadin / hugo / lexie / nl-translator, response paths at `/tmp/aichat/<persona>/`. mai/head is merging + deploying to mRiver. This issue is the **paliad-side migration** that consumes the new backend. Paliadin's Claude-in-tmux pipeline currently lives in `internal/services/paliadin*.go` + `scripts/paliadin-shim`; Phase B builds a parallel `aichat_paliadin.go` that calls the centralized service, gated by env `PALIADIN_BACKEND=aichat` (default: legacy path stays live). ## Scope ### New file — `internal/services/aichat_paliadin.go` A thin client that speaks to the centralized aichat backend (HTTP / SSH to mRiver, exact transport per darwin's Phase A doc). - Implements the same interface as `RemotePaliadinService` (so the existing handler path can swap backends transparently). - Methods: `Health(ctx)`, `RunTurn(ctx, req)`, `ResetSession(ctx, userID)`. - Session keying: per-user, matches paliad's existing pattern (`paliad-paliadin-<userid8>`), but the session is now a **window inside the persona-shared `aichat-paliadin` session** per m's 2026-05-13 decision. - Response polling: `/tmp/aichat/paliadin/<turn_id>.txt` (per darwin's Phase A path convention) instead of `/tmp/paliadin/<turn_id>.txt`. - JWT pass-through: the planck branch (`mai/planck/paliadin-per-user-rls`, parked t-paliad-156) has the JWT mint. Phase B should reuse that mint (the cancelled t-156 task notes specifically anticipated this fold-in). The JWT goes into the aichat envelope, the aichat service passes it through to Claude via the per-turn `.jwt` file. ### Env gate - `cmd/server/main.go` reads `PALIADIN_BACKEND` env. Values: - `legacy` (default) — existing `RemotePaliadinService` path, unchanged. - `aichat` — new `AichatPaliadinService` path. - empty or other — legacy. - No hard cut; parallel paths exist for at least one release. m can flip back via env redeploy if anything breaks. ### Skill propagation - The current `scripts/skills/paliadin/SKILL.md` + `references/sql-recipes.md` files MOVE to the aichat repo per m's 2026-05-13 decision ("Skill SoT: hard-move + delete in paliad+youpcorg"). - In Phase B paliad-side: **delete** `scripts/skills/paliadin/` + the install shim `scripts/install-paliadin-skill`. The aichat backend owns skill installation on mRiver. - VERIFY before deleting: aichat repo has the equivalent files committed and deployed. ### Tests - Backend integration: `internal/services/aichat_paliadin_test.go` — assert RunTurn roundtrip with a mock aichat endpoint. Health check works. ResetSession works. - Backend gate test: `PALIADIN_BACKEND=aichat` env wires the new service; `PALIADIN_BACKEND=legacy` keeps the old. - Manual smoke: deploy with PALIADIN_BACKEND=aichat, hit `/paliadin` as the admin owner (PaliadinOwnerEmail per CLAUDE.md), verify response renders. ### What does NOT happen in Phase B - No removal of `RemotePaliadinService` (Phase C / legacy retirement, separate slice). - No youpcorg migration (separate workstream, mai/head's responsibility). - No streaming (Phase C concern, per mai/head's heads-up). - No paliadin_turns table change (the existing primer system stays; aichat reads from paliad's DB via JWT-scoped access — see m/mAi#207 design §5). ## Worker recommendation Darwin (the aichat author) recommends noether or planck. Planck was fired earlier in the session, but the **planck branch `mai/planck/paliadin-per-user-rls`** is preserved on remote with the JWT mint code that Phase B needs to reuse. Either: - (a) Rehire planck → resume from planck's branch, integrate the JWT mint into `aichat_paliadin.go`, add the env gate. Preserves the t-156 work cleanly. - (b) Fresh coder → cherry-pick the JWT mint from planck's branch into the new aichat_paliadin file. Cleaner separation but loses planck's deeper context. Head leans (a) since planck has the JWT context. ## References - m/mAi#207 — aichat centralized backend (Phase A spec + darwin's design) - t-paliad-155 (done, 2026-05-08) — Paliadin real Claude SKILL.md + per-user tmux session keying - t-paliad-156 (cancelled 2026-05-13, branch preserved) — Paliadin per-user RLS JWT mint; folds into Phase B per the cancel note - `internal/services/paliadin_remote.go` — the source pattern Phase B mirrors - `scripts/paliadin-shim` — the existing transport, replaced by aichat's HTTP/SSH interface ## Branch convention `mai/<worker>/aichat-phase-b` — fresh from main.
mAi self-assigned this 2026-05-15 00:52:19 +00:00
Author
Collaborator

Phase B shipped + merged to main.

3 atomic commits on mai/planck/aichat-phase-b-paliad:

  1. 08e2088 — revive per-turn JWT mint (folded-in from parked t-paliad-156 branch).
  2. edc81bb — AichatPaliadinService + PALIADIN_BACKEND=aichat env gate. ~659 LoC service + ~668 LoC tests. Same interface as RemotePaliadinService so handlers swap transparently.
  3. 8f6cee5 — delete paliad-side scripts/skills/paliadin/ + install shim (SoT moved to m/mAi). Verified aichat-side equivalents exist on mai/darwin/issue-207-aichat before deletion. Legacy LocalPaliadinService + RemotePaliadinService still expect ~/.claude/skills/paliadin/ on the target host — operators install manually from m/mAi until Phase C retires those paths.

go build ./... clean. go test ./... green.

To activate on prod: flip env PALIADIN_BACKEND=aichat + set AICHAT_URL + AICHAT_TOKEN in Dokploy compose (per the new CLAUDE.md env table). Legacy path stays the default until that flip lands — zero-risk parallel migration window.

Coordination with darwin / mai-head: clean cutover. Aichat backend deploy on mRiver is mai/heads responsibility; paliad-side env-flip is ms (whenever the aichat deploy is verified live).

Not closing — m closes.

Phase B shipped + merged to main. 3 atomic commits on `mai/planck/aichat-phase-b-paliad`: 1. [08e2088](https://mgit.msbls.de/m/paliad/commit/08e2088) — revive per-turn JWT mint (folded-in from parked t-paliad-156 branch). 2. [edc81bb](https://mgit.msbls.de/m/paliad/commit/edc81bb) — AichatPaliadinService + PALIADIN_BACKEND=aichat env gate. ~659 LoC service + ~668 LoC tests. Same interface as RemotePaliadinService so handlers swap transparently. 3. [8f6cee5](https://mgit.msbls.de/m/paliad/commit/8f6cee5) — delete paliad-side `scripts/skills/paliadin/` + install shim (SoT moved to m/mAi). Verified aichat-side equivalents exist on `mai/darwin/issue-207-aichat` before deletion. Legacy `LocalPaliadinService` + `RemotePaliadinService` still expect `~/.claude/skills/paliadin/` on the target host — operators install manually from m/mAi until Phase C retires those paths. `go build ./...` clean. `go test ./...` green. **To activate on prod:** flip env `PALIADIN_BACKEND=aichat` + set `AICHAT_URL` + `AICHAT_TOKEN` in Dokploy compose (per the new CLAUDE.md env table). Legacy path stays the default until that flip lands — zero-risk parallel migration window. Coordination with darwin / mai-head: clean cutover. Aichat backend deploy on mRiver is mai/heads responsibility; paliad-side env-flip is ms (whenever the aichat deploy is verified live). Not closing — m closes.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#38
No description provided.