Primitiva: Conversation Event Canonical Schema
Contrato canônico para ingestão de conversas/threads de múltiplas plataformas (pi local, Telegram, WhatsApp, Matrix, Signal, etc.) sem acoplar a triagem a um provider específico.
Objetivo
- unificar eventos de conversa em formato único;
- permitir triagem operacional reproduzível (
unlock-nowvslater); - preservar governança (
evidence,no-auto-close, revisão do operador) independente da fonte.
Entidade canônica (v1)
{
"schemaVersion": "1.0",
"source": {
"provider": "pi|telegram|whatsapp|matrix|signal|custom",
"account": "optional-account-id",
"providerAccountKey": "provider[/account]",
"workspace": "optional-workspace-id",
"channelId": "optional-channel-id",
"threadId": "thread-123",
"branchId": "optional-branch-id"
},
"event": {
"id": "evt-uuid-or-stable-id",
"type": "message|summary|status|tool_call|tool_result|signal",
"timestampIso": "2026-04-15T12:34:56.000Z",
"role": "user|assistant|tool|system|agent|operator|bot",
"text": "conteúdo textual normalizado",
"labels": ["optional", "tags"],
"refs": {
"taskIds": ["TASK-BUD-020"],
"issueIds": ["#123"],
"runIds": ["c1|colony-..."]
}
},
"meta": {
"authorId": "optional-author",
"messageId": "provider-message-id",
"rawType": "provider-original-type",
"ingestedAtIso": "2026-04-15T12:35:10.000Z"
}
}
Campos obrigatórios mínimos
schemaVersionsource.providersource.threadId(ou equivalente estável por conversa)event.idevent.typeevent.timestampIsoevent.roleevent.text
Regras de normalização
timestampIsoem UTC (.toISOString()).event.textdeve ser texto plano (sem binário/HTML bruto).event.rolemapeado para vocabulário canônico.- IDs externos devem ficar em
meta(não substituirevent.id). - Resumos compactados de branch/sessão devem usar
event.type = "summary". source.providerAccountKeyé canônico em formatoprovider[/account]:- com identidade de conta disponível:
provider/account; - sem identidade de conta: fallback compatível
provider.
- com identidade de conta disponível:
Mapeamento rápido por plataforma
- pi JSONL
source.provider = "pi"source.accountopcional quando origem expõe identidade (ex.: conta/tenant/perfil)source.providerAccountKey = provider[/account]com fallback provider-onlyevent.role = message.roleevent.text = content(text)event.type = "message"(ou"signal"quando detectarCOLONY_SIGNAL)
- Telegram/WhatsApp/Signal/Matrix
source.providerconforme canalsource.threadId= chat/conversation idevent.rolevia direção (inbound/outbound + bot/operador)event.text= payload textual normalizado
Governança
- o schema descreve ingestão, não decide fechamento de task;
- decisões continuam no board canônico (
.project/tasks); - qualquer automação de estado precisa manter evidência e gate do operador.
Status de adoção
session-triagejá aceita histórico local do pi e ingestão opcional de arquivo canônico (--events).- Próxima etapa: adapters de captura por provider e persistência contínua de eventos canônicos.