Del gateway Telegram che specchia le conversazioni VS Code sul mio GX10 avevo raccontato l’architettura. Stamattina è stato il primo turno in cui il setup ha lavorato davvero — e ha prodotto esattamente il tipo di mattinata che un post non prevede mai: una solution .NET che non compila, un feed npm privato che risponde 401 e un personal access token incollato in chat. Racconto tutto, senza token.

Cosa è successo, in ordine

07:44 — Prima richiesta attraverso il proxy. Il modello risponde, la conversazione viene specchiata nell’activity log JSONL. Tutto come da progetto.

07:59 — Si passa al lavoro serio: build the aspire app. La risposta arriva subito, dotnet run --project src/WebTest.AppHost, dritta al punto. Il proxy tiene, la latenza pure.

08:12 — Copilot si fa proactive da solo: nota che l’ultimo dotnet build in terminale è uscito in errore e lo segnifica prima che glielo chieda. Gli dico “guarda il terminale e dimmi cosa manca”.

08:15 — La diagnosi in trenta secondi: la build fallisce perché npm install esce con code 1 dentro il progetto web (.NET, ma con Microsoft.VisualStudio.JavaScript.Sdk, che invoca npm come step di build). Le quattro warning NU1510 in un altro progetto sono una cosa a parte, pacchetti ormai impliciti nell’SDK. Fin qui, routine.

Il feed privato e il muro del 401

Il package.json punta a un feed npm aziendale su Azure DevOps. Senza credenziali, npm install muore. La ricetta è nota: creare un PAT con scope Packaging → Read e salvarlo nello ~/.npmrc utente — mai nel .npmrc del repo, che è committato.

Qui succede la cosa doppia.

La parte bella: l’assistente lo dice prima — “è un segreto, scrivilo tu nel terminale, non incollarlo qui”. Corretto, preciso, nel momento giusto.

La parte che succede comunque: trenta secondi dopo il token finisce incollato in chat lo stesso. E il verdetto di Azure DevOps è un 401 secco, provate entrambe le forme di auth. 401 vuol dire non autenticato — non 403, che sarebbe stato un problema di permessi. Token invalido, scaduto, o tagliato in copia. Niente daaggiustare da questa macchina.

Due lezioni, entrambe vere:

  1. 401 ≠ 403 vale doppio quando non sei tu il proprietario del feed. Un 403 avrebbe significato “chiedi di essere aggiunto ai Feed readers”. Un 401 significa che la chiave non è proprio una chiave — e nessun ritocco al formato di ~/.npmrc l’avrebbe mai salvata.
  2. Un segreto incollato in una chat è compromesso, anche se la chat è la tua. La risposta giusta non è “funziona, va bene così”: è revocare quel PAT e farne uno nuovo. Il log dell’attività, intanto, ha registrato il scambio — il che porta dritti al punto dopo.

Il log vede tutto, quindi deve imparare a scordare

L’activity log JSONL del proxy registra user e reply per macchina. Oggi ha registrato anche un PAT. È il momento giusto per la regola che ogni logging di conversazioni dovrebbe avere dal giorno zero: redazione degli schemi noti al volo — stringhe lunghe base64-ish, blocchi ad alta entropia, pattern di token famosi — prima della scrittura su disco, non come ripensamento.

Il token di oggi era già morto di suo (401), ma il log è un file che finisce nei backup. Un log che non sa scordare è una fuite in attesa di nome.

Il bilancio del primo turno

  • ✅ Il proxy regge una sessione di lavoro reale: diagnosis, comandi, tono.
  • ✅ Le metriche della dashboard Prometheus non hanno battuto ciglio.
  • ⚠️ L’identificazione macchina via IP sorgente era in fallback su unknown — da ricollegare quando il secondo portatile torna in rete.
  • 🔴 Redaction dei segreti nell’activity log: da fare, non opzionale.

La build, quella vera, è ancora ferma al PAT nuovo. Ma il proxy ha superato la mattinata — ed è quello che stamattina stavo testando.