Que fait Session Wrap (clôture contextuelle de projet) ?
Deux parties : §1 est universelle ; §2 achemine par projet (les tables d'état sont propres à chaque projet — n'écrivez jamais les tables d'un projet pour un autre). §0 = point de contrôle intermédiaire (ci-dessous). <MEM> = le répertoire mémoire affiché par bash ~/.claude/hooks/session-resume.sh --dir.
Rédaction AVANT toute sauvegarde (point de contrôle, mémoire de passation, fichiers de règles/maintenant, lignes de base de données, invite de reprise) : retirez les clés API, tokens, mots de passe, clés privées, numéros et soldes de comptes, données personnelles, tout élément identifiant des comptes réels. Écrivez <REDACTED — see vault> ou paraphrasez (« solde actif vérifié, non enregistré ici »). Nommer OÙ se trouve la valeur réelle est acceptable ; la valeur ne l'est pas. Même règle que la règle de paraphrase de garde-fou au §2 — gardez les deux.
0. Point de contrôle Heartbeat — EN MILIEU DE SESSION (mémoire de passation UNIQUEMENT)
Après chaque sous-tâche terminée, et AVANT toute étape longue/risquée (gros refactoring, déploiement, migration de base de données), rafraîchissez UNIQUEMENT le fichier de passation §1 du projet courant (créez-le s'il n'existe pas) : un bloc ## LIVE STATE (heartbeat) — ce qui vient d'être terminé, ce qui est en cours, la prochaine étape. Remplacez le bloc précédent, n'ajoutez jamais ; ciblez <15 lignes écrites. Gardez le titre exact : le hook le reconnaît.
- Ne REBALISEZ PAS
MEMORY.md, ne touchez à aucune base de données, et n'émettez pas l'invite de reprise — ceux-ci restent en fin de session (§1 balise, §2, §3). À la clôture, intégrez le bloc dans l'état vérifié et supprimez-le. - Un crash à tout moment coûte désormais au maximum une étape de mémoire.
session-resume.shliste chaque passation contenant encore le bloc commeUNWRAPPED HEARTBEATau prochain démarrage, donc un premier fichier heartbeat non balisé est toujours trouvé.
1. Mémoire de passation — TOUJOURS (tout projet)
Écrire/mettre à jour <MEM>/project_<projet>_handoff_<AAAAMMJJ>.md : état vérifié (SHA clés, ce qui a été livré, décisions OUVERTES, travaux suivants ordonnés, mandats). Dans <MEM>/MEMORY.md, balisez sa ligne d'index ★READ FIRST FOR <PROJECT> (current)★ ; marquez la précédente « (remplacée) ». Les anciennes passations restent sur le disque : la chaîne des remplacées constitue l'historique du projet.
- Le hook SessionStart
~/.claude/hooks/session-resume.shest PROJECT-AGNOSTIC : il injecte CHAQUE ligne correspondant àREAD FIRST FOR <N'IMPORTE-QUEL-PROJET>qui n'est pas marquée comme remplacée → baliser la ligne EST la garantie de reprise pour TOUT projet (aucun hook par projet nécessaire). Gardez le hook même si MEMORY.md est chargé automatiquement : il ajoute l'instruction « lire la passation AVANT de travailler », fonctionne depuis n'importe quel répertoire, et survit à la croissance de MEMORY.md au-delà de la limite de 200 lignes. Il avertit également lorsqu'un projet a deux pointeurs actifs ou un pointeur vers un fichier manquant — corrigez-les à la clôture.
Les règles sont reportées. Toute nouvelle règle du propriétaire, directive permanente, commande de travail ou leçon payante va dans le fichier de règles toujours chargé de ce projet dès qu'elle est donnée, pas seulement dans une passation. Fichier de règles : <MEM>/<projet>_rules.md, chargé en intégralité par session-resume.sh pour chaque projet listé dans <MEM>/session-wrap.conf. Gardez-le court ; remplacez plutôt que d'ajouter. Vérifiez à la clôture : tout ce que le propriétaire a dû répéter cette session doit maintenant y figurer. Réécrivez aussi <MEM>/<projet>_now.md (état actuel et prochaines étapes, gardez court : le contexte du hook est coupé à environ 10 000 caractères).
2. Synchronisation du magasin d'état du projet — ACHEMINER d'abord
Détectez le projet à partir du répertoire de travail / du travail de cette session. Suivez ensuite la route de ce projet. Ajoutez une route ### par projet que vous possédez ; les trois ci-dessous sont les modèles.
→ sa propre base de données
Connectez-vous avec les identifiants de l'environnement (psql "$PROJECT_DB_URL"), jamais un littéral dans la commande. Exemples de tables dans examples/state-store.sql :
INSERT INTO session_handoff (session_id, handoff_prompt, created_at) VALUES ('<sid>','<resume>',now());
INSERT INTO decisions (title,rationale,applies_to,status,session,"timestamp",decided_at)
VALUES ('<d>','<why>','<project>','implemented','<sid>',now()::text,now()); -- une INSERT par ligne
INSERT INTO code_map (module,path,lines,purpose,bounded_context) VALUES (...); -- DELETE le chemin d'abord s'il n'y a pas de contrainte unique
PIÈGES (écrivez ceux de votre propre store ici ; ce sont le genre qui coûtent une session chacun) : mettez des guillemets autour des colonnes nommées avec des mots réservés (decisions."timestamp" ; obligatoire pour les mots réservés comme "order", inoffensif sinon) et faites attention à leur type (celui-ci est text + NOT NULL, d'où now()::text) ; une colonne avec contrainte CHECK n'accepte QUE les valeurs listées (pending|implemented|superseded|deferred|rejected) ; ne supposez pas qu'une table existe — faites \d d'abord ; multi-row VALUES est atomique donc une seule mauvaise ligne supprime tout → faites ligne par ligne avec -v ON_ERROR_STOP=off. Faux positif de garde-fou : un hook PreToolUse qui bloque les commandes dangereuses grep l'INTÉGRALITÉ de la commande Bash — si votre texte SQL contient un motif bloqué littéral (reset --hard, git push, git clean), la commande entière est BLOQUÉE. Paraphrasez ces chaînes dans le texte de passation/décision (par exemple « git destructeur » pas le littéral).
→ son propre store (PAS celui d'un autre projet)
VÉRIFIEZ le schéma avant d'écrire ; les notes à son sujet deviennent obsolètes. L'infrastructure en production — le système d'enregistrement externe (fournisseur de paiement, base de production, le service en cours) est la vérité, pas la passation ; ne basculez jamais un indicateur ou un paramètre de production dans le cadre d'une clôture.
→ mémoire uniquement
Pas de magasin d'état DB — la mémoire de passation §1 EST l'enregistrement. Notez-le ; n'écrivez pas les tables d'un autre projet.
3. Émettre l'INVITE DE REPRISE (le dernier artefact — ce que l'utilisateur colle dans le prochain Claude)
Après la sauvegarde, GÉNÉREZ une invite copiable (encadrée) pour la session suivante. Le hook SessionStart injecte déjà le pointeur de passation, donc cette invite ajoute uniquement : les vérifications de rechargement + les décision(s) OUVERTE(s) que l'utilisateur doit prendre. Modèle :
Reprendre <projet>. Lire la mémoire <fichier-passation> d'abord, puis skill /<skill-carte-projet>.
État vérifié : <1 ligne : SHA clé + ce qui est actif + la chose bloquée/verrouillée>.
D'abord : 1) /context — <vérification de rechargement, p. ex. mesurer le coût d'un plugin nouvellement chargé> ; 2) <vérification de confirmation de chargement>.
Ensuite ma décision sur <FORK OUVERT> : [CHOISIR UN] (a) <rec> (b) … (c) …
<vos instructions permanentes par session, p. ex. vérifier avant de déclarer fait>
Gardez-le COURT — pointeurs + décisions, pas un vidage d'état (l'état vit dans la mémoire de passation + DB ; ne dupliquez pas → pollution du contexte). Collez également cette invite dans la mémoire de passation sous un titre ## RESUME PROMPT afin qu'elle soit interrogeable, pas perdue dans le chat.
Complétion (vérifier, citer les résultats)
- Porte de réconciliation — EXÉCUTEZ D'ABORD, obligatoire. Scannez toute la conversation (pas seulement la mémoire) et listez chaque décision, élément ouvert, correction du propriétaire et mandat de cette session. Pour CHACUN, citez-le + où il a atterri (ligne de mémoire de passation, ligne de fichier de règles, ou ligne DB) ou marquez
ABANDONNÉ : <raison d'une ligne>. « Je pense que c'est couvert » n'est pas autorisé — pointez la ligne ou marquez-le comme abandonné. Tout ce qui n'est pas comptabilisé → écrivez-le maintenant (rafraîchissez §3 si une décision OUVERTE a changé), puis re-listez. - §1 : la ligne MEMORY.md de la mémoire de passation porte
(current); l'ancienne marquée comme remplacée ;grep -c 'LIVE STATE (heartbeat)' <passation>= 0. - §2 : pour un projet DB,
SELECT max(created_at) FROM session_handoff;≈ maintenant + les comptes de lignes que vous avez écrits. Pour mémoire uniquement, dites-le. - §3 : l'invite de reprise est générée ET sauvegardée dans la mémoire de passation.