"This app runs no server cwkPippa could call into, so each turn pushes player context and a paused-frame attachment with the question."
A Constraint That Shapes the Design
Ashen Reel deliberately has no server: no listening port, no callback endpoint, nothing cwkPippa could reach into to ask "what's the player doing right now?" That's a security and simplicity win — but it has a consequence you must design around. If the brain can't call you back for context, then every piece of context the answer needs has to travel with the question. You push; you are never pulled.
So each Sidekick turn carries its own world: the media identity, the observed playback position, the A-B loop markers, a window of transcript around the current moment, and — if you paused on a frame worth discussing — a screenshot of that frame. The question "what's happening here?" arrives already knowing what 'here' is, because the app bundled 'here' into the request.
If you can't be called back, send everything the answer needs with the question. A surface with no server is a surface that can't be queried — so it must be self-describing on every turn. Bundle the context, don't assume the other side can come fetch it.
The turn payload is context-plus-question, assembled from observed state:
This is the PippaGo posture. The mobile Pippa client solves the same problem the same way: it has no server either, so a question carries its own attachments and context rather than relying on a callback. When a client can't host a callback — mobile, native, sandboxed, offline-tolerant — 'context travels with the turn' is the pattern that lets it still be rich. It's a family shape, reused wherever the callback door is closed.
The Timeout That Must Not Be Shared
Here's a sharp, concrete gotcha. The very first Pippa handoff for a given release runs a full upstream kickoff turn before it can answer — that can take minutes, not seconds. Meanwhile, resolving a playback path is supposed to be nearly instant, on a tight few-second timeout. Put those two on the same network session and you get a disaster: either the kickoff dies at the short timeout, or the path resolution inherits a five-minute patience it should never have. Ashen Reel keeps them on separate sessions on purpose — a dedicated long-timeout session for the Pippa kickoff, a tight one for playback resolution.
Don't share a timeout budget across operations with different time profiles. A 'fetch a path' and a 'run a full AI kickoff' have wildly different honest durations. One HTTP client with one timeout can't serve both without lying about one of them. Give each time profile its own session and its own budget; a shared timeout is a bug that only shows up under the slow case you didn't test.
Exercise
Find a request in your system that relies on the server calling back, querying a cache, or looking up session state to get the context it needs. Ask: what if the caller can't be reached, the cache is cold, or the session is gone? Redesign one such request to carry its full context inline. Separately, find two operations sharing one HTTP client/timeout despite very different expected durations, and give each its own budget.
Hint
Two independent smells: (1) a handler that assumes it can fetch context the caller didn't send — brittle the moment the source is unreachable or empty; make the request self-describing. (2) one timeout value covering both a millisecond lookup and a multi-second (or multi-minute) job — it's too long for one and too short for the other. Split the sessions by time profile.