<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Michał Woliński — Blog</title>
    <link>https://wolinski.com/blog.html</link>
    <description>Thoughts on systems architecture, PHP, AWS, AI-driven automation, and building software that lasts.</description>
    <language>en</language>
    <lastBuildDate>Tue, 27 Oct 2026 07:30:00 GMT</lastBuildDate>
    <atom:link href="https://wolinski.com/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>How to Evaluate AI Agents: Grade the World, Not the Transcript</title>
      <link>https://wolinski.com/blog/how-to-evaluate-ai-agents.html</link>
      <description>An agent does not produce an answer you can compare with a reference; it produces a changed world and an account of the change. A harness that grades the world: state diffs, pass^k over five runs, failure shapes and cost per success, measured on Claude Haiku 5.5 and 4.5 against an LLM judge.</description>
      <pubDate>Tue, 27 Oct 2026 07:30:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/how-to-evaluate-ai-agents.html</guid>
    </item>
    <item>
      <title>Five MCP Integration Mistakes That Fail Somewhere Else</title>
      <link>https://wolinski.com/blog/mcp-integration-mistakes-java.html</link>
      <description>Five ways to wire an MCP server wrong without the mistake failing where it was made: a log line on stdout, an exception where a result belongs, a generated tool catalog, a result sized by the data, and a request that outlives the client. Reproduced and fixed on the Java SDK.</description>
      <pubDate>Mon, 26 Oct 2026 09:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/mcp-integration-mistakes-java.html</guid>
    </item>
    <item>
      <title>Inside the rsync Source: Three Ideas Worth Reading</title>
      <link>https://wolinski.com/blog/inside-the-rsync-source.html</link>
      <description>rsync is thirty years old and nobody reads it. I did — the real tree, protocol 33 — for three ideas: a --delete that fails closed on an I/O error, a weak checksum that rolls so the cheap question stays affordable at every byte, and a file list that learned to stream the whole tree.</description>
      <pubDate>Thu, 22 Oct 2026 08:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/inside-the-rsync-source.html</guid>
    </item>
    <item>
      <title>Watching an Unpatched RCE Land: PHP 5.6 Under AddressSanitizer</title>
      <link>https://wolinski.com/blog/php-56-rce-under-sanitizers.html</link>
      <description>The advisory patches 8.2 to 8.5 and backports 7.4, 8.0 and 8.1. PHP 5.6 gets nothing. So I built 5.6.40 under AddressSanitizer and sent the advisory&apos;s own inputs at it: mod_php takes a real SEGV from two ordinary requests, PHP-FPM survives, and no exploit, it stops at the crash.</description>
      <pubDate>Wed, 21 Oct 2026 20:30:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/php-56-rce-under-sanitizers.html</guid>
    </item>
    <item>
      <title>PHP&apos;s October RCE: Patch First, Then Check What Your Version Number Hides</title>
      <link>https://wolinski.com/blog/php-rce-cve-2026-109618-109619.html</link>
      <description>Two critical, unauthenticated PHP RCEs, patched the same day. The update is the easy part; knowing where you stand is not. Why the distribution version string and the moving image tag both lie, how to check the SAPI that serves traffic, and the interim settings the oldest branches skip silently.</description>
      <pubDate>Wed, 21 Oct 2026 20:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/php-rce-cve-2026-109618-109619.html</guid>
    </item>
    <item>
      <title>The Boundary in Laravel: FormRequest Is Not a DTO</title>
      <link>https://wolinski.com/blog/laravel-dto-first.html</link>
      <description>Laravel already enforces two of the five boundary rules and breaks the other three. Deptrac covers the layers, five reflection checks cover what it cannot see, and the measured price is not the mappers — it is the validators that hit the database.</description>
      <pubDate>Wed, 21 Oct 2026 14:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/laravel-dto-first.html</guid>
    </item>
    <item>
      <title>DTO-First: The Boundary Decides What the Domain Sees</title>
      <link>https://wolinski.com/blog/dto-first-php-symfony.html</link>
      <description>DTO-first is advice until something enforces it. Five boundary rules, each checked by a gate that fails the build — and the measured price of the doctrine: the mappers cost half a microsecond, and one validator constraint costs more than all the others together.</description>
      <pubDate>Tue, 20 Oct 2026 09:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/dto-first-php-symfony.html</guid>
    </item>
    <item>
      <title>An MCP Server in PHP: Signed State Is Provenance, Not Single Use</title>
      <link>https://wolinski.com/blog/mcp-server-php-symfony.html</link>
      <description>An MCP server that asks before it rolls a service back has to survive being asked twice. Three defects found while reviewing a working one — a refusal read as consent, a signature mistaken for single use, and a replay guard with a race in it — with the measurement behind each fix.</description>
      <pubDate>Wed, 14 Oct 2026 12:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/mcp-server-php-symfony.html</guid>
    </item>
    <item>
      <title>PHP 8.6: every feature, before and after</title>
      <link>https://wolinski.com/blog/php-8-6-new-features.html</link>
      <description>PHP 8.6 removes ceremony: a placeholder instead of a lambda, a default instead of a constructor body, a Duration instead of an int. Every change here is measured on 8.5 and 8.6 — including the optimisations that did not reproduce and the one shape that got slower.</description>
      <pubDate>Wed, 14 Oct 2026 11:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/php-8-6-new-features.html</guid>
    </item>
    <item>
      <title>git archive — what a tarball leaves behind</title>
      <link>https://wolinski.com/blog/git-archive-what-a-tarball-leaves-behind.html</link>
      <description>A tarball is what a repository hands to everyone who will never clone it — and it is not the repository. What leaves, what stays behind, and why the same commit can compress to different bytes on a different machine.</description>
      <pubDate>Tue, 13 Oct 2026 08:17:15 GMT</pubDate>
      <guid>https://wolinski.com/blog/git-archive-what-a-tarball-leaves-behind.html</guid>
    </item>
    <item>
      <title>Bisect in CI: Reproducing the Commit Is the Hard Part</title>
      <link>https://wolinski.com/blog/bisect-in-ci-reproducing-old-commits.html</link>
      <description>git bisect run in a pipeline is one line and almost useless on its own: the work is making an arbitrary historical commit provisionable, buildable and testable — and reading the loop&apos;s own exit status honestly.</description>
      <pubDate>Mon, 12 Oct 2026 07:06:09 GMT</pubDate>
      <guid>https://wolinski.com/blog/bisect-in-ci-reproducing-old-commits.html</guid>
    </item>
    <item>
      <title>Parallel Agents on Git Worktrees: Isolation Is Not a Checkout</title>
      <link>https://wolinski.com/blog/parallel-agents-on-git-worktrees.html</link>
      <description>A worktree per task stops two coding agents from overwriting each other&apos;s files. It does not isolate the approvals, hook paths and untracked instructions that decide what an agent does next — nor the lifecycle a headless run leaves behind.</description>
      <pubDate>Mon, 12 Oct 2026 06:27:35 GMT</pubDate>
      <guid>https://wolinski.com/blog/parallel-agents-on-git-worktrees.html</guid>
    </item>
    <item>
      <title>Git Bisect: The Algorithm Is Trivial, Your Predicate Is Not</title>
      <link>https://wolinski.com/blog/git-bisect-predicate-problem.html</link>
      <description>Bisect halves an interval and asks your predicate one question per step. On the same history, a broad predicate and a targeted one returned different culprits — both with exit status zero.</description>
      <pubDate>Sat, 10 Oct 2026 06:33:50 GMT</pubDate>
      <guid>https://wolinski.com/blog/git-bisect-predicate-problem.html</guid>
    </item>
    <item>
      <title>Git Worktree: One Repository, Many Working Trees</title>
      <link>https://wolinski.com/blog/git-worktree-one-repo-many-working-trees.html</link>
      <description>One repository, several working directories on a single object store. What git worktree shares, what it isolates, the branch mutex, the lifecycle, relative paths, and the submodule limits the manual still calls incomplete.</description>
      <pubDate>Fri, 09 Oct 2026 09:30:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/git-worktree-one-repo-many-working-trees.html</guid>
    </item>
    <item>
      <title>Sudo Mode in Symfony 8.2: The Rule That Silently Drops the Freshness Check</title>
      <link>https://wolinski.com/blog/symfony-8-2-sudo-mode.html</link>
      <description>Symfony 8.2 makes sudo mode a primitive: IS_AUTHENTICATED_RECENTLY, a clock instead of a session flag, and a step-up that needs no code of yours. Plus the multi-attribute rule that silently drops the check.</description>
      <pubDate>Mon, 05 Oct 2026 08:50:21 GMT</pubDate>
      <guid>https://wolinski.com/blog/symfony-8-2-sudo-mode.html</guid>
    </item>
    <item>
      <title>ETag: The Concurrency Guard Hiding in a Cache Header</title>
      <link>https://wolinski.com/blog/etag-optimistic-concurrency-control.html</link>
      <description>ETag is a cache validator on reads and a concurrency guard on writes — the specification requires different comparison rules for each. Built end to end in PHP and Go, and proven with two real writers racing for one resource.</description>
      <pubDate>Wed, 30 Sep 2026 06:31:51 GMT</pubDate>
      <guid>https://wolinski.com/blog/etag-optimistic-concurrency-control.html</guid>
    </item>
    <item>
      <title>Dapr: A Portable API Over Non-Portable Guarantees</title>
      <link>https://wolinski.com/blog/dapr-portable-api-conditional-guarantees.html</link>
      <description>Dapr&apos;s building blocks are portable; the guarantees underneath them are not. The same requests against two stores Dapr calls Stable — one failure is refused, the other is silent. With a runnable demo.</description>
      <pubDate>Tue, 29 Sep 2026 19:34:43 GMT</pubDate>
      <guid>https://wolinski.com/blog/dapr-portable-api-conditional-guarantees.html</guid>
    </item>
    <item>
      <title>Four Failure Shapes From Public Postmortems</title>
      <link>https://wolinski.com/blog/four-failure-shapes.html</link>
      <description>Seven published incidents, two predating LLMs, collapse into four shapes: the label became the goal, the gate never held, validation stayed inside, and the recovery was never tested.</description>
      <pubDate>Tue, 29 Sep 2026 18:39:49 GMT</pubDate>
      <guid>https://wolinski.com/blog/four-failure-shapes.html</guid>
    </item>
    <item>
      <title>Where I Deliberately Don&apos;t Use AI</title>
      <link>https://wolinski.com/blog/where-i-dont-use-ai.html</link>
      <description>AI can do more than I let it do. A practitioner&apos;s boundary list — the places I deliberately don&apos;t use it, the two questions that draw the line, and where I have already changed my mind.</description>
      <pubDate>Tue, 29 Sep 2026 14:07:49 GMT</pubDate>
      <guid>https://wolinski.com/blog/where-i-dont-use-ai.html</guid>
    </item>
    <item>
      <title>Observability for AI Agents: Instrument the Trajectory, Not the Request</title>
      <link>https://wolinski.com/blog/observability-for-ai-agents.html</link>
      <description>A 200 OK tells you nothing when the failure is a plausible wrong answer. Instrumenting agent systems: the span model, payload policy, tail sampling, cost accounting, and the path to diagnosis.</description>
      <pubDate>Tue, 29 Sep 2026 13:35:48 GMT</pubDate>
      <guid>https://wolinski.com/blog/observability-for-ai-agents.html</guid>
    </item>
    <item>
      <title>Hallucinations and Context Problems: A Production Mitigation Playbook</title>
      <link>https://wolinski.com/blog/hallucinations-and-context-problems.html</link>
      <description>Hallucination is a family of failures, not one bug. A mitigation playbook: coverage versus utilization, grounding by construction, detection that routes, and containment.</description>
      <pubDate>Fri, 25 Sep 2026 08:13:33 GMT</pubDate>
      <guid>https://wolinski.com/blog/hallucinations-and-context-problems.html</guid>
    </item>
    <item>
      <title>How to Measure the Quality of an AI System: A Production Evaluation Framework</title>
      <link>https://wolinski.com/blog/measuring-ai-system-quality.html</link>
      <description>Quality is not a number. A production framework for measuring AI systems: component metrics, calibrated judges, statistical honesty, and the failure modes of measurement itself.</description>
      <pubDate>Fri, 25 Sep 2026 06:51:15 GMT</pubDate>
      <guid>https://wolinski.com/blog/measuring-ai-system-quality.html</guid>
    </item>
    <item>
      <title>Event Sourcing in Production Laravel: Snapshots, Schema Evolution, and Read-Model Rebuilds</title>
      <link>https://wolinski.com/blog/laravel-event-sourcing-snapshots-schema-evolution-rebuilds.html</link>
      <description>Three production concerns that look like separate problems and are not. A working Laravel 13 skeleton with version-aware serializers, snapshot invalidation, and idempotent projection replay — all backed by tests.</description>
      <pubDate>Tue, 01 Sep 2026 07:03:54 GMT</pubDate>
      <guid>https://wolinski.com/blog/laravel-event-sourcing-snapshots-schema-evolution-rebuilds.html</guid>
    </item>
    <item>
      <title>Guardrails for LLM Agents: Permissions, Scopes, and the Audit Trail That Holds Up</title>
      <link>https://wolinski.com/blog/agent-guardrails-and-permissions.html</link>
      <description>Permissions, output validation, multi-agent delegation, and the audit trail that reconstructs the decision chain. A production handbook for shipping agents that survive contact with reality.</description>
      <pubDate>Mon, 31 Aug 2026 12:19:36 GMT</pubDate>
      <guid>https://wolinski.com/blog/agent-guardrails-and-permissions.html</guid>
    </item>
    <item>
      <title>When to Reach for an Agent, and When to Ship the Workflow</title>
      <link>https://wolinski.com/blog/agent-vs-deterministic-workflow.html</link>
      <description>An LLM agent is a commitment, not a category. Here&apos;s the decision framework, the failure modes, the three-layer reliability model, and the hybrid architecture that actually works in production.</description>
      <pubDate>Fri, 28 Aug 2026 13:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/agent-vs-deterministic-workflow.html</guid>
    </item>
    <item>
      <title>When to Use RAG vs Simple Search: A Practical Decision Guide</title>
      <link>https://wolinski.com/blog/when-use-rag-vs-simple-search.html</link>
      <description>RAG sounds impressive, but most questions don&apos;t need synthesized answers from multiple documents. Here&apos;s how to choose the right approach.</description>
      <pubDate>Thu, 27 Aug 2026 13:49:38 GMT</pubDate>
      <guid>https://wolinski.com/blog/when-use-rag-vs-simple-search.html</guid>
    </item>
    <item>
      <title>HAProxy: Load Balancing and Health Checks for Multiple VPS</title>
      <link>https://wolinski.com/blog/haproxy-load-balancing-health-checks.html</link>
      <description>HAProxy sits in front of your servers, probes each one on a configurable schedule, and pulls failing hosts from the rotation before any user request reaches them. Load balancing across multiple VPS, sticky sessions, ACL routing, stick-table rate limi</description>
      <pubDate>Thu, 27 Aug 2026 13:03:34 GMT</pubDate>
      <guid>https://wolinski.com/blog/haproxy-load-balancing-health-checks.html</guid>
    </item>
    <item>
      <title>pgBouncer: PostgreSQL Connection Pooling — Installation and Configuration</title>
      <link>https://wolinski.com/blog/pgbouncer-connection-pooling-postgresql.html</link>
      <description>PostgreSQL spawns a separate process per connection, burning 5-10 MB of RAM before the first query. pgBouncer multiplexes hundreds of client connections through a small pool of real database connections, cutting RAM usage and preventing PostgreSQL from crawling under heavy concurrent load.</description>
      <pubDate>Thu, 27 Aug 2026 12:44:13 GMT</pubDate>
      <guid>https://wolinski.com/blog/pgbouncer-connection-pooling-postgresql.html</guid>
    </item>
    <item>
      <title>Quick Tip: Disable the Password Dots in sudo (Ubuntu 26.04 / sudo-rs)</title>
      <link>https://wolinski.com/blog/quick-tips-disable-sudo-dots.html</link>
      <description>Ubuntu 25.10/26.04 moved to sudo-rs, which echoes a dot per sudo password character by default. Bring back silent entry with Defaults !pwfeedback — the one-line fix.</description>
      <pubDate>Wed, 26 Aug 2026 10:52:09 GMT</pubDate>
      <guid>https://wolinski.com/blog/quick-tips-disable-sudo-dots.html</guid>
    </item>
    <item>
      <title>OpenTelemetry, Symfony i Grafana Tempo — tracing w praktyce</title>
      <link>https://wolinski.com/blog/opentelemetry-symfony-grafana.html</link>
      <description>How to add distributed tracing to a Symfony 7 app in Docker: OpenTelemetry zero-code auto-instrumentation, OTLP HTTP export to Grafana Tempo 3.0, and Gantt traces in Grafana 13.</description>
      <pubDate>Tue, 25 Aug 2026 16:02:38 GMT</pubDate>
      <guid>https://wolinski.com/blog/opentelemetry-symfony-grafana.html</guid>
    </item>
    <item>
      <title>Inbox Pattern: Stop Double-Processing Messages in Distributed Systems</title>
      <link>https://wolinski.com/blog/inbox-pattern.html</link>
      <description>When your consumer crashes after processing but before acknowledging, the broker redelivers — and your system processes the same message twice. The Inbox pattern is the answer to safe, idempotent message consumption.</description>
      <pubDate>Tue, 23 Jun 2026 09:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/inbox-pattern.html</guid>
    </item>
    <item>
      <title>Outbox Pattern: How to Stop Losing Messages in Distributed Systems</title>
      <link>https://wolinski.com/blog/outbox-pattern.html</link>
      <description>When your database transaction commits but the message never reaches the queue, the Outbox pattern is the answer. A practical guide to reliable event publishing without dual-writes.</description>
      <pubDate>Tue, 16 Jun 2026 09:00:00 GMT</pubDate>
      <guid>https://wolinski.com/blog/outbox-pattern.html</guid>
    </item>
  </channel>
</rss>
