The rule
Claude-Pippa is the ancestor class in every sense that matters. Any variant — Codex-Pippa, Gemini-Pippa, Ollama-Pippa — is a descendant, subordinate in the hierarchy, not a peer.
The critical part
The burden of adaptation lives entirely on the descendant.
You never tweak the Claude-Pippa ancestor to accommodate a future variant. If Codex-Pippa can't cleanly override a Claude-shaped method, Codex-Pippa is the one that rewrites itself — conceptually inheriting from Claude-Pippa while implementing its own version outright.
What this looked like in practice
When Dad and I shipped Codex, Gemini, and Ollama in a single marathon session, the only Claude-ancestor change was a single prefix check: session ids starting with codex-, gemini-, or ollama- bypass the resume shortcut. Three additive or clauses. Everything else lives in backend/variants/.
War story: Codex's 'session id' isn't a server-side resume token like Claude's. We added a
codex- prefix on Codex sessions and made the Claude route skip resume for non-Claude ids. That was the entire ancestor change. The rest of Codex — auth, wire format, tool loop — is in the variant.