diff --git a/.planning/phases/20-knowledge-base-cliente/20-CONTEXT.md b/.planning/phases/20-knowledge-base-cliente/20-CONTEXT.md
new file mode 100644
index 0000000..c7fe33b
--- /dev/null
+++ b/.planning/phases/20-knowledge-base-cliente/20-CONTEXT.md
@@ -0,0 +1,111 @@
+# Phase 20: Knowledge Base Cliente — Context
+
+**Gathered:** 2026-06-19
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+Aggiungere uno store di transcript datati per lead: l'admin incolla il testo grezzo di ogni call con data e titolo libero, la lista appare in ordine cronologico nel dettaglio lead, e i dati sono pronti per essere letti dall'agente AI in Phase 21.
+
+**In scope:** schema `client_transcripts` + server actions + UI nel LeadDetail
+**Out of scope:** UI per clienti (client_id FK presente ma non esposta), ricerca full-text sui transcript, trascrizione automatica da audio
+
+
+
+
+## Implementation Decisions
+
+### Schema — client_transcripts
+
+- **D-01:** La tabella `client_transcripts` ha **entrambe** le FK nullable: `lead_id` (references leads, onDelete cascade) e `client_id` (references clients, onDelete cascade). Ragionamento: prepara la struttura per transcript post-conversione senza richiedere una migration futura.
+- **D-02:** Campi: `id` (nanoid PK), `lead_id` (nullable FK), `client_id` (nullable FK), `title` (text, optional — titolo libero es. "Discovery call 12 giugno"), `content` (text NOT NULL — testo incollato, lunghezza illimitata), `call_date` (date NOT NULL — giorno della call, non timestamp), `created_at` (timestamp with timezone, defaultNow).
+- **D-03:** Migration mano-scritta come 0009 — drizzle-kit generate è rotto. Applicata a prod via SSH **prima** di pushare il codice dipendente (invariante bloccante del progetto).
+
+### UI — Solo lato lead in Phase 20
+
+- **D-04:** In Phase 20 la UI espone solo il lato lead. La FK `client_id` è nello schema ma **non ha form o lista** in questa fase — si aggiunge in futuro se serve la pagina `/admin/clients/[id]`.
+- **D-05:** I transcript sono listati in ordine `call_date DESC` nel dettaglio lead (chiamata più recente in cima).
+
+### Claude's Discretion
+
+Le seguenti aree non sono state discusse — Claude ha flessibilità:
+
+- **Metadati:** No tipo enum — `title` libero (optional) è sufficiente. Il testo del transcript parla da solo.
+- **Placement UI:** Nuova sezione "Transcript" collassabile in `LeadDetail`, dopo la sezione Attività esistente. Stessa convenzione visiva (Card + lista). Form/modal per aggiungere seguendo il pattern `LogActivityModal`.
+- **Nessun limite di lunghezza:** `content` è `text` PostgreSQL (illimitato). Textarea nel form senza troncatura.
+
+
+
+
+## Canonical References
+
+**Downstream agents MUST read these before planning or implementing.**
+
+### Requirements & Roadmap
+- `.planning/ROADMAP.md` — Phase 20 goal, success criteria, schema spec (`client_transcripts` con `lead_id/client_id, testo, data, titolo/tipo, created_at`)
+- `.planning/REQUIREMENTS.md` — KB-01 (schema additivo transcript), KB-02 (UI incolla/elenca)
+
+### Schema & Migrations
+- `src/db/schema.ts` — pattern tabelle append-only CRM: `activities` (lead_id, type, notes, activity_date), `reminders` (lead_id, due_date). La nuova `client_transcripts` segue questo pattern.
+- `src/db/migrations/0008_offer_tier_schema.sql` — ultimo esempio di SQL migration a mano (struttura e convenzioni da seguire)
+- `src/db/migrations/0005_phase_10_crm_leads_activities_reminders.sql` — migration originale di `activities` e `reminders` (pattern più vicino alla nuova tabella)
+
+### UI & Components
+- `src/components/admin/leads/LeadDetail.tsx` — struttura UI esistente del dettaglio lead (dove va inserita la sezione Transcript)
+- `src/components/admin/leads/LogActivityModal.tsx` — pattern modal per aggiungere dati CRM (da seguire per il form transcript)
+- `src/app/admin/leads/[id]/page.tsx` — pattern page con `Promise.all` per fetch parallele (aggiungere `getTranscripts(id)`)
+
+### Query & Actions Layer
+- `src/lib/lead-service.ts` — pattern query layer CRM (`getActivityLog`, `getUpcomingReminders` — aggiungere `getTranscripts`)
+- `src/app/admin/leads/actions.ts` — pattern server actions con `requireAdmin` guard (da seguire per `addTranscript`, `deleteTranscript`)
+
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- `LogActivityModal.tsx` — modal con form controllato (date picker + textarea + submit), pronto da clonare per il form transcript
+- `activities` / `reminders` pattern in `schema.ts` — FK `lead_id` con `onDelete: cascade`, `nanoid()` PK, `created_at` defaultNow — copia esatta per `client_transcripts`
+- `getActivityLog(leadId)` in `lead-service.ts` — query Drizzle con `where(eq(activities.lead_id, leadId))` e `orderBy(desc(activities.activity_date))` — pattern identico per `getTranscripts`
+- `Card`, `CardContent`, `CardHeader`, `CardTitle` da shadcn/ui — già usati nel LeadDetail per ogni sezione
+
+### Established Patterns
+- **Migration a mano**: ogni schema change è SQL scritto a mano (`CREATE TABLE IF NOT EXISTS`, tipi Postgres espliciti, FK con `ON DELETE CASCADE`). NON usare `drizzle-kit generate`.
+- **requireAdmin guard**: tutte le server actions in `actions.ts` iniziano con `await requireAdmin()` — obbligatorio anche per le nuove actions transcript.
+- **`revalidatePath`** dopo ogni mutation: `revalidatePath(\`/admin/leads/${leadId}\`)`.
+- **Promise.all fetch**: `page.tsx` del dettaglio lead usa `await Promise.all([...])` per fetch parallele — aggiungere `getTranscripts(id)` nello stesso array.
+
+### Integration Points
+- `src/app/admin/leads/[id]/page.tsx` — aggiungere `getTranscripts(id)` nel `Promise.all`, passare `transcripts` a ``
+- `src/components/admin/leads/LeadDetail.tsx` — aggiungere prop `transcripts` e sezione "Transcript" dopo ``
+- `src/db/schema.ts` — aggiungere definizione `client_transcripts` + relazioni Drizzle
+- `src/lib/lead-service.ts` — aggiungere `getTranscripts(leadId: string)`
+- `src/app/admin/leads/actions.ts` — aggiungere `addTranscript(leadId, data)` e `deleteTranscript(transcriptId)`
+
+
+
+
+## Specific Ideas
+
+- Il testo del transcript può essere molto lungo (trascrizioni complete di call). Il form deve avere una `
+
+
+## Deferred Ideas
+
+- **UI transcript per clienti** (`/admin/clients/[id]`): la FK `client_id` è nella tabella, ma la UI lato cliente è deferred a una fase futura (post v2.2 o su richiesta).
+- **Ricerca full-text sui transcript**: fuori scope v2.2 — i transcript vengono letti dall'AI in blocco, non cercati dall'admin.
+- **Trascrizione automatica da audio**: fuori scope — l'admin incolla manualmente il testo.
+
+
+
+---
+
+*Phase: 20-Knowledge Base Cliente*
+*Context gathered: 2026-06-19*
diff --git a/.planning/phases/20-knowledge-base-cliente/20-DISCUSSION-LOG.md b/.planning/phases/20-knowledge-base-cliente/20-DISCUSSION-LOG.md
new file mode 100644
index 0000000..3945bdd
--- /dev/null
+++ b/.planning/phases/20-knowledge-base-cliente/20-DISCUSSION-LOG.md
@@ -0,0 +1,50 @@
+# Phase 20: Knowledge Base Cliente — Discussion Log
+
+> **Audit trail only.** Do not use as input to planning, research, or execution agents.
+> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
+
+**Date:** 2026-06-19
+**Phase:** 20-knowledge-base-cliente
+**Areas discussed:** Lead-scoped o anche client?
+
+---
+
+## Lead-scoped o anche client?
+
+### Q1 — FK scope della tabella
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Solo lead per ora | `client_transcripts` ha solo `lead_id`. Semplice, sufficiente per Phase 21. La FK `client_id` si aggiunge in futuro se serve. | |
+| Prepara entrambe le FK ora | `lead_id` e `client_id` entrambi nullable nella tabella. Più lavoro ora, ma non serve una migration futura se vuoi trascrizioni anche per clienti esistenti. | ✓ |
+
+**User's choice:** Prepara entrambe le FK ora
+**Notes:** L'utente preferisce prepararsi alla flessibilità futura con una sola migration ora.
+
+---
+
+### Q2 — UI Phase 20 per client_id
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Solo dal dettaglio lead per ora | La FK `client_id` c'è nello schema ma non è esposta in UI in Phase 20. Si usa quando un lead è convertito — per dopo. | ✓ |
+| Anche dalla pagina admin cliente | Phase 20 aggiunge il blocco transcript sia nel LeadDetail che in `/admin/clients/[id]`. Più lavoro, ma copre subito clienti esistenti senza lead. | |
+
+**User's choice:** Solo dal dettaglio lead per ora
+**Notes:** L'UI Phase 20 è solo lato lead. `client_id` è nello schema ma non esposta.
+
+---
+
+## Claude's Discretion
+
+Le seguenti aree non sono state discusse e sono state lasciate al giudizio di Claude:
+
+- **Metadati del transcript** — Scelto: `title` (text, optional) + `content` (text, illimitato) + `call_date` (date). No enum tipo — il titolo libero è sufficiente.
+- **Collocazione UI nel LeadDetail** — Scelto: nuova sezione "Transcript" collassabile dopo le Attività, seguendo il pattern visivo esistente (Card + lista). Modal per aggiungere (come `LogActivityModal`).
+- **Ordinamento** — `call_date DESC` (chiamata più recente in cima).
+
+## Deferred Ideas
+
+- UI transcript nella pagina admin cliente (`/admin/clients/[id]`) — la FK è pronta, la UI è deferred post-v2.2.
+- Ricerca full-text sui transcript — fuori scope, i transcript vengono letti dall'AI in blocco.
+- Trascrizione automatica da audio — fuori scope v2.2.