<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>dmitriiev.dev</title><description>Test automation and security research. Technique over journey.</description><link>https://dmitriiev.dev/</link><item><title>The AI writes the tests. It doesn&apos;t get to grade them.</title><link>https://dmitriiev.dev/posts/ai-writes-tests-doesnt-grade-them/</link><guid isPermaLink="true">https://dmitriiev.dev/posts/ai-writes-tests-doesnt-grade-them/</guid><description>An LLM turns a described feature into a plausible Playwright spec cheaply. Trusting that spec is the hard part. So I built a pipeline where every stage is checked by something that did not produce it, and CI never calls a model at all.</description><pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate></item><item><title>Passing tests that never talk to the server</title><link>https://dmitriiev.dev/posts/passing-tests-never-talk-to-the-server/</link><guid isPermaLink="true">https://dmitriiev.dev/posts/passing-tests-never-talk-to-the-server/</guid><description>Inverting an assertion proves a test can fail, not that it checks the right value. A test can assert what the browser rendered instead of what the server sent, and stay green when the backend is wrong. So I corrupt the response and watch which greens never notice.</description><pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate></item><item><title>Your green tests are lying</title><link>https://dmitriiev.dev/posts/your-green-tests-are-lying/</link><guid isPermaLink="true">https://dmitriiev.dev/posts/your-green-tests-are-lying/</guid><description>A passing test only means something if it can fail. I inverted every primary assertion in a production Playwright suite to find out which greens were real. One test hadn&apos;t run in months.</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate></item><item><title>You revoked their access. Now go use it.</title><link>https://dmitriiev.dev/posts/revoke-that-didnt-take/</link><guid isPermaLink="true">https://dmitriiev.dev/posts/revoke-that-didnt-take/</guid><description>Everyone tests getting in. Almost nobody tests getting kicked out. The clean authz bug is the gap between the control plane saying revoked and the data plane still letting the old credential through.</description><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate></item><item><title>When the main app is clean, go count the URL fetchers</title><link>https://dmitriiev.dev/posts/ssrf-at-the-edges/</link><guid isPermaLink="true">https://dmitriiev.dev/posts/ssrf-at-the-edges/</guid><description>The core product passes every check, so you move on. The SSRF was in a side feature nobody armored: one of the half-dozen places the backend quietly fetches a URL on your behalf.</description><pubDate>Wed, 17 Jun 2026 00:00:00 GMT</pubDate></item><item><title>Your bug is real. Your report reads like ChatGPT. That&apos;s why it got closed.</title><link>https://dmitriiev.dev/posts/anti-ai-tells/</link><guid isPermaLink="true">https://dmitriiev.dev/posts/anti-ai-tells/</guid><description>Triagers now bounce AI-shaped reports on sight, valid or not. Here are the tells they pattern-match, and how to write so a human believes you.</description><pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate></item></channel></rss>