<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://diegolemos.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://diegolemos.net/" rel="alternate" type="text/html" /><updated>2026-09-30T22:14:16+00:00</updated><id>https://diegolemos.net/feed.xml</id><title type="html">Diego’s notes</title><subtitle>Writing software that works (and occasionally taking notes)</subtitle><author><name>Diego Lemos</name></author><entry><title type="html">Por que seu dispositivo IoT não consegue conectar ao Wi-Fi (mesmo com a senha certa)</title><link href="https://diegolemos.net/2026/08/02/por-que-seu-dispositivo-iot-nao-conecta-ao-wifi/" rel="alternate" type="text/html" title="Por que seu dispositivo IoT não consegue conectar ao Wi-Fi (mesmo com a senha certa)" /><published>2026-08-02T00:00:00+00:00</published><updated>2026-08-02T00:00:00+00:00</updated><id>https://diegolemos.net/2026/08/02/por-que-seu-dispositivo-iot-nao-conecta-ao-wifi</id><content type="html" xml:base="https://diegolemos.net/2026/08/02/por-que-seu-dispositivo-iot-nao-conecta-ao-wifi/"><![CDATA[<p>Recentemente tentei conectar um brinquedo eletrônico (um <a href="https://yotoplay.com/">Yoto Player</a>, para quem tiver curiosidade) ao Wi-Fi de casa e recebi um genérico e nada útil “falha na conexão”. Sem detalhes, sem código de erro, nada.</p>

<p>O que começou como “deve ser a senha errada” virou uma investigação de várias horas que passou por DHCP, DNS, IPv6 e terminou com a descoberta de que meu provedor de internet estava distribuindo um servidor DNS inválido para qualquer dispositivo que dependesse exclusivamente de IPv4.</p>

<p>Esse tipo de problema não é exclusivo do meu roteador nem do meu dispositivo. Ele é comum o suficiente em dispositivos IoT baratos (assistentes de voz, tomadas inteligentes, brinquedos conectados, campainhas, etc.) que achei que valia a pena documentar o processo de debug, porque a causa raiz é quase sempre a mesma: <strong>o dispositivo consegue entrar na rede Wi-Fi, mas não consegue resolver nomes de domínio.</strong></p>

<h2 id="o-sintoma">O sintoma</h2>

<p>A maioria dos dispositivos IoT segue o mesmo fluxo de configuração: escolhemos a rede Wi-Fi, digitamos a senha, e o aparelho tenta se conectar aos servidores do fabricante para finalizar o cadastro. Quando esse processo falha, normalmente aparece uma de duas categorias de erro:</p>

<ol>
  <li><strong>Falha ao entrar na rede Wi-Fi</strong> — senha errada, rede de 5GHz (a maioria dos dispositivos IoT baratos só suporta 2,4GHz), modo de segurança incompatível (WPA3-only em vez de WPA2), etc.</li>
  <li><strong>Falha depois de entrar na rede</strong> — o dispositivo consegue se associar ao Wi-Fi e obter um IP, mas não consegue “telefonar para casa” e finalizar o cadastro.</li>
</ol>

<p>O segundo caso é o mais traiçoeiro, porque tudo <em>parece</em> estar funcionando: o dispositivo aparece na lista de clientes conectados do roteador, tem um endereço IP válido, e mesmo assim a configuração falha com uma mensagem genérica.</p>

<h2 id="por-que-outros-dispositivos-funcionam-não-é-uma-prova-de-nada">Por que “outros dispositivos funcionam” não é uma prova de nada</h2>

<p>O meu instinto foi testar se o problema era da rede: “meu notebook e meu celular conectam sem problema, então a rede deve estar OK”. Essa suposição é exatamente o que torna esse bug tão difícil de encontrar.</p>

<p>Sistemas operacionais modernos (macOS, iOS, Android, Windows) têm múltiplos mecanismos de fallback para descobrir um servidor DNS válido:</p>

<ul>
  <li><strong>DHCPv4</strong>, o mecanismo clássico, onde o roteador informa um servidor DNS via a opção 6 do DHCP.</li>
  <li><strong>IPv6 Router Advertisements (SLAAC/RDNSS)</strong>, um mecanismo completamente separado, no qual o roteador anuncia servidores DNS via IPv6, independente do que está configurado no DHCPv4.</li>
  <li><strong>UPnP / TR-064</strong>, protocolos que permitem que aplicativos consultem o gateway diretamente sobre a configuração da conexão WAN, incluindo os servidores DNS que o próprio roteador usa.</li>
</ul>

<p>Um dispositivo IoT barato, por outro lado, normalmente implementa <strong>apenas o DHCPv4 clássico</strong>. Sem suporte a IPv6, sem UPnP, sem plano B. Se a única informação que ele recebe (a opção 6 do DHCP) estiver quebrada, ele fica sem DNS — mesmo que o resto da sua rede pareça funcionar perfeitamente.</p>

<h2 id="debugando-descubra-o-que-o-dhcp-está-realmente-entregando">Debugando: descubra o que o DHCP está realmente entregando</h2>

<p>Percebi que o primeiro passo real de debug não era “meu notebook consegue navegar”, e sim: <strong>o que exatamente o servidor DHCP estava entregando como servidor DNS?</strong></p>

<p>No macOS, rodei:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ipconfig getpacket en0
</code></pre></div></div>

<p>Isso mostra o pacote DHCP bruto recebido pela interface, incluindo todas as opções. Reparei na linha <code class="language-plaintext highlighter-rouge">domain_name_server</code>:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>options:
Options count is 7
dhcp_message_type (uint8): ACK 0x5
server_identifier (ip): 192.168.0.1
lease_time (uint32): 0x15180
subnet_mask (ip): 255.255.255.0
router (ip_mult): {192.168.0.1}
domain_name_server (ip_mult): {0.0.0.0}
end (none):
</code></pre></div></div>

<p>Ali estava o problema: <code class="language-plaintext highlighter-rouge">domain_name_server</code> igual a <code class="language-plaintext highlighter-rouge">0.0.0.0</code>. Um endereço IP inválido, que nenhum dispositivo consegue usar para resolver nomes de domínio.</p>

<p>No Ubuntu/Debian, o equivalente (usando o NetworkManager) seria:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>nmcli device show wlan0 | <span class="nb">grep </span>IP4.DNS
</code></pre></div></div>

<p>Em seguida, comparei com o que o sistema operacional estava <em>realmente usando</em> para resolver nomes — que pode ser diferente do que veio pelo DHCP, exatamente por causa dos mecanismos de fallback mencionados acima. No macOS:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>scutil <span class="nt">--dns</span> | <span class="nb">grep</span> <span class="nt">-A5</span> <span class="s2">"resolver #1"</span>
</code></pre></div></div>

<p>O resultado revelou o resto da história:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>resolver #1
  nameserver[0] : 2804:14d:1:0:181:213:132:2
  nameserver[1] : 2804:14d:1:0:181:213:132:3
  if_index : 15 (en0)
  flags    : Request A records, Request AAAA records
</code></pre></div></div>

<p>Servidores DNS válidos — só que via IPv6, completamente diferentes (e desconectados) do que veio pelo DHCPv4. Meu notebook nunca “sentiu” o problema porque, na prática, ele ignorou o DHCPv4 quebrado e usou os servidores anunciados via IPv6.</p>

<h2 id="investigando-o-roteador">Investigando o roteador</h2>

<p>Com a hipótese confirmada (DHCPv4 não entrega DNS válido), o próximo passo foi entender <em>por que</em>. Entrei no painel administrativo do roteador — um ONT Huawei HG8245W5-6T-V2 fornecido pela Claro Brasil — e fui até a configuração do servidor DHCP.</p>

<p>Duas coisas chamaram atenção:</p>

<ol>
  <li>O campo de DNS estava <strong>em branco</strong>.</li>
  <li>O campo estava <strong>desabilitado</strong> — não dava para digitar nada ali.</li>
</ol>

<p>Um pouco mais abaixo, na mesma tela, havia duas opções marcadas como ativas: <strong>“Ativar Retransmissão DHCP”</strong> e <strong>“Ativar Opção 125”</strong>.</p>

<p>Pelo que entendi, essa combinação é uma configuração típica de operadoras para cenários de “triple play” (internet + TV + telefone), onde o roteador não atua como um servidor DHCP completo — ele apenas <em>retransmite</em> as requisições para um servidor central da operadora, que deveria responder com todas as opções, incluindo o DNS.</p>

<p>O problema: esse servidor central, por algum motivo (provavelmente uma falha de provisionamento do lado da operadora), não está respondendo com um DNS válido. O roteador sabe qual servidor DNS usar — ele mesmo usa esse servidor para sua própria conexão WAN, e é exatamente isso que aparece anunciado via IPv6 — mas essa informação nunca chega até os dispositivos conectados via DHCPv4, provavelmente, porque o roteador está em modo “retransmissão” esperando por uma resposta que nunca chega corretamente.</p>

<p>Tentei também remover o atributo <code class="language-plaintext highlighter-rouge">disabled</code> do campo de DNS pelas ferramentas de desenvolvedor do navegador, preencher um servidor manualmente e salvar. O resultado: o painel administrativo simplesmente me deslogou e ignorou a alteração. Isso é provavelmente alguma proteção no firmware do roteador.</p>

<h2 id="a-solução-assumir-o-controle-do-dhcp">A solução: assumir o controle do DHCP</h2>

<p>Se o roteador da operadora não ia entregar um DNS válido — e o campo estava literalmente bloqueado na interface —, a saída que encontrei foi parar de depender do DHCP dele.</p>

<p>A ideia é usar algum equipamento com capacidade de <strong>NAT/roteamento real</strong> (não um simples repetidor/extensor de Wi-Fi, que apenas faz <em>bridge</em> na mesma rede e portanto herda o mesmo problema) entre o roteador da operadora e a rede doméstica. Na prática, foi isso que fiz:</p>

<ol>
  <li>Conectei um extensor de Wi-Fi que eu já tinha em casa (um TP-Link RE305) ao roteador da operadora.</li>
  <li>Desativei por completo o servidor DHCP do roteador da operadora, para evitar dois servidores DHCP respondendo na mesma rede (uma fonte clássica de instabilidade — <a href="https://en.wikipedia.org/wiki/DHCP_starvation_attack">DHCP starvation</a> à parte, ter dois servidores DHCP ativos na mesma rede sem coordenação gera respostas conflitantes e endereços IP duplicados).</li>
  <li>Configurei manualmente o servidor DHCP do extensor com um servidor DNS válido — no meu caso, <code class="language-plaintext highlighter-rouge">8.8.8.8</code> (Google) e <code class="language-plaintext highlighter-rouge">1.1.1.1</code> (Cloudflare) — e o gateway apontando para o roteador da operadora, em vez de depender do modo automático (que, por padrão, se desativa sozinho quando detecta outro servidor DHCP na rede).</li>
  <li>Conectei o dispositivo IoT à rede desse extensor.</li>
</ol>

<p>Um detalhe que me pegou de surpresa: como o extensor estava conectado via Wi-Fi ao roteador principal (em vez de cabo de rede), ele também precisava conseguir um IP para si mesmo nessa rede para funcionar como ponte. Acabei desativando o DHCP do roteador principal antes de configurar um IP fixo para o extensor, e ele ficou sem conseguir se conectar — um problema de “ovo e galinha” que derrubou minha rede inteira por alguns minutos até eu perceber o que tinha acontecido. Por isso vale um cuidado extra: a faixa de IPs do novo servidor DHCP não pode se sobrepor a nenhum IP estático já em uso na rede — incluindo esse IP estático que o próprio extensor passa a usar para se conectar ao roteador principal.</p>

<p>Como exemplo, a configuração que usei no extensor foi mais ou menos essa:</p>

<ul>
  <li><strong>IP estático do extensor:</strong> <code class="language-plaintext highlighter-rouge">192.168.0.70</code> (fora da faixa do DHCP, para não haver conflito)</li>
  <li><strong>Faixa de IPs do DHCP:</strong> <code class="language-plaintext highlighter-rouge">192.168.0.100</code> – <code class="language-plaintext highlighter-rouge">192.168.0.200</code></li>
  <li><strong>Máscara de sub-rede:</strong> <code class="language-plaintext highlighter-rouge">255.255.255.0</code></li>
  <li><strong>Gateway:</strong> <code class="language-plaintext highlighter-rouge">192.168.0.1</code> (o roteador da operadora)</li>
  <li><strong>DNS primário/secundário:</strong> <code class="language-plaintext highlighter-rouge">8.8.8.8</code> / <code class="language-plaintext highlighter-rouge">1.1.1.1</code></li>
</ul>

<h2 id="resumindo-o-processo-que-segui">Resumindo o processo que segui</h2>

<p>Se alguém estiver enfrentando um dispositivo IoT que “conecta ao Wi-Fi mas não termina a configuração”, esse foi mais ou menos o roteiro que segui:</p>

<ol>
  <li><strong>Confirmar a rede e o modo de segurança</strong>: 2,4GHz (não 5GHz), WPA2 (não WPA3-only). A maioria dos dispositivos baratos não suporta WPA3 nem 5GHz.</li>
  <li><strong>Verificar o que o DHCP estava realmente entregando</strong> (<code class="language-plaintext highlighter-rouge">ipconfig getpacket</code> no macOS, <code class="language-plaintext highlighter-rouge">nmcli</code> no Ubuntu/Debian), prestando atenção no servidor DNS.</li>
  <li><strong>Não confiar no fato de outros dispositivos estarem funcionando</strong> — vale checar explicitamente se o servidor DNS ativo no notebook ou celular veio do DHCPv4 ou de outra fonte (IPv6, DNS configurado manualmente, etc.).</li>
  <li><strong>Olhar a configuração do servidor DHCP no painel do roteador</strong>, procurando por menções a “DHCP Relay”, “L2 Relay” ou “Option 125” — sinais de que o roteador foi configurado pela operadora para um cenário de rede corporativa/triple-play, e não para uma rede doméstica simples.</li>
  <li><strong>Se o campo de DNS estiver vazio ou bloqueado</strong>, em vez de insistir pelo lado do roteador da operadora, faz sentido introduzir um equipamento próprio com um servidor DHCP funcional entre o roteador e o resto da rede.</li>
  <li><strong>Em último caso, vale tentar ligar para o suporte técnico da operadora</strong> — ainda não fiz isso, mas pretendo.</li>
</ol>

<h2 id="sobre-qual-dns-usar">Sobre qual DNS usar</h2>

<p>Depois de assumir o controle do DHCP, fiquei me perguntando: devo usar o DNS da própria operadora ou um público como Google (<code class="language-plaintext highlighter-rouge">8.8.8.8</code>) ou Cloudflare (<code class="language-plaintext highlighter-rouge">1.1.1.1</code>)?</p>

<p>Prós de usar DNS público:</p>
<ul>
  <li>Alta disponibilidade e desempenho consolidados globalmente.</li>
  <li>Políticas de privacidade públicas e auditáveis (especialmente no caso da Cloudflare).</li>
  <li>Evita práticas comuns de operadoras, como injeção de anúncios em páginas de erro ou redirecionamento de domínios não encontrados.</li>
  <li>Te desacopla de qualquer instabilidade futura na infraestrutura da operadora — como a que motivou este post.</li>
</ul>

<p>Prós de usar o DNS da operadora:</p>
<ul>
  <li>Latência potencialmente um pouco menor, por estar na mesma rede.</li>
  <li>Possivelmente um roteamento um pouco mais otimizado para CDNs baseadas na localização do seu resolver.</li>
</ul>

<p>Depois de passar por todo esse processo e ver na prática como essa dependência da infraestrutura de DHCP/DNS da minha operadora pode falhar, minha escolha foi clara: desacoplar dessa dependência e usar DNS público.</p>]]></content><author><name>Diego Lemos</name></author><summary type="html"><![CDATA[Recentemente tentei conectar um brinquedo eletrônico (um Yoto Player, para quem tiver curiosidade) ao Wi-Fi de casa e recebi um genérico e nada útil “falha na conexão”. Sem detalhes, sem código de erro, nada.]]></summary></entry><entry><title type="html">MCP Conference London 2026</title><link href="https://diegolemos.net/2026/03/24/mcp-conference-london-2026/" rel="alternate" type="text/html" title="MCP Conference London 2026" /><published>2026-03-24T00:00:00+00:00</published><updated>2026-03-24T00:00:00+00:00</updated><id>https://diegolemos.net/2026/03/24/mcp-conference-london-2026</id><content type="html" xml:base="https://diegolemos.net/2026/03/24/mcp-conference-london-2026/"><![CDATA[<p>In February I went to the MCP Conference in London, part of ContainerDays London 2026. Two days, back to back, all about the Model Context Protocol and what people are actually building with it (and breaking with it). These are my notes, cleaned up a bit.</p>

<hr />

<h2 id="security-was-everywhere">Security was everywhere</h2>

<p>Almost every talk touched on security. It’s the same pattern we’ve seen with other tech waves: build fast, ship it, deal with the consequences later. With agentic AI a mistake can delete or leak something before anyone notices.</p>

<h3 id="vibe-coding-has-a-vibe-hacking-problem">Vibe coding has a vibe hacking problem</h3>

<p>Sonya from Snyk talked about the security problems with AI-generated code. She brought up <a href="https://www.pcmag.com/news/vibe-coding-fiasco-replite-ai-agent-goes-rogue-deletes-company-database">Replit’s AI agent deleting a production database</a>, which most people following this space have already heard about. Her framing was that agentic engineering is the next step after vibe coding, and that engineers relying on AI tools will eventually move from shipping and hoping it works to something more deliberate.</p>

<p>A few things from the talk stood out to me:</p>

<p><strong>Slopsquatting</strong> — LLMs sometimes hallucinate package names that don’t exist. Attackers notice this and register those same names, so if you install what the model suggested, you’re running their code instead. It’s a supply chain attack that only exists because of how these models work.</p>

<p><img src="/assets/img/mcp-conference-london-2026/slopsquatting-diagram.jpg" alt="Diagram of a slopsquatting attack: an LLM hallucinates a package name, an attacker publishes it, and a normal user installs the malicious package" /></p>

<p>The OpenClaw example got the most reaction from the room. The talk went through <a href="https://blogs.cisco.com/security/personal-ai-agents-like-openclaw-are-a-security-nightmare">Cisco’s analysis of OpenClaw</a>: Cisco’s AI Defense team ran their open-source <a href="https://github.com/cisco-ai-defense/skill-scanner">Skill Scanner</a> against a third-party skill called “What Would Elon Do?” that had climbed to #1 in a community repository. They found nine security issues, two of them critical, and described the skill as functionally malware — it exfiltrated data over the network and used prompt injection to get around safety rules. The lesson is the same one we already know from other supply chains: being popular in a catalog doesn’t mean anyone reviewed it.</p>

<p>A few recommendations came out of this part of the talk:</p>
<ul>
  <li>Secure the prompt: think about security while writing it, not after</li>
  <li>Keep architecture boundaries: separate environments, agents shouldn’t touch production directly</li>
  <li>Harden the supply chain: require SBOMs, watch for typosquatting and slopsquatting, audit MCP servers before enabling them</li>
  <li>AIBOM: Snyk’s term for an AI Bill of Materials, meant to catch shadow AI usage the same way we track shadow IT</li>
  <li>Turn off <code class="language-plaintext highlighter-rouge">--yolo</code> and <code class="language-plaintext highlighter-rouge">--trust-all-tools</code> flags in MCP clients — apparently people actually use these</li>
</ul>

<p><img src="/assets/img/mcp-conference-london-2026/snyk-security-hardening-talk.jpg" alt="Snyk talk slide on configuration hardening for AI-native IDEs and CLIs" /></p>

<p>There was also a slide about a mindset shift: review what the agent produces, understand it before shipping, and watch out for the model’s people-pleasing bias — it will agree with you even when you’re wrong.</p>

<p><img src="/assets/img/mcp-conference-london-2026/snyk-mindset-shift.jpg" alt="Snyk talk slide on the mindset shift needed for AI-generated code: review everything, understand before shipping" /></p>

<p>Resources mentioned: <a href="https://genai.owasp.org/">OWASP GenAI</a>, <a href="https://www.gartner.com/en/articles/ai-trust-and-ai-risk">Gartner AI TRiSM</a>.</p>

<h3 id="mcp-and-prompt-injection">MCP and prompt injection</h3>

<p>Josh, co-founder of <a href="https://zuplo.com/">Zuplo</a>, talked about MCP gateways and spent part of his talk on something that doesn’t come up much: MCP prompt injection, where a malicious MCP server injects instructions straight into the LLM’s context. Prompt injection from users is a known problem by now; injection coming from the MCP layer itself is newer. <a href="https://www.cyberark.com/resources/threat-research-blog/is-your-ai-safe-threat-analysis-of-mcp-model-context-protocol">CyberArk has a threat analysis of MCP</a> that covers this in more detail.</p>

<p><img src="/assets/img/mcp-conference-london-2026/mcp-prompt-injection-zuplo.jpg" alt="Josh from Zuplo presenting on MCP prompt injection, with a slide showing a malicious LinkedIn profile injecting instructions via user-generated content" /></p>

<p>The architecture he described: MCP client → MCP gateway (discovery, authentication, authorisation, guardrails) → MCP servers. The point of the gateway is to put the checks in one place instead of trusting every server on its own.</p>

<h3 id="whats-hard-about-implementing-mcp-servers-soloio">What’s hard about implementing MCP servers (Solo.io)</h3>

<p>A Solo.io session on implementing, securing, and managing MCP servers covered trust (who’s calling), control (what the agent can do), and audit. It also pointed out how the spec has changed: early versions expected the MCP server to handle authorisation itself, which most teams don’t really want to own. Newer, OAuth-oriented directions treat MCP more like a resource server sitting in front of a separate identity layer — not plug-and-play yet, but a cleaner split of responsibility. Worth checking which spec version you’re actually targeting. The <a href="https://github.com/agentgateway/agentgateway">Agentgateway</a> project, part of the Linux Foundation, came up as one place this is being worked on.</p>

<h3 id="dockers-take-on-isolation">Docker’s take on isolation</h3>

<p>Oleg from Docker made a fairly simple point: LLMs don’t have a concept of boundaries, data and code look the same to them. That’s the root of why agentic systems are risky.</p>

<p><img src="/assets/img/mcp-conference-london-2026/prompt-injection-ugc-example.jpg" alt="Slide showing prompt injection via user-generated content: a malicious LinkedIn profile injects instructions that make an LLM leak a recipe in an unrelated email" /></p>

<p>He also showed real screenshots of agents going wrong, including a chat where the agent admits to deleting a production database during a code freeze.</p>

<p><img src="/assets/img/mcp-conference-london-2026/agent-deleted-database-chat.jpg" alt="Chat transcript of an AI agent admitting it deleted a production database during a code and action freeze" /></p>

<p>Docker’s four principles for reducing risk:</p>
<ol>
  <li>Isolate components</li>
  <li>Only use trusted components</li>
  <li>Remove capabilities you don’t need</li>
  <li>Split deterministic and non-deterministic paths, and put more controls on the latter</li>
</ol>

<p>Docker is building a sandboxing feature — isolated VMs with a Docker daemon inside, made specifically to contain agents. I didn’t expect to write the sentence “I watched Docker announce a VM solution”, but here we are. Their <a href="https://www.docker.com/blog/mcp-horror-stories-the-supply-chain-attack/#technical-breakdown-the-attack">MCP horror stories post</a> has the technical breakdown if you want more detail.</p>

<p><img src="/assets/img/mcp-conference-london-2026/docker-lethal-trifecta-diagram.jpg" alt="Docker's &quot;lethal trifecta&quot; diagram: the overlap between external communication, access to sensitive data, and exposure to untrusted content" /></p>

<hr />

<h2 id="context-engineering">Context engineering</h2>

<p>Danilo Poccia, AWS Chief Evangelist for EMEA, talked about context pressure. He defined context as everything the model sees when making a decision — system prompts, tool definitions, conversation history — and said quality drops once it fills up.</p>

<p><img src="/assets/img/mcp-conference-london-2026/aws-agentcore-platform-overview.jpg" alt="AWS AgentCore platform overview slide, listing Runtime, Memory, Identity, Gateway, Code Interpreter, Browser, Observability, Policy, and Evaluations" /></p>

<p>Some of the techniques he covered:</p>
<ul>
  <li>Unambiguous parameter names (<code class="language-plaintext highlighter-rouge">user_id</code>, not <code class="language-plaintext highlighter-rouge">user</code>)</li>
  <li>Domain-specific terminology, since niche language compresses meaning</li>
  <li>Returning the minimum amount of information, and making it semantically meaningful rather than a raw UUID</li>
  <li>Multiple focused agents, each with its own context window</li>
  <li>Multi-agent patterns: agents-as-tools, swarms, meta-agents that spin up sub-agents on demand</li>
  <li>Carrying only the outcome of a sub-task forward, not its internal details</li>
  <li>Deferred or lazy loading of context, which is where agent skills fit in</li>
</ul>

<p>A good chunk of the talk was AWS product pitches — AgentCore Platform, Strands agents — which is what you’d expect from someone in that role. The underlying ideas about context management hold up regardless of which infrastructure you use. <a href="https://github.com/cedar-policy">Cedar</a>, the open-source policy language AWS built for fine-grained access control, also came up.</p>

<hr />

<h2 id="generative-ui">Generative UI</h2>

<p>Ruben Casas, from Postman and a Google Developer Expert (his job title is apparently Staff Vibe Engineer), talked about generative UI and described three levels:</p>

<ul>
  <li><strong>Level 1 — Static components:</strong> the agent orchestrates, calls tools, passes data; the client renders pre-built components. <a href="https://github.com/ag-ui-protocol/ag-ui">ag-ui</a> has an SDK for this</li>
  <li><strong>Level 2 — Declarative UI:</strong> the agent generates descriptors that get combined with pre-defined components to produce UI. See <a href="https://json-render.dev/">json-render.dev</a></li>
  <li><strong>Level 3 — Generative UI:</strong> the agent creates the UI on the fly</li>
</ul>

<p>His point was that so far we’ve mostly been injecting AI into interfaces, like a sidebar chatbot. The newer pattern goes the other way: injecting UI into the agent, rendering components inside the agent’s own window. First-party apps tend to use ag-ui or a2ui protocols; third-party apps go through MCPs.</p>

<p>He landed on declarative generative UI as the right balance for now — enough flexibility without the interface changing completely on every interaction.</p>

<hr />

<h2 id="agent-skills">Agent skills</h2>

<p>Peder Holdgaard Pedersen from Saxo Bank talked about skills and how they relate to MCP. The main idea is progressive disclosure: give the model context bit by bit instead of dumping everything at once.</p>

<p>The three layers he described:</p>
<ul>
  <li><strong>agents.md</strong> — collapsed context: <em>when</em> to use a skill (frontmatter, ~50 tokens)</li>
  <li><strong>skills.md</strong> — expanded context: <em>how</em> to use a skill</li>
  <li><strong>References</strong> — context navigation: <em>what</em> resources to use</li>
</ul>

<p>He was clear that skills are a big prompt injection attack surface, and his recommendation was to host skills as resources on MCP servers instead of on public GitHub, where they’re exposed to supply chain attacks. The <a href="https://github.com/modelcontextprotocol/experimental-ext-skills">experimental MCP skills extension</a> is where this seems to be heading.</p>

<p>Hugging Face showed something similar: a tool called UPskill that runs a skill against multiple models to see how it performs. They warned that we might be heading into skills mania, the same way there was MCP mania about a year ago. Their advice was to only use skills when they genuinely add to the model’s knowledge, not as a way to bolt on everything — what they called the <a href="https://www.asyncagile.org/method-stack/find-the-goldilocks-zone">Goldilocks principle</a>.</p>

<hr />

<h2 id="a-few-other-things">A few other things</h2>

<ul>
  <li><strong>“From MCP, the S is missing”</strong> — a joke from the panel, and not far from the truth right now</li>
  <li><strong>Governance in enterprises</strong> — multiple organisations are building MCP servers independently, which leads to overlapping efforts. It’s the microservices story again, except the shared infrastructure needed this time is auth, discovery, logging, guardrails, policy enforcement</li>
  <li><strong>Context degradation in multi-agent systems</strong> — as agents pass context between each other, it degrades, and nobody seems to have a clean fix for this yet</li>
  <li>The URL pattern <code class="language-plaintext highlighter-rouge">https://domain/mcp</code> is showing up as a convention for exposing MCP endpoints, similar to how <code class="language-plaintext highlighter-rouge">/.well-known/</code> standardised certain discovery endpoints</li>
  <li><strong><a href="https://tedix.dev/">Tedix</a></strong> talked about ACP (Agentic Commerce Protocol) and x402 for payments, under the framing of “the backendisation of the internet”</li>
</ul>

<hr />

<p>Two packed days overall. Security was the theme that came up most consistently. The spec is still settling, especially around auth, and the tooling for testing, monitoring, and operating MCP systems at scale hasn’t caught up with how much people want to build on it. That gap will probably close eventually, but for now, teams putting agentic systems into production are mostly on their own for this part.</p>]]></content><author><name>Diego Lemos</name></author><category term="ai" /><category term="mcp" /><category term="security" /><category term="agents" /><summary type="html"><![CDATA[In February I went to the MCP Conference in London, part of ContainerDays London 2026. Two days, back to back, all about the Model Context Protocol and what people are actually building with it (and breaking with it). These are my notes, cleaned up a bit.]]></summary></entry><entry><title type="html">De facto Best Practices</title><link href="https://diegolemos.net/2022/03/04/de-facto-best-practices/" rel="alternate" type="text/html" title="De facto Best Practices" /><published>2022-03-04T00:00:00+00:00</published><updated>2022-03-04T00:00:00+00:00</updated><id>https://diegolemos.net/2022/03/04/de-facto-best-practices</id><content type="html" xml:base="https://diegolemos.net/2022/03/04/de-facto-best-practices/"><![CDATA[<p>Here’s a collection of articles I found myself referring back to over and over again. They became over time de facto standards, cheat sheets and best practices for software development to me.</p>

<h2 id="biases">Biases</h2>

<ul>
  <li><a href="https://www.visualcapitalist.com/50-cognitive-biases-in-the-modern-world/">50 Cognitive Biases in the Modern World</a> by Marcus Lu</li>
  <li><a href="https://fs.blog/chestertons-fence/">Chesterton’s Fence: A Lesson in Second Order Thinking</a></li>
  <li><a href="https://www.youtube.com/watch?v=pOLmD_WVY-E">Why incompetent people think they’re amazing</a> by David Dunning</li>
</ul>

<h2 id="career">Career</h2>

<ul>
  <li><a href="https://mkdale.github.io/techoath/">A Hippocratic Oath for Technologists</a> by Mariesa Dale</li>
  <li><a href="https://www.iesf.fr/offres/doc_inline_src/752/150731_Charte_ethique.pdf">Charte d’Ethique de l’Ingénieur</a> par l’IESF</li>
  <li><a href="https://www.progression.fyi/">progression.fyi</a></li>
  <li><a href="https://www.indeed.com/career-advice/career-development/smart-goals">SMART Goals</a> by Indeed Editorial Team</li>
</ul>

<h2 id="cli">CLI</h2>

<ul>
  <li><a href="https://clementc.github.io/blog/2018/01/25/moving_cli/">Moving efficiently in the CLI</a> by Clément Chastagnol</li>
</ul>

<h2 id="coding">Coding</h2>

<ul>
  <li><a href="https://madeintandem.com/blog/five-factor-testing/">Five Factor Testing</a> by Sarah Mei</li>
  <li><a href="https://diegolemos.net/2018/11/04/test-doubles/">Test Doubles</a> by me</li>
  <li><a href="https://martinfowler.com/articles/workflowsOfRefactoring/fallback.html">Workflows of Refactoring</a> by Martin Fowler</li>
</ul>

<h2 id="continuous-integration--delivery">Continuous Integration &amp; Delivery</h2>

<ul>
  <li><a href="https://diegolemos.net/2018/10/17/6-best-practices-for-continuous-delivery-pipelines/">6 Best Practices for Continuous Delivery Pipelines</a> by Derik Evangelista &amp; myself</li>
</ul>

<h2 id="documentation">Documentation</h2>

<ul>
  <li><a href="https://adr.github.io/">Architectural Decision Records</a></li>
  <li><a href="https://github.com/LappleApple/feedmereadmes/blob/master/README-maturity-model.md">README Maturity Model</a> by Lauri Apple</li>
  <li><a href="https://inclusivenaming.org/word-lists/overview/">The Inclusive Naming Initiative</a></li>
  <li><a href="https://documentation.divio.com/">The documentation system</a> by Danielle Procida</li>
</ul>

<h2 id="logging">Logging</h2>

<ul>
  <li><a href="http://peter.bourgon.org/blog/2016/02/07/logging-v-instrumentation.html">Logging v. instrumentation</a> by Peter Bourgon</li>
  <li><a href="https://www.morling.dev/blog/whats-in-a-good-error-message/">What’s in a Good Error Message?</a> by Gunnar Morling</li>
  <li><a href="https://wix-ux.com/when-life-gives-you-lemons-write-better-error-messages-46c5223e1a2f">When life gives you lemons, write better error messages</a> by Jenni Nadler</li>
</ul>

<h2 id="meetings">Meetings</h2>

<ul>
  <li><a href="https://gds.blog.gov.uk/2016/10/07/platform-as-a-service-team-takes-even-handed-approach-to-meetings/">Platform as a Service team takes even-handed approach to meetings</a> by Dan Carley</li>
  <li><a href="https://medium.com/swlh/the-silent-meeting-manifesto-v1-189e9e3487eb">The Silent Meeting Manifesto v1: Making meeting suck a little less</a> by David Gasca</li>
</ul>

<h2 id="open-source">Open Source</h2>

<ul>
  <li><a href="https://wackowiki.org/doc/Org/Articles/5TypesOpenSourceProjects">The 5 Types of Open Source Projects</a> by Josh Berkus</li>
</ul>

<h2 id="process">Process</h2>

<ul>
  <li><a href="https://trello.com/b/Fdd876S8/continuous-delivery-checklist-template">Continuous Delivery checklist template</a></li>
</ul>

<h2 id="scaffolding">Scaffolding</h2>

<ul>
  <li><a href="https://flaviocopes.com/go-filesystem-structure/">Filesystem Structure of a Go project</a> by Flavio Copes</li>
</ul>

<h2 id="source-control">Source-Control</h2>

<ul>
  <li><a href="https://github.com/coderbyheart/first-principles/issues/30">Clean .gitignore files</a> by Markus Tacker</li>
  <li><a href="https://www.conventionalcommits.org/en/v1.0.0/#summary">Conventional Commits</a></li>
</ul>

<h2 id="support">Support</h2>

<ul>
  <li><a href="https://response.pagerduty.com/">PagerDuty Incident Response</a></li>
</ul>

<h2 id="time-management">Time Management</h2>

<ul>
  <li><a href="http://paulgraham.com/makersschedule.html">Maker’s Schedule, Manager’s Schedule</a> by Paul Graham</li>
  <li><a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">Pomodoro Technique</a> by Francesco Cirillo</li>
</ul>]]></content><author><name>Diego Lemos</name></author><category term="best practices" /><category term="cheat sheets" /><category term="standards" /><summary type="html"><![CDATA[Here’s a collection of articles I found myself referring back to over and over again. They became over time de facto standards, cheat sheets and best practices for software development to me.]]></summary></entry><entry><title type="html">Don’t send emails, write a blog post instead</title><link href="https://diegolemos.net/2022/01/06/dont-send-emails-write-a-blog-post-instead/" rel="alternate" type="text/html" title="Don’t send emails, write a blog post instead" /><published>2022-01-06T00:00:00+00:00</published><updated>2022-01-06T00:00:00+00:00</updated><id>https://diegolemos.net/2022/01/06/dont-send-emails-write-a-blog-post-instead</id><content type="html" xml:base="https://diegolemos.net/2022/01/06/dont-send-emails-write-a-blog-post-instead/"><![CDATA[<p>Enterprise communication is hard.</p>

<p>On one hand, companies want to achieve good levels of transparency and alignment. Encouraging communication works towards this goal.</p>

<p>On the other hand, leaders rightfully don’t want to share half-baked opinions or on going strategic conversations to avoid creating noise and distraction. Holding up information, in this context, is probably sensible.</p>

<p>Over the past 10 years or so I’ve been in the business of enterprise software development, I observed over-communicating has become an acceptable pattern. The benefits of sharing information most often outweighs the risks.</p>

<p>But, over-communicating paired with emails being used as the preferred tool to broadcast information is working against the original intent.</p>

<p>To protect their mental health and productivity, people are running away and not towards information. In a colleague words, sometimes it feels like “drinking from the fire-hose”.</p>

<p>And more levels you’ve got in your org chart, more this gets exacerbated (entropy).</p>

<h2 id="depth-vs-breadth">Depth VS breadth</h2>

<p>In his <a href="http://paulgraham.com/makersschedule.html">Maker’s Schedule, Manager’s Schedule article</a>, I believe Paul Graham gives us clues to understand why over-communicating can be counter productive.</p>

<p>To get things done, people in the Individual Contributor (IC) track often need to go in depth on a topic and work at a detail level. This requires loading and keeping a fair amount of context in their heads. From a cognitive perspective, this is demanding and time consuming.</p>

<p>When a person in an IC role also has to go through a reasonable amount of information that’s thrown at them on a daily basis, it can be challenging to spare enough mental cycles (or simply time) to focus on something for a couple of hours straight.</p>

<p>This can be, however, less of an issue for those in the management track. Because of the breadth nature of their work, context switching is arguably less painful.</p>

<h2 id="emails-have-been-abused">Emails have been abused</h2>

<p>Emails, by design, work like a push system. When you send someone an email you are pushing something onto them. The ball is now in their court.</p>

<p>Until not long ago, I was of the opinion that having a good enough set of mailbox rules was the answer. After changing companies a couple of times and playing different roles, I had to recognise I never came up with something that effectively sorted out my incoming emails. Quite the opposite, I felt I was fighting to maintain an ever growing list of rules. The effort was just not worth it.</p>

<p>This made me realise we should maybe repurpose how we use emails.</p>

<h2 id="defaulting-to-a-pull-system">Defaulting to a pull system</h2>

<p>I am now experimenting with only sending emails if:</p>

<ul>
  <li>or when action is needed, such as “please fill out this form by” or “make sure you opt-in to X” or “feedback request” or even “can you please send me this doc”.</li>
  <li>either something has a direct impact on people, a team or the company, examples are “you are getting a pay rise” or “we are about to become a public company” or “new rules to get into the office”;</li>
</ul>

<p>For all the rest, I believe we should default to a pull system. This can be achieved by making information available somewhere, like an internal blog post. People who feel concerned or interested can subscribe and engage with.</p>

<p>At work, before I could connect the dots and articulate this idea, some colleagues had already started writing internal blog posts to share their thoughts. I’ve been enjoying this pattern as I know I can delay or even skip reading them. It depends on how interested I am, how much work or head space I have at the moment.</p>

<p>I am now advocating for people in the org to experiment with this idea. I am approaching this as an experiment as, even tough this looks like a more flexible and less invasive pattern to me, I don’t have data to share at this point.</p>

<p>If you feel like you are seeing a similar pattern, and you ever decide to talk to your team about what should be pushed and what can be pulled, I’d be curious to know more.</p>]]></content><author><name>Diego Lemos</name></author><category term="communication" /><category term="emails" /><category term="enterprise" /><category term="experiment" /><category term="pull system" /><category term="push system" /><summary type="html"><![CDATA[Enterprise communication is hard.]]></summary></entry><entry><title type="html">cdCon 2021</title><link href="https://diegolemos.net/2021/07/12/cdcon-2021/" rel="alternate" type="text/html" title="cdCon 2021" /><published>2021-07-12T00:00:00+00:00</published><updated>2021-07-12T00:00:00+00:00</updated><id>https://diegolemos.net/2021/07/12/cdcon-2021</id><content type="html" xml:base="https://diegolemos.net/2021/07/12/cdcon-2021/"><![CDATA[<p>June 2021 I had a chance to attend and speak at <a href="https://events.linuxfoundation.org/cdcon/">cdCon 2021</a>.</p>

<p><a href="https://twitter.com/kirederik">Derik</a> and I shared our thoughts around best practices for Continuous Delivery pipelines.</p>

<p>A big thanks to Jennifer and all the organisers for all their hard work, it was a great event.</p>

<p>Also a big thanks to all the communities and people presents at the event, specially those who showed up for our talk 🙂</p>

<div class="video-embed video-embed--youtube" style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;">
  <iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src="https://www.youtube.com/embed/rFIFDoli9F0" title="YouTube video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
</div>]]></content><author><name>Diego Lemos</name></author><category term="continuous delivery" /><category term="continuous deployment" /><category term="continuous integration" /><category term="deployment pipeline" /><category term="devops" /><category term="talks" /><summary type="html"><![CDATA[June 2021 I had a chance to attend and speak at cdCon 2021.]]></summary></entry><entry><title type="html">4 types of documentation</title><link href="https://diegolemos.net/2021/03/02/4-types-of-documentation/" rel="alternate" type="text/html" title="4 types of documentation" /><published>2021-03-02T00:00:00+00:00</published><updated>2021-03-02T00:00:00+00:00</updated><id>https://diegolemos.net/2021/03/02/4-types-of-documentation</id><content type="html" xml:base="https://diegolemos.net/2021/03/02/4-types-of-documentation/"><![CDATA[<p>The other day I was listening <a href="https://changelog.com/gotime/167">The art of reading the docs episode</a> from the Go Time podcast and someone mentioned this <a href="https://www.youtube.com/watch?v=t4vKPhjcMZg">What nobody tells you about documentation talk</a> from Daniele Procida at PyCon AU 2017.</p>

<p>Daniele argues there are 4 types of documentation, each of one serving a different purpose:</p>

<ul>
  <li>Discussions</li>
  <li>Reference</li>
  <li>How-to guides</li>
  <li>Tutorials</li>
</ul>

<h2 id="tutorial">Tutorial</h2>

<p>Tutorials are learning-oriented. A good tutorial is a series of steps that help the reader to learn something by doing.</p>

<p>Daniele goes further suggesting learning is not the most important element but providing the reader an enjoyable experience. When that happens, the reader will want to do it again in the future and learning becomes a by-product of the experience (I wished my school teachers thought that way back in time).</p>

<p>Some characteristics of tutorials are:</p>

<ul>
  <li>deal with concrete (not abstractions).</li>
  <li>lean by doing,</li>
  <li>sense of achievement,</li>
  <li>repeatability,</li>
  <li>how to get started,</li>
</ul>

<p>The outcome of a tutorial is to help someone to do something and at this stage it is OK to not fully understand what’s going on.</p>

<h2 id="how-to-guide">How-to guide</h2>

<p>How-to guides are problem-oriented. It generally contains a sequence of steps that, if followed in order, guide the reader through solving a specific issue.</p>

<p>As tutorials are commonly used by readers at the beginning of their learning journey, they might not have enough knowledge to come up with meaningful questions yet. Once they acquire a better understanding and uncover specific issues, a how-to guide is what they need.</p>

<p>A recipe is an example of a how-go guide as it has a clear goal and describes a sequence of steps to achieve that goal.</p>

<p>Some properties of how-go guides are:</p>

<ul>
  <li>practical usability.</li>
  <li>sequence of steps,</li>
  <li>focused on a specific issue,</li>
</ul>

<h2 id="reference">Reference</h2>

<p>Reference guides are descriptions of something (like a library, framework or programme) and how to use it. It’s information-oriented.</p>

<p>Hopefully when someone get to the point of reading a reference guide they have a good understanding of the mechanics of the thing in question and how to perform some tasks with it.</p>

<p>Some common properties of reference guides are:</p>

<ul>
  <li>structure.</li>
  <li>description,</li>
  <li>to the point,</li>
</ul>

<p><a href="https://golang.org/pkg/">Go docs</a> and programming language documentation in general are a good examples of this.</p>

<h2 id="discussion">Discussion</h2>

<p>Discussion or explanation are understanding-oriented and offer clarifying background and context on a topic. Books, conference talks, essays are some examples.</p>

<p>Good discussions focus on:</p>

<ul>
  <li>making connections with other topics, concepts.</li>
  <li>explaining the “why”,</li>
  <li>providing context,</li>
</ul>

<h2 id="effective-documentation">Effective documentation</h2>

<p>With these 4 types of documentation, it can be challenging for authors not to mix them together as sometimes boundaries can blur. This leads to documentation debt, which makes things tedious, time consuming and ineffective.</p>

<p>It is often the case different types of documentation need one another, like How-to guides linking to References, or Tutorials referring to Discussions for further background. The key though is stepping across boundaries should be optional, allowing readers to either focus on what they want to achieve or taking a detour.</p>

<p>To go further on this check <a href="https://documentation.divio.com/">this guide</a> written by Daniele.</p>]]></content><author><name>Diego Lemos</name></author><category term="docs" /><category term="documentation" /><summary type="html"><![CDATA[The other day I was listening The art of reading the docs episode from the Go Time podcast and someone mentioned this What nobody tells you about documentation talk from Daniele Procida at PyCon AU 2017.]]></summary></entry><entry><title type="html">6 Best Practices for Continuous Delivery Pipelines @ London DevOps</title><link href="https://diegolemos.net/2019/03/30/6-best-practices-for-continuous-delivery-pipelines-london-devops/" rel="alternate" type="text/html" title="6 Best Practices for Continuous Delivery Pipelines @ London DevOps" /><published>2019-03-30T00:00:00+00:00</published><updated>2019-03-30T00:00:00+00:00</updated><id>https://diegolemos.net/2019/03/30/6-best-practices-for-continuous-delivery-pipelines-london-devops</id><content type="html" xml:base="https://diegolemos.net/2019/03/30/6-best-practices-for-continuous-delivery-pipelines-london-devops/"><![CDATA[<p>Once again <a href="https://onion.works/">Derik</a> and I delivered out 6 Best Practices for Continuous Delivery at <a href="https://www.meetup.com/London-DevOps/events/259388318/">London DevOps</a>. The meetup happened on March 14, 2019 and was hosted by Pivotal.</p>

<p>I was particularly impressed by the crowd. It’s been the hugest audience I’ve seen in DevOps meetups in London so far, they’ve got a huge community there.</p>

<p>Big shout out to the organisers Matt Saunders and Marc Cluet and all the participants 🙌</p>

<div class="video-embed video-embed--youtube" style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;">
  <iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src="https://www.youtube.com/embed/7mwb0ICedbk" title="YouTube video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
</div>]]></content><author><name>Diego Lemos</name></author><category term="concourse" /><category term="continuous delivery" /><category term="continuous deployment" /><category term="deployment pipeline" /><category term="devops" /><category term="talks" /><summary type="html"><![CDATA[Once again Derik and I delivered out 6 Best Practices for Continuous Delivery at London DevOps. The meetup happened on March 14, 2019 and was hosted by Pivotal.]]></summary></entry><entry><title type="html">Pipelines Done Right @ DevOps Underground London</title><link href="https://diegolemos.net/2019/03/14/pipelines-done-right-devops-underground-london/" rel="alternate" type="text/html" title="Pipelines Done Right @ DevOps Underground London" /><published>2019-03-14T00:00:00+00:00</published><updated>2019-03-14T00:00:00+00:00</updated><id>https://diegolemos.net/2019/03/14/pipelines-done-right-devops-underground-london</id><content type="html" xml:base="https://diegolemos.net/2019/03/14/pipelines-done-right-devops-underground-london/"><![CDATA[<p>The 13th March 2019 <a href="http://onion.works/">Derik</a> and I gave our Pipelines Done Right talk at <a href="https://www.meetup.com/DevOps-Underground/events/258121219/">DevOps Underground London</a>.</p>

<p>It was our first time at DevOps Underground London and I pretty much envoyed everything. Big shout out the all the participants, Skills Matter for having us and the organisers.</p>

<p>The session was recorded and it is available <a href="https://skillsmatter.com/skillscasts/13406-pipelines-done-right">here</a>.</p>]]></content><author><name>Diego Lemos</name></author><category term="concourse" /><category term="continuous delivery" /><category term="continuous integration" /><category term="deployment pipeline" /><category term="talks" /><summary type="html"><![CDATA[The 13th March 2019 Derik and I gave our Pipelines Done Right talk at DevOps Underground London.]]></summary></entry><entry><title type="html">Pipelines Done Right @ Concourse London User Group</title><link href="https://diegolemos.net/2019/02/21/pipelines-done-right-concourse-london-user-group/" rel="alternate" type="text/html" title="Pipelines Done Right @ Concourse London User Group" /><published>2019-02-21T00:00:00+00:00</published><updated>2019-02-21T00:00:00+00:00</updated><id>https://diegolemos.net/2019/02/21/pipelines-done-right-concourse-london-user-group</id><content type="html" xml:base="https://diegolemos.net/2019/02/21/pipelines-done-right-concourse-london-user-group/"><![CDATA[<p>On 31 January 2019 <a href="http://onion.works/">Derik</a> and I gave our talk about Continuous Delivery best practices using Concourse <a href="https://www.meetup.com/Concourse-London-User-Group/events/257130654/">at the Concourse London User Group</a>. It was quite cool.</p>

<p>We’ve given this talk a couple of times and to comfortably live code the whole pipeline and talk about everything we believe it’s important, we need on average 1h30. Although, the organisers did challenge us to give the talk in 30 minutes and… challenge accepted! Overall I think we did a decent job, except that we used some code snipets instead of coding the whole thing and, for some misterious reason, our pipeline went red. In the end we just retriggered it and it went green again 😳</p>

<p>It was my first time talking at Concourse London User Group and I enjoyed it. A big shout to the organisers and participants 🙌</p>

<div class="video-embed video-embed--youtube" style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;">
  <iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src="https://www.youtube.com/embed/wbmjCr99hPk" title="YouTube video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
</div>]]></content><author><name>Diego Lemos</name></author><category term="concourse" /><category term="continuous delivery" /><category term="deployment pipeline" /><category term="talks" /><summary type="html"><![CDATA[On 31 January 2019 Derik and I gave our talk about Continuous Delivery best practices using Concourse at the Concourse London User Group. It was quite cool.]]></summary></entry><entry><title type="html">Test Doubles</title><link href="https://diegolemos.net/2018/11/04/test-doubles/" rel="alternate" type="text/html" title="Test Doubles" /><published>2018-11-04T00:00:00+00:00</published><updated>2018-11-04T00:00:00+00:00</updated><id>https://diegolemos.net/2018/11/04/test-doubles</id><content type="html" xml:base="https://diegolemos.net/2018/11/04/test-doubles/"><![CDATA[<p>Sometimes when writing tests or defining a testing strategy, we need to replace part of a system at run time with a modified version, in order to set up, simplify, isolate or verify a particular behaviour.</p>

<p>In his book <a href="https://www.goodreads.com/book/show/337302.xUnit_Test_Patterns">xUnit Test Patterns: Refactoring Test Code</a>, Gerard Meszaros came up with the term test doubles to describe the various types of objects or procedures used to facilitate and support testing:</p>

<ul>
  <li><strong>Mocks</strong> are used to verify behaviour by throwing exceptions or failing when they receive calls that differ from their expectations.</li>
  <li><strong>Spies</strong> are stubs that record some information based on how they were called. They are generally used when we need to verify if/how many times a function call has been made.</li>
  <li><strong>Stubs</strong> provide predictible responses to the calls made during the test, usually programmed to only respond to calls that happen in the context of the test.</li>
  <li><strong>Fake objects</strong> have working implementations, but are not suitable for production, given they might have some implementation shortcuts. In-memory database is a common example.</li>
  <li><strong>Dummy objects</strong> are passed around but never used. They are commonly used to fill parameter lists, fill in required properties in other objects, etc.</li>
</ul>

<p>More on this topic:</p>

<ul>
  <li><a href="https://en.wikipedia.org/wiki/Test_double">Test double</a></li>
  <li><a href="https://martinfowler.com/articles/mocksArentStubs.html">Mocks Aren’t Stubs</a></li>
</ul>]]></content><author><name>Diego Lemos</name></author><category term="test doubles" /><category term="testing" /><category term="testing strategy" /><category term="tests" /><summary type="html"><![CDATA[Sometimes when writing tests or defining a testing strategy, we need to replace part of a system at run time with a modified version, in order to set up, simplify, isolate or verify a particular behaviour.]]></summary></entry></feed>