name: pianeta-web-moat-extension description: Estensione del MOAT del Pianeta Web oltre il ristorante. Ricognizione reale (codice + DB prod), critical path corretto, piano PR atomiche P0-P3. Il sito generato e il prodotto, la qualita e il moat. last_update: 2026-06-05 owner: gregorio + claude status: P0 in esecuzione (sequenza raccomandata confermata dal founder 2026-06-05)
Pianeta Web · Estensione del MOAT oltre il ristorante
SSoT della decisione "come ogni sito generato diventa il migliore del suo settore". Correlati: skill
multiverbe-sector-onboarding+multiverbe-design-system·pianeta-web-compliance-2026-06-03.md(layer legale, gia in prod) · codicefrontend/multiverbe-app/src/lib/site-design/+sites-runtime/.
0. TL;DR
Una review adversariale aveva indicato il gap #1: "esiste una sola costituzione di design (restaurant)". La ricognizione reale su codice + DB di produzione ha trovato due buchi piu profondi:
- In produzione il generatore non produce NESSUN sito. Le uniche 2 righe in
site_constitutions(restaurant,hair-salon) sono letteralmente{"placeholder": true, "pending_review": true}eactive=false. La gold-standardrestaurant.ts(1640 righe) vive nel codice ma non e mai stata seedata in prod (migration2026-05-15gnon applicata). Il worker richiedeactive=true-> oggi ogni generazione muore conconstitution_not_found. - Il contratto
section_typee fratturato tra le due app. La pipeline persiste nomi lunghi (menu-showcase,booking-widget,contact-location,social-proof,about-story,private-events); la sites-runtime (renderer + schema.org SEO) si aspetta nomi corti (menu,booking,contact). Nessun mapping in mezzo. Anche seedando il ristorante, oggi renderizzerebbe solohero+gallery; tutto il resto ->return nullsilenzioso. Mai emerso perche un sito reale non e mai stato renderizzato.
Conseguenza strategica: "costituzioni prima" e l'ordine sbagliato. Una costituzione e dati inerti finche le sue sezioni non hanno schema Zod + prompt builder (app generatore) e un componente React (sites-runtime). Prima il contratto + la section library (codice), poi le costituzioni (dati).
1. Architettura attuale (data vs codice)
Tre strati che devono parlarsi, su due app separate (frontend/multiverbe-app Vite + sites-runtime Next.js 16):
| Strato | Dove | Natura |
|---|---|---|
| Costituzione di settore | site_constitutions (jsonb DB), autorata in TS src/lib/site-design/constitutions/*.ts |
DATI |
| Orchestratore 6-stage | src/lib/site-design/ai-pipeline/orchestrator.ts + Zod prompts/output-schemas/* + prompt prompts/by-section/* |
CODICE |
| Section Library (render) | sites-runtime/components/sections/index.tsx + lib/seo/structured-data.ts |
CODICE |
Pipeline: Stage 1 Brand Strategist -> 2 Art Director (sceglie sezioni+variant per pagina) -> 3 Copywriter (per sezione x locale, Kimi+QA Sonnet) -> 4 Visual Director (immagini) -> 5 CRO Auditor -> 6 Senior Reviewer (gate >=85, max 3 retry). Checkpoint su ai_generation_jobs. Cost-cap tier-aware. Il tipo SectorConstitutionEnriched (types.ts) e gia ricchissimo: multi-pagina, multi-locale (it/de/fr/en), moodSpecs, designDirectorBriefing, sectionRecipeEnriched (micro-interazioni + a11y + graceful degradation), localCROAdjustments CH, performance budget per device, A/B presets, seasonal rules.
Famiglie di sezione implementate oggi nella runtime: hero, menu, booking, gallery, contact, legal (6). Schemi+prompt nella pipeline: hero, menu, booking, gallery, social-proof, contact-location, about-story, private-events (8 — ma social-proof/about-story/private-events NON hanno renderer). I variantId combaciano gia tra le due app (es. menu-scroll-spy, contact-map-side): e solo la chiave-famiglia ad essere disallineata.
2. Critical path corretto · piano PR atomiche
P0 — Fondamenta: 1 settore vivo end-to-end (in corso)
- PR1 — Riconciliazione contratto
section_type(root-cause). SSoT unica family-resolver in sites-runtime, consumata daindex.tsx(renderer) +structured-data.ts(SEO). Accetta i nomi canonici lunghi effettivamente persistiti. Esito: menu/booking/contact tornano a renderizzare. Test. CI verde. - PR2 — 3 renderer mancanti (
social-proof,about-story,private-events): solo i componenti React (schema+prompt esistono gia). Osservatorio tokens, a11y AA, prefers-reduced-motion, i18n-ready, tabular-nums. Esito: il ristorante renderizza tutte le 8 famiglie del suo recipe. - PR3 — Seed + attiva la gold-standard
restaurant. Rigenera la migration darestaurant.ts, applica a prod. L'attivazione (active=true) e una scrittura su DB prod -> conferma founder (postura prodotto, reversibile = due costanti come i flag legali). - VERIFY adversariale: un sito ristorante reale renderizza tutte le sezioni, schema.org corretto, a11y AA, mobile, 4 lingue. Bar "agenzia $5-15k vs template".
P1 — Section library sector-neutral (il vero codice del moat)
Vertical slice completi (Zod schema upstream + prompt builder + content-type mirror runtime + componente + a11y AA/i18n/reduced-motion), 1 PR ciascuno:
services-pricing— lista servizi + prezzo (il #1 per parrucchiere/gym/studio pro).team— stylist / trainer / professionisti (foto, ruolo, bio breve).testimonials— recensioni clienti (distinto dalsocial-proofGoogle-live; riusa dove possibile).faq— domande frequenti (accordion accessibile + schema.org FAQPage).booking adattivo— oggi il booking hacoperti/partycablati al ristorante; serve un adattatore per modalita tavolo / appuntamento / corso-trial.
P2 — Costituzioni nuove (dati, sul gold-standard)
hair-salon (gia riga stub) -> gym -> studio-professionale. Ognuna SectorConstitutionEnriched modellata su restaurant.ts, seedata + attivata. Verifica adversariale per ciascuna.
P3 — Scoping onboarding
Finche un settore non ha costituzione viva, l'onboarding instrada solo ai settori pronti, con stato onesto "in arrivo" — niente 404, niente ristorante-forzato. Mappa i 28 settori (6 macro, skill onboarding) -> disponibilita costituzione.
3. Tensione col gate (onesta)
Il gate del 15 Giu ha come collo di bottiglia le vendite (0/5 paganti) + l'entita Sagl, non il prodotto. Questo lavoro non sblocca i 5 paganti. Vale la pena ORA solo se il Pianeta Web e parte della demo ("ti generiamo il sito"): in quel caso il fatto che oggi generi zero siti e un buco da chiudere. Decisione founder 2026-06-05: procedere con la sequenza raccomandata, P0 first (artefatto demo-abile il piu presto possibile).
4. Vincoli tecnici (hard)
- Due app.
frontend/multiverbe-app/api/e ESM NodeNext -> import relativi con.jsesplicito (guardscripts/check-api-esm-imports.mjs).sites-runtime= Next.js 16, package separato che mirrora a mano i tipi degli Zod output-schema (non importa la pipeline). - Toolchain locale Windows rotta (pnpm/tsc/vitest): la verita e la CI Linux (push feat/** -> frontend-ci.yml) + Vercel build (sites-runtime). Codice verde al primo giro.
- DB Supabase
yqhixdqipojvgzfadufoeu-central-1, RLS, workspace_id. Schema prod -> chiedi. PII pseudonimizzata prima di Anthropic. - Semgrep ERROR+WARNING bloccante. PR atomiche su branch feat/**, merge
--squash --adminsolo dopo CI verde.
5. Stato esecuzione
P0 codice completo e in master (2026-06-05, 3 PR atomiche, CI sites-runtime verde):
- [x] PR1 contratto
section_type(SSoTsectionFamily) — MERGED #218 - [x] PR2 3 renderer (
social-proof/about/events) — MERGED #220 - [x] PR3 seed
restaurantrigenerato (era stale vs Stream 4) — MERGED #223 - [ ] APPLY seed in prod +
active=true→ azione founder (Dashboard SQL editor: incolladatabase/migrations/2026-05-15g_seed_restaurant_constitution.sql, 66KB; pattern stabilito = Dashboard, non MCP). È il go-live del generatore: da "0 siti producibili" a "ristorante reale generabile". - [ ] VERIFY ristorante end-to-end (dopo l'apply: generazione reale o sito demo seedato → confermare che tutte le 8 famiglie renderizzano)
- [ ] P1 section library (services-pricing, team, testimonials, faq, booking adattivo)
- [ ] P2 costituzioni (hair-salon, gym, studio-professionale)
- [ ] P3 onboarding scoping
Nota CI: il check
types/supabase.ts ↔ prod schemae ROSSO pre-esistente (drift dei tipi dopo le RPC Booking, non legato a questo lavoro). Le 3 PR sono state mergiate via--admin. Fix alla radice (rigen via Supabase CLI) tracciato nel prompt di handoff step 5 "leave nothing behind"; il chip standalone e stato chiuso per non far partire una sessione doppia.
Handoff 2026-06-05: founder delega a una sessione autonoma successiva il GO-LIVE (apply seed, anche da browser) + P1-P3 + hardening/test finale. Prompt pronto:
pianeta-web-handoff-2026-06-05.md.
Nota: ricognizione 2026-06-05 su codice reale + query DB prod (site_constitutions = 2 stub inattivi). Non e una stima: e lo stato verificato.