chore(claude): architettura base .claude — skill preventivo e audit, hook di guardia, piani nel repo

La cartella aveva dentro solo rules/ e i settings: nessun posto dove mettere una
skill, un hook o un piano. Ora ha lo scheletro completo e un .claude/CLAUDE.md che
spiega cosa va dove — non duplica CLAUDE.md di progetto, che resta quello che comanda.

Due skill locali (le altre restano globali in ~/.claude/skills/):
- /preventivo — la catena agent.ts → schema.ts → assemble.ts → ProposalDeck e i tre
  modi di romperla, di cui uno solo fa rumore. Nessun prompt di generazione qui
  dentro: quello vive in agent.ts ed e' l'unico. Porta check-profilo.sh.
- /audit — guida scripts/audit-fonti.ts, nuovo, che mette in moto le cinque fonti di
  src/lib/audit/sources/, in prod dal 2026-08-19 ma mai chiamate da nessuno. Provate
  su giojello.com: 5 su 5, 42,7 s, PageSpeed mobile 58 / desktop 93.

Due hook, provati a mano (6 casi il primo, 5 il secondo):
- guardia-migration.sh BLOCCA l'SQL distruttivo sulle entita' protette — il vincolo
  Data Safety (LOCKED) fatto rispettare dalla macchina invece che dalla memoria.
- guardia-token.sh AVVISA sulle classi Tailwind grezze. Non blocca: con ~450
  occorrenze di debito, bloccare lo renderebbe un ostacolo da disattivare.

I tre piani di v2.5 entrano nel repo: stavano solo in ~/.claude/plans/ e STATE.md
avvertiva che senza quelli la milestone non era ricostruibile. Passati al setaccio
per credenziali prima di committarli.

Corretta in rules/memory-discipline.md la chiave della memoria persistente: e'
…-Vault-IAMCAVALLI-hub, non quella del workspace. Sedici file stavano nella prima,
la regola indicava la seconda.

Impeccable resta abilitato solo a livello globale: fuori da settings.json locale.

Nessun tocco al prodotto. Build e lint verdi, lint identico al baseline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-26 16:09:14 +02:00
parent bec7e039d7
commit 817a8cd5d1
22 changed files with 1601 additions and 24 deletions
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# PreToolUse su Write/Edit — vincolo Data Safety (LOCKED) di ../../CLAUDE.md.
#
# Blocca la scrittura di una migration che cancella dati dalle entita' protette.
# Non e' una prova: e' una rete. Un DROP scritto in modo esotico puo' passare —
# la revisione a occhio dell'SQL resta obbligatoria.
#
# exit 0 = passa · exit 2 = bloccato, il messaggio su stderr torna a Claude.
set -uo pipefail
INPUT=$(cat)
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty')
# Fuori da src/db/migrations/ questo hook non ha voce in capitolo.
case "$FILE" in
*src/db/migrations/*) ;;
*) exit 0 ;;
esac
# Write porta `content`, Edit porta `new_string`. MultiEdit porta un array.
SQL=$(printf '%s' "$INPUT" | jq -r '
[ .tool_input.content?,
.tool_input.new_string?,
(.tool_input.edits? // [] | .[].new_string?)
] | map(select(. != null)) | join("\n")
')
[ -z "$SQL" ] && exit 0
PROTETTE='clients|projects|payments|phases'
# Via i commenti, tutto minuscolo, una riga per statement: cosi' "DROP" e il nome
# della tabella devono stare nella STESSA istruzione per far scattare il blocco.
PULITO=$(printf '%s' "$SQL" \
| sed -E 's/--.*$//' \
| tr '\n' ' ' \
| sed -E 's;/\*[^*]*\*+([^/*][^*]*\*+)*/; ;g' \
| tr '[:upper:]' '[:lower:]' \
| tr ';' '\n')
COLPEVOLI=$(printf '%s\n' "$PULITO" \
| grep -E 'drop[[:space:]]+table|drop[[:space:]]+column|truncate|delete[[:space:]]+from' \
| grep -E "\\b($PROTETTE)\\b" || true)
if [ -n "$COLPEVOLI" ]; then
{
echo "BLOCCATO — Data Safety (LOCKED, ../CLAUDE.md)."
echo
echo "Questa migration cancella dati da un'entita' protetta (clients, projects,"
echo "payments, phases). Le migration sono additive: si aggiungono colonne e"
echo "tabelle, non si tolgono righe."
echo
echo "Istruzioni incriminate:"
printf '%s\n' "$COLPEVOLI" | sed 's/^[[:space:]]*/ · /'
echo
echo "Se la rimozione serve davvero, e' una decisione da confermare a voce con"
echo "l'utente prima di scriverla — non da aggirare qui."
} >&2
exit 2
fi
exit 0
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# PostToolUse su .tsx/.css — regola cardinale del design system:
# solo token semantici (bg-card, text-muted-foreground, border-border).
#
# AVVISA, non blocca: le eccezioni sanzionate esistono (vedi WHITELIST) e il
# debito storico e' gia' di ~450 occorrenze. Bloccare renderebbe l'hook un
# ostacolo da disattivare invece di un promemoria da leggere.
#
# exit 0 sempre. Il messaggio su stderr arriva a Claude come contesto.
set -uo pipefail
INPUT=$(cat)
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty')
case "$FILE" in
*.tsx|*.css) ;;
*) exit 0 ;;
esac
# Eccezioni sanzionate da ../CLAUDE.md § Design System:
# - StatusBadge: i colori di stato usano la palette con variante dark: esplicita
# - AdminShell: il verde brand della sidebar
# - mailer.ts / .html: l'HTML delle email non puo' usare variabili CSS
# - globals.css: e' il posto dove i token vengono *definiti*
# - design-reference/: i mock precedono la regola, si traducono non si copiano
case "$FILE" in
*StatusBadge*|*AdminShell*|*mailer*|*globals.css|*design-reference/*) exit 0 ;;
esac
TESTO=$(printf '%s' "$INPUT" | jq -r '
[ .tool_input.content?,
.tool_input.new_string?,
(.tool_input.edits? // [] | .[].new_string?)
] | map(select(. != null)) | join("\n")
')
[ -z "$TESTO" ] && exit 0
PALETTE='slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose'
GREZZE=$(printf '%s\n' "$TESTO" \
| grep -oE "\\b(bg|text|border|ring|from|to|via|fill|stroke|divide|outline|shadow|accent|decoration|placeholder)-($PALETTE)-[0-9]{2,3}\\b" \
| sort -u | head -12 || true)
HEX=$(printf '%s\n' "$TESTO" \
| grep -oE '#[0-9a-fA-F]{3,8}\b' | sort -u | head -6 || true)
if [ -n "$GREZZE" ] || [ -n "$HEX" ]; then
{
echo "AVVISO design system — token semantici, non palette grezza."
echo "File: $FILE"
[ -n "$GREZZE" ] && { echo " classi grezze: $(printf '%s ' $GREZZE)"; }
[ -n "$HEX" ] && { echo " hex letterali: $(printf '%s ' $HEX)"; }
echo
echo "Usa bg-card / text-muted-foreground / border-border: e' quello che fa"
echo "funzionare chiaro e scuro sul solo toggle della classe .dark."
echo "Riferimento: design-reference/DESIGN-SYSTEM.md"
echo "Eccezione sanzionata? Aggiungi il file alla WHITELIST di questo hook."
} >&2
fi
exit 0