Roadmap — apêndice de épicos (E*)
Status: corrigir · Escopo: Inventário histórico de épicos — não é o guia diário · Atualizado em: 2026-08-04
[!IMPORTANT] Guia diário de prioridade:
focus.md(agora / próximo / depois). Escopo de produto:DIRECTION.md.Este arquivo é apêndice: notação
E#/E#.T#, útil pra arqueologia e status pontual. Vários itens estão desalinhados com o shipped atual — corrigir ao tocar, não usar como fila.
Legenda de status
Seção intitulada “Legenda de status”| Marca | Significado |
|---|---|
| ✅ | Escopo da task entregue — código + testes (ou harness) ponta a ponta |
| ✅ parcial | Caminho feliz wired; falta borda, prod multi-tenant, persistência ou hardening |
| (vazio) | Não iniciado ou só schema/spec |
| ⏳ | Pendência explícita na sequência |
| N/A v1 | Decisão consciente de não fazer na v1 |
| Cancelada ou absorvida por outra task |
Tabelas E0–E4 e E28 usam coluna Status. Demais épicos prefixam a Descrição com a mesma marca (ex.: ✅ parcial | …).
Docs de apoio vivos:
../../DIRECTION.md— escopo e prioridade atuais../engineering/padrao-documentacao.md— como escrever docs../text-pipeline/architecture/conversation-quality-lab.md— eval/replay (texto)../text-pipeline/architecture/blueprint-code-alignment.md— divergências blueprint ↔ runtime- História / planos done:
docs/archive/
Norte 10/10 — critérios de saída
Seção intitulada “Norte 10/10 — critérios de saída”O roadmap não termina quando “funciona no harness”. Ele termina quando o produto passa por estes gates:
| Gate | Critério | Por quê importa |
|---|---|---|
| G0 — Qualidade base | pnpm quality verde; contratos gerados sem drift; worker e LLM typecheck verdes | Sem gate verde, qualquer tuning vira areia movediça |
| G1 — Isolamento tenant | RLS fail-closed + runInTenantScope real + teste cross-tenant negativo | Cross-tenant leak mata produto enterprise |
| G2 — Exactly-once prático | Prova por testes de crash/retry inbound e outbound; nenhuma duplicata silenciosa | Mensagem duplicada ou sumida destrói confiança |
| G3 — Conversa consultiva | Golden/replay cobre greeting, informação, objeção, deferral, concorrente, reengage, handoff | O produto ganha no detalhe da conversa, não no “tem IA” |
| G4 — Tuning rápido | Toda regressão vira fixture/replay; bot score melhora sem depender só de chat manual | Resolve o gargalo atual de otimizar comportamento |
| G5 — Dados de outcome | treatment_snapshot + outcome_signals + propensity auditáveis por SQL | Moat de dados só existe com causalidade |
| G6 — Produção multi-tenant | Meta credentials por endpoint, opt-out/consent por canal, dashboards operacionais | Base para clientes reais e expansão |
Ordem executiva atual
Seção intitulada “Ordem executiva atual”| P | Programa | Entrega 10/10 | Épicos |
|---|---|---|---|
| P0 | Deploy produção (tactflow.io) | Worker no domínio real, secrets, seed demo, Stripe webhook — ver production-deploy-v1.md | E34 |
| P0 | Distribuição / trilha G | Design partners pagantes, case com número de conversão, pricing validado — ver docs/archive/gtm-execution-v1.md | G0–G5 (comercial) |
| P0 | Gate verde e isolamento | Typecheck/testes verdes, tenant scope fail-closed, repo guards auditados | E0, E16, E21 |
| P0 | Exactly-once | Inbound/outbound com crash-window testado e fallback explícito | E3.T7, E10.T8 |
| P1 | Conversation Quality Lab | Replay de conversas reais, golden cases, LLM judge calibrado, taxonomia de regressões | E18, E20 |
| P1 | Orchestrator sustentável | Quebrar god functions em fases; ports claros; menos remendos regex | E6, E10, E29 |
| P1 | Memória/RAG útil | Ingest cliente real, recall confiável, promoção profile, claims grounded | E13, E14 |
| P2 | Learning loop | Experimentos com propensity, OPE, canary e policy patches allowlisted | E19 |
| P2 | Pesquisa aplicada profunda | RAG/memória/harness, prompt engineering e ciência comportamental viram protótipos/evals | E30 |
| P2 | Produto comercial | Admin, copilot workspace, multicanal/outbound, dogfooding como case | E22–E27 |
Regras de execução:
- Não promover prompt por gosto. Mudança comportamental precisa virar fixture, replay ou outcome.
- Regex é triagem, não semântica. Regex pode detectar mecânica local (pontuação, idempotência, PII), mas não deve decidir intenção comercial complexa quando há contrato/LLM/eval melhor.
- Locale copy não entra hardcoded no core. PT-BR de exemplo vive em fixtures, policy, RAG ou eval; runtime deve ser language-agnostic quando possível.
- Guard não reescreve voz. Guard bloqueia segurança/policy mecânica; voz e estilo são generate/eval.
- Toda divergência blueprint ↔ código entra em
blueprint-code-alignment.md.
Execução paralela atual — modelo forte vs Composer
Seção intitulada “Execução paralela atual — modelo forte vs Composer”Use esta divisão para manter velocidade sem transformar decisões de produto em refactor mecânico.
| Faixa | Dono recomendado | Próximas entregas | Critério de pronto |
|---|---|---|---|
| Quality review UX | Composer 2.5 | Ajustes no pnpm quality:review, navegação, resumo, docs, testes | quality:review --help, quality:reviews:summary, eval:quality-lab verdes |
| Fixture/golden expansion | Composer 2.5 | Minerar reviews, exportar fixtures, atualizar IDs/seed, ampliar casos multilíngues | Nenhum skippedCaseIds; expected sem P-ASSUME-CANDIDATE/L-LOCALE |
| Quality insights | Modelo forte | Transformar quality-reviews.jsonl em diagnóstico: causa raiz, camada provável, hipótese mínima | Diagnóstico antes de editar; 1 causa raiz por batch; evals definidos |
| Replay real | Modelo forte | eval:replay --conversation <id> com reconstrução de contexto e comparação before/after | Sem LLM live por padrão; diff auditável; promove só com evidência |
| Judge/rubrica | Modelo forte | LLM judge calibrado contra reviews humanos | Viés medido; judge não bloqueia deploy sem calibração |
| Mudança comportamental | Modelo forte → Composer | Modelo forte define hipótese/policy; Composer implementa patch pequeno/testável | eval:quality-lab + golden/replay relevante verdes |
| Hardening mecânico | Composer 2.5 | SQL dashboards, docs, anti-hardcode scan, refactors localizados | Sem mudança ampla de tese; typecheck/testes verdes |
Regra prática: se a tarefa decide como o bot deve se comportar, começa com modelo forte. Se a tarefa aplica uma decisão já escrita, Composer executa.
Princípio de sequência
Seção intitulada “Princípio de sequência”flowchart LR F[Fase 0<br/>Fundação + walking skeleton] --> C[Fase 1<br/>Core runtime v1] C --> Q[Fase 1<br/>Qualidade/segurança v1] Q --> O[Fase 2<br/>Optimization + simulação v1.1+] O --> FUT[Fase 3<br/>Copilot/outbound/booking — futuro]Walking skeleton primeiro: uma fatia fina inbound→ack→fila→persistência→outbound trivial→entrega, ponta a ponta, antes de qualquer inteligência. Tudo depois pendura nesse esqueleto.
Fase 0 — Fundação + walking skeleton (v1, caminho crítico)
Seção intitulada “Fase 0 — Fundação + walking skeleton (v1, caminho crítico)”E0. Scaffold & plataforma
Seção intitulada “E0. Scaffold & plataforma”| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E0.T1 | ✅ | Monorepo: apps/api-worker (TS/Workers) + apps/llm-service (Python/FastAPI) + packages/contracts + packages/test-fixtures | — | §4.4, §20 |
| E0.T2 | ✅ | Tooling + quality gates: Astral (uv, Ruff, ty), Biome, Vitest/pytest, dependency-cruiser, import-linter, pre-commit — ver docs/live/engineering/coding-standards.md | E0.T1 | §6.2 |
| E0.T3 | ✅ | Wrangler config (Workers, Queues, DO, R2 bindings); .dev.vars.example | E0.T1 | §4.1, §6 |
| E0.T4 | ✅ | Cliente Neon + camada de acesso a dados (storage/client, repos observability TS, writer llm_calls Python) | E0.T1 | §6 |
| E0.T5 | ✅ | Contratos: Pydantic → OpenAPI → TS (pnpm contracts:gen); FastAPI /v1/*; LlmGateway HTTP adapter | E0.T1 | §4.4, §14 |
E1. Schema & harness de validação (anti-regressão)
Seção intitulada “E1. Schema & harness de validação (anti-regressão)”| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E1.T1 | ✅ | Migrations versionadas a partir do data-model-v1.md (schema/migrations) | E0.T4 | §DataModel |
| E1.T2 | ✅ | seed.sql + canonical_queries.sql + invariants.sql | E1.T1 | §10b |
| E1.T3 | ✅ | ensure_monthly_partitions + schema/jobs/ensure-partitions.sql; GHA mensal (.github/workflows/ensure-partitions.yml) | E1.T1 | §C6, §10b |
| E1.T4 | ✅ | CI: branch Neon efêmera (parent production) ou DATABASE_URL dev → harness → derruba | E1.T2 | proc §4b |
| E1.T5 | ✅ | uuid_generate_v7 + extensões (pgcrypto,vector) em 0001_extensions.sql | E1.T1 | §0 |
E2. Walking skeleton (fatia fina ponta a ponta)
Seção intitulada “E2. Walking skeleton (fatia fina ponta a ponta)”| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E2.T1 | ✅ | Webhook inbound: ack rápido (202) + enfileira payload normalizado | E0.T3 | §4.6, §8 |
| E2.T2 | ✅ | Consumer de fila: persiste messages + idempotência + observability | E2.T1, E1.T1 | §8 |
| E2.T3 | ✅ | ConversationRuntimeDO — serialização /turn + alarm stub | E2.T2 | §7 |
| E2.T4 | ✅ | Outbound trivial (echo) via outbox + mark sent | E2.T2 | §9 |
| E2.T5 | ✅ | Writers de observabilidade (timeline_events,runtime_logs) no fluxo | E2.T2 | §5.10, §6.4 |
Gate Fase 0: mensagem real entra, persiste, é coordenada pelo DO e sai — com trace. A partir daqui, cada componente é incremento.
Fase 1 — Core runtime (v1)
Seção intitulada “Fase 1 — Core runtime (v1)”E3. Channel Gateway (§5.1)
Seção intitulada “E3. Channel Gateway (§5.1)”| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E3.T1 | ✅ | Verificação de assinatura/secret do webhook (Meta) + GET hub.challenge | E2.T1 | §5.1 |
| E3.T2 | ✅ | Normalização → contrato unificado de mensagem (Meta WABA + compat dev stub) | E2.T1 | §5.1 |
| E3.T3 | ✅ | Idempotência inbound: consumer tryClaim + webhook hasInboundKey skip re-enqueue | E1.T1 | §4.7, §10b |
| E3.T4 | ✅ | Captura seletiva payload raw → R2 + índice channel_payloads | E2.T2 | §6.5 |
| E3.T5 | ✅ parcial | Normalização mídia + media_ref (Graph download quando META_ACCESS_TOKEN; senão media_id) | E3.T2 | §4.13, §5.1 |
| E3.T6 | ✅ | Reply-to inbound: message.context.id → messages.reply_to_external_id + quoted_message no pack | E3.T2 | §14, schema-decisions 8.2 |
| E3.T7 | ✅ parcial | Inbound idempotency: claimed→processed, duplicate terminal, recovery when message persisted but turn not processed; inbound outbox still future | E3.T3 | §4.7, reliability-exactly-once.md |
| E3.T8 | Meta credentials por channel_endpoints (multi-WABA) | E3.T1 | §4.9 |
E4. Identity / Contact Resolution (§5.2)
Seção intitulada “E4. Identity / Contact Resolution (§5.2)”| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E4.T1 | ✅ | Resolver endpoint do negócio por phone_number_id → tenant+unit | E3.T2 | §4.9, §5.2 |
| E4.T2 | ✅ | Resolver/crear channel_identities → contacts (escopo tenant) | E4.T1 | §5.2 |
| E4.T3 | ✅ | Get-or-create conversations (tenant+unit+endpoint+contact) | E4.T2 | §5.2, §5.3 |
E5. Conversation State + Burst (§5.3)
Seção intitulada “E5. Conversation State + Burst (§5.3)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E5.T1 | ✅ | Máquina de estados runtime_state (transições no DO + fallback worker) | E2.T3 |
| E5.T2 | ✅ | Burst handling: coletar, debounce, selar (message_bursts) | E5.T1 |
| E5.T3 | E5.T1 | §16.2 | |
| E5.T4 | ✅ | pacing_state sync com eventos runtime | E5.T1 |
| E5.T5 | ✅ | Interrupção multi-burst: inbound em decision_pending/response_scheduled/responding → interrupted | E5.T2 |
| E5.T6 | ✅ | Runtime FSM: responding + interrupted → collecting_burst (P0 unicorn) | E5.T5 |
| E5.T7 | ✅ | Transições pacing ghost (response_sent, awaiting_reply, cooldown/dormant) | E5.T4 |
E6. Interaction Orchestrator ⭐ (§5.4)
Seção intitulada “E6. Interaction Orchestrator ⭐ (§5.4)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E6.T1 | ✅ parcial | Contrato de decisão (input/output §14) | E5.T2 |
| E6.T2 | ✅ parcial | LLM propõe response_delay_ms; Worker clamp + interrupt; ver pacing-planner.md | E6.T1 |
| E6.T3 | ✅ | Fragmentação + verbosidade → response_plans + response_fragments (conteúdo no send) | E6.T1 |
| E6.T4 | ✅ | Gate memory_commit + timeline committed/skipped | E6.T1 |
| E6.T5 | ✅ | Confidence gate → escalated + handoff_pending | E6.T1, E12 |
| E6.T6 | ✅ | delivery_mode + window_state_at_decision (janela 24h) | E6.T1, E8 |
| E6.T7 | ✅ parcial | Steering + style envelope (policy + lead inference; persist E13 pendente) | E6.T1, E7.T3 |
E7. Policy Engine (§5.5)
Seção intitulada “E7. Policy Engine (§5.5)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E7.T1 | ✅ parcial | policy_profiles tenant default + override por unit → merge no orchestrator | E1.T1 |
| E7.T2 | ✅ | Disclosure level (none / brand_assistant / explicit_ai) → ContextPack.disclosure_level + generate prompt | E7.T1 |
| E7.T3 | ✅ parcial | Envelope de comunicação (rules.communication) → style_hints + pacing rules | E7.T1 |
| E7.T4 | ✅ | rules.escalation.enabled (opt-in, default off) + confidence_threshold → confidence gate / objective | E7.T1, E12.T3 |
E8. Channel-aware messaging (§4.10)
Seção intitulada “E8. Channel-aware messaging (§4.10)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E8.T1 | ✅ | Derivação de window_state por messaging_window_expires_at (inbound + decision snapshot) | E4.T3 |
| E8.T2 | message_templates — espelho de status da Meta + categorias | E1.T1 | §4.10 |
| E8.T3 | Messaging tier / rate por channel_endpoints aplicado no outbox | E10.T1 | §4.10 |
E9. Workflow Runtime — stage engine (§5.6)
Seção intitulada “E9. Workflow Runtime — stage engine (§5.6)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E9.T1 | ✅ parcial | pipeline_stage_* no Context Pack via workflow_instances + fallback tenant default | E1.T1 |
| E9.T2 | ✅ | workflow_instances: criar no get-or-create + backfill lazy — docs/archive/implementation-e13-t7-e9-t2.md § E9.T2 | E9.T1, E4.T3 |
| E9.T3 | ✅ | evaluateStageTransition pós-understand; advanceToStage + timeline workflow_stage_advanced / workflow_stage_handoff | E9.T2 |
| E9.T4 | ✅ | handoff_context_exported timeline + outcome_signals.handoff on escalation | E9.T3 |
E10. Actions Layer + resiliência outbound (§5.8, §4.7)
Seção intitulada “E10. Actions Layer + resiliência outbound (§5.8, §4.7)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E10.T1 | ✅ parcial | DO alarm + outbox + Meta outbound (dev stub); fila outbound-send ✅ (E10.T9); Meta live multi-tenant pendente | E2.T4 |
| E10.T2 | ✅ | Retries + backoff exponencial + DLQ (dead) no send alarm; resume parcial por fragmento | E10.T1 |
| E10.T3 | Rich/interactive (botões, listas) | E10.T1 | §5.8 |
| E10.T4 | ✅ parcial | Template send fora da janela 24h (execute-template-send, dev_stub; Meta live multi-tenant pendente) | E10.T1, E8.T2 |
| E10.T5 | Ação operacional: agendamento (intenção) + link de pagamento (Pix) | E10.T1 | §5.8 |
| E10.T6 | ✅ | Follow-up/reengage via DO Alarm + generate; followup_schedule wired (seed + mode from policy) — spec reengagement-objections-v1.md | E2.T3, E8.T1 |
| E10.T7 | Outbound reply-to: citar mensagem do usuário (context.message_id Meta) | E10.T1, E3.T6 | schema-decisions 8.2 |
| E10.T8 | ✅ parcial | Outbound exactly-once: claimSending + provider_trace_id + resume skip + ambiguous sending fail-closed (dead) | E10.T1 |
| E10.T9 | ✅ | Fila outbound-send consumer — DO enfileira, worker executa LLM/send + /outbound-send-complete | E10.T8 |
E11. Prompting Layer — Python/Pydantic (§5.7)
Seção intitulada “E11. Prompting Layer — Python/Pydantic (§5.7)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E11.T1 | ✅ | Agente Pydantic AI em /understand (output_type=UnderstandingResult); fallback heurístico sem OPENROUTER_API_KEY | E0.T5 |
| E11.T2 | ✅ parcial | Context pack: working + episodic (episodic_summary, structured arrays) + profile (profile_facts) | E11.T1, E13 |
| E11.T3 | ✅ parcial | /generate no send com fragments[] + agent/stub; typing por bloco no texto gerado | E11.T1, E10.T1 |
| E11.T4 | Variantes de resposta (variant_id) | E11.T3 | §17.4 |
| E11.T5 | ✅ | Audit llm_calls (modelo, tokens, custo, latência, prompt_ref) em understand/generate/guard | E11.T1 |
| E11.T6 | ✅ parcial | Humanização explícita no prompt /generate via style_hints | E11.T3, E6.T7 |
E12. Safety & Guardrails (§5.13)
Seção intitulada “E12. Safety & Guardrails (§5.13)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E12.T1 | ✅ | /v1/guard antes do send (LLM ou local); guard_blocked timeline | E11.T3 |
| E12.T2 | ✅ | Defesa inbound prompt injection (wrap + timeline) | E11.T1 |
| E12.T3 | ✅ | confidence_evaluated timeline + threshold → escala/handoff | E11.T3 |
E13. Memory Layer (§5.11, §16)
Seção intitulada “E13. Memory Layer (§5.11, §16)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E13.T1 | Episodic: conversation_summaries (append/version) | E1.T1 | §16.2 |
| E13.T2 | ✅ parcial | Leitura contact_profile_facts.communication.* no orchestrator | E1.T1 |
| E13.T3 | ✅ parcial | Consumer memory.extract pós-memory_commit — structured (E13.T3b) + LLM /v1/memory/extract + persist episodic/profile | E6.T4, E11.T1 |
| E13.T3b | ✅ parcial | Identificador estruturado → upsertFact sem LLM | E13.T3 |
| E13.T4 | Promoção episodic→profile por confidence threshold | E13.T3 | §16.1 |
| E13.T5 | ✅ | Timeline memory_committed / memory_commit_skipped no orchestrator | E13.T3 |
| E13.T6 | ✅ parcial | Episódico estruturado no Context Pack (episodic_key_events, episodic_objections, episodic_intents) | E13.T3 |
| E13.T7 | ✅ parcial | Recall reativo (memory.recall): janelas SQL + /v1/memory/recall-window → recall_evidence no pack — ver docs/archive/implementation-e13-t7-e9-t2.md § E13.T7 | E13.T3, E11.T2 |
E14. Knowledge & Grounding — RAG (§5.12)
Seção intitulada “E14. Knowledge & Grounding — RAG (§5.12)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E14.T1 | ✅ parcial | Ingestão single URI + batch sitemap/urls + HTML→texto + timeline | E1.T1 |
| E14.T2 | ✅ parcial | /v1/embed (OpenRouter ou stub determinístico) + seed com embedding harness | E14.T1, E11.T1 |
| E14.T3 | ✅ parcial | Retrieval HNSW (cosine) com pré-filtro tenant/unit + fallback keyword ILIKE | E14.T2 |
| E14.T4 | ✅ parcial | grounded_on persistido no plano + guard local bloqueia hard claims sem chunks | E14.T3, E6.T1 |
| E14.T5 | ✅ parcial | Reindex incremental: source_version bump + purge chunks < version | E14.T2 |
E15. Multimodal (§4.13)
Seção intitulada “E15. Multimodal (§4.13)”Prioridade ↑ (2026-06): E15.T1 deixa de ser “futuro” — lead BR manda áudio o tempo todo; sem transcrição, qualquer deploy WhatsApp BR real é capenga (
docs/archive/path-to-valuation.md§brechas item 2). Pré-requisito prático do primeiro design partner BR (trilha G1).
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E15.T1 | Transcrição de áudio → messages.transcript (Whisper/Deepgram via gateway LLM) — gate de deploy BR | E3.T5, E11.T1 | §4.13 |
| E15.T2 | Visão de imagem/documento → descrição | E3.T5, E11.T1 | §4.13 |
E16. Persistence & Observability (§5.9, §5.10)
Seção intitulada “E16. Persistence & Observability (§5.9, §5.10)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E16.T1 | Repositórios por entidade (escopo tenant/unit — C9) | E1.T1 | §5.9, §C9 |
| E16.T2 | Retenção Hot/Warm/Cold (Neon drop partition + R2 lifecycle) — gate escala, não Ato 1; ver payload-retention.md | E1.T3 | §6.6 |
| E16.T3 | Tracing correlacionado (trace_id) ponta a ponta | E2.T5 | §6.4 |
| E16.T4 | Queries operacionais Postgres-first (dashboards via SQL) | E16.T1 | §6.4 |
E17. Privacy / LGPD (§4.11)
Seção intitulada “E17. Privacy / LGPD (§4.11)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E17.T1 | Consent management (consent_events, scope tenant/unit) | E1.T1 | §4.11 |
| E17.T2 | ✅ | Enforcement de opt-out (bloqueia envio/reengage; consent_events) | E17.T1, E10.T6 |
| E17.T3 | Erasure: anonimização in-place (PII null + erased_at) | E16.T1 | §4.11, §10b |
| E17.T4 | Cripto de PII (envelope encryption) | E0.T3 | §4.11 |
| E17.T5 | Profundidade healthcare em camadas (decisão): a tese é dominar a operação inteira da vertical (switching cost), entrando por camadas — comercial (agora) → relacionamento → gestão operacional → clínica/prontuário (camada 4, gate explícito). Camada 4 só com: vertical 1 vencida (G5), caixa p/ compliance (LGPD art. 11, cripto E17.T4, BAA/HIPAA em dental/healthcare US) e demanda registrada na trilha G. Dado de saúde citado em conversa já é sensível → E17.T1/T4 sobem de prioridade ao entrar clínica BR séria — ver docs/archive/master-strategy-v1.md §6 | — | strategy §6 |
E18. Quality & Evaluation (§5.14)
Seção intitulada “E18. Quality & Evaluation (§5.14)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E18.T1 | ✅ parcial | Golden eval-cases.json + worker suite + eval_runs repo + pnpm eval:golden:record; LLM judge FU via py:eval | E11.T1 |
| E18.T2 | ✅ parcial | outcome_signals writer (user_replied) + join plan↔outcome; exploration/propensity em response_plans (delay) — ver analytics-optimization.md | E10.T1 |
| E18.T2b | ✅ | prompt_version no plano pós-generate | E18.T2 |
| E18.T3 | ✅ parcial | Replay offline de decisão/policy (replay-policy-decision, fixtures policy-replay-cases.json, adapter timeline_events → input, pnpm eval:replay:record) | E18.T1 |
| E18.T4 | ✅ parcial | pnpm eval:conversation <id> — triagem heurística por plano (DB); replay com reexecução LLM pendente | E18.T3, E16.T4 |
| E18.T5 | ✅ parcial | Taxonomia Q-*/P-*/F-*/G-*/L-LOCALE em heurísticas + fixtures âncora; eval:quality-fixtures:audit; persistência em eval_runs parcial | E18.T1 |
| E18.T6 | LLM judge calibrado para objective_fulfillment, maieutic_quality, anti_pitch, mobile_ergonomics, grounding, policy_compliance, naturalness | E18.T1, E18.T4 | §5.14 |
| E18.T7 | ✅ parcial | Âncoras reais exportadas (conversation-anchor-cases.json, eval:conversation:export-anchor) — 019e8709…019e8879 | E18.T4 |
| E18.T8 | ✅ parcial | pnpm eval:mine-regressions — SQL (F-DROP, G-REGEN, LLM error/fallback, fragmento longo) + heurísticas no sample | E18.T2, E16.T4 |
| E18.T8a | ✅ parcial | pnpm quality:review — revisão humana TUI com score 1–5, labels, root cause guess e fixture export opcional | E18.T5, E18.T8 |
| E18.T8b | ✅ parcial | pnpm quality:insights — agrupar quality-reviews.jsonl, separar falso positivo/needs improvement/fixture e sugerir 1 causa raiz prioritária (diagnóstico, sem editar código) | E18.T8a, E18.T11 |
| E18.T9 | eval:compare --before --after com diff de respostas, scores e rationale; usado antes de promover prompt/policy | E18.T4, E18.T6 | §5.14 |
| E18.T10 | Anti-hardcode suite: falha se regra de negócio depender de frase PT-BR fixa no core sem fixture/eval correspondente | E18.T5 | coding-standards.md |
| E18.T11 | Dashboard Postgres-first de qualidade: regressões por tipo, fallback/model errors, guard revisions, opt-out pós-reengage, custo por turno | E18.T8, E16.T4 | §6.4 |
Motivo E18: hoje o tuning do bot depende demais de inspeção manual (pnpm chat). E18 transforma todo bug conversacional em fixture/replay, reduzindo o ciclo de melhoria e evitando regressões por prompt.
Definition of done E18 10/10:
- Todo bug percebido em conversa real tem
conversation_id, classificação e replay. - Golden/replay roda em CI sem chamar LLM live por padrão.
- LLM judge é calibrado contra amostra humana antes de bloquear deploy.
- Nenhum prompt/policy amplo é promovido sem diff antes/depois.
- Conversas âncora reais não regrediram.
Gate Fase 1 (v1): todas as features ✅ do escopo §3 entregues, com captura de aprendizado (§17.3) ligada desde o dia 1.
Gate runtime produto (validação consultiva — sem UI)
Seção intitulada “Gate runtime produto (validação consultiva — sem UI)”Motor técnico ✅ — inbound→orchestrator→LLM→outbound roda em dev (
pnpm chat, Neon, stub/live parcial). Produto consultivo 🟡 — falta confiança em objeção, concorrente e regressão (E18). E28 CLI entregue cedo para dogfood; o gate abaixo mede confiança de conversa, não existência do pipeline.
| Capacidade | Status | O que falta (se 🟡/⏳) | Épico(s) |
|---|---|---|---|
| Contexto rico no turno | 🟡 | Episodic append maduro (E13.T1/T4); recall já no pack | E13.T6–T7, E13.T1 |
| Funil com intenção | ✅ | Admin/regras por cliente (E27 futuro) | E9.T2–T4 |
| Triagem / qualificação | 🟡 | Sinais wired; falta golden + tuning de stage/objective | E9, E6, E11, E18 |
| Playbooks de objeção | 🟡 | playbookObjectiveExtension wired; falta cobertura OBJ-* / deferral eval | E6, E18, reengagement-objections-v1.md |
| Concorrente / comparação | 🟡 | RAG + guard wired; falta ingest cliente real + eval “não inventar” | E14.T1–T4, E18 |
| Reengage proativo | ✅ | followup_schedule + alarm + generate | E10.T6, E7 |
| Policy → prompt | ✅ | Tenant/unit merge, objectives, disclosure, escalação opt-in | E7, client-config-surface.md |
| Qualidade / regressão | 🟡 | Golden suite ✅ + replay policy offline ✅; falta expandir LLM judge OBJ/COMP + replay de conversas reais completas | E18.T1–T3 |
| Dev ergonomia | ✅ | pnpm chat + --debug (generate_objective completo) | E28 |
Próximo foco: E18 (golden + replay) + E14 ingest real → fechar gate 🟡→✅. Exactly-once final (E3.T7/E10.T8) e tenant guard repos (E21) em paralelo para prod multi-tenant.
Fase 2 — Optimization + simulação (v1.1+)
Seção intitulada “Fase 2 — Optimization + simulação (v1.1+)”E19. Analytics & optimization (§17)
Seção intitulada “E19. Analytics & optimization (§17)”Gate: Ato 2+ / volume WhatsApp async com exploration ligada. Ato 1 (single-turn web) usa eval offline + SQL de conversão —
payload-retention.md.
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E19.T1 | Feature mart SQL: (contexto, treatment, outcome) canônico por response_plan_id | E18.T2, E16.T4 | §17 (L2) |
| E19.T2 | Export de eventos/features (Parquet/warehouse) | E19.T1 | §17 (L2) |
| E19.T3 | Modelos de sobrevivência para timing e follow-up (reply_latency_ms, dormancy, reengage) | E19.T1 | §17.4 |
| E19.T4 | Uplift / efeito causal dos nudges e fragmentação (fragment_count, verbosity, reengage mode) | E19.T1 | §17.4 |
| E19.T5 | OPE (IPS/SNIPS/DR) antes de qualquer patch automático em policy | E19.T4 | analytics-optimization.md |
| E19.T6 | Canary 1–5% por tenant/unit com guardrails (opt_out, complaint, delivery_error, cost`) | E19.T5 | §17 |
| E19.T7 | Patch allowlisted em policy_profiles.rules com rollback automático | E19.T6 | parameter-registry.ts |
| E19.T8 | Relatório semanal: quais parâmetros melhoraram outcome real vs proxy judge | E19.T7 | §17 |
Motivo E19: sem loop causal fechado, “AI que aprende” é narrativa. E19 transforma instrumentação em vantagem composta.
Definition of done E19 10/10:
- Cada treatment otimizável tem
exploration,propensity, contexto e outcome. - Nenhuma mudança automática é promovida só por LLM judge.
- Todo patch tem OPE, canary, guardrails e rollback.
- O produto consegue responder: “qual política converte melhor, para qual contexto, com qual confiança?”
E20. Ambiente de simulação (§17.5)
Seção intitulada “E20. Ambiente de simulação (§17.5)”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E20.T1 | simulation_personas — liga de personas (action_space, p_ghost) | E1.T1 | §17.5 |
| E20.T2 | Runner: persona-LLM ⇄ contrato de inbound (environment) | E20.T1, E2.T1 | §17.5 |
| E20.T3 | Não-contaminação: filtros production + dedicação de custo | E20.T2 | §10b C10 |
| E20.T4 | Calibração sim-to-real (distribuição de outcomes) | E20.T2, E19.T1 | §17.5 |
| E20.T5 | Export branch→prod (postgres_fdw, só agregados) | E20.T2 | §17.5, Q32 |
| E20.T6 | Persona adversarial suite: confuso, apressado, preço, objeção trust, concorrente, opt-out, ghost | E20.T2, E18.T5 | conversation-quality-lab.md |
| E20.T7 | Simulação de regressão por conversa âncora: persona tenta reproduzir falhas reais já vistas | E20.T6, E18.T7 | §17.5 |
| E20.T8 | Score sim-to-real: distância entre distribuição simulada e tráfego real por intent/outcome | E20.T4, E19.T1 | §17.5 |
Motivo E20: simulação acelera exploração e stress test, mas não substitui tráfego real. Usar para achar bugs antes, não para declarar PMF.
E21. Hardening v1.1
Seção intitulada “E21. Hardening v1.1”| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E21.T1 | ✅ parcial | RLS Postgres + FORCE RLS + runInTenantScope wired (inbound/outbound/DO/knowledge ingest) | E16.T1 |
| E21.T1a | ✅ Tenant RLS predicate fail-closed: app.tenant_id unset não permite tenant row; seed/harness setam tenant explícito | E21.T1 | Q17 |
| E21.T1b | ✅ runInTenantScope escopa queries/batches com set_config na mesma transação | E21.T1a | Q17 |
| E21.T1c | ✅ parcial | Teste integração valida predicate fail-closed e scoped client A≠B; row visibility A≠B ainda depende de role sem BYPASSRLS | E21.T1a |
| E21.T1d | ✅ parcial | Repo tenant guard audit: guards explícitos em conversation, messages, summaries, pacing, response plans, outcomes, bursts e stage context; role sem BYPASSRLS ainda pendente | E16.T1, E21.T1c |
| E21.T2 | Logfire / OTel SaaS (telemetria de IA) | E11.T5 | Q13 |
| E21.T3 | Grafana (datasource Postgres) | E16.T4 | Q12 |
| E21.T4 | Gate verde obrigatório: worker typecheck, LLM ty, tests e boundaries sem erro antes de qualquer tuning de prompt | E0.T2 | coding-standards.md |
| E21.T5 | LLM degradation policy: stub/fallback gera timeline/alert e nunca degrada silenciosamente em prod | E11.T3, E11.T5 | audit P1 |
| E21.T6 | HTTP LLM gateway com retry/backoff/circuit breaker para falha transitória, preservando idempotência | E11.T1, E16.T3 | §4.7 |
| E21.T7 | ✅ parcial | Runtime observability single pane: pnpm conversation:trace <id> junta thread, plans/findings, timeline, llm_calls e deliveries; outcome ainda pendente | E16.T4, E18.T11 |
Motivo E21: é a fronteira entre “demo séria” e produto multi-tenant confiável.
Definition of done E21 10/10:
- Typecheck e testes verdes na branch principal.
- Cross-tenant leak impossível por teste e por RLS.
- Degradação LLM é visível e acionável.
- Operador consegue diagnosticar uma conversa ruim sem abrir 5 tabelas manualmente.
E28. CLI de conversa local (dev only)
Seção intitulada “E28. CLI de conversa local (dev only)”Deferido de propósito — REPL no terminal para simular lead (WhatsApp dev stub), ver bolhas outbound, timeline e debug de policy. Não é produto nem substitui E20 (simulação em escala). Não inclui UI de vendedor (E22).
| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E28.T1 | ✅ | pnpm chat: loop REPL → POST /webhooks/whatsapp (contrato dev harness) → poll messages outbound | E2 | dev ergonomics |
| E28.T2 | ✅ | Modo --fast: hint BURST_DEBOUNCE_MS reduzido (iteração local) | E28.T1, E7 | — |
| E28.T3 | ✅ | Modo --debug: timeline, steering_mode, generate_objective completo, prompt_version | E28.T1, E16.T3 | observability |
| E28.T4 | ✅ parcial | Doc: client-config-surface.md § chat + README quick start | E28.T1 | README / engineering |
Nota E28: CLI entregue para dogfood local; gate runtime produto ainda 🟡 até E18 + RAG cliente validarem objeção/concorrente.
E29. Code health & arquitetura sustentável
Seção intitulada “E29. Code health & arquitetura sustentável”Reduzir complexidade acumulada sem refatorar por estética. O alvo é tornar o runtime mais fácil de testar, explicar e evoluir sem quebrar conversa real.
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E29.T1 | Quebrar run-post-burst-orchestration.ts em fases explícitas: bootstrap, understand, memory/recall, policy, decision, stage/handoff, plan persist | E18.T3, E21.T4 | coding-standards.md |
| E29.T2 | Quebrar execute-scheduled-send.ts em phases: generate, guard/polish, delivery, reconcile, score | E10.T8, E21.T4 | §4.7 |
| E29.T3 | Afinar ConversationRuntimeDO: wiring/alarm apenas; lógica de domínio em application services | E5, E10.T9 | §7 |
| E29.T4 | Ports explícitos para cross-context em application/; reduzir imports diretos entre contexts | E29.T1 | boundaries |
| E29.T5 | Auditoria anti-regex/hardcode: mover exemplos PT-BR para fixtures/policy/eval quando forem regra de negócio | E18.T10 | conversation-quality-lab.md |
| E29.T6 | Slice tests por fase do orchestrator, reduzindo dependência de um teste monolítico com dezenas de mocks | E29.T1 | §10 |
| E29.T7 | ADRs curtos para divergências aceitas: LLM propõe timing, guard auto-fix, NativeOutput Qwen, tenant scope | E21, E18 | blueprint-code-alignment.md |
Motivo E29: os três hotspots (run-post-burst-orchestration.ts, execute-scheduled-send.ts, conversation-runtime-do.ts) concentram valor, mas também risco de manutenção. Fatiar por fases reduz regressão e acelera tuning.
Definition of done E29 10/10:
- Cada fase crítica tem função/serviço nomeado, input/output testável e timeline clara.
- Teste de regressão conversa não precisa mockar o mundo inteiro.
- Regex/locale hardcode restante tem justificativa, fixture e owner.
E30. Pesquisa aplicada — memória, prompt e comportamento humano
Seção intitulada “E30. Pesquisa aplicada — memória, prompt e comportamento humano”Esteira contínua para estudar profundamente técnicas novas e antigas que podem tornar a Tactflow uma máquina superior de conversa, memória, consulta e persuasão ética.
Documento-base: applied-research-agenda.md.
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E30.T1 | Survey RAG/memória/harness contemporâneo: RAT, Self-RAG, CRAG, HyDE, RAG-Fusion, RAPTOR, GraphRAG, LongRAG, MemGPT, eval harnesses | E18, E13, E14 | applied-research-agenda.md |
| E30.T2 | Survey prompt engineering/orquestração: instruction hierarchy, structured output, ReAct, Tree/Graph of Thoughts, DSPy, prompt compression, model routing | E11, E18 | idem |
| E30.T3 | Survey comportamento humano/persuasão: maiêutica, SPIN, Challenger, Cialdini, Voss, MI, Fogg, JTBD, Kahneman/Tversky, DBT validation | E18, E6 | idem |
| E30.T4 | Prototipar 2 técnicas de consulta/memória em replay real antes de adotar | E18.T4, E14 | idem |
| E30.T5 | Prototipar prompt optimization por eval e comparar contra prompt manual | E18.T6, E18.T9 | idem |
| E30.T6 | Red-team de persuasão ética: detectar pressão indevida, urgência falsa, manipulação e over-personalization | E18.T5, E12 | idem |
| E30.T7 | Revisão trimestral research → roadmap: adotar, rejeitar, adiar ou transformar em policy/eval | E30.T1–T6 | idem |
Motivo E30: o moat de longo prazo não vem de uma regra de prompt; vem de estudar continuamente memória, raciocínio, linguagem e comportamento humano melhor que concorrentes.
Definition of done E30 10/10:
- Toda técnica pesquisada tem memo, decisão e critério de adoção.
- Nenhum paper entra no runtime sem protótipo + eval.
- Playbooks humanos têm limite ético explícito e teste red-team.
- O research backlog alimenta E13/E14/E18/E19, não vira biblioteca morta.
E27. Backoffice / admin do cliente (antecipação parcial — gap de ops)
Seção intitulada “E27. Backoffice / admin do cliente (antecipação parcial — gap de ops)”Auditoria 2026-06-15: o maior gap de operação não é conversa, é não haver superfície para o dono do negócio. Hoje config vive em
seed-demo-tenant.mjs+config/tenants/*.json+ DB, e observabilidade é CLI do time (report:conversion,conversation:trace). E27 é épico de Fase 3 (painel de rede), mas um subconjunto mínimo é Ato 1 — operado por nós no primeiro design partner, self-serve depois. Verdocs/archive/master-strategy-v1.md§5 item 4.
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E27.T1 | Backoffice mínimo — gap não mapeado em task, auditoria 2026-06-15: CRUD de service_offerings, business_hours, config.requireDeposit + feed de conversas e de agendamentos/pagamentos (substitui editar via seed/DB) | E16.T1, E31.T1 | strategy §5 |
| E27.T2 | Auth/RBAC de tenant — gap não mapeado: login + sessão + escopo por negócio (hoje só API-key de plataforma; assignees.user_id é “auth futuro”) | E21.T1 | §4.9 |
| E27.T3 | Dashboard do cliente: conversão (lead→depósito) e saúde do bot visíveis ao dono (hoje só pnpm report:conversion no terminal; reusa E18.T11) | E16.T4, E18.T11 | §6.4 |
Motivo E27 (antecipação): sem T1/T2 cada design partner depende de nós editando JSON/SQL — não escala além de “operado à mão”. É a ponte de “vendável operado por nós” → “self-serve” da auditoria.
E31. Loop de receita — hardening transacional (book → depósito → confirma)
Seção intitulada “E31. Loop de receita — hardening transacional (book → depósito → confirma)”O V5 Walking Skeleton (
docs/live/product/v5-walking-skeleton-runbook.md) provou o loop qualificar →check_availability→book_appointment→generate_checkout→paid_confirmedponta a ponta, mas só no canal web (/book/:slug/chat) e com mecânicas centrais ainda stub. Este épico fecha o que a tese competitiva vende como diferencial e hoje não está enforced. Ver §8 dedocs/archive/competitive-matrix-v1.md.
| Task | Status | Descrição | Deps | Ref |
|---|---|---|---|---|
| E31.T1 | ✅ parcial | Trava de no-show: releaseExpiredHolds (held vencido → cancelled + cancel_reason) chamado on-read antes de check_availability/book_appointment; listBookedInRange ignora holds vencidos → slot volta a ser ofertado e re-bookável. Pendente: varredura agendada (cron) p/ holds nunca reconsultados, marcar payment expired, contabilizar no_show | E2, billing | runbook §loop |
| E31.T2 | ✅ | Encadeamento determinístico book→checkout: estado pending_payment + auto-injeção de appointment_id no generate_checkout em vez de depender do LLM chamar dentro do budget de 3 ações | E31.T1 | web-turn.ts, dispatch.ts |
| E31.T3 | ✅ | Depósito explícito no prompt: rotular o valor como depósito (não preço) e tornar a regra “agendamento só finaliza após pagamento” inequívoca no agent_turn_rules.py | E31.T2 | agent_turn.py |
| E31.T4 | ✅ parcial | Lembrete/expiração visível ao lead: mensagem “seu horário segura até HH:MM” + follow-up in-page 10 min antes do reaper (web widget); follow-up proativo fora da sessão web pendente | E31.T1 | §followup |
| E31.T5 | Loop transacional no WhatsApp (gate BR, P0 — auditoria 2026-06-15): reusar check_availability/book_appointment/generate_checkout (já existem no path web) no caminho WhatsApp/orchestrator; hoje o WhatsApp só qualifica (booking_ready vira só outcome, não agenda). Alinhar thesis-brazil.md WhatsApp-first | E31.T2, E6, E15.T1 | thesis-brazil | |
| E31.T6 | ✅ | Eval/golden do loop: hold expira e libera, double-book bloqueado, checkout reemitido — booking-loop-cases.json + booking-loop-golden.test.ts | E31.T1, E18 | §quality |
| E31.T7 | ✅ | Depósito/checkout opcional por tenant/unit (config.requireDeposit, default true): quando false, generate_checkout não é ofertado, book_appointment confirma na hora (sem hold/expiração, reaper-safe), objetivo e regras do LLM (build_agent_turn_rules) removem o passo de depósito | E31.T1, E31.T2 | client-config-surface |
| E31.T8 | Confirmação de pagamento BR (Asaas webhook) — gap não mapeado, auditoria 2026-06-15: POST /webhooks/asaas idempotente → confirma appointment + paid_confirmed, espelhando o caminho Stripe (handle-checkout-completed.ts). Hoje create-asaas-checkout.ts cria a cobrança PIX mas nunca confirma (webhook ausente do router.ts) | E31.T2 | competitive-matrix §8 | |
| E31.T9 | Take rate / pilar payments (3b) — preservar opção barata (docs/archive/master-strategy-v1.md §4, docs/archive/pricing-packaging-v1.md §5): coluna fee_bps/application_fee_cents (nullable) na próxima migration que tocar payments + Stripe Connect application_fee_amount. Não ativar agora; só não fechar a porta | E31.T2 | strategy §4 |
Motivo E31: a tese de valor (“agenda + cobra de verdade, anti no-show”) só é defensável se a trava existir de fato — hoje o hold de 30 min é metadado decorativo (HOLD_MINUTES escrito, nunca liberado). Depósito é table-stakes nos PMS verticais; o diferencial é a execução transacional confiável acoplada à qualificação consultiva.
Definition of done E31 10/10:
- Slot
heldsem pagamento é liberado automaticamente e some da disponibilidade. book_appointmentbem-sucedido sempre leva a um checkout (determinístico), sem depender de sorte do modelo.- No-show e expiração de pagamento são estados reais, auditáveis por SQL e por eval.
- O mesmo loop roda em ≥1 canal além do web demo, ou há decisão consciente registrada de não fazer.
E32. Canal web instalável + agenda externa (gates de venda US)
Seção intitulada “E32. Canal web instalável + agenda externa (gates de venda US)”Os dois bloqueadores de adoção do mercado US (
docs/archive/master-strategy-v1.md§5): o produto US é um widget que o dono cola no site (embed.js✅ parcial), e clínica real não migra a agenda — a Tactflow precisa sincronizar com a agenda que já existe. Ambos alimentam diretamente a trilha G (demo G0, objeção recorrente G1).Decisão produto (2026-06-14): um runtime, perfis de conversa distintos — ver
docs/archive/product-today.md§Perfis de conversa. Web wedge = transacional (self_serve) ou concierge leve (concierge); WhatsApp = consultivo (orchestrator);landing_chat= superfície futura (E32.T8).
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E32.T1 | ✅ parcial | embed.js instalável: <script src=".../embed.js" data-slug> → balão + iframe /book/:slug/widget; tema via config.theme no widget. Smoke: pnpm smoke:booking (+ --harness); snippet GTM em docs/archive/gtm-execution-v1.md | E31.T2 |
| E32.T2 | ✅ parcial | UI rica no widget: offered_slots → botões clicáveis; checkout Stripe em modal; reschedule unificado chat+widget; FAQ via grounded_snippets. Pendente (auditoria 2026-06-15): copy do checkout modal ainda hardcoded em inglês → localizar en/pt/es | E32.T1 |
| E32.T3 | ✅ parcial | Google Calendar sync (read+write): OAuth, freebusy, create/delete on hold expiry; pendente hardening com OAuth de clínica real em piloto + UX self-serve de conexão (clínica conecta sozinha; hoje OAuth é rota interna com API-key) | E31.T1 |
| E32.T4 | Webhook/iCal fallback para agendas não-Google (Outlook, iCal feed) | E32.T3 | — |
| E32.T5 | Adapters de PMS vertical (Mangomint/Boulevard/iClinic) — avaliar por demanda da trilha G, não especular | E32.T3, G1 | matriz §2.1 |
| E32.T6 | ✅ parcial | Vanity paths: public_site_routes (route_key legível + aliases); resolver unificado; slug legado backward compat | E32.T1 |
| E32.T7 | Custom domain (book.cliente.com): public_hostnames, routing por Host, SSL — gate Ato 3 / WL | E32.T6 | public-routes-v1.md · matriz §8 |
| E32.T8 | landing_chat profile (backlog): superfície /landing/:slug ou rota dedicada com mais persuasão que self_serve, menos peso que orchestrator WhatsApp; só se G1 registrar abandono pré-picker | E32.T2, E14 | docs/archive/product-today.md |
| E32.T9 | Onboarding Demo Effect (spawn:demo chain) — gap de eng não mapeado, auditoria 2026-06-15: site do prospect → fetch + Readability/Firecrawl (reusa E14) → LLM structured extract (serviços/preços/horários) → seed-demo-tenant → /book/:slug em minutos. Braço de engenharia de docs/archive/gtm-execution-v1.md G0.T1b | E14.T1, E31.T7 | gtm G0.T1b |
| E32.T10 | Booking E2E (Playwright) — gap não mapeado, auditoria 2026-06-15: fluxo real no widget book→hold→checkout→paid_confirmed + restore de picker, rodando em CI antes da demo G0 (hoje só pnpm smoke:booking) | E32.T2, E31.T6 | scorecard wedge |
| E32.T11 | ✅ | Encerramento pós-booking — confirmação → “mais alguma dúvida?” → Q&A via LLM (sem tools) → end_conversation / timeout → runtime_state=closed + rotação de session_id + fade no widget e /book/:slug. Hub “meus agendamentos / reagendar” fica backlog futuro | E31.T7, E32.T2 |
| E32.T12 | ⚠️ parcial | “Continuar como X” / resume profile — profile phone-only; lead stage unlock no widget; edge cases multi-tab pendentes | E32.T2 |
| E32.T13 | Restore UI pós-reload — /history re-hidrata offered_slots, checkout modal state, contact form (não só transcript) | E32.T2, E32.T10 | web-booking-wedge.md §Gaps |
Motivo E32: sem T1 não há produto instalável para vender nos EUA; sem T3 a objeção “minha agenda já vive no Google/PMS” mata a venda. São gates comerciais, não features.
Definition of done E32 10/10:
- Dono de clínica instala o widget em < 5 min num site WordPress/Webflow sem suporte.
- Booking via bot aparece na agenda Google da clínica em segundos; slot ocupado no Google some da disponibilidade do bot.
- Demo G0.T1 usa o widget real, não a hosted page.
- URLs públicas: slug técnico estável; vanity path (T6) antes de exigir custom domain (T7).
E33. Voz inbound US — Vapi adapter (home services wedge)
Seção intitulada “E33. Voz inbound US — Vapi adapter (home services wedge)”Decisão revisada (2026-06-17): voz continua sendo hero product US (
docs/archive/competitive-matrix-v1.md§1), mas não construímos STT/TTS/telephony DIY no Ato 1. Usamos Vapi como adapter; moat permanece no Worker (dispatchAction, booking, Neon). Home services exige voz antes de med spa fechar 100% do chat — verdocs/archive/voice-architecture-v1.md.Gate: chat happy path documentado (E32.T10–T13 backlog explícito) ou proposta HS vendendo só voz + SMS owner.
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E33.T0 | ✅ parcial | Vapi webhook (POST /webhooks/vapi): assistant-request + tool-calls → check_availability / book_appointment; tenant via config.voice.vapiPhoneNumberId; owner SMS Twilio pós-book | E31.T7, E32.T2 |
| E33.T0.1 | ✅ | Qualificação estruturada — record_service_intake + profile facts → owner SMS (urgency, address, summary); tool Vapi | E33.T0 |
| E33.T0.2 | ✅ | Owner SMS no path com depósito (pós-Stripe) + helper compartilhado + intake no web chat | E33.T0.1 |
| E33.T0.3 | Piloto manual: número Vapi real + smoke script | E33.T0.1 | |
| E33.T1 | Piloto E2E: 1 número Vapi + 10 ligações instrumentadas + owner SMS + case gravado | E33.T0.3 | G1 design partner HS |
| E33.T2 | Provisionamento de número — API Vapi/Twilio; 1 número/tenant; area code; registro em channel_endpoints; runbook onboarding (forward vs substituir site) | E33.T1 | matriz §3 |
| E33.T3 | Port-in número existente do cliente + cláusula contratual (número nosso até port-out) | E33.T2 | — |
| E33.T4 | (deferido) Twilio/Telnyx inbound DIY → STT streaming → agent turn → TTS — só se Vapi limitar latência/custo em escala | E33.T1 | legado E33 |
| E33.T5 | Latência alvo < 1.5s por turno (preset Vapi + respostas curtas + barge-in) | E33.T0 | — |
| E33.T6 | Rebilling voz — fair use min/mo + overage retail (docs/archive/pricing-packaging-v1.md) | E33.T1, G3 | §1b |
E34. Deploy produção — tactflow.io (gate antes de G0 comercial)
Seção intitulada “E34. Deploy produção — tactflow.io (gate antes de G0 comercial)”O produto não é ofertável com link
*.workers.devnem site antigo de agência no apex. Runbook:production-deploy-v1.md.
| Task | Descrição | Deps | Ref |
|---|---|---|---|
| E34.T1 | Remover site antigo (Pages) + rotas tactflow.io / www → Worker | — | wrangler routes |
| E34.T2 | PUBLIC_BASE_URL, secrets prod, seed glow-medspa, smoke | E34.T1 | seed + smoke |
| E34.T3 | Stripe webhook + redirect URLs em tactflow.io | E34.T2 | billing |
Definition of done: prospect abre https://tactflow.io/book/glow-medspa, agenda, paga depósito test mode.
Fase 3 — Futuro (v1.5 / v2)
Seção intitulada “Fase 3 — Futuro (v1.5 / v2)”| Épico | Descrição | Ref |
|---|---|---|
| E22 | Copilot UI / workspace do vendedor | §2.4 |
| E23 | Sugestões em tempo real + copilot de negociação | §2.4 |
| E24 | Booking completo (bookings,resources,offerings) | §11 v1.1+ |
| E25 | Outbound / outreach (cadências, SMS, email) — tese global | thesis-global |
| E26 | Canais adicionais (Instagram, webchat, voz) | §5.1 |
| E27 | Painel admin de rede/unidades — subconjunto mínimo (T1/T2/T3) antecipado para Ato 1, ver seção E27 | §3 |
| E28 | CLI de conversa local (dev) — dogfood; gate produto consultivo ainda 🟡 | §dev tooling |
| E29 | Code health & arquitetura sustentável — reduzir hotspots e hardcodes | §20 |
| E30 | Pesquisa aplicada profunda — memória, prompt, harness e comportamento humano | research |
| E31 | Loop de receita — hardening transacional (trava no-show, book→checkout determinístico, loop multicanal) | runbook V5 / matriz §8 |
| E32 | Canal web instalável (embed.js) + sync agenda externa (Google Calendar/PMS) — gates de venda US, prioridade de Ato 1 | strategy §5 / matriz §8 |
| E33 ✅ | Voz inbound US — Vapi adapter + gestão de números (HS wedge); DIY Twilio deferido (E33.T4). Shipped: atende, intake, disponibilidade, agenda, remarca (supersede). Cancelar não existe (nem tool, nem ação) — ver voice-runtime-map.md §3. Mapa técnico: voice-runtime-map.md | docs/archive/voice-architecture-v1.md |
| E34 ✅ parcial | Deploy produção — no ar em workers.dev; chat.tactflow.io (DNS + [[routes]]) adiado. Secrets de voz ok, TWILIO_* pendentes (A2P). — Worker + DNS + secrets + Stripe webhook + runbook executável | production-deploy-v1.md |
| E35 ✅ | Follow-up pós-intake de voz (30 min) — lead de voz qualificado que não agendou recebe follow-up contextual; o fosso vs GHL | revenue-recovery-cycle.md |
| E36 ✅ | Confirmação + lembrete de agendamento (T-24h/T-1h, quiet-hours, consentimento TCPA). ⚠️ construído mas não entrega: TWILIO_* ausente em produção (bloqueado em A2P 10DLC) | revenue-recovery-cycle.md |
| E37 ⏳ | Review request pós-job automático (social proof → leads orgânicos) | revenue-recovery-cycle.md |
| E38 ⏳ | Integração field-service software (ServiceTitan/Jobber) — lock-in permanente. Hoje só Google Calendar existe | revenue-recovery-cycle.md |
| E39 ⏳ | Follow-up pós-orçamento não respondido (cadência 24h/3d/7d) | revenue-recovery-cycle.md |
| E40 ⏳ | Text-back de chamada perdida — ligação não atendida/abandonada → SMS imediato. Hoje end-of-call-report não é tratado em handle-vapi-webhook.ts. É o coração do “never lose a lead” | DIRECTION.md §3 |
| E41 ⏳ | SMS inbound (Twilio) — fundação existe (normalize-twilio-inbound, twilio-signature, sms-opt-out) mas não há rota /webhooks/twilio. Destrava remarcar por texto | DIRECTION.md §3 |
| E42 ⏳ | Value report — relatório de valor pro dono (chamadas atendidas, bookings, $ estimado recuperado). Conservador, evidence-linked, rotulado como estimativa. Primeiros clientes: concierge, não maquinário | DIRECTION.md §3 |
Esteira de prontidão para produção (auditoria 2026-05)
Seção intitulada “Esteira de prontidão para produção (auditoria 2026-05)”Due diligence técnica:
docs/archive/unicorn-readiness-audit.md· personalização:customization-model.md· exactly-once design:reliability-exactly-once.md
| Prioridade | Task | Status |
|---|---|---|
| P0 | E5.T6 — interrupt em responding | ✅ |
| P0 | E3.T7 — inbound idempotency ordering | ✅ parcial |
| P0 | E10.T8 — outbound exactly-once | ✅ parcial |
| P1 | E9.T1 — stage no Context Pack | ✅ parcial |
| P1 | E13.T6 — episodic structured no pack | ✅ parcial |
| P1 | E7.T4 — escalation opt-in + confidence threshold from policy | ✅ |
| P1 | E10.T9 — outbound queue consumer | ✅ |
| P1 | E21.T1 — RLS Postgres | ✅ parcial |
| P2 | E5.T7 — pacing ghost states | ✅ |
| P2 | E13.T7 — recall reativo | ✅ parcial |
Sequência sugerida (atualizada 2026-06): E5.T6 → E3.T7/E10.T8 parcial → E7.T4 → E13.T7 → E9.T2–T4 → E10.T6 → E10.T9 → E14 parcial → E28 CLI → E18 review/insights (quality:review → quality:insights) → E18 replay/judge (eval:replay, judge calibrado) → E14 (ingest cliente + eval concorrente) → E13.T1/T4 → gate runtime produto ✅ → E21/E3/E10 hardening prod.
Trilha de venda em paralelo (atualizada 2026-06-17): E34 deploy tactflow.io → E31 ✅ → E32.T1–T2 ✅ parcial → chat hardening backlog explícito (E32.T11–T13) → E33.T0 Vapi (HS) → G0 comercial → E32.T9 (spawn:demo) → E32.T3 piloto real → gate BR (E31.T5/T8). Ver docs/archive/voice-architecture-v1.md.
Ciclo de recuperação de receita (atualizado 2026-07-02): o fosso competitivo vs GHL/agências. Não é “atende ligações” (commodity) — é o loop completo de recuperação de lead. E35 ✅ e E36 ✅ construídos (E36 aguarda A2P para entregar). Próximos: E40 text-back de chamada perdida → E41 SMS inbound → E42 value report → E37 (review) → E39 (orçamento) → E38 (lock-in). Escopo e fila: DIRECTION.md §3. Ver revenue-recovery-cycle.md.
Scorecard produto (2026-06-14) — ⚠️ DESATUALIZADO
Seção intitulada “Scorecard produto (2026-06-14) — ⚠️ DESATUALIZADO”⚠️ Snapshot de 2026-06-14, pré-pivô de voz. Trata “wedge web booking” como o wedge (hoje é voz) e não reflete E33/E35/E36. Mantido só pela nota honesta de 0 clientes pagantes, que segue verdadeira. Estado atual:
DIRECTION.md§1–§2.
Snapshot honesto para alinhar engenharia vs comercial. Narrativa:
docs/archive/product-today.md.
| Área | Nota | Gap principal |
|---|---|---|
| Arquitetura / runtime | 8/10 | Exactly-once enterprise, RLS prod, E18 judge |
| Wedge web booking (E32) | 7/10 | E2E Playwright, restore de picker, multi-lead browser |
| Convencimento web | 5/10 | self_serve + FAQ ok; landing_chat (E32.T8) não existe |
| Comercial / G0 | 2/10 | 0 clientes pagantes; G0.T2–T5 não iniciados |
| Saída Ato 1 (20+ logos, US$ 15k MRR) | 3/10 | Receita e case — não demo técnica |
Regra anti-dispersão (reforço): retorno marginal imediato está em G0, não em polish do wedge. E32.T8 e backlog browser multi-lead só entram com evidência de G1.
Mapeamento auditoria de produto US/BR (2026-06-15)
Seção intitulada “Mapeamento auditoria de produto US/BR (2026-06-15)”Rastreabilidade dos gaps da auditoria de prontidão (US web wedge vs BR WhatsApp) para o roadmap. Regra aplicada: reusar task existente; criar nova só quando o gap não estava mapeado. “novo” = task criada nesta passagem.
| Gap (auditoria) | Mercado | Mapeado em | Situação |
|---|---|---|---|
No-show enforcement (cron sweep, payment expired, no_show) | US/BR | E31.T1 | já mapeado (pendência descrita na task) |
| Encadeamento determinístico book→checkout | US | E31.T2 | ✅ entregue |
| Loop transacional no WhatsApp | BR | E31.T5 | já mapeado; reescopado como gate BR P0 |
| Confirmação de pagamento BR (Asaas webhook) | BR | E31.T8 (novo) | não estava mapeado → criado |
Take rate / Connect application_fee | US/BR | E31.T9 (novo) + pricing §5 | parcial (preservar coluna, não ativar) |
| Transcrição de áudio inbound | BR | E15.T1 | já mapeado (gate de deploy BR) |
| Multi-tenant Meta credentials (multi-WABA) | BR | E3.T8 / E10.T1 | já mapeado, não iniciado |
| WhatsApp interativo (botões/listas, card PIX) | BR | E10.T3 / E10.T5 | já mapeado |
| Outbound reply-to no WhatsApp | BR | E10.T7 | já mapeado |
| Google Calendar self-serve (clínica conecta sozinha) | US | E32.T3 | parcial; nota self-serve adicionada |
| Checkout modal localizado (en/pt/es) | US | E32.T2 | nota adicionada à task |
| Booking E2E (Playwright) em CI | US | E32.T10 (novo) | não estava mapeado → criado |
Onboarding Demo Effect (spawn:demo chain) | US/BR | E32.T9 (novo) + gtm G0.T1b | braço de eng não estava em task → criado |
| Backoffice mínimo do cliente | US/BR | E27.T1 (novo) | épico existia só como linha futura → task criada |
| Auth/RBAC de tenant | US/BR | E27.T2 (novo) | não estava mapeado → criado |
| Dashboard de conversão/qualidade p/ cliente | US/BR | E27.T3 (novo) / E18.T11 | parcial (CLI existe, falta superfície) |
| Cancelamento iniciado pelo lead + política/fee | US/BR | E24 (futuro) | mapeado como futuro; não puxar p/ Ato 1 |
Leitura: dos 17 gaps, 9 já estavam mapeados (só ajustei escopo/notas), 6 viraram task nova (E31.T8/T9, E32.T9/T10, E27.T1/T2) e 2 ficaram como parcial/futuro consciente. O motor (runtime, RLS, exactly-once, loop web) está construído; o que falta é distribuição + operação + paridade transacional no WhatsApp.
Caminho crítico (o que destrava o resto)
Seção intitulada “Caminho crítico (o que destrava o resto)”flowchart LR E0[E0 scaffold] --> E1[E1 schema+harness] --> E2[E2 walking skeleton] E2 --> E3[E3 gateway] --> E4[E4 identity] --> E5[E5 state+burst] E5 --> E6[E6 orchestrator] --> E11[E11 prompting] E6 --> E10[E10 actions/outbox] E11 --> E13[E13 memory] & E14[E14 grounding] & E12[E12 guardrails]Orchestrator (E6) + Prompting (E11) são o coração. Tudo de qualidade (E12/E13/E14/E18) pendura neles. E10 (outbox) e E3/E4/E5 são pré-requisito de qualquer resposta real.
Matriz de cobertura (blueprint → épico)
Seção intitulada “Matriz de cobertura (blueprint → épico)”| Componente / princípio | Épico(s) |
|---|---|
| 5.1 Channel Gateway | E3 |
| 5.2 Identity/Contact | E4 |
| 5.3 Conversation State | E5 |
| 5.4 Orchestrator ⭐ | E6 |
| 5.5 Policy Engine | E7 |
| 5.6 Workflow Runtime | E9 |
| 5.7 Prompting Layer | E11 |
| 5.8 Actions Layer | E10 |
| 5.9 Persistence | E16 |
| 5.10 Observability | E16 |
| 5.11 Memory Layer | E13 |
| 5.12 Knowledge/Grounding | E14 |
| 5.13 Safety/Guardrails | E12 |
| 5.14 Quality/Eval | E18 |
| 4.6 Aceitar rápido | E2, E3 |
| 4.7 Resiliência (filas/outbox) | E10 |
| 4.9 Tenant/units | E4, E7 |
| 4.10 Channel-aware | E8 |
| 4.11 Privacy/LGPD | E17 |
| 4.12 Grounding | E14 |
| 4.13 Multimodal | E15 |
| 4.14 Safety/confidence | E12 |
| 4.15 Quality loop | E18 |
| 16 Memória (4 camadas) | E5 (working), E13 (episodic/profile/recall), E7 (policy) |
| 17 Analytics/optimization | E19 |
| 17.4 Parâmetros de controle | E6 (captura), E19 (otimização) |
| 17.5 Simulação | E20 |
| Pesquisa aplicada (memória/prompt/comportamento) | E30 |
| Dev CLI conversa (pós-produto runtime) | E28 |
| Validação executável (proc §4b) | E1 |
Cobertura 100%: todo macrocomponente (5.1–5.14) e princípio acionável (4.6–4.15, §16, §17) tem ≥1 épico. Itens ❌ do escopo §3 estão na Fase 3 (futuro), conscientemente fora do v1.