feat(deco): add cacheable-matchers skill#13
Conversation
Deep-dive skill for making deco storefront pages with matcher blocks (A/B tests, date windows, sticky segments) cacheable at the CDN edge. Companions the existing 'cache' skill which gives a broad three-layer overview. This one focuses specifically on the matcher-aware page cache decision shipped in deco@1.201.0 + apps@0.154.0, and the five gotchas a site author has to navigate to get a matcher-wrapped page to actually emit Cache-Control: public: 1. Site loaders default to cache: "no-store" 2. Custom matchers default cacheable to undefined (strict === true check) 3. cacheKey defaults to () => "" — silent correctness bug for prop-varying loaders 4. Foreign Set-Cookies kill caching (framework cookies are exempt) 5. Personalizing loaders called from Header/Footer disqualify every page Includes a 6-step diagnostic checklist, reference list of cacheable vs non-cacheable matchers in apps@0.154.0, and an agent workflow for applying the fixes in priority order. Based on the rollout against Lojas Torra (lojastorra-2) which took the site from 0% PDP HIT rate to active edge caching with measurable origin-side cost reduction (CPU −43%, egress −14% from baseline). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 1 file
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Updates from the Lojas Torra full rollout this morning: - Bumped minimum deco version 1.201.0 → 1.201.2 and added a version-history table explaining what each bump shipped (the framework cookie-aware decision, the inline-cookie script, the Set-Cookie strip). - Updated "How the framework decides cacheability" to show the final 1.201.2 response shape — no Set-Cookie for framework cookies, inline document.cookie script in body. Documents the JS-dependent stickiness trade-off explicitly. - Refined Gotcha #2 (custom matcher cacheable) with a per-matcher-type decision table, plus a real-world site-matcher audit example from Torra (canonical, multipleCanonical, hasKitlook, hasProduct marked safe; utm NOT marked because the CDN strips utm params from cache key — collision risk). - Added a new section: "The cold-visitor bias" — explains what visitors see when sticky-session matchers are marked cacheable (every cold visitor in a 5-min cache window sees the same variant), when this matters (concentrated traffic, content-different tests), and rule-of-thumb / mitigations. - Added a diagnostic-checklist step for the catch-all `/*` page trap — Torra hit this exact pattern (PLPs without their own page JSON went no-store because `pages-category-*.json` used a non-cacheable matcher). - Refined the diagnostic checklist for 1.201.2: look for the inline cookie script in HTML body, expect Set-Cookie for framework cookies to be absent. - Added an "agent workflow" step #8 explicitly calling out the cold-visitor bias acceptance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".claude-deco/skills/cacheable-matchers/SKILL.md">
<violation number="1" location=".claude-deco/skills/cacheable-matchers/SKILL.md:265">
P2: Regex too strict for matcher cookie name. It can miss valid `deco_matcher_*` cookies and mislead diagnosis. Relax matcher-name match.</violation>
<violation number="2" location=".claude-deco/skills/cacheable-matchers/SKILL.md:324">
P3: Header-only curl here. Next line asks to check HTML body script. Use a command that actually fetches body.</violation>
<violation number="3" location=".claude-deco/skills/cacheable-matchers/SKILL.md:407">
P3: Cookie-name example conflicts with earlier format. Keep one matcher key format to avoid debugging wrong header shape.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| UA="Mozilla/5.0 Chrome/126" | ||
| curl -sD /tmp/h -A "$UA" -o /tmp/b "https://your-site.com/your-page/p" | ||
| grep -iE "x-powered-by|cache-control|vary|deco-cache-vary-cookies|^set-cookie" /tmp/h | ||
| grep -oE 'document\.cookie="deco_(matcher_[a-z0-9_]+\.[0-9]+|segment)[^<]{0,180}' /tmp/b | head -3 |
There was a problem hiding this comment.
P2: Regex too strict for matcher cookie name. It can miss valid deco_matcher_* cookies and mislead diagnosis. Relax matcher-name match.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .claude-deco/skills/cacheable-matchers/SKILL.md, line 265:
<comment>Regex too strict for matcher cookie name. It can miss valid `deco_matcher_*` cookies and mislead diagnosis. Relax matcher-name match.</comment>
<file context>
@@ -214,18 +259,28 @@ Work down this list in order. Each step is independent — once you find the cul
+UA="Mozilla/5.0 Chrome/126"
+curl -sD /tmp/h -A "$UA" -o /tmp/b "https://your-site.com/your-page/p"
+grep -iE "x-powered-by|cache-control|vary|deco-cache-vary-cookies|^set-cookie" /tmp/h
+grep -oE 'document\.cookie="deco_(matcher_[a-z0-9_]+\.[0-9]+|segment)[^<]{0,180}' /tmp/b | head -3
</file context>
</details>
```suggestion
grep -oE 'document\.cookie="deco_(matcher_[^=]+|segment)[^<]{0,180}' /tmp/b | head -3
| When the framework emits a cacheable response, it includes: | ||
|
|
||
| ``` | ||
| Deco-Cache-Vary-Cookies: deco_matcher_3425517349_0.5, deco_segment |
There was a problem hiding this comment.
P3: Cookie-name example conflicts with earlier format. Keep one matcher key format to avoid debugging wrong header shape.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .claude-deco/skills/cacheable-matchers/SKILL.md, line 407:
<comment>Cookie-name example conflicts with earlier format. Keep one matcher key format to avoid debugging wrong header shape.</comment>
<file context>
@@ -253,81 +308,128 @@ For each loader, verify `cache` is declared (and not `'no-store'` unless intenti
+When the framework emits a cacheable response, it includes:
+
+```
+Deco-Cache-Vary-Cookies: deco_matcher_3425517349_0.5, deco_segment
+```
+
</file context>
| Deco-Cache-Vary-Cookies: deco_matcher_3425517349_0.5, deco_segment | |
| Deco-Cache-Vary-Cookies: deco_matcher_<hash>, deco_segment |
| ### 6. Try with no cookies (cold visitor) | ||
|
|
||
| ```bash | ||
| curl -sI -A "Mozilla/5.0 Chrome" https://your-site.com/your-page/p |
There was a problem hiding this comment.
P3: Header-only curl here. Next line asks to check HTML body script. Use a command that actually fetches body.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .claude-deco/skills/cacheable-matchers/SKILL.md, line 324:
<comment>Header-only curl here. Next line asks to check HTML body script. Use a command that actually fetches body.</comment>
<file context>
@@ -253,81 +308,128 @@ For each loader, verify `cache` is declared (and not `'no-store'` unless intenti
```bash
-curl -sI -A "Mozilla/5.0 Chrome" https://your-site.com/your-pdp-slug/p
+curl -sI -A "Mozilla/5.0 Chrome" https://your-site.com/your-page/p
</file context>
</details>
Summary
Adds a deep-dive skill for making deco storefront pages with matcher blocks (A/B tests, date windows, sticky segments) cacheable at the CDN edge.
Companions the existing
cacheskill (which gives a broad three-layer overview). This one focuses specifically on the matcher-aware page cache decision shipped indeco@1.201.0+apps@0.154.0, and the five gotchas a site author has to navigate to actually get a matcher-wrapped page to emitCache-Control: public.What's in it
cache: "no-store"(single most common cause of stuck no-store pages)cacheabletoundefined— framework checks strict=== truecacheKeydefaults to() => ""— silent correctness bug for prop-varying loadersdeco_matcher_*/deco_segmentare exempt)apps@0.154.0have / don't havecacheable=trueProvenance
Distilled from the Lojas Torra (
lojastorra-2) rollout that took the site from 0% PDP HIT rate to active edge caching with measurable origin-side cost reduction (CPU −43%, egress −14% vs baseline). The skill captures every gotcha that bit us during that rollout so other sites can skip the hour-by-hour debugging.Scope deliberately excluded
The skill does NOT cover CDN-side configuration (cache rule bodies, custom cache key cookies, edge TTL overrides). That's a deco-internal concern handled separately and the surface area differs per CDN provider. Site authors only need to make their origin emit the right headers; the deco CDN setup takes it from there.
Test plan
1.201.0runtime behavior.apps@0.154.0source.🤖 Generated with Claude Code
Summary by cubic
Adds a new cacheable-matchers skill to make matcher-based pages cacheable at the CDN edge. Updated for
deco@1.201.2+apps@0.154.0with cookie handling changes and a clearer troubleshooting flow.deco@1.201.2and adds a brief version history (cookie-aware decision, inline cookie script, Set-Cookie strip).Set-Cookie, inlinedocument.cookie,Deco-Cache-Vary-Cookies)./*catch-all trap) and adds a section on cold-visitor bias with mitigations and an agent-workflow callout.Written for commit b2c92aa. Summary will update on new commits. Review in cubic