sdd-layer 0.19.0

Spec-Driven Development CLI and agent harness
# SDD Bot

Integração Slack-first para o fluxo SDD. O bot conecta Slack, um work tracker (Jira ou GitHub Issues/Projects), um repo provider (Bitbucket ou GitHub) e o CLI `sdd` para transformar uma descrição de feature em card, ciclo `agentic-sdd-loop`, checkpoints e retomadas supervisionadas — sem sair do Slack.

---

## O que o bot faz

Ao receber `/bot start <descrição>` em um canal de comandos, o bot executa automaticamente:

1. Gera um título conciso para o card usando o LLM configurado.
2. Cria o card no work tracker configurado com status `/bloqueado` por comentário.
3. Resolve a entrada com `sdd resolve-input`.
4. Roda `sdd workflow run agentic-sdd-loop --json` até o checkpoint.
5. Guarda apenas a correlação Slack/card/demanda em `.sdd/bot/sessions.json`.
6. Envia resumo, contexto e botões de aprovação/rejeição para o Slack.
7. Após aprovação verificada, retoma com `sdd auto run --real` até o próximo limite supervisionado.

O bot não é fonte de verdade. Artefatos, checkpoints e estado canônico continuam em `docs/<slug>/`, `.sdd/state`, `.sdd/workflows` e traces locais. MCP permanece read-only.

---

## Pré-requisitos

| Requisito | Versão mínima | Observação |
|---|---|---|
| Node.js | 20.x LTS | `node --version` |
| npm | 10.x | incluído no Node 20 |
| pm2 | qualquer | `npm i -g pm2` |
| CLI `sdd` | instalado e autenticado | `sdd doctor` |
| Slack App | configurada com Socket Mode | veja seção abaixo |
| Jira ou GitHub | Work tracker acessível | Jira API token ou GitHub App/token |
| Bitbucket ou GitHub | Repo provider acessível | token com permissão de push/PR |

## Resiliência de integrações

Os providers Jira/GitHub usam timeout explícito, classificação de status (`auth_forbidden`, `not_found`, `rate_limited`, `server_error`) e redaction de tokens em mensagens de erro. Leituras seguras (`GET`) fazem retry limitado em timeout/conexão, `429` e `5xx`; escritas como criação de issue, comentário e PR não são repetidas automaticamente.

No GitHub, os parâmetros opcionais `request_timeout_ms`, `max_attempts` e `retry_base_delay_ms` permitem ajustar a política por projeto. O receiver de webhooks valida assinatura HMAC, limita payload e responde `413 payload_too_large` para corpos acima do limite configurado.

---

## Instalação rápida

```bash
# 1. A partir da raiz do projeto SDD, instale as dependências do bot
cd bot
npm install

# 2. Gere o arquivo de configuração interativamente
sdd bot install
# O assistente solicita tokens e valida cada campo antes de gravar
# .sdd/bot/sdd-bot.config.yaml (adicionado ao .gitignore automaticamente).

# 3. Inicie o bot em produção com pm2
pm2 start npm --name sdd-bot -- run start
pm2 save

# 4. Verifique o status
sdd bot status
```

Para iniciar sem pm2 (sessão única):

```bash
npm run start
```

---

## Comandos disponíveis

### `/bot start <descrição>`

**Canal:** `<prefix>-comandos`

Cria um novo card SDD, inicia `agentic-sdd-loop` e responde com checkpoint, docs e ações Slack.

Exemplo:

```
/bot start Adicionar autenticação OAuth2 com Google no portal do cliente
```

`/bot create <descrição>` é alias compatível de `/bot start`.

### `/bot approve <id> --gate prd|techspec|refinement`

Aprova gate via Slack. O usuário precisa estar em `bot_policy.allowed_slack_approvers` ou `bot_policy.admin_user_ids`, e também em `sdd.config.yaml > approvers.slack`.

### `/bot reject <id> --gate ... --reason <motivo>`

Reprova gate e reabre a etapa correspondente.

### `/bot run <id> --through execution|review|memory`

Retoma execução supervisionada depois do planejamento aprovado. Não usa `--unattended` por padrão.

### `/bot status [id]`

Mostra visão consolidada de workflow, motor autônomo e health.

### `/bot context <id>`

Mostra handoff/contexto compacto a partir das superfícies SDD locais.

### Comandos legados

`/bot update`, `/bot list`, `/bot view` e `/bot aproved` continuam disponíveis para compatibilidade; `/bot aproved <id>` é alias legado de aprovação PRD.

---

## Estrutura de canais

O bot organiza os canais usando um prefixo derivado dos 4 primeiros caracteres de `slack.session_name`. Com `session_name: "cijira"` o prefixo é `ciji`.

| Canal | Visibilidade | Finalidade |
|---|---|---|
| `ciji-comandos` | Público ou privado | Entrada de comandos `/bot start` |
| `ciji-logs` | Privado (admins) | Auditoria de todas as operações do bot |
| `ciji-tasks` | Grupo | Contém os canais individuais de cada card ativo |
| `ciji-tasks-<card-id>` | Privado | Sessão isolada de cada card (criado automaticamente) |

Os canais de sessão podem ser arquivados após o ciclo ser concluído e registrado em `memory`.

---

## Estrutura de arquivos por card

Para cada card `<PROJ-ID>`, o bot cria:

```
.worktree/
  <PROJ-ID>/                    # worktree git isolado (branch <PROJ-ID>)
    docs/
      <PROJ-ID>/
        risk-classification.md  # saída da etapa sdd risk
        idea.md                 # saída da etapa sdd idea
.sdd/
  bot/
    sessions.json               # estado das sessões ativas (gerado em runtime)
    sdd-bot.config.yaml         # configuração do bot (não versionar)
```

Os arquivos de artefato incluem um cabeçalho com metadados de rastreabilidade (card ID, versão, status) gerenciado pelo `FileHeaderManager`.

---

## Permissões da Slack App

Crie a Slack App em [api.slack.com/apps](https://api.slack.com/apps) e configure:

### Bot Token Scopes (OAuth & Permissions)

| Escopo | Necessário para |
|---|---|
| `channels:manage` | Criar e arquivar canais públicos |
| `channels:read` | Ler informações de canais públicos |
| `chat:write` | Postar mensagens |
| `files:write` | Enviar arquivos de artefatos |
| `groups:write` | Criar e arquivar canais privados |
| `groups:read` | Ler informações de canais privados |
| `users:read` | Resolver IDs de usuários admin |
| `users:read.email` | Resolver usuários por e-mail (opcional) |
| `commands` | Registrar o slash command `/sdd` |

### App-Level Token Scopes (Socket Mode)

| Escopo | Necessário para |
|---|---|
| `connections:write` | Conexão via Socket Mode (sem servidor HTTP exposto) |

### Slash Commands

Registre o comando `/sdd` apontando para qualquer URL placeholder (Socket Mode não usa URL). Habilite **Socket Mode** em Settings → Socket Mode.

---

## Configuração

Copie o template e preencha os valores:

```bash
cp .sdd/bot/sdd-bot.config.example.yaml .sdd/bot/sdd-bot.config.yaml
```

O arquivo contém comentários detalhados para cada campo. As seções obrigatórias são `slack`, `llm` e `sdd`, além do provider selecionado em `integrations.work_tracker`/`integrations.repo`. Veja `.sdd/bot/sdd-bot.config.example.yaml` para Jira/Bitbucket e GitHub.

Para GitHub:

```yaml
integrations:
  work_tracker: github
  repo: github

github:
  owner: minha-org
  repo: meu-repo
  base_branch: main
  auth:
    app_id: "12345"
    installation_id: "67890"
    private_key_env: GITHUB_APP_PRIVATE_KEY
    token_env: GITHUB_TOKEN
  project:
    owner_type: organization
    owner: minha-org
    number: 1
  webhook_secret_env: GITHUB_WEBHOOK_SECRET
  webhook:
    enabled: false
    port: 8787
    path: /github/webhook
  request_timeout_ms: 10000
  max_attempts: 3
  retry_base_delay_ms: 250
```

Para aprovações Slack supervisionadas, configure também:

```yaml
bot_policy:
  allowed_slack_approvers:
    - U123456
  admin_user_ids: []
  max_workflow_iterations: 3
  command_timeout_ms: 300000
  allow_unattended: false
  default_through: review
```

E no `sdd.config.yaml` do projeto:

```yaml
approvers:
  slack:
    - U123456
```

O bot cria Issues como `GH-<número>`, adiciona ao Projects v2 quando configurado, usa comentários `/bloqueado`/`/aprovado` como gate compatível com o CLI e cria draft PR quando uma branch/worktree local existir. O provider GitHub usa timeout explícito, retry conservador e tratamento de `429`; ajuste `request_timeout_ms`, `max_attempts` e `retry_base_delay_ms` apenas quando o ambiente exigir. O receiver de webhooks é opcional: ele valida `X-Hub-Signature-256` e despacha `issues`, `issue_comment`, `pull_request`, `check_suite`, `workflow_run` e eventos Projects v2 best-effort.

Para uma única conta Slack operando múltiplos projetos/repositórios por canal, veja a especificação em `docs/BOT-MULTI-REPO-SLACK-SPEC.md`.

Variável de ambiente opcional para sobrescrever a raiz do projeto:

```bash
export SDD_BOT_ROOT=/caminho/absoluto/para/o/projeto
```

---

## Resolução de problemas

**O bot não inicia — erro de configuração**

```bash
sdd bot status
# ou
sdd doctor
```

Verifique se `.sdd/bot/sdd-bot.config.yaml` existe e se todos os campos obrigatórios estão preenchidos. O bot exibe a seção e o campo ausentes na mensagem de erro.

**Erro `session_name deve ter ao menos 4 caracteres`**

O campo `slack.session_name` no config tem menos de 4 caracteres. Ajuste para um nome com no mínimo 4 letras.

**Erro ao criar worktree — branch já existe**

A branch `<card-id>` já existe no repositório. Verifique com `git branch -a` e remova a branch conflitante antes de retentar.

**Mensagens duplicadas no canal**

Reiniciar o bot sem arquivar a sessão anterior pode causar duplicatas. Execute `sdd bot status` para listar sessões ativas e arquive manualmente os canais com sessão aberta antes de reiniciar.

**Erro de permissão Jira / Bitbucket**

Confirme que o token configurado tem acesso ao projeto (`project_key`) e ao repositório (`repo_slug`) respectivos. Tokens Jira expiram; gere um novo em id.atlassian.com se necessário.

---

## Desenvolvimento

```bash
# Modo de desenvolvimento com ts-node (hot-reload manual)
npm run dev

# Build para produção
npm run build

# Iniciar a partir do build
npm run start
```

Os testes de unidade ficam em `bot/test/` (quando presentes) e podem ser executados com:

```bash
npm test
```

Para inspecionar logs do pm2 em tempo real:

```bash
pm2 logs sdd-bot
```