Skip to main content

Engineering the open web.

Long-form writing on Drupal, PHP frameworks, AI tooling, automated testing and everything else in a working programmer's stack — shipped from production, not theory.

The malware was in .claude/settings.json: when opening a repo becomes code execution
ai

The malware was in .claude/settings.json: when opening a repo becomes code execution

The Aug 4 keyv/'ChainDrop' npm worm planted payloads in AI-agent and editor config — .claude/settings.json SessionStart hooks, .vscode/tasks.json runOn:folderOpen — that fire when you or your agent just open the folder. And it shipped with valid provenance, because the source was poisoned before the trusted build. Opening a repo is now a code-execution decision.

2026-08-13 / 04 min
Every app that lets strangers sign up is an unauth RCE waiting on one box
security

Every app that lets strangers sign up is an unauth RCE waiting on one box

Two fresh RCEs — Gitea's diffpatch hook (CVE-2026-60004, 9.8, open registration on by default) and n8n's Git node (CVE-2026-21877, 9.9) — make the one-box lesson concrete: default-open signup turns 'authenticated' RCE into anonymous RCE, and co-located apps share a blast radius. Kill open signup, segment Docker networks, don't co-locate automation with a public site.

2026-08-13 / 04 min
The phar wrapper that wouldn't die: parse_url() ate PhpSpreadsheet's patch
php

The phar wrapper that wouldn't die: parse_url() ate PhpSpreadsheet's patch

CVE-2026-45034 (CVSS 9.2) bypasses an earlier PhpSpreadsheet fix because one extra slash makes parse_url() return false, walking past the guard and re-enabling phar deserialization. The real villain isn't the library — it's using parse_url() as a security boundary, a recurring PHP footgun the advisory itself warns against.

2026-08-13 / 04 min
SWE-bench went from 60% to nearly 100%. That's the benchmark dying, not progress.
ai

SWE-bench went from 60% to nearly 100%. That's the benchmark dying, not progress.

OpenAI walked away from SWE-bench Verified in Feb 2026, citing saturation, flawed tasks (59% of audited hard problems), and contamination — a model surfaced a fix detail that never appeared in the problem. The 'SWE-Bench Illusion' paper measured the memorization. Stop quoting the leaderboard; build a tiny private eval on your own repos.

2026-08-13 / 04 min
Cache tags vs cache contexts: the mental model that ends “why won't my block update?”
drupal

Cache tags vs cache contexts: the mental model that ends “why won't my block update?”

The single most misunderstood corner of Drupal, and the root of ~90% of 'stale content' and 'user B sees user A's data' bugs. The one-line model: stale = a missing cache tag, leaking = a missing cache context. How they bubble, why max-age:0 quietly poisons a whole page, and the debug header that finds the culprit in seconds.

2026-08-03 / 04 min
Your 1M-token context window is a lie (context rot)
ai

Your 1M-token context window is a lie (context rot)

Chroma tested 18 models: accuracy falls well before the advertised limit, and semantically-similar distractors hurt more than the raw token count — models even did better on a shuffled haystack than a coherent one. Plus RULER's 'effective context' and Lost-in-the-Middle. Why curated retrieval still beats stuffing everything in the window.

2026-08-03 / 04 min
Subscribe to Home
One email a week. No noise.
Every new article, plus the tools and patches I’m watching.