Date: 2026-02-11
Author: jclyne
Status: Draft
Related Plan: thoughts/shared/plans/2026-02-10-actioncard-completescenario-plasma-flow.md
Related Research: thoughts/shared/research/2026-02-10-clientrenderable-actioncard-plasma-flow-architecture.md
Related Review: thoughts/shared/reviews/2026-02-11-actioncard-completescenario-design-review.md
Redesign the blocker response system to use a sealed class hierarchy that clearly separates agent-friendly blockers (handled conversationally by the LLM) from form-required blockers (rendered as native UI by the client). Replace the flat BlockerInfo entity and StructuredBlockerResponse DTO with a two-tier sealed class: a service-layer BlockerResponse and a transport-layer McpBlockerResponse. Rename submit_blocker to submit_blocker_data with a new input model supporting ACCEPT, DECLINE, and CANCEL actions.
BlockerInfo(service entity) — flat data class withrequiresForm,isSensitive,displayMessage, etc.
This document describes how moneybot-core classifies and routes Plasma flow blockers through two distinct paths based on the agentFriendly metadata field: conversational resolution (handled entirely by the LLM agent) and native UI rendering (rendered inline in the chat by the client, bypassing the LLM for data collection). Confirmation blockers (e.g., HumanConfirmation) are always natively rendered to guarantee that human intent is correctly captured.
When a customer interacts with Moneybot (the AI-powered Cash App assistant), certain operations — such as enabling or disabling a Cash Card — require passcode verification via Plasma blockers. The plaintext passcode must never be visible to the LLM, pass through the MCP tool layer, or flow through any intermediary service (such as kgoose). The passcode must travel exclusively from the client to moneybot-core. Additionally, a customer may be asked for their passcode multiple times within a single Moneybot session if multiple operations require verification.
- Remove passcode from the LLM context — The plaintext passcode must never pass through the MCP tool layer, be visible to the LLM, or flow through any upstream service (e.g., kgoose). It is handled exclusively by the client and moneybot-core.
- Tokenize once, reuse within a session — Collect the customer's passcode once per Moneybot session via a dedic
The memory system enables the Cash App advisor to remember information about users across conversations. When memory extraction is triggered, the system processes conversation history, extracts meaningful memory items using an LLM, and stores them for retrieval in future conversations.
┌─────────────────────────────────────────────────────────────────────────────┐
│ MEMORY LIFECYCLE │
├─────────────────────────────────────────────────────────────────────────────┤
| import com.google.inject.AbstractModule | |
| import com.google.inject.Guice | |
| import com.google.inject.multibindings.OptionalBinder | |
| import jakarta.inject.Inject | |
| import java.util.Optional | |
| import kotlin.jvm.optionals.getOrNull | |
| class Greeter(val name: String) { | |
| fun greet() = println("Hello $name") |
This document aims to describe how coroutine usage on the server is implemented within frameworks, outlining best practices and providing educational guidance for developers.
This is not an exhaustive explanation of coroutines and all their features. For comprehensive coroutine documentation, refer to the official Kotlin coroutines documentation. This guide focuses specifically on server-side usage within our frameworks (Misk, event-client, etc.), addressing the unique considerations and patterns that apply to server environments.