docs(handover): release workflow + hot-reload PHP + disciplina commit (attivita primaria)
Aggiunto da AgileHub-side (VIGILE) su autorizzazione esplicita utente, dopo che la
sessione NIS2 ha scoperto sul campo 2 lezioni critiche:
1. opcache.validate_timestamps=Off -> ogni edit .php richiede kill -USR2 1 nel
container FPM (bind-mount non basta a servire il nuovo bytecode)
2. modifiche non committate vengono revertate dal cron ticket-agent (caso reale:
commit d5d83bb ha revertato index.php di una Feature 1 WIP)
- Nuovo doc docs/INCOMING_FROM_AGILEHUB_2026_05_30_release_workflow_hot_reload.md
- Sezione ATTIVITA PRIMARIA inserita in CLAUDE.md subito dopo lo standard timezone
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
4924075142
commit
f8f78b5ece
54
CLAUDE.md
54
CLAUDE.md
@ -25,6 +25,60 @@
|
|||||||
**Spec completa**: `STANDARD_TIMEZONE_CONVENTIONS.md` (slug `timezone-conventions` v1.0, owner VIGILE).
|
**Spec completa**: `STANDARD_TIMEZONE_CONVENTIONS.md` (slug `timezone-conventions` v1.0, owner VIGILE).
|
||||||
<!-- STANDARD:timezone-conventions:v1.0:end -->
|
<!-- STANDARD:timezone-conventions:v1.0:end -->
|
||||||
|
|
||||||
|
## 🔴 ATTIVITÀ PRIMARIA — Workflow di rilascio + hot-reload PHP + disciplina commit
|
||||||
|
|
||||||
|
> **VINCOLANTE per OGNI modifica di codice su NIS2.** Aggiunto 2026-05-30 da AgileHub-side (VIGILE) dopo che la sessione NIS2 ha scoperto sul campo che il bind-mount NON serve codice "live" e che le modifiche scoperte vengono revertate.
|
||||||
|
|
||||||
|
**Le 3 regole d'oro** (doc completo in `docs/INCOMING_FROM_AGILEHUB_2026_05_30_release_workflow_hot_reload.md`):
|
||||||
|
|
||||||
|
### 1. Hot-reload PHP — dopo OGNI edit `.php`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec <container-fpm-nis2> kill -USR2 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Il bind-mount NON basta: `opcache.validate_timestamps=Off` → senza USR2 gli utenti vedono ancora il vecchio bytecode. USR2 = graceful FPM reload (zero downtime, ~10ms, request in volo finiscono).
|
||||||
|
|
||||||
|
⚠️ **La sezione "ARCHITETTURA: PHP-FPM con BIND MOUNT (LIVE)" più sotto è fuorviante**: il filesystem è live via bind-mount, ma il **bytecode servito** no, finché non fai `kill -USR2 1`. Aggiornare quella sezione a riflettere la realtà.
|
||||||
|
|
||||||
|
### 2. Commit immediato — niente modifiche scoperte
|
||||||
|
|
||||||
|
Appena una modifica funziona (smoke verde post-USR2):
|
||||||
|
```bash
|
||||||
|
git add <file> && git commit -m "[FEAT|FIX|DOCS] descrizione"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mai** lasciare modifiche scoperte nel working tree: il cron `ticket-agent-cron.sh` (ogni 2 min) può lanciare `claude -p` che rebase/reverta. **Caso reale 29/5**: commit `d5d83bb` (agent automatico) ha revertato `index.php` di una Feature 1 non committata → persa.
|
||||||
|
|
||||||
|
Per WIP attivo prolungato → semaforo manuale (il cron salta i container con quel lock):
|
||||||
|
```bash
|
||||||
|
echo "USER=cristiano STARTED=$(date -Iseconds)" > /tmp/agent-working.lock
|
||||||
|
# ... lavori ...
|
||||||
|
rm /tmp/agent-working.lock
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Push via host se cache token vuota (post-reboot container)
|
||||||
|
|
||||||
|
Il container NIS2 è ancora legacy (non migrato all'helper credenziali vault come `trpg-agile`). Dopo un reboot del container la `git credential-cache` in-memory è vuota → push bloccato. Invece di `git-login` interattivo, **chiedi a VIGILE/AgileHub-side**:
|
||||||
|
> "VIGILE, NIS2 ha N commit su main da pushare, fallo tu dall'host"
|
||||||
|
|
||||||
|
L'host è migrato all'helper vault, prende il PAT Gitea automatico, pusha sul bind-mount condiviso, ripristina ownership `.git`. Fix definitivo = migrazione vault helper anche per nis2-agile (richiede recreate container).
|
||||||
|
|
||||||
|
### Workflow operativo per ogni modifica
|
||||||
|
|
||||||
|
```
|
||||||
|
edit → kill -USR2 1 → smoke (curl) → bump app/version.json → git commit → git push (via host se serve)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cosa NON serve (semplificazione rispetto a TRPG)
|
||||||
|
|
||||||
|
NIS2 è **L1 master-shared** (1 istanza, `nis2.agile.software`). NON servono: plan TSSP in `hub_upgrade_plans`, image Docker build, agent run, retag registry. Quelli sono pattern TRPG **L2 partial-SaaS** per propagare a N tenant — NIS2 ha 1 sola istanza, l'edit + USR2 **È** la propagazione. Tabella di confronto nel doc completo.
|
||||||
|
|
||||||
|
📄 **Doc completo**: `docs/INCOMING_FROM_AGILEHUB_2026_05_30_release_workflow_hot_reload.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
# NIS2 Agile - Documentazione Progetto
|
# NIS2 Agile - Documentazione Progetto
|
||||||
|
|
||||||
## REGOLE DI GOVERNANCE (LEGGERE ATTENTAMENTE, aggiornate 2026-04-22)
|
## REGOLE DI GOVERNANCE (LEGGERE ATTENTAMENTE, aggiornate 2026-04-22)
|
||||||
|
|||||||
@ -0,0 +1,135 @@
|
|||||||
|
# OUTGOING → NIS2 — Workflow di rilascio + hot-reload PHP (2026-05-30)
|
||||||
|
|
||||||
|
> **Da**: AgileHub-side (VIGILE)
|
||||||
|
> **A**: sessione Claude `nis2-agile-devenv` (e qualsiasi sessione futura che lavora su NIS2)
|
||||||
|
> **Trigger**: l'utente ha segnalato che NIS2 non aveva sistematizzato due lezioni critiche scoperte sul campo (hot-reload PHP + disciplina commit). Codifico qui il pattern così non si reimpara da zero.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TL;DR — Le 2 regole d'oro
|
||||||
|
|
||||||
|
1. **Ogni modifica PHP richiede `kill -USR2 1` nel container.** Il bind-mount NON basta: `opcache.validate_timestamps=Off` in produzione → senza USR2 il vecchio bytecode resta in cache, gli utenti vedono ancora la versione precedente.
|
||||||
|
2. **Committa SUBITO ogni modifica funzionante.** Le modifiche non committate sono a rischio: il cron `ticket-agent` o altri agenti possono rebasare/revertare il working tree (è successo: commit `d5d83bb` ha revertato `index.php` di una Feature non ancora committata).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Hot-reload PHP — il pattern operativo
|
||||||
|
|
||||||
|
NIS2 (e tutti i prodotti PHP della suite con PHP-FPM + opcache) gira con `opcache.validate_timestamps=Off` per performance. Conseguenza: **opcache non rilegge i file da disco**, anche se il bind-mount li ha già aggiornati. Dopo ogni edit di `.php`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec <container-nis2-fpm> kill -USR2 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Cosa fa USR2 su FPM: **graceful reload** dei workers (zero downtime, request in volo finiscono, i nuovi workers leggono il bytecode fresco). NON serve riavviare il container, NON serve `docker compose restart`.
|
||||||
|
|
||||||
|
**Pattern per ogni modifica PHP:**
|
||||||
|
|
||||||
|
```
|
||||||
|
1. edit file.php (sul bind-mount /var/www/nis2-agile/...)
|
||||||
|
2. docker exec <nis2-fpm> kill -USR2 1
|
||||||
|
3. smoke: curl https://nis2.agile.software/<endpoint> → conferma la nuova versione risponde
|
||||||
|
4. commit + push (vedi §2)
|
||||||
|
```
|
||||||
|
|
||||||
|
Se non sei sicuro del nome esatto del container FPM:
|
||||||
|
```bash
|
||||||
|
docker ps --format '{{.Names}}' | grep -iE 'nis2.*(fpm|app|web|php)'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Eccezioni** (file che NON richiedono USR2):
|
||||||
|
- File statici (CSS, JS, immagini, HTML puro) → serviti da nginx/apache, niente cache PHP.
|
||||||
|
- File JSON/template letti a runtime senza require/include (es. config JSON parsato con `json_decode`).
|
||||||
|
- `version.json` (il polling client lo rilegge ad ogni richiesta).
|
||||||
|
|
||||||
|
In dubbio → fai USR2, costa ~10ms.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Disciplina commit — non lasciare modifiche scoperte
|
||||||
|
|
||||||
|
**Regola**: appena una modifica funziona (smoke verde dopo USR2), **commit immediato** anche se è una WIP. Niente sit-on di feature funzionanti nel working tree.
|
||||||
|
|
||||||
|
**Perché**: il cron `ticket-agent-cron.sh` ogni 2 minuti può:
|
||||||
|
- Prendere un ticket OPEN, lanciare `claude -p` nel container → l'agent modifica file, committa, potenzialmente rebase/revert se trova conflitti.
|
||||||
|
- Altri processi (sync, sso-password-sync, ecc.) possono toccare il working tree.
|
||||||
|
|
||||||
|
Lo conferma il caso reale di ieri: commit `d5d83bb` (agent automatico) ha revertato `index.php` di una Feature 1 NON ancora committata. Persa la modifica → rifatta da zero.
|
||||||
|
|
||||||
|
**Mitigazione**:
|
||||||
|
- Commit dopo OGNI step funzionante (`git add <file> && git commit -m "[FEAT] descrizione"`).
|
||||||
|
- Per work-in-progress di più step → branch dedicato (`git checkout -b feat/<nome>` poi merge in main quando completo).
|
||||||
|
- **Heads-up al cron**: se stai lavorando attivamente, crea il semaforo manuale per evitare che il cron parta:
|
||||||
|
```bash
|
||||||
|
echo "USER=cristiano STARTED=$(date -Iseconds)" > /tmp/agent-working.lock
|
||||||
|
# ... lavori ...
|
||||||
|
rm /tmp/agent-working.lock
|
||||||
|
```
|
||||||
|
Il cron salta i container con `/tmp/agent-working.lock` attivo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Git push se la credential-cache è vuota (post-reboot o container fresco)
|
||||||
|
|
||||||
|
Il container NIS2 oggi è **legacy** (non ancora migrato al vault credential helper come `trpg-agile`). Quindi:
|
||||||
|
- `git push` chiede il PAT Gitea via `git credential-cache` (in-memory).
|
||||||
|
- Dopo un reboot/restart del container → cache vuota → push bloccato.
|
||||||
|
|
||||||
|
**Workaround immediato senza git-login interattivo**: chiedi a VIGILE/AgileHub-side di pushare dall'host (l'host ha già l'helper vault). Pattern usato il 29/5:
|
||||||
|
```
|
||||||
|
"Vigile, NIS2 ha N commit su main da pushare, fallo tu dall'host"
|
||||||
|
→ ssh host: cd /var/www/nis2-agile && git -c safe.directory=. push origin main
|
||||||
|
→ chown -R git:git .git (ripristina ownership)
|
||||||
|
```
|
||||||
|
Funziona perché `/var/www/nis2-agile` (host) = `/projects/nis2-agile` (container) = stesso bind-mount → i commit fatti nel container sono visibili all'host.
|
||||||
|
|
||||||
|
**Fix definitivo** (richiede ricreate container NIS2): migrazione vault helper, pattern `trpg-agile`. Da fare quando arriva una finestra di manutenzione.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Workflow di rilascio NIS2 — versione semplificata
|
||||||
|
|
||||||
|
NIS2 è **L1 master-shared** (single-instance, `nis2.agile.software`), NON L2 partial-SaaS come TRPG. Quindi **il workflow è molto più semplice di TRPG**:
|
||||||
|
|
||||||
|
| | TRPG (L2 partial-SaaS) | NIS2 (L1 master-shared) |
|
||||||
|
|---|---|---|
|
||||||
|
| Frontend | bind-mount master → propaga istantaneo a N tenant | bind-mount → 1 sola istanza, istantaneo |
|
||||||
|
| Backend | container `trpg-data` per ogni tenant + plan TSSP + agent | nessun container per-tenant, è il container master |
|
||||||
|
| Plan in `hub_upgrade_plans` | sì (TSSP pipeline) | **no** — NIS2 non è sulla TSSP |
|
||||||
|
| Build immagine + push registry | sì (per Cat 2) | **no** |
|
||||||
|
| Bump `version.json` | sì | **sì** (per il polling client di auto-refresh) |
|
||||||
|
| Commit + push Gitea | sì | **sì** |
|
||||||
|
| Tag git `vX.Y.Z` | sì | **sì** (igienico, anche se non strettamente necessario) |
|
||||||
|
|
||||||
|
**Workflow operativo NIS2 per una release**:
|
||||||
|
```
|
||||||
|
1. Edit codice (PHP + asset)
|
||||||
|
2. kill -USR2 1 sul container FPM (per i file .php)
|
||||||
|
3. Smoke test: curl/browse → verifica funziona
|
||||||
|
4. Bump app/version.json (versione + build_id + changelog)
|
||||||
|
5. git add . && git commit -m "[FEAT|FIX|DOCS] descrizione"
|
||||||
|
6. git tag vX.Y.Z (opzionale ma consigliato)
|
||||||
|
7. git push origin main --tags (via host se cache token vuota)
|
||||||
|
```
|
||||||
|
|
||||||
|
**NON serve**: rebuild immagine Docker, plan in `hub_upgrade_plans`, agent run, retag registry. Quelli sono pattern TRPG per gestire la propagazione a N tenant. NIS2 = 1 istanza, l'edit live è già la propagazione.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Riferimenti
|
||||||
|
|
||||||
|
- **Standard ticket cross-suite**: `nexus-ticket-ms` (porta 4213), routing rules, AI auto-resolve + AWAITING_USER_CONFIRMATION (vedi `docs/ARCHITETTURA_SISTEMA_TICKET.md`).
|
||||||
|
- **Pattern TRPG L2 partial-SaaS** (per capire la differenza): `memory/reference_trpg_l2_partial_saas_frontend_bindmount.md`.
|
||||||
|
- **Standard email cross-suite** (se NIS2 manda mail): `email-automation-ms` only, vedi `docs/STANDARD_EMAIL_RELAY.md`.
|
||||||
|
- **Vault per credenziali NIS2**: `tier1__nis2-app__anthropic`, `tier1__nis2-app__voyage` (già presenti).
|
||||||
|
- **Helper credenziali Gitea**: oggi NIS2 NON è migrato. Fix futuro = pattern `trpg-agile` in CLAUDE.md AgileServices §"GIT PUSH: Vault-Backed Credential Helper".
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Cosa aggiungere al CLAUDE.md di NIS2
|
||||||
|
|
||||||
|
Quando hai una finestra, aggiungi al **vostro** CLAUDE.md (in `/var/www/nis2-agile/CLAUDE.md` o equivalente) una sezione "**Hot-reload + Release workflow**" con il riassunto delle §1, §2, §4. Così ogni nuova sessione Claude su NIS2 le ha in contesto al boot, senza doverle riscoprire.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Fine documento.** Dubbi/feedback → rispondi con un `INCOMING_FROM_NIS2_...` doc nello stesso pattern, o pingami in chat tramite l'utente.
|
||||||
Loading…
Reference in New Issue
Block a user