From 6a9c36401248132c611fd72fb1580d0040504d5e Mon Sep 17 00:00:00 2001 From: Malin Date: Sun, 2 Aug 2026 21:09:58 +0200 Subject: [PATCH] feat: add parallel-delegate-shared-files skill from iWP Cache incident --- README.md | 3 + .../parallel-delegate-shared-files/SKILL.md | 92 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 skills/parallel-delegate-shared-files/SKILL.md diff --git a/README.md b/README.md index fd8b2fd..cc9a276 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,9 @@ than assuming the delegate can fetch it itself. configuration strength, including reverse-proxy-layer gotchas. - `code-sanitization` -- framework-agnostic injection-prevention baseline (SQLi, XSS, command injection, path traversal, uploads, deserialization). +- `parallel-delegate-shared-files` -- never have 2+ parallel delegates edit + the same bootstrap/wiring file; use self-registration instead. Real + incident from the iWP Cache build (lost updates, twice). ## Provenance diff --git a/skills/parallel-delegate-shared-files/SKILL.md b/skills/parallel-delegate-shared-files/SKILL.md new file mode 100644 index 0000000..7c4d848 --- /dev/null +++ b/skills/parallel-delegate-shared-files/SKILL.md @@ -0,0 +1,92 @@ +--- +name: parallel-delegate-shared-files +description: Use when briefing 2+ delegates to work in parallel on the same plugin/theme/module. Never have them edit one shared bootstrap file -- design for self-registration instead. +license: MIT +source: original, from a real incident on the iWP Cache build (CloudHost/iWP-Cache) +--- + +# Parallel Delegates and Shared Files + +**Running delegates in parallel is fine. Having them edit the same file in +parallel is not.** If two delegates (agy, kimi, vibe, a Claude subagent, +codex -- any combination) each read-modify-write the same file at +overlapping times, one edit silently wins and the other is lost. No error, +no conflict marker, no delegate-side signal that anything went wrong -- +both will self-report success, because from each one's point of view its +own write did land. + +## The incident + +Building `iWP Cache`, the plan called for a shared `iwp-cache.php` bootstrap +that each module (minify, db-cleanup, cdn, lazyload, preload, invalidation) +would wire into via its own `require_once` + `new IWP_Cache_X()` line inside +the shared constructor, added by whichever delegate built that module. +Two different delegates' edits to that same block landed close enough +together that one was clobbered -- confirmed by session Claude's own +re-read of the file after both delegates reported success, not by either +delegate noticing anything wrong. It then happened a second time to a +different module. Both times the result was dead code: a fully-built, +individually-correct module class that was simply never instantiated, +because the line wiring it in had been overwritten. + +## The fix: self-registering modules, not a shared wiring file + +Each module file registers itself at the bottom of its own file: + +```php +add_action('plugins_loaded', function () { + new IWP_Cache_ModuleName(); +}); +``` + +The bootstrap file never lists individual modules. It either requires a +fixed set of foundation files that never grow (config/engine/core -- built +once, by one person, not touched again) plus an auto-glob for everything +else: + +```php +foreach (glob(IWP_CACHE_PATH . 'includes/class-iwp-cache-*.php') as $file) { + if (!in_array(basename($file), $foundation_files, true)) { + require_once $file; + } +} +``` + +With this shape, a new delegate adding a new module touches exactly one +file -- their own -- and nothing else. There is no shared line for two +delegates to race on, so there is nothing to lose. + +## When briefing delegates under this pattern + +Tell each delegate explicitly: +- "Your module is self-contained in `includes/class-iwp-cache-yourmodule.php`. + Do not edit the main plugin bootstrap file. Register your class with + `add_action('plugins_loaded', ...)` at the bottom of your own file." +- If a module genuinely needs to be wired into a *different* shared + resource (an admin menu, a settings schema) that can't be glob-discovered, + that wiring is session Claude's job to add after all delegates finish -- + not something to hand to whichever delegate gets there first. + +## Verify it actually worked + +Self-registration removes the race, but still verify after the fact -- +per [[verification-before-completion]]. After all delegates report done: + +```bash +grep -rn "new IWP_Cache_" includes/ *.php +``` + +Confirm every module class is instantiated exactly once (watch for the +inverse bug: a leftover direct `new X()` call in the old shared +constructor that an auto-merge or a stale delegate edit restored, +double-instantiating a class that also self-registers -- this happened +once too, caught by re-reading the bootstrap file before declaring the +refactor done, not by trusting the diff summary). + +## General rule beyond this one plugin + +Any time 2+ delegates are briefed to work in parallel on the same +codebase, ask first: do any of their file sets overlap? If yes, either +serialize those specific delegates (not the whole batch -- just the ones +touching the shared file), or restructure the work so the shared surface +is auto-discovered rather than hand-edited by each contributor.