PRISM

Sessions/2026-06-19-petsmart-pipeline-codification-log.md

PetSmart Audit — Pipeline Codification Log (2026-06-19)

Purpose: Run the full Algolia Search Audit for PetSmart ONCE, manually orchestrated, capturing every step + decision + gotcha so the flow can be codified into a repeatable PRISM pipeline. End-goal product: a living interactive prospect-research dashboard with an embedded Athena chat (see memory prism-vision-living-deliverable). This log is append-only; updated at each wave.

Roles / architecture being validated (the "hybrid, full-dispatcher" model)

  • Athena (Hermes default profile) = ORCHESTRATOR. Devises strategy, creates/advances tasks on a Kanban board, reviews wave outputs, synthesizes. Confirmed she can drive the board with her own kanban tools.
  • Claude harness (this session) = EXECUTOR (prism-exec). Claims board tasks, runs the real algolia-* skills with the MCP tools, writes scratchpads/deliverables, posts results back to the board over SSH. The tools + 22 skills live HERE, not on Hermes — that constraint is load-bearing.
  • Bridge = the Hermes Kanban board (petsmart board, created this run). Athena owns it; prism-exec executes against it.

Environment / inventory (as-found)

  • Skills: 22 algolia-* at ~/.claude/skills/ (orchestrator algolia-search-audit + AGENT-CONTEXT.md = the contract). Sub-skill pattern: orchestrator spawns an isolated agent that calls the Skill tool, then a verification gate.
  • Audit home (CORRECT): /Users/arijitchowdhury/AI-Development/Algolia Search Audit (per Arijit). NOT the Google Drive path in AGENT-CONTEXT (empty/unmaterialized), NOT Dropbox.
  • Reference audits (quality bar): HomeDepot-Mexico (full set), plus Nike/Dell/DSW/etc. SPA deck screenshots: ~/AI-Development/PIP/docs/SPA-screenshots.
  • PRISM platform repo: ~/Dropbox/AI-Development/PIP (Python prism_platform/ + frontend/). Vercel hub: GitHub arijitchowdhury80/algolia-arian-v2 → auto-deploys; gallery via generate-index.ts; publish via publish-audit.sh.
  • Tooling present: deno, node, python3, vercel CLI, Chrome MCP, BuiltWith MCP, Apify MCP, Yahoo Finance MCP, Crossbeam MCP. MISSING: SimilarWeb MCP; Playwright (py) not importable; Scout (localhost:8421) down.

Pipeline as executed

  • Intake → understanding: read PRISM vault + PIP + AGENT-CONTEXT + HDM reference + 22 skills (a reading workflow produced the DAG: Wave0 gate → Wave1 parallel intel → Wave2 queries → Wave3 browser → Wave4 report → Wave5 synthesis → Wave6 factcheck/eval).
  • Athena kickoff directive: PE/EBITDA framing for BC Partners; species-specific search pathing (dog/cat/fish/reptile…); Chewy head-to-head benchmark + a named "what Chewy's search does that yours doesn't" slide; sequencing rule = competitor-intel before test-queries.
  • Wave 0 (company-context): PASSED. PetSmart confirmed PRIVATE (BC Partners ~$8.7B LBO 2015), no ticker; Chewy (CHWY) correctly kept separate. Buyer map: Ken Hicks (CEO), Greg Fancher (CITO = technical buyer), Jesica Duarte (CCO = economic buyer). Competitors: Petco, Chewy, Amazon, Walmart, Tractor Supply.
  • Wave 1 (10 parallel intel modules): complete; 11 research scratchpads consolidated. HEADLINE REFRAME: PetSmart is an EXISTING Algolia customer → this is an EXPANSION audit, not displacement/greenfield. Evidence: live petsmart.com/search payload exposes Algolia index p-US_products + queryID + Algolia-only fields; algolia.io in CSP; public algolia.com/customers/PetSmart case study. Stack: SFCC/Demandware + headless Next.js on Vercel + Contentful; Akamai Bot Manager (browser wave needs stealth); fragmented personalization (Granify + SFCC Einstein + Algolia) = consolidation angle. Revenue ~$9.8B (private, triangulated), digital ~$0.9–1B, EBITDA amber ~5–8%. Mobile-discovery vs desktop-purchase split.

GOTCHAS / lessons for PRISM codification (the gold)

  1. PATH NONDETERMINISM (critical). Wave-1 agents scattered outputs across THREE trees: ~/AI-Development/... (correct), ~/AI-Development-OLD/... (stale sibling — separate real dir, not a symlink), and ~/Dropbox/.../PIP/TEMP/audits/... (old). Cause: ALGOLIA_AUDIT_DIR doesn't survive across an agent's separate Bash calls (shell state doesn't persist) and skills have multiple fallback path behaviors. PRISM fix: a single, deterministic, injected workspace path — no env-var/cwd fallbacks; every module writes via one resolved root.
  2. Tool-key/availability fragility. BuiltWith API key unset (worked via MCP + hardcoded fallback); SimilarWeb absent → traffic ran degraded on public-page estimates; Scout down → WebSearch fallback; chrome-devtools MCP locked to a running profile. PRISM fix: a tool-capability preflight that declares per-module degraded modes up front.
  3. Algolia-detection must NOT auto-abort. The techstack module's default "Algolia detected → ABORT" logic was correctly overridden by existing-customer handling → reclassify EXPANSION + continue. PRISM fix: first-class audit-type branch (displacement | expansion | greenfield) set at Wave 0/1, threaded to report + business case.
  4. Athena CAN drive Kanban directly (created a task with her own tools) — the dispatcher won't auto-spawn a non-profile assignee (prism-exec), so external-executor tasks sit ready until claimed over SSH. Good bridge pattern.
  5. Sub-skill via isolated Agent + Skill tool + verification gate works reliably (Wave 0 proved it; agentType general-purpose has the Skill tool).

End-product vision (what we're building)

New company → Hermes/Athena orchestrates → Claude/executor runs pipeline → output = functional dashboard + embedded Athena chat for AE/BDR to interrogate the prospect interactively. PRISM platform hosts it. This run = the reference to codify.

Open codification questions

  • How much of Athena's orchestration becomes deterministic code vs. agent judgment?
  • Where do degraded-tool fallbacks get standardized?
  • Dashboard/chat: served from PRISM platform (FastAPI + frontend) consuming {slug}-audit-data.json? Chat = a scoped Athena bound to that audit's data.

Wave 2 — test-queries (DONE, clean)

  • prism-exec ran algolia-intel-queries05-test-queries.md (19 queries, 17.9KB). Path discipline HELD — zero stray files. The explicit single-path instruction + AGENT-CONTEXT warning fixed the scatter → validates PRISM lesson #1 (deterministic injected path) as the right design.
  • Built to Athena's expansion spec: species forks (dog/cat/fish/reptile/bird/equine) as the spine, NeuralSearch long-tail, Recommend cross-sell, AI-personalization re-ranking (anon vs dog-browsed session), 9 Chewy head-to-head queries, typos from real traffic keywords, + a 2c–2q browser-audit mapping table.

Dispatcher loop — VALIDATED

  • Full Athena → board → prism-exec → board → Athena loop works end-to-end: Athena (Hermes), with her own kanban tools, created the W1 task, closed it with a comment + marked done, re-steered strategy on the EXPANSION reframe, and opened W2. prism-exec (Claude) executed and posted back.
  • Key insight for codification: Athena's re-steer materially improved the audit (displacement → consolidation thesis). Orchestrator judgment at wave boundaries is high-value, not ceremony — keep a human/agent decision gate between waves in PRISM, don't fully auto-chain.

Wave 3 — live browser audit (DONE; high integrity)

  • prism-exec ran the browser audit; stealth (patchright + stealth plugin) fully bypassed PetSmart's Akamai Bot Manager — 25 real PetSmart screenshots (145KB–906KB, zero WAF blanks), 33 PNGs total.
  • Bonus intel: live network capture pulled PetSmart's Algolia App ID 97P6EWKR25, JS client v4.24.0, 3 live indices (p-US_products, _query_suggestions, _best-sellers) → appended to 02-tech-stack. (AE can verify the exact account.)
  • 5 findings (3 HIGH / 2 MEDIUM), expansion-framed: F1 NeuralSearch dead-ends (all 3 conversational queries → 0 results), F2 AI-Personalization inert (anon vs dog-session pixel-identical, userToken unused for re-ranking → personalization runs off-Algolia), F4 zero-results dead-end, F5 services/federation siloed. Strengths to DEFEND: SAYT, typo tolerance, synonyms, species faceting, Insights/Click Analytics.
  • Chewy head-to-head HONESTLY blocked: Chewy returned HTTP 429 to all automation → c00–c07 are block pages, NOT results; agent asserted nothing from them. Flagged: manual/residential-proxy Chewy run before AE call. (Integrity > fabrication — correct call, and a key product rule.)
  • Codification gotchas: shared audit-browser.js uses hardcoded generic queries — can't do species forks / session re-runs / Chewy / Algolia-payload capture → agent wrote company-specific PetSmart/scripts/petsmart-expansion-audit.js. Company scripts need NODE_PATH→skill node_modules. Chewy needs non-headless / residential proxy. macOS lacks timeout. → PRISM: per-company audit scripts as a first-class concept + a real competitor anti-bot strategy.

Pipeline ENHANCEMENT discovered mid-run — Usage/Consumption API (existing-customer audits)

  • For an EXISTING Algolia customer, the Algolia Usage REST API (GET https://usage.algolia.com/1/usage/{statistic}/period/{period}, headers X-Algolia-Application-Id + a usage-scoped API key) returns up to 12 months of real consumption: total_search_operations, records, etc. (period/year returns 365 daily points.)
  • PetSmart pull: ~10.69B search ops trailing-12mo; ~395K records; Black Friday peak 70M ops/day (2025-11-28); a sustained ~45% step-down since ~2026-03-27 (run-rate ~11B→~5.5B annualized). See research/12-usage-consumption.md.
  • Why it matters: sizes the opportunity at real scale (turns "NeuralSearch is off" into "off across billions of searches") and surfaces a dated urgency signal (the step-down). HIGH value for the expansion branch + the ROI business case.
  • Codification rules: (1) make Usage-API pull a first-class step in the EXPANSION audit branch; (2) the usage key is a SECRET — handle transiently, NEVER persist to workspace / sub-agent prompts (their transcripts persist) / memory. Here it was used solo in the main session only, never passed to a sub-agent, and only derived numbers were written. (3) needs the customer App ID + a usage-scoped key (AE-obtainable). Don't expose the raw account telemetry source verbatim in prospect-facing deliverables.

Pipeline ENHANCEMENT #2 — Analytics API (existing-customer audits) = the killer data layer

  • Algolia Analytics REST API (https://analytics.algolia.com/2/..., headers App-Id + analytics-scoped key, REQUIRES index param) gives the prospect's REAL search performance. Endpoints used: /2/searches/noResultRate, /2/searches/noResults, /2/searches, /2/clicks/clickThroughRate, /2/conversions/conversionRate, /2/clicks/averageClickPosition, /2/searches/noClicks, /2/filters.
  • PetSmart (30d, p-US_products): no-results 15.98% (~1 in 6, ~100M/yr), CTR 10.98%, avg click position 13.1, CVR 4.41%. Real zero-result queries (organic dog food, orijen, dr marty, gift card) and a hero no-click (good dog food brands → 1,552 results, 0 clicks). See research/13-search-analytics.md.
  • This is the differentiator: the audit critiques with the prospect's OWN telemetry, not inference. Turns every browser finding (F1/F2/F4) into a data-backed claim with volume.
  • NEW DELIVERABLE ELEMENT (per Arijit, anticipated): a "Your Search, By the Numbers" deck section/tab — metric tiles (no-results %, CTR, avg click position, CVR) + real zero-result & no-click query tables. → PRISM should add a search_analytics block to audit-data.json schema + a render section (schema → render fn → CSS → register).
  • Codification rules (same as Usage API): analytics key is a SECRET — transient, never persisted / never to sub-agents; needs customer App-Id + analytics-scoped key + the index name. First-class step in the EXPANSION branch.

NEW AUDIT ARCHETYPE discovered — "Existing-Customer, Data-Driven, Value-Realization" audit

PetSmart proved a distinct archetype that PRISM must support as a first-class branch, separate from the default displacement audit. When the prospect is an EXISTING Algolia customer AND we can pull Usage + Analytics APIs, the whole deliverable changes: - Positioning flips: displacement → value-realization / expansion / NRR + renewal protection. "Activate, don't migrate." - Angle library (data-grounded, reusable): 1. "Your own data indicts the gap" — lead with the prospect's real no-results %, CTR, avg click position, hero no-click query. Unarguable; beats any inference-only audit. 2. "Activate, don't migrate" — every fix is config + indexing on the live App ID (NeuralSearch, Re-Ranking, Personalization, Query Suggestions). Fastest TTV, no replatform. 3. "Paying for the engine, using half of it" — value-leak / renewal-protection frame for the CITO + the AE. 4. "The decline is the urgency" — the search-ops step-down (here ~45% since Mar 2026) as a dated hook. 5. "Re-aim the competition" — not Algolia vs other search vendors; it's the customer + Algolia vs Amazon Rufus / Walmart GenAI. Defend with the AI they already own. 6. "ROI on real volume" — size on actual searches/yr × real no-results × real CVR × AOV, not benchmark uplift %. - New deck elements: "Your Search, By the Numbers" (real metric tiles + zero-result/no-click query tables); feature-activation roadmap (replaces migration plan); search-volume trend/decline chart; recoverable-revenue-from-no-results table. - Codification: PRISM should detect audit-type at Wave 1 (algolia_detected → expansion branch) and route to this archetype's template, angle library, scoring philosophy (expansion-ROI, not "broken"), and the Usage/Analytics data pulls. The golden first-party data is the moat — it's what makes the deliverable "VERY unique" and worth paying for (Arijit, 2026-06-19).

Wave 4 — report + SPA (DONE, clean)

  • algolia-audit-report produced: petsmart-audit-data.json (valid, score 5.8 "Strong Foundation, Unactivated Upside", 5 findings), index.html SPA (rendered via render-audit.ts; brand-CSS injected ×2, 0 unreplaced tokens, window.AUDIT_DATA present — render contract held), ae-report/battle-card/leave-behind HTML, petsmart-book.html (1.28MB binder), strategic-signal-brief. Path discipline held (no strays).
  • Scoring landed exactly on the expansion-ROI lens: strengths 8–9 (latency, typo, intent, merchandising, search-intelligence), gaps 3–5 (semantic/NLP=3 F1, query-suggestions=4 F4, personalization=5 F2, recommendations=5 F3, content-UX=5 F5).
  • Real telemetry folded into the deck (findings impact_stats, score narrative, signals, snapshot): 15.98% no-results, click position 13.1, "good dog food brands" 1,552 results/0 clicks, the ~45% March step-down — framed discreetly as "your Algolia analytics."
  • CODIFICATION BUGS for PRISM: (1) generate-audit-data.py calls .get() on outgoing_traffic which is a LIST in canonical schema → crash; agent worked around by authoring fields directly + validating. Fix the patcher's list/dict guard. (2) generate-pdf.sh/wkhtmltopdf availability unverified in sandbox — book.html used instead of PDF. (3) clearbit logo DNS blocked in sandbox → DuckDuckGo fallback (cosmetic).

Wave 5 — LAUNCHED (background workflow woacx0igf)

  • Sequential: business-case → sales-plays → ABX, grounded in golden data + the 6-angle expansion library. Running through the persist/compaction; check result on resume.

Wave 4b — "Your Search, By the Numbers" deck section (DONE — first-class archetype element)

  • Built the new analytics section as a proper PRISM platform change, per AGENT-CONTEXT §9 (schema → render fn → CSS → register → render), NOT a hand-edit of index.html: 1. Schema: added SearchAnalytics/SearchAnalyticsMetric/SearchAnalyticsQuery Pydantic models (Optional, extra:allow) to scripts/audit_data_schema.py + a search_analytics property to templates/audit-data.schema.json. Backward-compatible (other audits omit the key → no effect). 2. Data: search_analytics block in petsmart-audit-data.json (window, source_label, index, 4 metrics w/ severity, volume, 8 zero-result + 4 no-click query rows) — sourced from research/13. 3. Render fn: renderSearchByNumbers() added to templates/index-template.html (client-side; reads D.search_analytics; gated — early-returns when absent so displacement/greenfield audits skip it; section display:none until populated). Reuses existing CSS-var conventions; no raw font-size/hex (style-token gate passed). 4. Verified: brand CSS ×2, 0 unreplaced tokens, runtime-tested in a faithful Node vm DOM (4 tiles, trend note, query tables, comma-formatted volumes; whole boot runs without throwing).
  • Codification: search_analytics is now the canonical block for the existing-customer/value-realization archetype. PRISM detects algolia_detected → expansion branch → pull Usage+Analytics → emit search_analytics → SPA auto-renders the section.

Wave 5 — synthesis (DONE)

  • business-case.md (PE/board-grade, 3 telemetry-grounded components → $60–71M cons. / $146–173M mod., 76–177x, payback <1 quarter), playbook.md (AE/BDR, "activate don't migrate", MEDDPICC, 5 talking points each w/ verbatim exec quote), abx-campaign/ (5 emails + LinkedIn + Loom + collateral schedule, 9 touches in abx_sequence).
  • GOTCHA — concurrent workflows: the prior session's Wave 5 background workflow (woacx0igf) was STILL ALIVE (survives /clear, not just /compact) and completed alongside the new Wave 5b (whca553oe). Both wrote the same files. They converged cleanly because the agents verified-rather-than-clobbered (read inputs → ran the skill's verification gate → confirmed the existing passing artifact instead of regenerating). JSON stayed valid. PRISM rule: before relaunching a "likely-dead" background workflow, check for the original still running (TaskList / notifications); design skill agents to verify-then-skip on an already-passing artifact.

Wave 6 — quality gates (DONE)

  • Factcheck: ACTION PROCEED, 9.2/HIGH, 0 blocking, 0 fabrications. All 6 Algolia case-study URLs WebFetch-verified live. search_analytics byte-identical across deck/business-case/playbook/signal-brief/research. Scoring math verified (40.5/7.0 = 5.8).
  • Eval: 10.0/10 PASS (all 5 dims 2.0). Source density ~10× the bar (144 research URLs).
  • Polish fixes applied from the warnings: removed now-stale [UNVERIFIED] tags (all URLs verified); corrected personalization-lift attribution to BCG (2017) alone (was "Econsultancy/Google Cloud/BCG"); relabeled F01/F02/F03 impact_stat_source from the marketing case-study page to "PetSmart Algolia search analytics (30-day window)" (honest provenance for dashboard-derived numbers); aligned ~99M→~100M rounding.

ROI reconciliation (DECISION — Arijit, 2026-06-19)

  • Deck originally showed a conservative blended-conversion ladder ($6.8M/$13.5M/$27M+); business-case decomposed to $60–71M/$146–173M (~9× higher). Arijit chose: align the deck UP to the decomposed bands. Updated all 8 ROI surfaces in audit-data.json (roi_scenarios + KPI fields conservative_lift_label/search_roi_est/roi_multiple/payback + secondary ladder + precall headline) to $60–71M cons. / $146–173M mod. / $173M+ opt., ~76–177x, payback <1 quarter. The ABX email to Duarte (which already framed $6.8M as "one component / the floor" then stacked to $60–71M) was left intact — it was already coherent. Re-rendered SPA + all 3 AE docs from the corrected JSON so the whole set tells one story.

Vercel publish (DONE — surgical)

  • Hub ~/algolia-arian-v2 has untracked WIP for ~8 other companies → manual surgical publish, never git add -A. Mirrored the homedepot-mexico/ layout: petsmart/{index.html, ae-report.html, battle-card.html, leave-behind.html, screenshots/×33} + top-level + in-dir petsmart-audit-data.json. Staged ONLY petsmart paths (safety-checked: 0 non-petsmart staged), committed (Opus 4.8 co-author), pushed to main → Vercel auto-deploys algolia-arian-v2.vercel.app/petsmart/.
  • GOTCHA — publish-audit.sh layout mismatch: the script expects $CWD/$SLUG/index.html, but the contract (AGENT-CONTEXT §7) + actual layout is deliverables/index.html (slug once). Did the copy/stage/push manually instead.
  • GOTCHA — SPA bare-token bug (caught post-publish, fixed): index-template.html used bare COMPANY_NAME/AUDIT_DATE in the <title> + topbar, but render-audit.ts's replaceTokens only substitutes {{...}} → the published deck title/topbar showed literal "COMPANY_NAME". Client JS never set them either. Fixed at source: braced the 3 chrome tokens in the template; re-rendered + re-pushed. PRISM rule: SPA chrome tokens MUST be {{braced}}; the render verification should grep the rendered <title> for literal ALL-CAPS tokens (current checkUnreplacedTokens only catches {{...}}, so bare tokens fail-open).
  • GOTCHA — render gates fail-open from non-scripts cwd: running render-audit.ts with cwd=deliverables makes the style + JSON-schema gate subprocesses report "not found" and skip (they can't import audit_data_schema without scripts on PYTHONPATH). Ran both gates manually before trusting the render. PRISM: fix the subprocess cwd/PYTHONPATH or run gates explicitly.

Athena final synthesis + board close (DONE — dispatcher loop validated end-to-end)

  • Athena (Hermes default) delivered a CEO-level executive verdict (saved to deliverables/athena-executive-verdict.md) and closed all 4 petsmart-board tasks (t_7c4f3924 W1, t_23278698 W2, t_ee7ac11e W3, t_b94ac894 W4) → board complete. The full Athena↔board↔prism-exec hybrid dispatcher loop is now validated across a complete audit.

FINAL STATE

PetSmart expansion audit COMPLETE & PUBLISHED. Score 5.8, factcheck PROCEED 9.2, eval 10.0. The existing-customer/value-realization archetype is proven AND codified into the schema + renderer (search_analytics block + By-the-Numbers section). Outstanding (flagged, non-blocking): Chewy head-to-head still HTTP-429 blocked (needs residential proxy before the AE call); gallery index.html not regenerated (deck is live at the direct /petsmart/ route).

⚠️ CRITICAL CORRECTION — wrong SPA template shipped, then fixed + skill restored (2026-06-19, later)

  • Defect: the entire deck (Waves 4–6 + first publish) was rendered from the skill's index-template.html, which had silently regressed to a stripped-down role-tab template (~170KB, AE/BDR/Sales-Leader) instead of the rich renderSections design (~500-660KB, glow/bounce/proof-pill, tabbed McKinsey deck) that all 15 other shipped audits use. PetSmart was the only simple one of 16.
  • Why it slipped through (root cause): the render verification only checks injection (grep "Algolia Brand CSS" ≥1, 0 unreplaced {{tokens}}) — both PASS on a regressed template. SESSION.md/this log therefore claimed "render contract held." I trusted that and published. A passing token-gate says nothing about design correctness. → New rule (memory verify-rendered-output-vs-reference): diff rendered output against a known-good reference (grep -c renderSections, size, nav structure) or screenshot it; never trust a prior "verified" note for presentation.
  • Deeper root cause: the skill's RICH index-template.html had been overwritten by the simple stub at some point and is not git-tracked — no history to restore from. render-audit.ts site (the official path, per algolia-audit-report SKILL.md) therefore produced simple output. The rich renderSections source survived ONLY inside the 15 compiled audit HTML files + the PIP Reference-DSW-Audit-Report.html.
  • Fix (deck): rebuilt PetSmart's deck by grafting its data onto a shipped rich shell (nike donor), scrubbed donor-company literals (107.6M/$9.6B/Nike.com/Nike 10-K/competitor fallback), verified headless across all 5 tabs (0 JS errors, 0 donor leakage, PetSmart ×73, 15.98%/good-dog-food/$60-71M present, Amazon competitor). Published live, then re-rendered via the official pipeline once the template was restored, so the live deck is reproducible.
  • Fix (skill — root cause): reconstructed a company-neutral rich index-template.html from the nike compiled output (stripped the embedded window.AUDIT_DATA<!-- AUDIT_DATA_PLACEHOLDER -->, stripped the injected brand-CSS block so the renderer re-injects it, genericized all hardcoded company literals). Installed it (simple stub backed up to templates/index-template.simple.bak.html) and verified render-audit.ts petsmart site now emits the rich design (renderSections ✓, 5 tabs ✓, 0 leakage ✓, 0 JS errors ✓). Future audits render rich again.
  • Process gotchas: (1) PetSmart was never rich even in Wave 4 (original index.html was 156KB = simple) — the regression predates this session; the prior session made the same mistake and recorded it as success. (2) Bash heredoc $ expansion bug: use <<'PY' (quoted) for any inline Python containing $ literals ($110, $9.6B) — an unquoted <<PY let the shell mangle the scrub strings.

Pipeline run complete 2026-06-19; deck-template defect found + corrected + skill restored same day. This log is the reference for codifying the expansion-audit branch into PRISM — including the rule that the rich SPA template must be design-verified, not just token-verified.