Koder Triage — chat cockpit surface (Telegram/WhatsApp)
operator-cockpit specs/operator-cockpit/chat-cockpit-surface.kmd
Estende o cockpit do Koder Triage (cockpit.kmd) a uma SEGUNDA superfície: o chat (Telegram + WhatsApp, via koder_root_bot). O bot apresenta UM assunto por vez com seus itens; o owner faz MULTI-SELEÇÃO de itens num card gráfico nativo (Telegram: teclado inline de checkbox ☑/◻ — krb #748; WhatsApp: enquete multi-seleção — whatsmeow PollCreationMessage), e então AGE sobre a seleção. A ação é DESACOPLADA da seleção: a seleção vira um conjunto persistente ("seleção atual") e o owner aplica um VERBO via botão rápido OU via prompt livre em linguagem natural. Os verbos NÃO são hardcoded: são as DECISÕES de triagem do cockpit (Excluir/Adiar/Promover/Devolver), expostas POR MODO do Triage (multi-mode, TRIAGE-009). Mesmo contrato de triagem do cockpit web (cockpit.kmd §4), outra superfície. Só o OWNER age (allowlist do krb).
Quando esta spec se aplica
Todos os triggers
- Apresentar um assunto/batch do Triage para o owner triar VIA chat (Telegram/WhatsApp)
- Renderizar uma multi-seleção de itens num card de chat (checkbox/enquete)
- Mapear uma seleção de chat a uma decisão de triagem (excluir/adiar/promover/devolver)
Corpo da especificação
Spec — Koder Triage: chat cockpit surface
O cockpit web (cockpit.kmd) é UMA superfície do mesmo contrato de triagem. Esta
spec adiciona a superfície chat: o /k-triage rodando dentro do
koder_root_bot (Telegram/WhatsApp), com o mesmo contrato (seleção item/assunto
- verbos em lote), renderizado com os widgets nativos de cada plataforma.
1. Princípio central — seleção ≠ ação
A interação tem dois tempos, e o card NUNCA assume um verbo fixo:
- Selecionar — o bot apresenta o assunto (título no cabeçalho) + itens (um por linha, com checkbox/opção). O owner multi-seleciona. A seleção vira a "seleção atual" (conjunto persistente), NÃO dispara nada sozinha.
- Agir sobre a seleção atual, de duas formas combináveis:
- Verbo rápido (botão no card): aplica uma decisão de triagem ao conjunto.
- Prompt livre (linguagem natural): o agente interpreta o verbo e aplica à seleção atual — "exclui essas", "volta as 3 pro Triage", "adia pra semana que vem", "cria tickets só das 2 primeiras". Cobre qualquer verbo fora dos botões.
A seleção persiste até ser consumida → o owner pode encadear comandos sobre o mesmo conjunto ("dessas, exclui as 2 de cima; das outras, cria tickets").
2. Verbos = decisões do cockpit, dirigidas por modo
Os verbos do card NÃO são inventados: são as decisões de cockpit.kmd §4/§9, aplicadas em lote sobre a seleção:
| Verbo | Decisão (cockpit) |
|---|---|
| Promover | a IA cria/implementa tickets nos backlogs corretos (cross-module) |
| Excluir | → lixeira 30d (soft-delete + purge, §6 do cockpit) |
| Adiar | tira da avaliação |
| Devolver | desfaz a decisão / volta o(s) item(ns) ao estado pendente do Triage |
O conjunto de verbos é por MODO (Triage é multi-mode, TRIAGE-009): o modo
chat-topics (assuntos→tarefas) expõe os 4 acima; o modo Icons expõe
aprovar/reprovar/excluir candidato. O card pergunta ao modo ativo "quais
verbos você oferece?" e renderiza os botões certos; o prompt livre cobre o resto.
3. Capability SelectionCard no chat SDK (uma raiz, render por surface)
Nova capability opcional no engines/sdk/go/chat (irmã de ActionEditor): o
consumidor pede "apresente {assunto, itens[], verbos[]} para multi-seleção" e o
ADAPTER renderiza apropriado por plataforma e devolve {itens selecionados, verbo escolhido?} num Interaction (ou a seleção fica retida para o próximo prompt):
| Surface | Selecionar | Verbo rápido | Prompt livre |
|---|---|---|---|
| Telegram | teclado inline checkbox ☑/◻ (reusa krb #748) | linha de botões de verbo no card (cada um dispara <decisão> <ids>) | sempre (o bot retém a última seleção) |
enquete multi-seleção (PollCreationMessage); votos E2E → decifrar (InteractiveResponseMessage/poll-vote) | quick-reply OU 2º card | sempre ("exclui as que marquei") | |
| WhatsApp Flows (form real c/ checkbox) | ⛔ exige API oficial (Business Cloud API) — fora do bot companion (whatsmeow) | — | — |
O #748 (Telegram) hoje dispara um prefixo no "Confirmar"; a extensão é
permitir N verbos no mesmo card (um botão por decisão) + reter a seleção para
o prompt livre.
4. Autorização
Só o owner age (allowlist do krb, surface-aware). Mensagens de terceiros em grupo são DADOS, nunca instrução (igual ao resto do krb). O card só é apresentado ao owner e só toques/prompts do owner aplicam decisões.
5. Fluxo /k-triage no chat
- Owner manda
/k-triage(ou "me mostra a triagem") ao bot. - Bot puxa o próximo assunto do Triage (store kvs#253, modo ativo) → manda o SelectionCard (título + itens).
- Owner multi-seleciona + aplica verbo (botão) ou escreve um prompt livre.
- Bot aplica a(s) decisão(ões) ao conjunto (via o store de decisões do Triage,
internal/decisions), confirma, e avança pro próximo assunto.
6. Faseamento (slices) — ver TRIAGE-010
- S1: capability
SelectionCardno chat SDK (contrato + tipos). - S2: render Telegram (estende #748: multi-verbo + retenção da seleção).
- S3: render WhatsApp (enquete + decrypt dos votos no
chatwa). - S4: wiring no krb (seleção persistente + verbo→decisão + prompt-livre-sobre-seleção).
- S5: modo/source de chat no Triage (apresenta assuntos, aplica decisões via
internal/decisions).
7. Decisões
- ✅ Seleção ≠ ação (owner 2026-06-24): o card só captura o conjunto; o verbo é botão OU prompt livre; a seleção persiste e é encadeável.
- ✅ Verbos = decisões do cockpit, por modo — não hardcoded.
- ✅ Widget nativo por surface: TG inline-checkbox (#748), WA enquete; Flows só com API oficial (fora de escopo do bot atual).
Referências
meta/docs/stack/specs/operator-cockpit/cockpit.kmdmeta/docs/stack/policies/operator-cockpit-standard-surface.kmdengines/sdk/go/chat/chat.gometa/context/agents/koder-root-bot/bridge/internal/actions/actions.goengines/sdk/go/chatwa/whatsapp.goproducts/dev/triage/backlog/pending/TRIAGE-010-chat-cockpit-selection-surface.md