Content Studio — infra da provisionare (founder), passo-passo
Il codice del routing sovrano è in PR #145 (repo Multiverbe) ed è fail-closed: finché queste env non ci sono, la generazione risponde 503
sovereign_routing_required(mai fallback a un endpoint consumer). Appena le imposti, si attiva da sola. I nomi delle env qui sotto sono esattamente quelli letti dal codice.
🔵 Stato 2026-06-04 (sessione "sblocco infra" · verifica REALE pre-azione)
Probe
GET /api/content/sovereign-status(live) +sovereignty_register_vverificati ORA, non dalle note. Stato vero:
- Testo:
vertex_gemini=true·vertex_claude=true✅ —mistral✅ VERIFICATO LIVE 2026-06-04 (keymultiverbe-prodcreata + envMISTRAL_API_KEYProduction+Preview + redeploy prod → probemistral:true). Outreach sbloccato. Resta compliance: (a) toggle training Mistral era ON → mettere OFF (/plateforme/privacy); (b) ZDR + DPA = richiesta a Mistral (contract-level).- Immagini:
imagen_fast=true·imagen_ultra=true✅ —flux=false(opzionale, P5).- Provenance:
c2pa_signing=false→ leggi la nota P2 qui sotto: NON provisionare il cert adesso.- Register
sovereignty_register_v= 0 righe. I provider sono configurati (probe verde) ma nessuna generazione reale è ancora passata dalla UI: lo farà la sessione Content. NON è un blocco infra.⚠️ P2 — C2PA cert: NON ancora provisionabile (finding di questa sessione). Nel codice non esiste un firmatario C2PA reale: nessuna dipendenza
c2pa-node/c2patoolinpackage.json, eisC2paSigningConfigured()si limita a flipparesigned:truenel manifest (content-provenance.ts). ImpostareC2PA_SIGNING_CERT/_KEYadesso marcherebbe i manifest comesigned:truesenza firmarli davvero = dichiarazione di provenienza falsa (peggio dell'onestosigned:false, e contro la stessa logica anti-claim di SOV7). Sequenza corretta: prima si implementa il firmatario reale (c2pa-node+ cert X.509 + embedding), poi si provisiona il cert. Fino ad allora il cert resta OFF (manifestsigned:false, già il comportamento corretto). → cert path documentato sotto, ma gate = signer implementato.✅ CHIUSURA sessione (pomeriggio 2026-06-04) — Chrome connesso, eseguito dal vivo:
- P1 Mistral COMPLETO: key live + training toggle OFF (era ON) + DPA in vigore + richiesta ZDR pronta (
mistral-zdr-dpa-request-2026-06-04.md).- ⛔ P4 video / P5 Azure FLUX / P6 voce = PREMATURI (stessa classe di C2PA): adapter inesistenti nel codice (
dispatchAudio/Videoassenti,azure-fluxlanciaimage_adapter_not_implemented). NON creare account/pagare: il blocco è codice (adapter), consegnato a Content/Video. MettereAZURE_FOUNDRY_*ora introdurrebbe un bug latente nel fallback immagini.- P3 DPA COMPLETO: Mistral + Google CDPA in vigore by-reference (progetto
multiverbe-2606030125confermato); sub-processor list arricchita con le DPA URL verificate → PR #172.- P7 SOV7 GREENLIT (founder, incl. outreach): clausola L8 ToS redatta in
sov7-claim-l8-tos-2026-06-04.md; gate pre-pubblico = legale CH + L8 + conferma ZDR.- P8 eseguito: PR #170 (commitlint
prefix:"chore"+deps-devenum) + 6 PR superseded chiuse. Verde sui check reali, pronta da mergiare. Post-merge:@dependabot recreatesu #162/#165/#166/#167.
✅ Stato 2026-06-03 (sera) — Vertex EU VERIFICATO LIVE (text + image)
#155/#159 mergiati → Content sovrano in prod. Probe
GET /api/content/sovereign-status=vertex_gemini/claude/imagen true · ready.text/image true. GCP Vertex confermato attivo (il punto A sotto è CHIUSO). Restano per la sessione "sblocco infra" (content-handoff-prompts-2026-06-03.md· prompt B): B1MISTRAL_API_KEY(probemistral:false→ outreach 503) · C2PA signing cert (C2PA_SIGNING_CERT/_KEY) · provider video (DEC#2 Synthesia/Runway/Firefly) · DPA (Google/Mistral/Azure/fal) · SOV7. Migrazionecontent_brand_signalsapplicata (oltre a a→e).⏳ Stato 2026-06-03 (mattina) — handoff verifica (storico, ora superato)
Il founder ha già provisionato la parte GCP, da verificare l'accensione:
- Progetto GCP creato:
multiverbe-2606030125· regioneurope-west4· billing attivo · service accountvertex-runtime@multiverbe-2606030125.iam.gserviceaccount.com+ ruoloroles/aiplatform.user.- Le 4 env (
GCP_VERTEX_PROJECT/LOCATION/SA_CLIENT_EMAIL/SA_PRIVATE_KEY) inserite in Vercel (multiverbe-app, prj_yWNM0v8ejuLHtLCLXZvSKvHnA4k9). Il primo tentativo era con la chiave incompleta; reinserita.- DA VERIFICARE: (1) Redeploy eseguito dopo il salvataggio delle env; (2) una generazione reale dal Pianeta Content (multiverbe.app). Finora
content_generations= 0 righe, log runtime vuoti → mai testato.- Come confermare dal MCP (in 10s, senza login utente):
SELECT created_at, ai_model, provider, provider_region, sovereign FROM public.sovereignty_register_v ORDER BY created_at DESC LIMIT 5;→ deve comparireprovider = vertex-gemini-eu,sovereign = true. In più i log runtime Vercel (teamteam_temx7lcMkSnWbL1DrH4KQqlc, project sopra).- Se la generazione dà errore 502 invece del post: quasi sempre è la
GCP_SA_PRIVATE_KEYincompleta (deve includere righe BEGIN+corpo+END) o il Redeploy non fatto. Se dà il banner 503 sovereign_routing_required: env non attive su Production.- Migrazioni a→e: già applicate in prod (questa sessione, via MCP). Advisor sicurezza pulito.
A. Vertex AI EU — testo + immagini (Imagen) · sblocca SOV1 + il motore immagini
Modo veloce (Cloud Shell, dal browser, ~5 min, niente da installare)
Apri shell.cloud.google.com (sei già loggato col tuo account Google), poi incolla questo blocco (cambia PROJECT_ID se vuoi un nome diverso o usa un progetto esistente):
export PROJECT_ID="multiverbe-prod" # nome progetto (o un id esistente)
export REGION="europe-west4" # EU Olanda · oppure europe-west1 (Belgio)
# crea il progetto (salta se ne usi uno esistente) + impostalo
gcloud projects create "$PROJECT_ID" 2>/dev/null; gcloud config set project "$PROJECT_ID"
# IMPORTANTE: il progetto deve avere il billing attivo (Console > Billing) o l'API non parte
# abilita Vertex AI
gcloud services enable aiplatform.googleapis.com
# service account + ruolo Vertex
gcloud iam service-accounts create vertex-runtime --display-name="Multiverbe Vertex runtime"
export SA_EMAIL="vertex-runtime@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="serviceAccount:${SA_EMAIL}" --role="roles/aiplatform.user"
# chiave JSON (resta privata nella tua Cloud Shell)
gcloud iam service-accounts keys create vertex-key.json --iam-account="$SA_EMAIL"
# stampa i 3 valori non-segreti da mettere in Vercel
echo "GCP_VERTEX_PROJECT=$PROJECT_ID"
echo "GCP_VERTEX_LOCATION=$REGION"
echo "GCP_SA_CLIENT_EMAIL=$SA_EMAIL"
echo "--- per GCP_SA_PRIVATE_KEY copia il campo private_key qui sotto (è SEGRETO, va solo in Vercel) ---"
cat vertex-key.json
Poi in Vercel → progetto app → Settings → Environment Variables (Production) aggiungi le 4 env (i nomi esatti letti dal codice):
GCP_VERTEX_PROJECT,GCP_VERTEX_LOCATION,GCP_SA_CLIENT_EMAIL= i valori stampati;GCP_SA_PRIVATE_KEY= il valore del campo"private_key"dal JSON (incolla così com'è, con i\n: il codice li normalizza). Mai incollare la chiave in chat.
Fai Redeploy (Vercel lo propone al cambio env). Da quel momento il testo del Pianeta Content gira reale e sovrano, e Imagen (immagini) è disponibile con le stesse credenziali. Sicurezza: la chiave la gestisci tu in Vercel, io non la vedo mai (regola "segreti mai in chat").
Imagen usa le stesse credenziali (nessuna env extra). Veo (video) resta OFF: è geo-bloccato in CH e Pre-GA non commerciale (vedi roadmap) → il video userà la via DACH-safe quando la costruiamo.
Modo manuale (Console, se preferisci cliccare)
- GCP project: usa o crea un progetto Google Cloud (es.
multiverbe-prod). - Abilita l'API: Vertex AI API (
aiplatform.googleapis.com). - Regione EU: scegli
europe-west1(Belgio) oeurope-west4(Olanda). Usa la stessa ovunque. - Service account: creane uno (es.
vertex-runtime@…), ruoloroles/aiplatform.user. - Chiave JSON: crea una key JSON e scaricala (NON committarla).
- Claude su Vertex (per il routing premium Business): in Vertex Model Garden abilita i modelli Anthropic per la regione (accetta i termini) e annota l'id esatto del modello.
- Veo / Imagen: abilitali nella stessa regione (stesse credenziali, nessuna env extra).
- Env su Vercel (project app):
GCP_VERTEX_PROJECT= id progettoGCP_VERTEX_LOCATION=europe-west1(oeurope-west4)GCP_SA_CLIENT_EMAIL=client_emaildal JSONGCP_SA_PRIVATE_KEY=private_keydal JSON (lascia i\ncome sono, il codice li normalizza)- (opz.)
GCP_VERTEX_CLAUDE_MODEL= id modello Claude su Vertex (defaultclaude-sonnet-4-6)
- DPA: firma il Google Cloud Data Processing Addendum + conferma data residency EU e no-training.
→ Quando A è fatto: il testo del Pianeta Content gira reale e sovrano (e l'outreach se aggiungi B2).
B. Provider sovrani aggiuntivi
B1 · Mistral FR (outreach, già quasi pronto) · sblocca L2 in prod
MISTRAL_API_KEY(probabilmente già presente).- Account Mistral: abilita Zero Data Retention + firma il DPA Mistral.
B2 · Immagini via Azure Foundry FLUX (alternativa a Imagen) · SOV2 + SOV4
- Crea una risorsa Azure AI Foundry in regione EU, deploya FLUX.
AZURE_FOUNDRY_ENDPOINT,AZURE_FOUNDRY_KEY.- SOV4: apri un ticket Microsoft per forzare EU Data Boundary sulla risorsa (default è "global").
- (Se preferisci, salta B2 e usa Imagen via Vertex EU dal punto A — meno fornitori da gestire.)
B3 · Voce · sblocca voce + C9
AZURE_SPEECH_ENDPOINT,AZURE_SPEECH_KEY(TTS neurale EU/CH).ELEVENLABS_API_KEY(solo cloning premium, dietro consensovoice_clone_consent).- C9: A/B reale qualità voce IT (Voxtral/Azure vs ElevenLabs) prima di scegliere il default.
C. Legale / DPA · SOV5
- Firma DPA con: Google Cloud, Mistral, (se usi B2) Microsoft Azure, (se userai il fallback economico) fal.ai.
- Versiona la lista sub-processor accettata per-workspace (tabella
legal_acceptances, document_typesub_processor_list, già sbloccato dalla migration 2026-06-02a).
D. Database · applicare in ordine (Dashboard SQL, NON MCP)
database/migrations/2026-06-02a_content_compliance.sql(L4 + L5 + registro sovranità + attestazioni Art.50)database/migrations/2026-06-02b_content_engine.sql(concept layer + jobs + review_log/ai_disclosure)database/migrations/2026-06-02c_content_quota_ring.sql(cap testo/media + ring)database/migrations/2026-06-02d_idempotency_keys.sql(idempotency · non urgente, gli endpoint degradano fail-open senza)
Nota: l'endpoint di firma editoriale api/content/approve.ts (esonero AI Act Art.50) resta in 503 finché a+b non sono applicate.
Ogni file ha un pre-check in cima: eseguilo prima (deve dare zero righe in conflitto).
E. Solo DOPO A–D testati · SOV7
Sblocca il claim marketing "i tuoi dati restano in Europa / sei già a norma". Prima di allora il claim è pubblicità potenzialmente ingannevole (art. 3 LCSl) + responsabilità verso il cliente. Tienilo spento finché il routing EU non è verificato in prod.
F. Decisioni residue (non bloccanti per il codice)
- C9: scelta default voce dopo A/B (sopra B3).
- L8: ToS — riscrivere la clausola indennizzi ("ti giriamo le garanzie del fornitore ove esistenti e nei loro limiti, senza garanzia di Multiverbe"). Far passare da legale + humanizer.
- Adozione LIA cold outreach:
ops/lia-cold-outreach-2026-06-02.md(firma + data nel decisions-log).