Mémoire Engram via MCP
Vérité de référence : @sentropic/engram 0.22.0 candidate (fb223377), fournisseur sentropic.engram.memory, connecteur engram-memory, contrat 1.0.0. Tout ce qui est marqué non vérifié n'est pas établi par les sources listées à la fin.
0. Ce que l'hôte possède (lire en premier)
- Jamais dans les arguments : tenant, workspace, scope, principal,
agent_id, session, credential,auditId, deadline, cancellation, confirmation (elicitationRef). L'hôte les lie par appel. Chaque schéma d'entrée est fermé (additionalProperties: false) : un champ supplémentaire estINVALID_SCHEMA. Omettre les champs optionnels ; ne jamais envoyernull. - Isolation du tenant et du workspace : chaque appel est lié à un seul scope exact choisi par l'hôte ; les arguments ne portent aucun sélecteur de scope. Les autorisations sont limitées par
{tenantId, workspaceId}et un scope étranger est refusé. Vous ne voyez jamais la mémoire d'un autre tenant : une cible inconnue et une cible hors de votre scope retournent toutes deuxNOT_FOUND. purpose_ref(search, get, capture) doit correspondre aupurpose_reflié par votre hôte ; une non-correspondance est un refus de protocole. La façon dont l'hôte indique lepurpose_refà l'agent estnon vérifiée: si vous ne l'avez pas, demandez à l'opérateur hôte.- Les appels mutatifs (capture, request_admission, withdraw, forget) passent la protection de mutation de l'hôte (réservation d'idempotence et condensé de l'opération).
withdrawetforgetnécessitent toujours la protection de confirmation de l'hôte (une approbation humaine liée à la capacité, à la cible et au condensé de l'opération, TTL au maximum de 300 secondes, exécution dans les 30 secondes). Capture et request_admission la nécessitent lorsque la sélection de l'hôte marque la confirmation comme requise. Vous ne pouvez pas confirmer par vous-même : unconfirmed: trueécrit par le modèle n'a aucun effet. - La maintenance n'est jamais une capacité de l'agent : administrer, bootstrap, rotation, révocation, sauvegarde, restauration, migration, invalidation de projection, supersession, contestation, rembobinage, expiration, historique ou inspection de candidat sont en dehors des six outils. L'autorisation de maintenance (
['read','maintain']) est réservée à l'hôte et n'atteint jamais le chemin de l'agent. - Chaque outil est découvert et autorisé indépendamment ; activer la mémoire ne donne pas les six outils. Un outil manquant signifie que vous ne disposez pas de cette capacité ; aucun outil de mémoire signifie que la mémoire est désactivée pour vous (désactivée par défaut ; l'hôte et le tenant doivent s'y inscrire). Ne cherchez pas d'autre voie.
- Les erreurs de protocole ne sont pas des réponses de mémoire :
-32603 Contexte d'invocation de confiance indisponible(contexte hôte manquant ou non fiable, purpose, principal, tenant ou source non correspondants, référence de confirmation manquante) et-32602 Outil inconnu. Arrêtez, signalez à l'opérateur hôte, ne réessayez pas avec des arguments modifiés.
1. Quand utiliser la mémoire, et quand ne pas l'utiliser
Utilisez-la pour les connaissances durables et réutilisables qui méritent d'être retrouvées dans une session ultérieure ou par un autre agent : décisions avec justification, faits vérifiés sur un système avec une source citable, conventions, pièges récurrents et leur correctif, faits de passation.
Ne l'utilisez pas pour : l'état de travail en cours ou brouillon, les transcriptions de chat, les sorties brutes d'outils, les notes locales à une tâche, les spéculations, ou tout ce qui est mentionné au §4. Search et get divulguent uniquement les enregistrements accepted_current ; les enregistrements en attente, rejetés, retirés, contestés, historiques, expirés, invalides par confiance et tombstonés ne sont jamais retournés.
2. Les six outils
Chaque résultat est une enveloppe. Succès : {ok: true, output: {schema_version: 1, value}, auditId, redactionClass: "high"}. Échec : {ok: false, auditId, redactionClass: "high", error: {code, message, retriable}}. Il est transporté dans structuredContent avec une copie texte JSON identique ; isError est égal à !ok. Les messages sont des chaînes sanitizées constantes : agissez sur code et retriable, jamais sur le message.
Encodages courants. Les références opaques (purpose_ref, component_id, primary_component_id, citation_id, source_ref, evidence_ref, reason_ref) sont des chaînes NFC de 1 à 512 octets UTF-8. Copiez candidate_id, record_id et page_cursor exactement comme retournés. Les instants (observed_at, expires_at) sont au format AAAA-MM-JJTHH:mm:ss.sssZ (UTC canonique, précision milliseconde). L'objet argument sérialisé fait au maximum 1 048 576 octets UTF-8.
engram_memory_search (lecture seule) : trouver les souvenirs courants avec citations et un reçu de classement.
- Entrée :
query(1 à 8 192 octets UTF-8),purpose_ref. Optionnel :limit(1 à 50, défaut 10),max_packet_bytes(4 096 à 1 048 576, défaut 65 536),capability_policy{minimum_channels: "lexical" | "lexical_and_semantic", network: "forbid" | "allow"}(défaut lexical / forbid ;allown'accorde rien),page_cursor(lenext_page_cursorprécédent, même requête et paramètres). - Sortie :
{records[], rank_receipt, next_page_cursor?, response_digest}; chaque paquet d'enregistrement est{record, redacted_fields, redaction_receipt_digest, score, rank}.recordest expurgé ;record.record_idest toujours présent. - Erreurs typiques :
STALE_PAGE(démarrer une nouvelle recherche sanspage_cursor),RANKING_UNAVAILABLE(un canal sémantique requis est indisponible ; pas de repli silencieux ; réessayer ou demander lexical),PROJECTION_OVERSIZED/RESULT_TOO_LARGE(réduirelimitou ajustermax_packet_bytes). Une listerecordsvide signifie aucune correspondance : les défaillances d'infrastructure ne sont jamais retournées comme un succès vide.
engram_memory_get (lecture seule) : lire un enregistrement courant connu sans classement.
- Entrée :
record_id(motif^mem_[a-z2-7]+$),purpose_ref. Optionnel :max_packet_bytes. - Sortie :
{record, redacted_fields, redaction_receipt_digest, read_receipt, packet_digest};read_receiptcontientrecord_id,record_digest,valid_as_of,system_as_of,validated_through_cursor,authorization_receipt_digest,revalidation_receipt_digest,checked_at,receipt_digest. - Erreurs typiques :
NOT_FOUND(inconnu, hors de votre scope, ou actuellement non éligible ; indistinguable par conception ; ne pas sonder les variantes),PROJECTION_OVERSIZED.
engram_memory_capture (ajout) : soumettre du matériel cité comme candidat en attente chiffré.
- Entrée :
idempotency_key,payload,evidence.payload:schema_version: 2,purpose_ref,valid_time {t, t_end?}(entiers sûrs,t_end >= t; utiliser millisecondes epoch : le chemin de lecture courant expédié les compare avec les instantsDate.parse, donc une autre unité peut laisser un enregistrement limité jamais courant),components(1 à 64 de{component_id, kind: "context" | "decision" | "evidence", text (1 à 65 536 octets), citation_ids (1 à 256, distincts)}),primary_component_id,primary_event {at, type_ref, citation_id}(atest un entier sûr ; son unité estnon vérifiée),citations(1 à 256 de{citation_id, source_ref, locator {scheme, value}, content_digest, observed_at? (Instant)}). Optionnel :retention {derivative_rule: "retain" | "make-ineligible", expires_at? (Instant, strictement après le moment de capture, dans le plafond de l'hôte)},reconciliation {family_refs}(triés, uniques, au maximum 64).- Références croisées : les valeurs
citation_idsont uniques ; les valeurscomponent_idsont uniques ; chaque citation de composant se résout danscitations;primary_component_idse résout danscomponents;primary_event.citation_idest danscitationset dans le composant principal. evidence:{evidence_ref, evidence_digest, citation_ids (1 à 256, distincts), attestation?};citation_idsdoit se résoudre danspayload.citations;attestationau maximum 4 096 octets.
- Sortie :
{status: "committed_pending" | "duplicate_exact", candidate_id, record_digest?, cursor, transaction_receipt_digest}.duplicate_exactest la relecture de la même identité d'idempotence avec un contenu identique. - Erreurs typiques :
INVALID_SCHEMA(y compris unexpires_atqui n'est pas après le moment de capture) ;UNAUTHORIZED(pas d'autorité de capture,retainnon autorisé par la politique de l'hôte,expires_atau-delà du plafond de l'hôte, une famille de réconciliation sans consentement de l'hôte) ;DIGEST_CONFLICT;MUTATION_OUTCOME_UNKNOWN;POLICY_UNAVAILABLE.
engram_memory_request_admission (transition d'état) : demander à la politique d'admission de l'hôte de décider d'un candidat en attente.
- Entrée :
candidate_id,idempotency_key. - Sortie :
{outcome: {status: "accepted" | "rejected" | "pending_adjudication" | "duplicate_exact", candidate_id, record_id?, cursor, decision_receipt_digest, transaction_receipt_digest}, replayed}.acceptednécessiterecord_id. Le moteur intégré l'émet lors de l'acceptation ; le schéma publié permet unrecord_idoptionnel sur d'autres statuts. Interprétezoutcome.statusetreplayed, pas la simple présence de champ ; la sémantique d'admissionduplicate_exactrestenon vérifiée.rejectedetpending_adjudicationsont des résultats de domaine réussis, pas des erreurs. - Erreurs typiques :
NOT_FOUND,POLICY_STALE(retriable),DIGEST_CONFLICT,MUTATION_OUTCOME_UNKNOWN.
engram_memory_withdraw (transition d'état, protégé par confirmation) : terminer un candidat en attente.
- Entrée :
candidate_id,idempotency_key,reason_ref(référence opaque, 1 à 512 octets). - Sortie :
{receipt: {event_id, operation: "withdraw", from_state: "pending", to_state: "withdrawn", cursor, event_digest, authorization_receipt_digest, transaction_receipt_digest}, replayed, key_destruction: "pending" | "complete"}. - Erreurs typiques :
gate_failed(pas de confirmation hôte valide),NOT_FOUND,DIGEST_CONFLICT,MUTATION_OUTCOME_UNKNOWN.
engram_memory_forget (transition d'état, protégé par confirmation) : rendre un enregistrement admis définitivement inéligible.
- Entrée :
record_id,idempotency_key,reason_ref. - Sortie :
{receipt: {..., operation: "tombstone", from_state: among accepted_current | accepted_disputed | historical | expired | trust_invalid, to_state: "tombstoned"}, replayed, projection_invalidation: "pending" | "complete", coverage_receipt_digest?}. - Erreurs typiques : comme withdraw.
Codes d'erreur et que faire. Si retriable est true, reculer et réessayer ; pour une mutation, réessayer avec la même idempotency_key et des arguments identiques. Si false, ne pas réessayer inchangé.
| Code | Action |
|---|---|
INVALID_SCHEMA, INVALID_DIGEST | Corriger les arguments par rapport au schéma fermé (limites, NFC, références croisées, format de condensé sha256: + 64 hex minuscules). |
UNAUTHORIZED, AUTHORIZATION_EXPIRED, AUTHORIZATION_REVOKED | Arrêter. Vous n'avez pas l'autorisation. Signaler à l'hôte ; ne jamais réessayer sous une autre identité. |
NOT_FOUND | Traiter la cible comme indisponible pour vous. Ne pas sonder. |
DIGEST_CONFLICT | La clé a déjà été utilisée avec un contenu ou une cible différent. Trouver pourquoi ; utiliser une nouvelle clé uniquement pour une opération vraiment nouvelle. |
ILLEGAL_TRANSITION, ALREADY_TERMINAL | L'état du cycle de vie l'interdit. Revérifier avec search ou get ; ne pas boucler. |
MUTATION_OUTCOME_UNKNOWN | L'opération a peut-être été validée. Réessayer avec la même clé et les mêmes arguments jusqu'à un résultat définitif. Ne jamais présumer que rien ne s'est passé. |
gate_failed | La confirmation ou la porte de politique n'est pas satisfaite. Demander à l'humain via l'hôte. |
STALE_PAGE | Nouvelle recherche sans page_cursor. |
RESULT_TOO_LARGE, PROJECTION_OVERSIZED | Réduire limit ou ajuster max_packet_bytes dans les limites. |
RATE_LIMITED, DEADLINE_EXCEEDED, CANCELLED, STORE_UNAVAILABLE, FENCE_LOST, CURSOR_GAP, POLICY_UNAVAILABLE, POLICY_STALE, PROJECTION_STALE, RANKING_UNAVAILABLE | Retriable : reculer, réessayer (même clé pour les mutations). Signaler si persistant. |
CAPABILITY_UNAVAILABLE, JOURNAL_CORRUPT, BLOB_MISSING, REGISTRY_VERSION_UNAVAILABLE, BACKUP_INVALID, RESTORE_REFUSED, MIGRATION_LEDGER_INVALID | Défaut opérationnel. Arrêter et signaler à l'opérateur hôte. |
3. Discipline
- Rechercher avant de capturer. Le
duplicate_exactde capture ne couvre qu'une nouvelle tentative de la même clé avec le même contenu ; ce n'est pas une vérification de duplication sémantique. Si un enregistrement courant équivalent existe, citez sonrecord_idau lieu de capturer à nouveau. - La capture crée un brouillon gouverné. Le candidat est en attente et chiffré ; il n'est pas consultable ni lisible, et un
candidate_idn'est pas unrecord_id. - L'admission est demandée, jamais présumée. Vous ne pouvez pas fournir la décision. Rapportez le résultat exact. Contenu oublié : une nouvelle capture retourne toujours
committed_pending. Surrequest_admission, une décision par ailleurs acceptante est maintenue commepending_adjudicationsi le condensé effectif de la charge utile correspond à un enregistrement tombstoné dans le même scope ; un rejet de politique ordinaire retourne encorerejected. La réutilisation de la clé de capture originale avec le même contenu est une relecture de capture (duplicate_exact), pas une nouvelle adjudication. Rapportez le résultat retourné ; ne modifiez ni ne reformulez jamais le contenu oublié pour contourner cette protection. - Provenance. Chaque composant cite au moins une citation ;
content_digestest un condensésha256:du contenu cité (canonisation exactenon vérifiée). Les citations, preuves et raisons restent des assertions jusqu'à ce que le vérificateur hôte les contrôle ; la classe de confiance est attribuée par l'hôte, jamais par vous. Votre identité d'acteur est le principal lié à l'hôte,agent_idet session ; un nom écrit danstextne porte aucune autorité. - Idempotence. Les appels mutatifs nécessitent une
idempotency_keyNFC de 16 à 256 octets UTF-8 (utiliser au moins 16 caractères ASCII ; laminLengthdu schéma JSON publié est plus laxiste que la vérification d'exécution). Une clé par opération logique, limitée à votre principal. Enregistrez-la avant d'appeler afin qu'une nouvelle tentative la réutilise. Même clé et même contenu : relecture (duplicate_exactoureplayed: true). Même clé et contenu, cible ou outil différent :DIGEST_CONFLICT. Le stockage lie chaque identité de validation à un hachage d'intention interne ; vous ne l'envoyez jamais, et une non-correspondance se manifeste commeDIGEST_CONFLICT. Les nouvelles tentatives réutilisent la rétention résolue lors de la première capture. - Rétention. Omettre
retentionsauf instruction contraire. La règle de dérivée par défaut estmake-ineligible;retainnécessite une autorisation explicite de l'hôte ; unexpires_atau-delà du plafond de l'hôte est refusé avecUNAUTHORIZED. Aucune valeur de rétention approuvée par le propriétaire n'existe dans les sources : la rétention est un point ouvert au niveau propriétaire.
4. Ce qu'il ne faut jamais stocker
- Secrets, credentials, tokens, clés API ou de signature, mots de passe, chaînes de connexion, valeurs
.env, cookies de session, et les credentials de liaison de l'hôte.
5. Références
- @sentropic/engram (référentiel source)
- Spécification du protocole MCP
- Schémas et documentation de l'outil Engram Memory