---
title: "L'architettura giusta è quella dimensionata sul problema."
url: "https://simonebova.com/it/colophon"
lang: "it"
author: Simone Bova
alternates:
  it: "https://simonebova.com/md/it/colophon"
  en: "https://simonebova.com/md/en/colophon"
  pl: "https://simonebova.com/md/pl/colophon"
---

# L'architettura giusta è quella dimensionata sul problema.

Il problema qui è preciso: un archivio personale che deve essere veloce, costare zero, farsi leggere da umani, crawler e agenti, e lasciarsi mantenere in autopilot. Da lì discende tutto il resto di questa pagina.

## Requisiti → decisioni

- **Leggero:** HTML statico servito da CDN, client JS solo dove c'è interazione. Il collo di bottiglia dev'essere la lettura, mai il caricamento.

- **Zero overhead:** Nessun server, nessun database, nessun CMS: niente da patchare, niente che si buca, niente che chiama alle 3 di notte. Un archivio personale non deve chiedere attenzione operativa.

- **Economico:** Build statica su piano hobby: il costo marginale di una visita è ~zero, e il costo fisso pure. I soldi vanno nei contenuti, non nell'hosting.

- **Autopilot:** Il sito si mantiene da solo: io dico cosa serve, [code-os](https://github.com/yempik-ai/code-os) lo costruisce, il gate decide se si spedisce. [agent-memory](https://github.com/yempik-ai/code-os) con le regole e la definition of done, decisioni registrate come ADR: una sessione agentica nuova è produttiva al primo prompt, senza di me a fare da memoria.

- **Findability / token:** Anche l'architettura dei dati è per gli agenti: dati tipizzati in src/content con path prevedibili, un componente per responsabilità, nomi che dicono cosa fanno. Qualsiasi cosa si trova senza bruciare token in esplorazione: il contesto minimo sufficiente è una proprietà della repo, non del prompt.

- **SEO + GEO:** Statico è crawlabile per definizione, e uso Next per quello che sa fare: Metadata API per canonical e OpenGraph, sitemap e robots tipizzati, OG image generate a build time con ImageResponse, font self-hosted via next/font (zero layout shift), JSON-LD nei layout. Per chi cerca via AI: llms.txt e /api/dossier, dalla stessa fonte delle pagine.

- **Non commerciale:** Niente funnel, niente popup, niente tracker di terzi (analytics cookieless e basta). È un archivio da leggere, non una landing da convertire.

*// anche questa pagina: ho detto cosa volevo, l'harness l'ha costruita, il gate l'ha approvata.*

## Architettura

- **CONTENT / SSoT:** src/content/*.ts: essay, principi, work: dati tipizzati, 3 lingue

- **REACT SERVER COMPONENTS:** route thin, sezioni SRP, client JS solo dove interagisci

- **STATIC BUILD:** ogni route è HTML a build time, anche OG, llms.txt, JSON

- **EDGE / CDN:** Vercel: zero compute a runtime, costo marginale ~0

lo stesso contenuto esce da /llms.txt e /api/dossier

- **GATE:** eslint, tsc --noEmit, next build. verde, o non si committa

- **INVARIANTI:** a11y AA, reduced motion, un solo accento, SSoT-derived, parità i18n. regressione = bug

## Decision record

### ADR-001: Zero dipendenze, più una

2026-07-12 · accepted

Runtime: Next + React + react-aria-components (accessibilità dei widget: focus management, press semantics, focus trap: cose che sbagli se le riscrivi). Niente Tailwind, CMS, UI kit, librerie di animazione. Conseguenza: superficie di update minima, ogni riga in bundle è giustificabile.

### ADR-002: Tutto statico, sempre

2026-07-12 · accepted

Ogni route (HTML, OG image, llms.txt, /api/dossier) è generata a build time e servita da CDN. Nessun compute a runtime: niente cold start, superficie d'attacco ridotta al minimo, costo marginale per request ~zero. Il vincolo è accettato: contenuto nuovo = nuovo deploy.

### ADR-003: Il contenuto è un tipo, non una pagina

2026-07-12 · accepted

Essay, principi, work vivono in src/content come oggetti tipizzati (SSoT). Archivio, homepage, sitemap, OG, llms.txt e /api/dossier derivano dalla stessa fonte. Conseguenza: un contenuto si scrive una volta e non può divergere tra i formati.

### ADR-004: Un solo accento

2026-07-12 · accepted

#E35B2D, ovunque; sulla neve una sfumatura più scura (#B8481C) per il contrasto AA su testo piccolo: stessa tinta, non un secondo colore. Vale anche negli easter egg: una nevicata ha esattamente un fiocco arancione.

### ADR-005: Motion come decorazione, mai come gate

2026-07-12 · accepted

Lo stato nascosto dello scroll-reveal esiste solo con JS attivo (@media scripting) e motion consentito. JS spento o prefers-reduced-motion: contenuto integro. Le animazioni sono un layer sopra il contenuto, non una precondizione per leggerlo.

### ADR-006: Accessibilità come invariante

2026-07-12 · accepted

Skip-link con target focusabile, focus ring visibile, aria-current sulla navigazione, contrasti AA, link esterni annunciati, aria-live anche per gli easter egg. Trattata come i test: una regressione è un bug, non un compromesso.

### ADR-007: Leggibile dalle macchine

2026-07-12 · accepted

/llms.txt per gli agenti, /api/dossier per curl, JSON-LD per i crawler: tutti generati dallo stesso SSoT delle pagine, quindi mai disallineati. Il contesto su di me lo servo io, nel formato di chi lo consuma.

### ADR-008: Tre lingue, un SSoT

2026-07-16 · accepted

IT, EN, PL come route statiche (/it /en /pl), hreflang per pagina, slug condivisi. Niente middleware: la detection è un redirect statico. La parità tra lingue è verificata a build time: una traduzione mancante rompe la build, non la fiducia.

### ADR-009: Il mondo è il banner

2026-10-28 · accepted

Il sito diventa SimoFree: il banner LinkedIn, vivo. Canvas disegnato una volta sola per dimensione (niente loop), tutto ciò che si legge o si preme è DOM sopra il canvas, nella stessa camera. Neve come base, inchiostro, un solo accento. L'easter egg è un gioco vero, opzionale.

### ADR-010: Due lettori: persone e agenti

2026-10-28 · accepted

Ogni pagina ha un gemello Markdown generato dalla stessa fonte, più llms.txt, llms-full.txt e un server MCP in sola lettura. L'HTML resta canonico; il Markdown è noindex. Lo switch Umano / Agente mostra cosa legge un agente.

### ADR-011: Run e piste

2026-10-28 · accepted

I casi sono run (slug condivisi, storie senza numeri del cliente); i modi di lavorare sono piste (slug per lingua, una frase cercata per pagina, difficoltà codificata per forma, mai solo per colore).

### ADR-012: Classifica di SimoFree verificata per replay

2026-10-30 · accepted

Il server non si fida di un numero. Dà il seed, il browser registra gli input a passo fisso (120 Hz) e il server rigioca la discesa con la stessa simulazione pura per calcolare il punteggio. Ticket monouso, tempo reale minimo, limiti per IP salvati come HMAC, solo punteggi positivi, top 100 su Upstash.

### ADR-013: Un solo movimento continuo: il cielo nel footer

2026-11-08 · accepted

La discesa finisce di notte: nel footer c'è un cielo a puntini (dither 1 bit) con lo yeti in orbita. Il canvas si disegna una volta per dimensione; lo yeti è un layer DOM spostato solo con transform, scritto solo quando la posa cambia di un pixel. Il loop gira solo se il cielo è a schermo e nessuno lo ha messo in pausa (WCAG 2.2.2). Con reduced motion lo yeti sta fermo e il loop non parte. È l'eccezione alla regola niente animazioni infinite; ADR-014 estende lo stesso contratto al resto del sito.

### ADR-014: Il mondo si muove: una regia, un interruttore

2026-11-08 · accepted

La testata è il banner vivo: Simone scende, salta dalla cornice (un trick diverso a ogni giro, una caduta ogni quattro) e lo yeti lo insegue e perde. La coreografia è una funzione pura del tempo, testata, e si apre sul fotogramma esatto del banner. Il canvas resta fermo; si muovono solo layer DOM via transform. Ogni animazione ambientale passa da un solo hook (a schermo, mai in background) e da un solo interruttore di pausa per tutto il sito. Lo scroll è una discesa: nella nav una porta per sezione. Torino, Milano e Warszawa all'orizzonte.

### ADR-015: Anche la scrollbar è della pista

2026-11-08 · accepted

Su mouse e trackpad la barra nativa diventa un binario sottile: il cursore è un box HUD nell'accento quando lo usi, ogni sezione numerata è una porta con il suo nome, da trascinare o cliccare. Lo scroll nativo resta intatto (tastiera, rotella, touch, tecnologie assistive), il binario lo rispecchia soltanto ed è aria-hidden. La barra nativa sparisce solo dopo che il binario è montato, quindi senza JS o su touch resta quella del sistema. Segue lo scroll, non è movimento ambientale: una variabile CSS per frame.

## Per le macchine

Il contenuto su di me lo servo io, nel formato di chi lo consuma. Gli agenti leggono /llms.txt; chi preferisce il terminale ha un endpoint JSON generato dallo stesso SSoT delle pagine:

- [llms.txt](https://simonebova.com/llms.txt): concise site index.
- [llms-full.txt](https://simonebova.com/llms-full.txt): every English page in full.
- [Dossier JSON](https://simonebova.com/api/dossier): structured public profile.
- [MCP](https://simonebova.com/mcp): POST JSON-RPC over stateless Streamable HTTP, initialize then tools/list and tools/call.

*// stessa fonte, tre formati: HTML per te, llms.txt per gli agenti, JSON per curl.*

[simone@yempik.ai](mailto:simone@yempik.ai) · [Book a call](https://calendar.app.google/LKDrQPKGV2EAFCMN9)
