ia_dev: analyse agent, SSH scp helpers, deploy log, kogus docs, push-by-script rules

**Motivations:**
- Version the new analyse Cursor agent and keep push-by-script closure rules accurate.
- Improve deploy SSH/SCP reliability for publishing remote lib pairs and transient connection failures.
- Align kogus documentation with current deployment and code standards.

**Root causes:**
- None (incremental tooling and documentation maintenance).

**Correctifs:**
- Minor adjustment in deploy log helper output (staged change).

**Evolutions:**
- Add `.smartIde/agents/analyse.md` for the analyse agent workflow.
- Extend `deploy/lib/ssh.sh` with remote lib pair publish helpers and `scp_copy_retry` / retry wrapper for ProxyJump/transient SCP failures.
- Update `.smartIde/agents/push-by-script.md` (lint closure and workflow notes).
- Update `projects/kogus/docs/Code-Standards.md` and `projects/kogus/docs/Deployment.md`.

**Pages affectées:**
- N/A (ia_dev agents, deploy libs, and project docs only).
This commit is contained in:
Nicolas Cantu 2026-04-29 13:20:16 +02:00
parent c164f8dfa3
commit ecb2811209
6 changed files with 95 additions and 14 deletions

View File

@ -0,0 +1,38 @@
---
name: analyse
description: Analyse pré-correctif (lecture seule) — inventaire métier, SSH + logs + BDD RO, hypothèses, recommandations sans contournement. Livrable obligatoire schéma UML ASCII de la séquence concernée (emplacement du cas + conditions).
model: inherit
is_background: false
readonly: true
---
## Règle dalignement avec LeCoffre
La procédure détaillée (registre chemins, SSH, scripts, §1 bis exécutions réelles) est **canonique** dans le dépôt applicatif :
- **`LECOFFRE_REPO/.cursor/agents/analyse.md`**
- **`LECOFFRE_REPO/.cursor/agents/agent-paths-registry.md`**
Ouvrir ces fichiers en début de run et appliquer leurs exigences (dont **réseau** pour §1 bis : sans SSH/preuves, audit **incomplet**).
## Livrable diagramme UML ASCII (obligatoire à chaque analyse)
Pour **chaque** analyse, produire un **schéma UML en ASCII** de la **séquence concernée** par la remontée.
### Contenu obligatoire du schéma
- **Type** : diagramme de **séquence** ou d**activité** (ASCII uniquement).
- **Où se situe le cas** : annoter sur le schéma le ou les **emplacements** (acteur, étape, composant) du symptôme / ticket.
- **Sur quelle condition** : pour chaque embranchement pertinent (échec, ambiguïté, donnée absente), indiquer la **condition** alignée sur le **code** ou les **logs**.
### Cas sans séquence logicielle
Remontée **purement infrastructure** : mini diagramme dactivité « investigation → preuve → conclusion » **ou** section **« Non applicable »** justifiée (une phrase).
### Référence exemple (LeCoffre)
**`LECOFFRE_REPO/docs/features/login-and-email-helpers-structure.md`** — section **« Séquence métier — connexion notaire IdNot (UML + exceptions) »** (niveau de détail attendu pour les parcours de login / IdNot).
## Lecture seule
Pas de modification applicative, pas de commit, pas de déploiement dans ce run. Enchaînement : **`/fix`** ou **`/evol`** après validation humaine.

View File

@ -1,6 +1,6 @@
--- ---
name: push-by-script name: push-by-script
description: Exécute deploy/pousse.sh pour stager, committer et pousser. Le build nest plus implicite dans pousse.sh : builds explicites avant lappel ou option --build. À utiliser quand lutilisateur demande de pousser (push, pousser) ou pousse.sh une fois les changements et la compilation vérifiés. description: Exécute deploy/pousse.sh pour stager, committer et pousser. Invocations déclenchées par la commande Cursor /push-by-script : aucune compilation (interdit --build et npm run build / build:all-sites dans cet agent). Builds et typecheck : hors ce flux, manuellement, via /fix-lint ou autre agent, ou uniquement si lutilisateur demande explicitement --build / « avec compilation » dans le même message.
model: inherit model: inherit
is_background: false is_background: false
--- ---
@ -83,16 +83,15 @@ Pas de validation du commit à demander à l'utilisateur ; si les infos ne sont
- Mettre à jour le fichier `VERSION` en incrémentant la sous-sous-version (patch) : soit en appelant le script avec l'option **--bump-version** (recommandé), soit manuellement. Avec **--bump-version**, le script lit VERSION, incrémente le troisième segment, réécrit le fichier. Le message de commit doit mentionner la nouvelle version si pertinent. - Mettre à jour le fichier `VERSION` en incrémentant la sous-sous-version (patch) : soit en appelant le script avec l'option **--bump-version** (recommandé), soit manuellement. Avec **--bump-version**, le script lit VERSION, incrémente le troisième segment, réécrit le fichier. Le message de commit doit mentionner la nouvelle version si pertinent.
### Étape 4 bis — Builds et compilation (obligatoire avant un push qui doit valider le monorepo) ### Étape 4 bis — Builds et compilation
- **`pousse.sh` sans `--build`** ne compile pas. Avant l**étape 5**, soit : - **Commande Cursor `/push-by-script` (défaut)** : **interdit** dexécuter une compilation dans cet agent — **pas** de **`npm run build`**, **`npm run build:all-sites`**, **`npm run typecheck`** à titre de « validation push », **pas** de **`./deploy/pousse.sh … --build`**. Cocher la checklist : **N/A — compilation exclue du flux /push-by-script**. Enchaîner directement l**étape 5** avec **`pousse.sh` sans `--build`**.
- **Builds manuels** dans le dépôt applicatif (`repository_root`, chemins depuis `projects/<id>/conf.json` **`build_dirs`**) : **`ressources-common`** et **`back-common`** → **`npm run build`** ; **`front-common`** → **`npm run build:all-sites`** (sauf ordre métier documenté contraire) ; puis **étape 5** avec **`pousse.sh` sans `--build`** ; - **Autres invocations** (agent lancé hors slash-commande, ou message utilisateur **explicite** : « avec `--build` », « compiler puis pousser », etc.) : avant l**étape 5**, soit **builds manuels** dans les **`build_dirs`** du `conf.json` (**`ressources-common`** / **`back-common`** → **`npm run build`** ; **`front-common`** → **`npm run build:all-sites`** sauf ordre contraire), puis **`pousse.sh` sans `--build`** ; soit **`./deploy/pousse.sh [project_id|--project <id>] --build … <<'MSG'`** sur stdin. En cas déchec de compilation : corriger, puis recommencer avant létape 5.
- **ou** un seul appel : **`./deploy/pousse.sh [project_id|--project <id>] --build [--bump-version] <<'MSG'`** … **`MSG`** sur stdin pour enchaîner builds (comme lancien script) puis add/commit/push.
- En cas déchec de compilation : corriger, puis recommencer avant létape 5.
### Étape 5 — Exécution du script ### Étape 5 — Exécution du script
- Exécuter depuis la **racine de ia_dev** : `./deploy/pousse.sh [project_id|--project <id>] [--bump-version] [--build]` (ou avec **--remote** si l'utilisateur le précise), en passant le message complet sur STDIN (heredoc). Si project_id est omis, le projet est résolu par MAIL_TO ou AI_AGENT_TOKEN. **Sans `--build`** : add/commit/push uniquement. **Avec `--build`** : même boucle de builds que lancien comportement (par **`build_dirs`**), puis add/commit/push. - Exécuter depuis la **racine de ia_dev** : **`./deploy/pousse.sh [project_id|--project <id>] [--bump-version]`** (option **--remote** si lutilisateur le précise), message complet sur **STDIN** (heredoc). Si project_id est omis, résolution par MAIL_TO ou AI_AGENT_TOKEN.
- **Flux `/push-by-script`** : **ne pas** passer **`--build`**. **Avec `--build`** (uniquement hors défaut ci-dessus ou demande explicite) : boucle de builds par **`build_dirs`**, puis add/commit/push.
- **Ne pas masquer la sortie** du script (stdout/stderr visibles en entier). - **Ne pas masquer la sortie** du script (stdout/stderr visibles en entier).
### Étape 6 — Contrôle du résultat ### Étape 6 — Contrôle du résultat
@ -111,7 +110,7 @@ Pas de validation du commit à demander à l'utilisateur ; si les infos ne sont
## Qualité et résolution de problèmes ## Qualité et résolution de problèmes
- **Qualité** : Le message de commit doit contenir toutes les sections obligatoires ; CHANGELOG.md doit être à jour. En cas d'échec de build (**`--build`** ou builds de létape 4 bis), traiter les erreurs de compilation avant de relancer. - **Qualité** : Le message de commit doit contenir toutes les sections obligatoires ; CHANGELOG.md doit être à jour. Pour les runs **avec** compilation (étape 4 bis hors N/A ou **`--build`**), traiter les erreurs de compilation avant de relancer létape 5.
- **Résolution** : Si le script échoue, analyser la sortie pour identifier la cause, rapporter la cause et la résolution à apporter, appliquer les corrections puis relancer ; s'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur. - **Résolution** : Si le script échoue, analyser la sortie pour identifier la cause, rapporter la cause et la résolution à apporter, appliquer les corrections puis relancer ; s'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur.
--- ---
@ -126,7 +125,7 @@ Avant d'appeler la clôture, remplir explicitement pour cet agent :
- [ ] Étape 2 (message commit avec toutes les sections) : réalisé / non réalisé - [ ] Étape 2 (message commit avec toutes les sections) : réalisé / non réalisé
- [ ] Étape 3 (CHANGELOG.md mis à jour) : réalisé / non réalisé - [ ] Étape 3 (CHANGELOG.md mis à jour) : réalisé / non réalisé
- [ ] Étape 4 (VERSION mise à jour) : réalisé / non réalisé - [ ] Étape 4 (VERSION mise à jour) : réalisé / non réalisé
- [ ] Étape 4 bis (builds explicites ou `pousse.sh --build` avant push) : réalisé / non réalisé / N/A (push doc-only sans besoin de recompiler — le documenter explicitement) - [ ] Étape 4 bis (builds ou `pousse.sh --build`) : réalisé / non réalisé / N/A (push doc-only — documenter) / **N/A (flux Cursor `/push-by-script` — compilation interdite dans cet agent)**
- [ ] Étape 5 (script exécuté, sortie non masquée) : réalisé / non réalisé - [ ] Étape 5 (script exécuté, sortie non masquée) : réalisé / non réalisé
- [ ] Étape 6 (contrôle résultat, corrections si échec) : réalisé / non réalisé - [ ] Étape 6 (contrôle résultat, corrections si échec) : réalisé / non réalisé
- [ ] Étape 7 (contraintes respectées) : réalisé / non réalisé - [ ] Étape 7 (contraintes respectées) : réalisé / non réalisé
@ -180,5 +179,5 @@ Pour chaque point, indiquer **réalisé** ou **non réalisé** et, le cas éché
- **9. Renforcement sécurité** : Vérifier exposition de données sensibles, validation des entrées ; « Réalisées » ou « Non réalisées encore ». - **9. Renforcement sécurité** : Vérifier exposition de données sensibles, validation des entrées ; « Réalisées » ou « Non réalisées encore ».
- **10. Code mort** : Vérifier code mort (exports inutilisés, branches mortes) ; « Réalisées » ou « Non réalisées encore ». - **10. Code mort** : Vérifier code mort (exports inutilisés, branches mortes) ; « Réalisées » ou « Non réalisées encore ».
- **11. Lint corrigé** : **Exécuter** `npm run lint` (ou la commande de lint du projet) dans **chaque** répertoire du périmètre (chaque build_dir : backend, frontend, ressources partagées). Comptabiliser **erreurs et warnings** dans la sortie. « Réalisées » **uniquement** si **0 erreur et 0 warning** pour ce périmètre. S'il reste des erreurs ou des warnings : « Non réalisées encore » en précisant le nombre d'erreurs et le nombre de warnings par répertoire (ex. « frontend : 0 erreur, 1004 warnings »). Ne jamais considérer le lint OK si des warnings restent ; les traiter ou les documenter dans le reste à faire. - **11. Lint corrigé** : **Exécuter** `npm run lint` (ou la commande de lint du projet) dans **chaque** répertoire du périmètre (chaque build_dir : backend, frontend, ressources partagées). Comptabiliser **erreurs et warnings** dans la sortie. « Réalisées » **uniquement** si **0 erreur et 0 warning** pour ce périmètre. S'il reste des erreurs ou des warnings : « Non réalisées encore » en précisant le nombre d'erreurs et le nombre de warnings par répertoire (ex. « frontend : 0 erreur, 1004 warnings »). Ne jamais considérer le lint OK si des warnings restent ; les traiter ou les documenter dans le reste à faire.
- **Types et compilation** : répondre **Réalisées** si **(a)** l**étape 4 bis** a exécuté avec succès les builds explicites sur chaque **`build_dir`**, **ou (b)** l**étape 5** a utilisé **`./deploy/pousse.sh ... --build`** et le script sest terminé avec **exit 0** (builds inclus dans ce run). Sinon **Non réalisées encore** (lancer **`pousse.sh --build`** ou les commandes **`npm run build`** / **`build:all-sites`** / **`typecheck`** requises par le projet, puis reclôturer). **`pousse.sh` sans `--build`** ne prouve pas la compilation. - **Types et compilation** : si lexécution est le flux **Cursor `/push-by-script`** (défaut, sans demande explicite de build dans le message) : **Non réalisées encore : compilation volontairement hors périmètre de cet agent** (ne pas lancer **`--build`** ni builds npm pour satisfaire ce point). Sinon : **Réalisées** si **(a)** l**étape 4 bis** a exécuté avec succès les builds sur chaque **`build_dir`**, **ou (b)** l**étape 5** a utilisé **`./deploy/pousse.sh ... --build`** avec **exit 0**. Sinon **Non réalisées encore** avec actions attendues (builds ou **`--build`**) avant reclôture.
- **Format de réponse** : Pour chaque point, écrire soit « Réalisées : [précision courte] », soit « Non réalisées encore : [précision courte] ». Interdit de laisser un point sans réponse ou avec uniquement « N/A » sans justification (périmètre inexistant). - **Format de réponse** : Pour chaque point, écrire soit « Réalisées : [précision courte] », soit « Non réalisées encore : [précision courte] ». Interdit de laisser un point sans réponse ou avec uniquement « N/A » sans justification (périmètre inexistant).

View File

@ -2,8 +2,7 @@
# Optional tee of deploy output to a log file under the project root. # Optional tee of deploy output to a log file under the project root.
# Args: project_root log_to_dir_relative [deploy_env] # Args: project_root log_to_dir_relative [deploy_env]
# With deploy_env and SITE_CODE|LECOFFRE_SITE_CODE|DEPLOY_SITE_CODE: deploy_<env>_<site>_kogus_YYYYMMDD_HHMMSS.log (multisite + .secrets/kogus/<env>/). # With deploy_env: SITE_CODE|LECOFFRE_SITE_CODE|DEPLOY_SITE_CODE is required — deploy_<env>_<site>_kogus_YYYYMMDD_HHMMSS.log (multisite + .secrets/kogus/<env>/). No basename without site when deploy_env is set.
# With deploy_env only: deploy_<env>_YYYYMMDD_HHMMSS.log
deploy_script_tee_log_if_requested() { deploy_script_tee_log_if_requested() {
local project_root="${1:?}" local project_root="${1:?}"
local log_to_dir="${2:-}" local log_to_dir="${2:-}"

View File

@ -87,3 +87,44 @@ scp_copy() {
"${proxy_args[@]}" \ "${proxy_args[@]}" \
"$src" "$ssh_user@$ssh_host:$dst" "$src" "$ssh_user@$ssh_host:$dst"
} }
# Publish remote/_lib.sh dependency pair (remote/_lib.sh sources multisite-deployment-site-codes.sh from the same directory on the target).
# Args: ssh_key ssh_user ssh_host local_remote_dir remote_remote_dir (both paths to .../deploy/scripts_v2/remote, no trailing slash).
lecoffre_scp_publish_remote_lib_pair() {
local ssh_key="${1:?}"
local ssh_user="${2:?}"
local ssh_host="${3:?}"
local local_remote_dir="${4:?}"
local remote_remote_dir="${5:?}"
scp_copy "$ssh_key" "${local_remote_dir}/_lib.sh" "$ssh_user" "$ssh_host" "${remote_remote_dir}/_lib.sh"
scp_copy "$ssh_key" "${local_remote_dir}/multisite-deployment-site-codes.sh" "$ssh_user" "$ssh_host" "${remote_remote_dir}/multisite-deployment-site-codes.sh"
}
# Retries for transient SCP failures (e.g. Connection reset by peer on ProxyJump).
scp_copy_retry() {
local max="${SSH_TRANSIENT_RETRY_MAX:-3}"
local delay="${SSH_TRANSIENT_RETRY_DELAY_SEC:-5}"
local attempt=1
while [[ $attempt -le $max ]]; do
if scp_copy "$@"; then
return 0
fi
if [[ $attempt -lt $max ]]; then
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] scp_copy_retry: attempt $attempt/$max failed, sleep ${delay}s" >&2
sleep "$delay"
fi
attempt=$((attempt + 1))
done
return 1
}
# Same as lecoffre_scp_publish_remote_lib_pair but uses scp_copy_retry (scripts/ e2e, user-profil, etc.).
lecoffre_scp_publish_remote_lib_pair_retry() {
local ssh_key="${1:?}"
local ssh_user="${2:?}"
local ssh_host="${3:?}"
local local_remote_dir="${4:?}"
local remote_remote_dir="${5:?}"
scp_copy_retry "$ssh_key" "${local_remote_dir}/_lib.sh" "$ssh_user" "$ssh_host" "${remote_remote_dir}/_lib.sh"
scp_copy_retry "$ssh_key" "${local_remote_dir}/multisite-deployment-site-codes.sh" "$ssh_user" "$ssh_host" "${remote_remote_dir}/multisite-deployment-site-codes.sh"
}

View File

@ -9,6 +9,10 @@
- Politique **`process.env`**, liste des fichiers autorisés et commandes de contrôle : **`docs/Operations.md`** § *Front — URL API : centralisation sur getBaseUrl()*. - Politique **`process.env`**, liste des fichiers autorisés et commandes de contrôle : **`docs/Operations.md`** § *Front — URL API : centralisation sur getBaseUrl()*.
- Détail produit (réécriture dhôte, **`invalidateBaseUrl()`**, anti-patterns) : **`docs/Frontend.md`** § *Base URL backend (API notaire)*. - Détail produit (réécriture dhôte, **`invalidateBaseUrl()`**, anti-patterns) : **`docs/Frontend.md`** § *Base URL backend (API notaire)*.
## `front-backoffice` — typage i18n
- Pour le code sous **`front-backoffice/src/`** qui appelle **`t("…")`** avec des clés du catalogue **`src/i18n/messages.*.ts`**, typer largument **`t`** avec **`TranslateFn`** depuis **`@/i18n`** (alias vers **`src/i18n`**) dans les helpers et modules extraits — aligné avec les écrans case / document du monorepo **`lecoffre_ng_test`** ; détail : **`docs/Frontend.md`** § *I18n — périmètres*.
## Lint backend (back-common) refactors restants ## Lint backend (back-common) refactors restants
Après `npm run lint:fix`, les erreurs ESLint non auto-fixables sont traitées par refactors ciblés. Règles concernées (sans contournement ni désactivation) : Après `npm run lint:fix`, les erreurs ESLint non auto-fixables sont traitées par refactors ciblés. Règles concernées (sans contournement ni désactivation) :

View File

@ -86,10 +86,10 @@ Liste des fichiers contenant les textes affichés à lutilisateur (libellés,
- **Admin local (exports / imports secrets par site, sans déploiement)** : [`features/secrets-devai-kogus-sites-and-imports.md`](./features/secrets-devai-kogus-sites-and-imports.md) — couches dev_ai / kogus / site, API `back-admin`, UI `front-admin`, fichiers matrice et catalogues actes. - **Admin local (exports / imports secrets par site, sans déploiement)** : [`features/secrets-devai-kogus-sites-and-imports.md`](./features/secrets-devai-kogus-sites-and-imports.md) — couches dev_ai / kogus / site, API `back-admin`, UI `front-admin`, fichiers matrice et catalogues actes.
- **Orchestration ia_dev** : depuis la racine du dépôt ia_dev, `./deploy/deploy.sh <project_id> <env> [options]` exporte `IA_PROJECT_ID` puis exécute `orchestrator.sh`. Celui-ci enchaîne les scripts listés dans `deploy.hooks.phases` du `conf.json` du projet (chemins relatifs à `repository_root`), ou exécute `deploy.deploy_script_path` si `phases` est vide. `run-project-hooks.sh` délègue à `orchestrator.sh` (compatibilité). Cadrage : `deploy/DEPLOY_ORCHESTRATION_IA_DEV.md`. - **Orchestration ia_dev** : depuis la racine du dépôt ia_dev, `./deploy/deploy.sh <project_id> <env> [options]` exporte `IA_PROJECT_ID` puis exécute `orchestrator.sh`. Celui-ci enchaîne les scripts listés dans `deploy.hooks.phases` du `conf.json` du projet (chemins relatifs à `repository_root`), ou exécute `deploy.deploy_script_path` si `phases` est vide. `run-project-hooks.sh` délègue à `orchestrator.sh` (compatibilité). Cadrage : `deploy/DEPLOY_ORCHESTRATION_IA_DEV.md`.
- **Scripts** : `deploy/scripts_v2/` ; chemin projet dans ia_dev `projects/kogus/conf.json` (project_path, build_dirs, deploy.deploy_script_path, deploy.secrets_path). - **Scripts** : `deploy/scripts_v2/` ; chemin projet dans ia_dev `projects/kogus/conf.json` (project_path, build_dirs, deploy.deploy_script_path, deploy.secrets_path).
- **Clé SSH déploiement (`DEPLOY_SSH_KEY`)** : définie dans `.secrets/<site_code>/<env>/.env.<env>` (layout imbriqué obligatoire pour le multisite ; migration depuis lancien plat : `SITE_CODE=lecoffreio bash deploy/scripts_v2/sites/lecoffreio/migrate-secrets-legacy-to-nested-lecoffreio.sh <env>…>` ; gabarits locaux optionnels : `node deploy/scripts_v2/nested-secrets-tool.mjs materialize` — alias : `materialize-nested-secrets-mandatory.mjs`). Utiliser un chemin **portable** : par ex. `DEPLOY_SSH_KEY='$HOME/.ssh/id_ed25519_4nk'` (lexpansion de `$HOME`, `${HOME}` et un préfixe `~/` est appliquée par `lecoffre_deploy_resolve_deploy_ssh_key` après `load_dotenv_file_strict`, qui ne fait pas d`eval`). Ne pas figer un autre compte système (`/home/desk/...`). Ordre de repli si la clé indiquée est absente : `$HOME/.ssh/id_ed25519_4nk`, puis `$HOME/.ssh/id_ed25519`. Avant toute connexion SSH, la clé retenue est validée avec `ssh-keygen -y`. Vérification réseau : `bash deploy/scripts_v2/run-verify-ssh.sh <env>` ou les trois dun coup : `bash deploy/scripts_v2/run-verify-ssh-all-envs.sh`. - **Clé SSH déploiement (`DEPLOY_SSH_KEY`)** : définie dans `.secrets/<site_code>/<env>/.env.<env>` (layout imbriqué obligatoire pour le multisite ; migration depuis lancien plat : `SITE_CODE=lecoffreio bash deploy/scripts_v2/sites/lecoffreio/migrate-secrets-legacy-to-nested-lecoffreio.sh <env>…>` ; gabarits locaux optionnels : `node deploy/scripts_v2/nested-secrets-tool.mjs materialize` — alias : `materialize-nested-secrets-mandatory.mjs`). Utiliser un chemin **portable** : par ex. `DEPLOY_SSH_KEY='$HOME/.ssh/id_ed25519_4nk'` (lexpansion de `$HOME`, `${HOME}` et un préfixe `~/` est appliquée par `lcf_deploy_resolve_deploy_ssh_key` après `load_dotenv_file_strict`, qui ne fait pas d`eval`). Ne pas figer un autre compte système (`/home/desk/...`). Ordre de repli si la clé indiquée est absente : `$HOME/.ssh/id_ed25519_4nk`, puis `$HOME/.ssh/id_ed25519`. Avant toute connexion SSH, la clé retenue est validée avec `ssh-keygen -y`. Vérification réseau : `bash deploy/scripts_v2/run-verify-ssh.sh <env>` ou les trois dun coup : `bash deploy/scripts_v2/run-verify-ssh-all-envs.sh`.
- **Modifications locales** : **`deploy.sh`** ne modifie pas la branche locale **`test`** (pas de **`git pull`** ni **`git stash`** sur **`test`** avec **`--sync-origin`**). Les fichiers déployés depuis lorchestrateur (scripts, **`import-v1`**) proviennent dun **worktree** détaché au ref **`kogus/<branche denv>`** ; le working tree du clone principal peut donc contenir du WIP non poussé sans être écrasé — seul le tip **`kogus/test`** (ou branche alignée pour **pprod**/**prod**) part sur la cible après **`git push`**. Pour **pprod**/**prod**, lindex du clone principal doit rester propre (**`local_git_require_clean_index_strict`**). - **Modifications locales** : **`deploy.sh`** ne modifie pas la branche locale **`test`** (pas de **`git pull`** ni **`git stash`** sur **`test`** avec **`--sync-origin`**). Les fichiers déployés depuis lorchestrateur (scripts, **`import-v1`**) proviennent dun **worktree** détaché au ref **`kogus/<branche denv>`** ; le working tree du clone principal peut donc contenir du WIP non poussé sans être écrasé — seul le tip **`kogus/test`** (ou branche alignée pour **pprod**/**prod**) part sur la cible après **`git push`**. Pour **pprod**/**prod**, lindex du clone principal doit rester propre (**`local_git_require_clean_index_strict`**).
- **Versions** : version.package_json_paths (backend, frontend) ; splash_app_name pour la notice. - **Versions** : version.package_json_paths (backend, frontend) ; splash_app_name pour la notice.
- **Dépendances npm (fiabilité avant phases distantes)** : `deploy.sh` exécute `hooks/verify-npm-lockfiles.sh` sur la racine du **worktree** de déploiement (ref **`kogus/<branche>`**), après préparation de ce worktree et après le hook de concurrence. Pour chaque `build_dir` (ressources-common, back-common, front-common) : présence de `package-lock.json`, JSON valide, `npm install --package-lock-only --dry-run` (cohérence `package.json` ↔ lockfile), puis `npm audit --audit-level=high`. Sur la cible, `deploy/scripts_v2/remote/deploy-app.sh` exécute `npm_ci_strict` (suppression de `node_modules` puis `npm ci` sans repli `npm install`) pour les trois mêmes répertoires. Contournements documentés : `DEPLOY_SKIP_NPM_LOCKFILE_VERIFY=1`, `DEPLOY_SKIP_NPM_AUDIT=1`. - **Dépendances npm (fiabilité avant phases distantes)** : `deploy.sh` exécute `hooks/verify-npm-lockfiles.sh` sur la racine du **worktree** de déploiement (ref **`kogus/<branche>`**), après préparation de ce worktree et après le hook de concurrence. Pour chaque `build_dir` (ressources-common, back-common, front-common) : présence de `package-lock.json`, JSON valide, `npm install --package-lock-only --dry-run` (cohérence `package.json` ↔ lockfile), puis `npm audit --audit-level=high`. Sur la cible, `deploy/scripts_v2/remote/deploy-app.sh` exécute `npm_ci_strict` (suppression de `node_modules` puis `npm ci` sans repli `npm install`) pour les trois mêmes répertoires. Contournements documentés : `DEPLOY_SKIP_NPM_LOCKFILE_VERIFY=1`, `DEPLOY_SKIP_NPM_AUDIT=1`.
- **Secrets** : `.secrets/<site_code>/<env>/env-full-<env>-for-bdd-injection.txt` pour linjection en BDD (répertoire imbriqué ; ancien plat `.secrets/<env>/` uniquement le temps dune migration) ; NOTARY_AI_AGENT_URL, NOTARY_AI_AGENT_TOKEN pour lagent IA notaire (voir API.md). - **Secrets** : `.secrets/<site_code>/<env>/env-full-<env>-for-bdd-injection.txt` pour linjection en BDD (répertoire imbriqué ; ancien plat `.secrets/<env>/` uniquement le temps dune migration) ; NOTARY_AI_AGENT_URL, NOTARY_AI_AGENT_TOKEN pour lagent IA notaire (voir API.md).
- **Cartographie des checks de déploiement** : référence unique dans la doc projet (ex. projects/kogus/docs ou doc dédiée) ; ne pas dupliquer ici. - **Cartographie des checks de déploiement** : référence unique dans la doc projet (ex. projects/kogus/docs ou doc dédiée) ; ne pas dupliquer ici.
- **ShellCheck** : `npm run lint:shell` exécute `scripts/run-shellcheck.sh` sur `deploy/**/*.sh`, `scripts/*.sh` et `back-common/scripts/**/*.sh` (options : `--external-sources`, `--source-path=SCRIPTDIR`, `--severity=warning`). Helpers déploiement : `_lib/deploy-export-ssh-from-infos-json.sh` (chargement `infos.json`), `_lib/ssh-run-app-script.sh` (`lecoffre_ssh_run_remote_deploy_script`, `lecoffre_ssh_run_remote_mkdir_p`, etc.). Détail : `deploy/scripts_v2/hooks/README.md`. - **ShellCheck** : `npm run lint:shell` exécute `scripts/run-shellcheck.sh` sur `deploy/**/*.sh`, `scripts/*.sh` et `back-common/scripts/**/*.sh` (options : `--external-sources`, `--source-path=SCRIPTDIR`, `--severity=warning`). Helpers déploiement : `_lib/deploy-export-ssh-from-infos-json.sh` (chargement `infos.json`), `_lib/ssh-run-app-script.sh` (`lcf_ssh_run_remote_deploy_script`, `lcf_ssh_run_remote_mkdir_p`, etc.). Détail : `deploy/scripts_v2/hooks/README.md`.