Skip to content

Baseline do qa-docker: smoke e e2e da imagem v0.1 #34

Closed

Description

@patrickbrandao

Contexto

Este é o gate de aceite do milestone v0.1: a imagem construída a partir da main, com todas as issues de código fechadas, passa por smoke, e2e, contratos e pela matriz mínima de harnesses no Docker Desktop local (desktop-linux, arm64), seguindo o procedimento de .claude/agents/qa-docker.md. Também fica registrada a linha de base (tempo de build, tamanho da imagem, bases) para comparar com os upgrades do v0.2.

Escopo

  • Build de docker/Dockerfile → thinker:qa-<id> (arm64 nativo; amd64 via buildx, ao menos o build). Registrar tempo, tamanho, imagens base e versão do Postgres.
  • Compose isolado (thinker-qa-<id>), com segredos descartáveis e health.
  • Boot negativo: sem THINKER_ENCRYPTION_KEY falha; com a chave igual ao BETTER_AUTH_SECRET falha (THINKER_ENCRYPTION_KEY obrigatória e separada do BETTER_AUTH_SECRET #27).
  • Smoke:
  • Sem phone-home, verificado na rede (não basta ler os logs: falhas de saída são engolidas, ex.: provider-param-spec.service.ts:113 herdado):
    • stack numa rede Docker internal: true (sem rota para fora), com o provedor mock e o Postgres na mesma rede;
    • o container do Thinker usa como DNS um sidecar que registra todas as consultas (ex.: CoreDNS com o plugin log, ou dnsmasq com --log-queries) e responde NXDOMAIN para nomes externos;
    • um sidecar de captura no namespace de rede do Thinker (network_mode: service:thinker, ex.: tcpdump -n no nicolaka/netshoot) registra tentativas de conexão para fora da sub-rede, inclusive para IPs literais;
    • janela de observação: do boot até pelo menos 10 minutos depois, com o smoke rodando dentro dela. Os jobs agendados (cron diário e horário) ficam cobertos pela conferência estática de README e documentação do usuário em PT-BR #33; se o tempo permitir, a janela cruza o minuto :34 de uma hora (o antigo cron do modelparams.dev);
    • duas rodadas, com os destinos aprovados no ADR 0003 (Catálogos externos de modelos e preços versus a regra de não fazer phone-home #11) e a chave implementada em Catálogos públicos: chave THINKER_CATALOG_SYNC e OpenCode Go só com provedor cadastrado #39:
      • padrão, sem provedor OpenCode Go cadastrado: só podem aparecer openrouter.ai e models.dev, e nenhum outro, nem raw.githubusercontent.com;
      • com THINKER_CATALOG_SYNC=false: nenhuma consulta DNS nem conexão externa;
    • nenhum acesso a modelparams.dev, *.manifest.build, api.github.com, raw.githubusercontent.com/mnfst ou Sentry em nenhuma rodada;
    • todo destino observado está na lista de docs/usuario/privacidade.md (README e documentação do usuário em PT-BR #33). Anexar ao relatório o log de DNS e o resumo da captura.
  • e2e: packages/backend/test contra o Postgres da mesma imagem do compose; contracts/gateway contra o container (THINKER_BASE_URL).
  • Matriz mínima de harnesses, com mock e sem credenciais reais: Claude Code (ANTHROPIC_BASE_URL + thk_), Codex/OpenCode, snippet OpenClaw/Hermes, SDKs OpenAI e Anthropic.
  • CLI thinker (CLI thinker #23): login, agent list.
  • Guard de nomes legados em modo bloqueante: node scripts/check-legacy-names.js --strict sem nenhuma ocorrência fora da allowlist (depois de Guia do desenvolvedor do Thinker #32 e README e documentação do usuário em PT-BR #33).
  • Relatório como comentário nesta issue; cada falha vira uma issue de bug no milestone v0.1, com o label da área.

Fora de escopo

Critérios de aceite

  • Todos os passos com pass (ou skip justificado), sem bug bloqueante aberto no milestone.

Dependências

Agente responsável

qa-docker

Activity

  1. added this to the v0.1 milestone on Oct 10, 2026
  2. added
    area:infraInfra: CI, Docker, imagem multi-arch, releases, templates de deploy
    on Oct 10, 2026
  3. patrickbrandao commented on Oct 11, 2026

    @patrickbrandao
    OwnerAuthor

    Herdado da revisão do PR #52: o e2e proxy-no-plan-gate faz stub de fetch só para api.openai.com e deixa os outros hosts irem para a rede real. Garantir que a suíte não faça egress real, o que se encaixa no teste de ausência de egress desta issue.

  4. patrickbrandao commented on Oct 11, 2026

    @patrickbrandao
    OwnerAuthor

    Robustez do guard de egress (nits da revisão do PR #70), para considerar no teste de rede desta issue:

    • egress-recorder.cjs não registra dns.resolve4 nem conexões diretas a IP. Hoje nenhum código usa isso, mas a verificação no nível de rede (DNS e captura de pacotes) cobre.
    • O preload bloqueia host de banco fora de loopback (ex.: postgres numa rede compose), e o boot falha de um jeito confuso.
  5. patrickbrandao commented on Oct 11, 2026

    @patrickbrandao
    OwnerAuthor

    Observação dos QAs de 2026-10-11 (#103, #104): no primeiro boot com volume novo, o log mostra uma linha ERROR [Better Auth]: Database schema mismatch / Missing tables antes de o Better Auth rodar a própria migração; setup e login funcionam logo depois. Verificar no baseline se dá para evitar o falso erro (rodar a migração antes da checagem ou rebaixar para info).

  6. patrickbrandao commented on Oct 14, 2026

    @patrickbrandao
    OwnerAuthor

    qa-docker: baseline v0.1 (run qdb081a) - PASS on every step executed

    Tested SHA: 3b7ab345e190768b1f2b87f1a8f90aaef503d10a (origin/main). Docker Desktop desktop-linux, arm64. Mock provider only, THINKER_CATALOG_SYNC=false, no real external host contacted by Thinker.

    Step Result
    Build linux/arm64 (thinker:qa-qdb081a) pass: 24 s (layer cache warm), 427 MB on disk / 79.5 MB content
    Build linux/amd64 (buildx, QEMU, no push) pass: 65 s (partly cached), 79.5 MB content
    Install via docker/install.sh --yes (compose served from a local HTTP server through THINKER_INSTALLER_SOURCE, local image via THINKER_VERSION, run-scoped project) pass, healthy
    Setup token from docker compose logs thinker | grep 'setup token', wrong token 403, first admin 201, public sign-up then refused (SIGNUP_DISABLED) pass
    Agent + thk_ key, custom provider (mock), default tier, model: auto (M101 before the tier, pong after, x-thinker-* headers) pass
    /v1/models, /v1/chat/completions, /v1/messages, /v1/responses, each stream and non-stream pass (8/8 plus models)
    Playground run (SSE) and history pass
    MCP: OAuth (register, authorize, consent, PKCE token) then tools/list (18 tools) and thinker_agent_list pass
    Recordings: written to the volume, encrypted (MRE1 envelope, no plaintext); log "retention 30 days, storage filesystem" pass
    No phone-home, THINKER_CATALOG_SYNC=false pass: see below
    contracts/gateway against the container pass (9/9)
    Backend e2e (test:e2e:docker, postgres:16-alpine pinned) pass (74 suites, 635 tests, 159 s)
    Restart, then install.sh --upgrade (same version): login, setup status (needsSetup:false), agent, key and auto chat all intact; no new setup token pass
    "manifest" grep: logs 0 hits; SPA 2 hits; backend dist: migrations plus 3 intentional legacy files pass
    First-boot Better Auth "schema mismatch" ERROR (note on this issue) not reproduced: no ERROR line at first boot

    Egress (network level)

    Isolated bridge (internal: true, 10.77.77.0/24) with Postgres, mock, a DNS sink as the Thinker container's resolver (logs every query, answers NXDOMAIN) and a nicolaka/netshoot tcpdump sidecar in the Thinker network namespace. Window: boot 15:28:47Z to 15:39:43Z (about 11 min, crossing :34; smoke ran at about 15:29).

    • DNS sink: 0 queries.
    • tcpdump (3331 lines): every IP packet is inside 10.77.77.0/24 (peers: Postgres .4, mock .3); the only other traffic is ARP/ICMPv6 link chatter. No packet to any other address. The namespace has no default route (ip route: only 10.77.77.0/24).
    • Mock received exactly the 7 requests of the smoke (6 chats + 1 Playground).
    • Not run: the default-sync round (openrouter.ai and models.dev only) and the cron/hourly jobs beyond the window (covered by README e documentação do usuário em PT-BR #33).

    Docs

    Nothing wrong found in docs/usuario/instalacao-docker.md and primeiros-passos.md when followed literally. Notes: the setup token grep works on the colored logs; the browser/curl Origin must equal BETTER_AUTH_URL (localhost, not 127.0.0.1), which the docs already say.

    Observations (no failure)

    1. The backlog item says node scripts/check-legacy-names.js --strict, but that script does not exist on main (scripts/ has no such file, nothing in CI). The strict guard step was not run; the manual grep above stands in for it.
    2. The run logs WARN [Better Auth]: Rate limiting could not determine a client IP and is falling back to a single shared per-path bucket for requests from the host through Docker Desktop with the compose default TRUST_PROXY=loopback. Harmless here, but all clients behind that path share one auth bucket.
    3. Build times are with warm layer cache, so they are not a cold-build baseline.

    Baseline

    Base images (pinned in the Dockerfile): node:24-alpine@sha256:ebfe2f90...e2f905ec1c1 (deps/build), node:24-slim@sha256:d6aa754f...87f7b20 (prod-deps), runtime gcr.io/distroless/nodejs24-debian13:nonroot@sha256:9eeb7f58...3fa278e. Postgres 16.15 (postgres:16-alpine@sha256:721873c3...6080ea).

    Not covered in this run (outside the requested scope)

    Negative boot (#27), harness matrix, CLI (login, agent list), default-sync egress round.

    Teardown: both Compose projects removed with down -v after checking labels; no run-labelled volume, container or network left; worktree removed.

  7. patrickbrandao commented on Oct 15, 2026

    @patrickbrandao
    OwnerAuthor

    A baseline passou na main 3b7ab34: veja o relatório acima. A release 0.1.0 foi gerada a partir de cda88cb, que só acrescenta o #169 (docs).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:infraInfra: CI, Docker, imagem multi-arch, releases, templates de deploy

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions