Skip to content
Back to skills

Sessions

BSecurity

Gerencia sessões do sistema Ravi. Use quando o usuário quiser: - Listar, ver detalhes ou renomear sessões - Resetar ou deletar sessões - Configurar modelo ou thinking level por sessão - Limpar sessões inativas com dry-run e filtros explícitos - Criar sessões efêmeras com TTL - Estender, manter ou excluir sessões efêmeras - Enviar prompts, perguntas ou comandos entre sessões - Ler histórico de mensagens de uma sessão - Inspecionar trace SQLite de uma sessão para incidentes de runtime/canal - A...

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 20, 2026
ai-agentsgobashsql

Works with

  • terminal
  • cli

Security analysis

B75/100
  • criticalImpersonates system messages to override safety constraints

Pro shows the line behind each finding and how to fix it

Scanned October 20, 2026

npx -y skills add filipexyz/ravi --skill sessions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sessions?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sessions
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/filipexyz-sessions/badge)](https://www.skillsdirectory.com/skills/filipexyz-sessions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sessions
description: |
  Gerencia sessões do sistema Ravi. Use quando o usuário quiser:
  - Listar, ver detalhes ou renomear sessões
  - Resetar ou deletar sessões
  - Configurar modelo ou thinking level por sessão
  - Limpar sessões inativas com dry-run e filtros explícitos
  - Criar sessões efêmeras com TTL
  - Estender, manter ou excluir sessões efêmeras
  - Enviar prompts, perguntas ou comandos entre sessões
  - Ler histórico de mensagens de uma sessão
  - Inspecionar trace SQLite de uma sessão para incidentes de runtime/canal
  - Atachar um chat como output target de uma sessão
  - Atachar múltiplos chats numa mesma sessão sem fork de histórico
---

# Sessions Manager

> Verbos: AGIR (mandar a chat ou sessão) · RELATAR (followups). Compõe com: triggers, whatsapp.
> Solução com mais de uma peça? `ravi skills show solucoes` primeiro.

Sessões são conversas persistentes entre agents e usuários. Cada sessão tem um nome único, um agent associado, e pode ter canal de saída (WhatsApp, Matrix, etc).

Sessões são a superfície de comunicação do Ravi. Não são o task runtime. Se o trabalho precisa de dono, progresso e estado terminal, use `ravi tasks ...`. Se a pergunta é medir regressão ou comparar comportamento, use `ravi eval ...`.

## Contrato Do CLI

Rode com `--json` sempre que for decidir programaticamente. Com `--json`, falha sai em envelope `{success:false, op, error:{code, message, retryable, suggestedAction, acceptedFlags?}}`.

Taxonomia de saída:

- `0` sucesso.
- `1` erro de execução (ex.: `SESSION_NOT_FOUND`, `MESSAGE_NOT_FOUND`). `SESSION_NOT_FOUND` NÃO traz `suggestions` de propósito: o isolamento de escopo mascara sessão não-autorizada como not-found, e sugerir nomes reais vazaria sessões de outros escopos. Liste as visíveis com `ravi sessions list --json`.
- `2` erro de uso (flag/argumento inválido). O envelope traz `acceptedFlags`: corrija a chamada, não insista na mesma sintaxe.
- `3` freio de escrita — não é erro. Nada foi gravado; o envelope traz `dryRun:true` e `plan`. Revise e repita com `--execute`.

Onde o freio existe hoje: `reset` (contexto é irrecuperável), `delete` (permanente), `delete-message`, `edit-message` (mutação irreversível no canal) e runtime `follow-up`/`rollback`/`fork` (disparam trabalho ou alteram histórico) são dry-run por default e exigem `--execute`. `prune` já era dry-run nativo com `--execute` e mantém seu payload rico de candidatos (exit 0 no preview). Mensagens rotineiras, configurações reversíveis e runtime `interrupt`/`steer` continuam imediatos; o stop de emergência não ganha uma confirmação que aumentaria o dano.

Compact mode: `sessions list` aceita `--fields a,b,c` (ex.: `--fields name,agentId,updatedAt`).

Checklist antes de responder sobre sessões:

- Tratei exit 3 como freio (revisei o `plan`) e não como falha?
- Chequei `ravi sessions list --json` antes de declarar que uma sessão não existe?

## Tipos de Sessão

- **Permanent** (padrão): Sessão normal, sem expiração.
- **Ephemeral**: Sessão com TTL (time-to-live). Expira automaticamente após o tempo definido. 10 minutos antes de expirar, o agent recebe um aviso com comandos CLI para estender, manter ou excluir.

## Comandos

### Listagem e Info

```bash
# Listar todas as sessões (mostra tipo e data de expiração)
ravi sessions list

# Filtrar por agent
ravi sessions list --agent <id>

# Listar só efêmeras
ravi sessions list --ephemeral

# Ver detalhes de uma sessão
ravi sessions info <name>

# Ler histórico durável da sessão (normalizado, sem tool calls; atravessa restarts/resets de provider)
ravi sessions read <name> [-n count]

# Recap computado e limitado de uma sessão (identidade, goal, cauda recente; sem MEMORY.md)
ravi sessions recap <name> [--json]

# Inspecionar timeline operacional persistida em SQLite
ravi sessions trace <name> --since 2h --explain
```

### Gerenciamento

```bash
# Renomear o nome canonico da sessao (sessions.name)
ravi sessions rename <name> <novo-nome-canonico>

# Definir label humano/display-only
ravi sessions set-display <name> "Novo Nome Humano"

# Definir modelo override (vence agent/global/env no próximo turno)
ravi sessions set-model <name> <model>

# Definir provider override (eixo independente do model)
ravi sessions set-provider <name> <provider|clear>

# Defaults globais do próximo turno (sem restart; env fica só fallback)
# ravi settings set runtime.defaultProvider claude
# ravi settings set runtime.defaultModel opus

# Definir thinking level
ravi sessions set-thinking <name> <level>

# Resetar sessão (limpa conversa, mantém config; sem --execute é dry-run, exit 3)
ravi sessions reset <name> --execute

# Deletar sessão permanentemente (abort + delete; sem --execute é dry-run, exit 3)
ravi sessions delete <name> --execute

# Preview de limpeza por inatividade (não apaga nada)
ravi sessions prune --inactive-for 2d --json

# Deletar sessões inativas há mais de 2 dias
ravi sessions prune --inactive-for 2d --execute
```

`prune` usa `updated_at`/última atividade da sessão, não `created_at`.
Isso evita apagar uma sessão antiga que teve atividade recente.

Filtros úteis:

```bash
ravi sessions prune --inactive-for 1d --agent dev
ravi sessions prune --inactive-for 2d --name-prefix task-
ravi sessions prune --inactive-for 12h --ephemeral
```

Sem `--execute`, `prune` é sempre dry-run. Use o dry-run antes de apagar em lote.

### Attach (multiple chats, one history)

**Diferença chave vs routes:** `routes` decide qual *agent* atende um chat; `attach` decide quais chats alimentam uma sessão. Cada inbound responde automaticamente no próprio chat ou thread. O default só é usado por turnos sem origem inbound.

**Regra crítica:** `sessions attach` NÃO cria, corrige nem troca a route do chat. Use attach apenas quando a route já resolve para o agent correto, ou depois de criar uma route explícita para esse agent. Para chat novo/rota errada, configure a rota primeiro; se quiser forçar a mesma sessão já na route, use `ravi instances routes add <instance> <pattern> <agent> --session <session>`.

Ver spec `sessions/attach` pro modelo completo.

```bash
# Listar chats atachados e qual é o output default
ravi sessions subscriptions <session>

# Atachar um chat e selecioná-lo como output default da sessão
ravi sessions attach <session> --chat <chat-id> [--reason "..."]

# Desatachar subscription/output
ravi sessions detach <session> --chat <chat-id>
```

**Receitas operacionais (validadas em produção):**

1. **Responder em outro grupo com a mesma sessão.** Caso típico: você está falando com `dev` no grupo de teste, mas quer que o resultado apareça no grupo principal.
   - `sessions attach dev --chat <chat-id-do-grupo-principal>`
   - Inbounds continuam respondendo no próprio chat. O grupo principal vira o default apenas para turnos sem inbound.
   - O comando imprime o hint de detach para desligar esse output depois.

2. **Unificar histórico de N grupos numa sessão.** Caso: dev atende o grupo `ravi - dev` e você quer que o mesmo dev também receba inbound de `ravi - dev - test`.
   - Primeiro garanta que a route do grupo novo aponta para o agent `dev`: `ravi instances routes add <instance> "group:<id>" dev --priority 10`.
   - Se a intenção é fixar a sessão canônica já na route, prefira: `ravi instances routes add <instance> "group:<id>" dev --session dev --priority 10`.
   - Se o grupo novo já criou uma sessão paralela (`dev-2`, vazia), apague a paralela (`sessions delete dev-2 --execute`) antes de consolidar.
   - Depois use `sessions attach dev --chat <chat-id-do-test>` para ligar o chat à sessão existente.

3. **Migrar grupo de um agent pra outro (sem unificar sessão).** Caso: grupo nasceu na sessão de onboarding (auto-criada pelo default agent da instance), você quer mover pro agent `dev` com sessão SEPARADA.
   - `ravi instances routes add <instance> group:<id> <novo-agent> --priority 10`
   - O `routes add` faz cleanup automático de session conflitante (chama `Cleaned N conflicting session(s)`).
   - Próxima inbound: matchRoute → novo agent → cria sessão nova pra esse (agent, grupo).
   - Não confunda com attach — essa NÃO compartilha histórico.

**Como compõe na prática (sequence diagram resumido):**

```
inbound chega ─► consumer normaliza chat
              ─► matchRoute resolve agent + session_key candidato
              ─► [Fase 2] consumer.findSessionByAttachedChat(chat_id)
                 │ se subscription existe ─► matched.sessionKey = subscription.sessionKey
                 │ (subscription override prevalece sobre matchRoute)
              ─► policy checks
              ─► commitMatchedRoute + attachChatToSession (idempotente)
              ─► dispatch turn na sessão escolhida
              ─► runtime gera resposta
              ─► resolveSessionOutputTarget:
                 1. inbound com source inscrito → source
                 2. turno sem inbound → output default
                 3. source não inscrito ou nenhum destino → fail closed
              ─► gateway emite no target resolvido
```

**Anti-patterns:**

- ❌ Adicionar route pra "trocar destino" quando o chat já está atachado em outra sessão. A subscription override puxa o inbound de volta. Use detach/delete da sessão antiga antes, ou attach explícito na nova.
- ❌ Usar `sessions attach` como se ele configurasse route. Attach não muda o agent que atende o chat; ele só liga o chat a uma sessão quando a route/agent já está correta.
- ❌ Tentar usar `focus` pra responder em outro chat. Focus foi removido; `attach` é o primitive que escolhe o chat de output.
- ❌ Deixar inbound-route bookkeeping roubar o default escolhido pelo operador.
- ❌ Esperar que `attach` sozinho mude o agent que atende o chat. Attach decide sessão; agent vem da route ou do default da instance.

**Quando route vs attach:**

| Você quer | Use |
|-----------|-----|
| Outro agent atender o chat (histórico isolado) | `instances routes add` |
| Mesma sessão em chat cuja route já aponta para o agent correto | `sessions attach` |
| Mesma sessão em chat novo ou com route errada | `instances routes add ... --session <name>` e depois `sessions attach` |
| Forçar uma sessão específica num chat | `routes add ... --session <name>` (redirect estático) |

### Sessões Efêmeras

```bash
# Tornar sessão efêmera com TTL (ex: 5h, 30m, 1d)
ravi sessions set-ttl <name> <duration>

# Estender TTL de uma sessão efêmera (+5h default)
ravi sessions extend <name> [duration]

# Tornar sessão efêmera em permanente
ravi sessions keep <name>
```

**Fluxo automático:**
1. Sessão criada com `set-ttl` recebe TTL
2. 10 min antes de expirar, o agent recebe aviso via `[System] Inform:` com os comandos CLI
3. O agent pode executar `extend`, `keep`, ou `delete`
4. Sem ação → sessão é automaticamente deletada pelo runner

### Session Followups

Use `sessions followups` para cadências de inatividade em sessões/chats/listas. Isso é diferente de cron: `--every` conta a partir da última atividade externa relevante.

```bash
# Criar followup simples
ravi sessions followups add "Follow-up ravi-dev" --target-chat <chat-id> --every 15m --message "Revise o contexto e faça follow-up curto."

# Criar cadência progressiva
ravi sessions followups add "Follow-up ravi-dev" --target-chat <chat-id> \
  --step "15m=Revise o contexto e faça um follow-up curto." \
  --step "30m=Estude o próximo passo relevante e recomende uma ação concreta."

# Editar uma cadência existente sem recriar
ravi sessions followups update <id> \
  --step "15m=Revise o contexto e faça um follow-up curto." \
  --step "30m=Estude o próximo passo relevante e recomende uma ação concreta."

# Atualizar mensagem de cadência single-step
ravi sessions followups update <id> --message "Nova mensagem."
```

Regras:

- Use `update`, não recrie/pausa cadência, quando a intenção é editar nome, descrição, barrier, mensagem ou steps.
- Em cadências progressivas, `--step` substitui a lista inteira de steps. Não use `--message` para tentar editar o segundo step.
- `update` preserva `nextRunAt` por padrão; use `--recalculate-next` só quando quiser recalcular a próxima execução.

### Comunicação Inter-Sessão

```bash
# Enviar prompt/contexto
ravi sessions send <name> "mensagem" [-w] [-a agent] [-i]
# -w: espera e streama a resposta
# -a: cria sessão com esse agent se não existir
# -i: modo interativo (loop)

# Perguntar algo (fire-and-forget, agent pergunta no chat se não souber)
ravi sessions ask <name> "pergunta" [sender]

# Responder uma pergunta de outra sessão (agent NUNCA silencia)
ravi sessions answer <name> "resposta" [sender]

# Executar comando (fire-and-forget, agent executa sem responder)
ravi sessions execute <name> "tarefa"

# Informar algo (fire-and-forget, agent pode silenciar se irrelevante)
ravi sessions inform <name> "info"
```

### Threads do Slack (orquestração)

A sessão de um DM ou canal do Slack orquestra as threads que abre; cada thread é uma sessão filha. Os comandos inferem a sessão atual.

```bash
# Abrir uma thread nova na raiz do canal; a mensagem é a raiz visível e a primeira instrução da filha
ravi sessions create-thread "<mensagem inicial>" [--model <model>]

# Na sessão do canal: listar as threads (abertas; --all inclui fechadas) e mandar instruções para uma
ravi sessions threads [--all] --json
ravi sessions thread-send <sessão-da-thread|request-id|thread-ts> "instruções"

# Na thread: avisar a sessão do canal sem fechar, e fechar (com ou sem resultado)
ravi sessions report "progresso, bloqueio ou decisão"
ravi sessions close-thread [--return "resultado"]
```

A raiz da thread aparece no canal como um card: a primeira linha da mensagem inicial é o título (escreva um título curto nela), o resto vira um resumo, e a mensagem inteira abre a thread quando não cabe no card. O card mostra quem pediu (quem escreveu o turno; nos turnos do operador, o contato dono) e o status, e muda sozinho com `report`, `close-thread` e quando `thread-send` reabre a thread.

Progresso e resultado chegam na sessão do canal como `[System] Inform: Slack thread "<título>" (<sessão-da-thread>) ...`. `thread-send` reabre uma thread fechada; a filha responde dentro da thread.

`sessions send` envia prompt/contexto para a sessão do agent; ele não publica texto visível diretamente em WhatsApp, Telegram, Matrix ou outro canal externo. Se o objetivo é falar com uma pessoa/canal, deixe a sessão responder normalmente ou use uma CLI explícita de canal/mídia/outbound apropriada.

### Session Trace

Use `ravi sessions trace` quando precisar entender uma sessão real ponta a ponta:
inbound de canal, routing, prompt publish, decisões de dispatch, request final
do adapter, tools, resposta, delivery e falhas.

SQLite (`ravi.db`) é a fonte canônica do trace. NATS/logs são apoio para debug
ao vivo, não a fonte primária para reconstruir incidente.

```bash
# Golden path de incidente
ravi sessions trace <name> --since 2h --explain

# Filtros úteis
ravi sessions trace <name> --turn <turn_id> --explain
ravi sessions trace <name> --run <run_id>
ravi sessions trace <name> --message <source_message_id> --explain
ravi sessions trace <name> --correlation <correlation_id> --raw --explain

# Cortes de leitura
ravi sessions trace <name> --only adapter
ravi sessions trace <name> --only tools
ravi sessions trace <name> --only delivery
ravi sessions trace <name> --only dispatch
ravi sessions trace <name> --only turn
ravi sessions trace <name> --since 30m --limit 40
ravi sessions trace <name> --json

# Payloads grandes só quando necessário
ravi sessions trace <name> --show-system-prompt
ravi sessions trace <name> --turn <turn_id> --show-user-prompt
ravi sessions trace <name> --turn <turn_id> --raw
```

`--show-system-prompt` resolve o system prompt mais recente da sessão e não
depende do `turn` estar visível no recorte/limit. User prompt e raw request
continuam escopados a turn/request.

Leitura rápida:

- `channel.message.received` = inbound chegou no Ravi.
- `route.resolved` = rota escolheu sessão e agent.
- `prompt.published` = prompt entrou no stream da sessão.
- `dispatch.*` = cold start, push em sessão viva, queue, interrupt, restart ou task barrier.
- `runtime.start` = runtime começou ou falhou antes do provider.
- `adapter.request` = Ravi montou a request final para o provider. Se existe, chegou no handoff.
- `tool.start` / `tool.end` = atividade de tool do provider.
- `assistant.message` = texto do assistant recebido do provider.
- `response.emitted` = Ravi emitiu resposta para o gateway.
- `delivery.*` = gateway observou delivered, failed, dropped ou outro status.
- `turn.complete` / `turn.failed` / `turn.interrupted` = estado terminal do turno.
- `session.stalled` = evento legado do watchdog de runtime; hoje deve aparecer só em traces históricos. Código novo deve fechar o turno via evento terminal do provider.

Achados comuns do `--explain`:

- `prompt-without-adapter-request`: prompt nao chegou no handoff do provider; olhar dispatch, debounce, task barrier ou runtime startup.
- `adapter-request-without-terminal-turn`: request foi criada, mas nao houve terminal turn; olhar provider/runtime apos handoff.
- `response-without-delivery`: resposta saiu do runtime mas nao teve delivery observado.
- `delivery-failed` / `delivery-dropped`: falha ou drop no outbound; olhar payload de delivery e target.
- `interruption-or-abort`: houve interrupt/abort; ler `abortReason`, `session.abort` e `dispatch.interrupt_requested`.
- `runtime-stalled`: trace historico contem `session.stalled` do watchdog removido; verificar se foi produzido por daemon antigo.
- `timeout`: timeout interrompeu a sessao/turno.
- `resume-disabled-with-provider-session`: havia provider session id mas `resume=false`; investigar reset/delete/fork/troca de provider ou modelo.
- `tool-start-without-end`: tool iniciou e nao completou no trace.
- `system-prompt-changed`: hashes de system prompt mudaram entre turns.

Golden path SDE para "agent viu a mensagem mas nao respondeu":

1. `ravi sessions trace <name> --since 2h --explain`
2. `ravi sessions trace <name> --message <source_message_id> --explain`
3. `ravi sessions trace <name> --turn <turn_id> --explain`

Classifique pela ultima linha confiavel:

- sem `channel.message.received`: inbound nao chegou ou janela/sessao errada.
- `channel.message.received` sem `route.resolved`: routing/contact resolution.
- `route.resolved` sem `prompt.published`: publish no stream da sessao.
- `prompt.published` sem `adapter.request`: dispatch, task barrier, debounce, concorrencia ou runtime startup.
- `adapter.request` sem terminal turn: provider/runtime apos handoff.
- `session.stalled`: trace histórico do watchdog removido; se aparecer em evento novo, há daemon antigo rodando.
- `assistant.message` sem `response.emitted`: resposta silenciosa, suppressao ou interrupcao.
- `response.emitted` sem `delivery.*`: gateway/outbound observation.
- `delivery.failed` / `delivery.dropped`: entrega final no canal.

Para abort/context loss, procure `session.abort`, `session.timeout`,
`turn.interrupted`, `provider_session_id_before`, `provider_session_id_after` e
hash de system prompt. `resume=false` com provider session id existente e
suspeito, exceto se reset/delete/fork/troca de provider/modelo/capability
explicar.

Use placeholders em runbooks e issues (`<name>`, `<turn_id>`, `<message_id>`).
Nao cole telefones reais, ids de grupo/chat, prompts de cliente, context keys,
tokens ou provider session ids em documentacao compartilhada.

## Notas

- **Reset vs Delete**: `reset` limpa a conversa mas mantém nome/routing/config. `delete` remove a sessão inteira.
- **Session names**: nomes canonicos unicos usados em routing, historico e topicos NATS. Use um token sem espacos, pontos (`.`), `*` ou `>`. `sessions rename` muda esse nome canonico e atualiza rotas que apontavam para o nome antigo.
- **Display labels**: labels humanos vivem em `display_name`. Use `sessions set-display` para nomes com espaco, acentos ou contexto visual; isso nao altera routing nem historico.
- **Source automático**: Todos os comandos de comunicação incluem source (channel/chatId) automaticamente — o agent sabe onde responder.
- **`send` vs `inform`**: `send` é a opção mais geral e pode esperar resposta com `-w`; `inform` é fogo-e-esqueça explícito para contexto.
- **Isolamento de contexto**: `sessions read` deve recuperar apenas a sessão atual. Nunca use histórico de outro grupo/DM como fallback para responder uma sessão fria.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.