8 min de lecture

Comment enregistrer les actions d'agent annulées sans mentir

Définissez honnêtement les résultats d'audit des actions d'agent annulées pour les délais d'attente, les déconnexions et les accusés de réception perdus, afin d'enquêter en toute sécurité sur les effets inconnus.

Comment enregistrer les actions d'agent annulées sans mentir

Un journal d'audit qui qualifie chaque action d'agent annulée d'« échouée » ment. L'agent a peut-être cessé d'attendre, mais la ligne de la base de données existe peut-être déjà, le déploiement est peut-être déjà en cours, ou la commande distante continue peut-être de s'exécuter après la disparition de la connexion.

La solution n'est pas d'allonger la liste des codes d'échec. Il faut un modèle de résultat qui distingue ce que la passerelle a observé de ce qui s'est produit sur la cible. Les enquêteurs doivent pouvoir différencier une action qui n'a jamais quitté la machine, une action refusée par la destination, une action terminée avec un reçu et une action dont l'effet reste inconnu.

Le résultat de l'appelant n'est pas celui de l'action

L'appelant ne voit qu'une petite partie de l'action : il envoie le travail et attend une réponse. L'action traverse plusieurs systèmes qui n'ont ni la même horloge, ni la même durée de vie de processus, ni une voie de retour fiable. Lorsque l'appelant annule, se déconnecte ou atteint son délai limite, il apprend quelque chose sur sa propre attente. Il n'a pas nécessairement obtenu d'information définitive sur l'effet distant.

Cette distinction compte surtout pour les opérations qui modifient l'état. Créer un ticket, effectuer un remboursement, appliquer des changements d'infrastructure, supprimer un objet, renouveler un jeton d'accès et exécuter une commande distante peuvent tous produire des effets qui survivent à l'absence de réponse. Si votre journal écrit failed parce que le processus de l'agent s'est arrêté le premier, une nouvelle tentative peut créer un deuxième ticket, effectuer un deuxième remboursement ou exécuter deux fois la commande destructive.

Les opérations de lecture exigent la même honnêteté, même si le risque est différent. Une récupération annulée peut renvoyer une vue incomplète et conduire l'agent à prendre une mauvaise décision. Elle ne modifie généralement pas le système à elle seule. Un POST, un PATCH, un DELETE ou une commande shell distante le peuvent.

Séparez toujours trois éléments dans chaque enregistrement :

  • Décision de l'appelant : terminée, annulée, déconnectée ou interrompue par délai d'attente.
  • Preuve d'envoi : jamais démarrée, démarrée localement, octets remis au transport ou reçu confirmé par le système distant.
  • Résultat de l'effet : aucun effet, réussie, refusée, partiellement exécutée ou effet inconnu.

Les équipes fusionnent souvent le premier et le troisième champ parce qu'une seule colonne d'état est pratique. Cette commodité tient jusqu'à l'examen d'un incident. Il faut alors expliquer pourquoi « requête annulée » apparaît à côté d'un objet qui existe manifestement en production.

La règle pratique est simple : n'écrivez aucun effet que lorsque les preuves excluent l'exécution. Écrivez effet inconnu lorsque l'exécution reste plausible et qu'aucun résultat fiable n'est disponible. L'inconnu n'est pas une lacune gênante du journal. C'est le résultat exact d'une action distribuée dont le chemin d'observation a été interrompu.

Enregistrez la limite des preuves, pas une histoire supposée

Chaque action a besoin d'une limite explicite au-delà de laquelle la passerelle ne peut plus promettre honnêtement que rien ne s'est produit. Appelez-la limite d'envoi. Pour HTTP, elle peut correspondre au moment où la requête est validée sur une connexion et remise au système d'exploitation, ou au moment où un service en amont confirme sa réception. Pour SSH, elle peut correspondre au moment où l'outil auxiliaire envoie la demande de commande sur un canal authentifié.

Ne prétendez pas qu'un simple booléen sent=true règle la question. Les écritures locales peuvent être mises en mémoire tampon. Une bibliothèque de transport peut signaler une écriture avant que l'application distante ne lise les données. Un pair peut recevoir une requête, appliquer la modification et perdre la réponse sur le chemin du retour. Le journal doit décrire la preuve la plus solide disponible, sans transformer un détail d'implémentation en preuve.

Un enregistrement d'action utile contient des identifiants immuables et une suite d'observations. Cette structure compacte convient aussi bien à un appel d'API qu'à l'exécution d'une commande :

{
  "action_id": "act_01JQ7M4V6K",
  "session_id": "ses_01JQ7M2Y8A",
  "channel": "http",
  "intent": {
    "method": "POST",
    "target": "api.example.internal/v1/releases",
    "request_fingerprint": "sha256:...",
    "idempotency_token": "release_01JQ7M4V6K"
  },
  "observations": [
    {"at": "2026-07-22T16:40:01Z", "kind": "authorized"},
    {"at": "2026-07-22T16:40:02Z", "kind": "dispatch_started"},
    {"at": "2026-07-22T16:40:03Z", "kind": "transport_write_completed"},
    {"at": "2026-07-22T16:40:33Z", "kind": "caller_deadline_exceeded"}
  ],
  "caller_disposition": "timed_out",
  "effect_outcome": "unknown_effect",
  "outcome_basis": "response_not_observed_after_dispatch"
}

L'empreinte de la requête identifie ce qui a été tenté sans placer dans le journal un identifiant bearer, le corps brut de la requête ou un argument de commande secret. L'identifiant doit rester stable entre les nouvelles tentatives et la vérification ultérieure. Si un opérateur ne peut pas relier la requête d'origine, sa nouvelle tentative et l'objet distant final, la trace d'audit ne répond pas à la question importante.

Il existe une différence importante entre dispatch_started et transport_write_completed. Le premier indique que la passerelle a commencé l'opération. Le second indique que le transport local a accepté les données sortantes. Aucun des deux ne signifie que l'application distante les a exécutées. Si votre implémentation ne peut pas les distinguer, consignez le fait le moins précis et indiquez-le dans la base du résultat.

Une annulation avant l'envoi peut signifier aucun effet

Une annulation peut justifier la conclusion « aucun effet », mais uniquement avant que la passerelle n'engage l'action sur un canal extérieur. C'est le cas clair : l'agent retire sa demande alors qu'elle attend encore une autorisation locale, avant le déverrouillage du coffre, avant le début d'une requête HTTP ou avant qu'une commande SSH soit remise à l'outil de transport.

L'entrée d'audit doit expliquer pourquoi cette conclusion est sûre. « Annulée » ne suffit pas à indiquer à l'enquêteur où l'annulation est intervenue. Enregistrez une étape et un point de preuve local.

{
  "action_id": "act_01JQ7P1N2R",
  "caller_disposition": "canceled",
  "effect_outcome": "no_effect",
  "outcome_basis": "cancellation_observed_before_dispatch",
  "last_observed_stage": "awaiting_authorization"
}

Ce résultat convient également lorsque la barrière locale refuse l'action avant toute requête extérieure. Une approbation manquante, un coffre verrouillé, une session révoquée ou une requête locale invalide peuvent tous produire aucun effet, à condition que la passerelle n'ait jamais envoyé le travail. Le journal doit distinguer une requête refusée d'une requête annulée, car elles racontent des choses différentes sur le contrôle humain et le comportement de l'agent, même si les deux peuvent affirmer que la cible n'a rien reçu.

N'appliquez pas cette étiquette après avoir créé une connexion et commencé une écriture, simplement parce que l'appel de transport renvoie une erreur d'annulation. De nombreuses bibliothèques utilisent une même valeur d'erreur pour plusieurs situations : annulation dans la file d'attente, pendant une écriture, en attendant les en-têtes de réponse ou pendant la lecture du corps. Ces situations ne sont pas interchangeables.

La propagation de l'annulation a une utilité, mais ce n'est pas une machine à remonter le temps. Les recommandations de gRPC indiquent qu'une annulation du client signale qu'il n'a plus besoin du résultat de l'appel RPC et recommandent aux serveurs d'arrêter le travail et de propager l'annulation aux opérations en aval. C'est une bonne hygiène des ressources. Cela ne prouve pas qu'un effet secondaire antérieur a été annulé et ne peut pas annuler une écriture validée indépendamment.

Si le service récepteur propose un point de terminaison d'annulation explicite associé à un identifiant d'opération, enregistrez-le comme une seconde action. Son résultat ne peut modifier le résultat de l'effet initial que si le service fournit une déclaration fiable sur l'opération d'origine. Une demande d'annulation faite au mieux, dont la réponse arrive après une coupure réseau, crée un autre effet inconnu. Elle ne nettoie pas la première par magie.

Un délai d'attente après l'envoi produit un effet inconnu

Une échéance est une limite locale d'attente. Ce n'est pas un verdict sur l'exécution distante. Une fois que l'action a franchi la limite d'envoi, un délai d'attente doit par défaut produire un effet inconnu, sauf si un reçu du protocole ou une vérification ultérieure apporte une preuve supplémentaire.

HTTP est facile à mal interpréter, car les libellés d'état semblent définitifs. RFC 9110 indique qu'un 408 signifie que le serveur n'a pas reçu un message de requête complet dans le délai qu'il acceptait d'attendre. Un 504 signifie qu'une passerelle n'a pas reçu à temps une réponse d'un serveur en amont. Les deux énoncés décrivent un observateur et un échange précis. Aucun ne prouve qu'un autre système n'a pas agi sur des données déjà reçues.

Imaginez un agent qui envoie POST /v1/releases avec une échéance de 30 secondes. L'API valide la requête, insère une ligne de version, demande à un contrôleur de déploiement de démarrer, puis reste bloquée en préparant sa réponse. Au bout de 30 secondes, l'agent voit un délai d'attente. La version existe. Une nouvelle tentative sans jeton d'idempotence peut créer une autre version, même si le premier appel est marqué « échoué » dans la transcription de l'agent.

L'enregistrement honnête ressemble à ceci :

{
  "caller_disposition": "timed_out",
  "effect_outcome": "unknown_effect",
  "outcome_basis": "deadline_after_transport_write_no_remote_receipt",
  "recovery_required": "lookup_by_idempotency_token"
}

N'utilisez pas failed comme raccourci pour inconnu. Réservez les résultats d'échec aux faits que vous pouvez établir : un service distant a renvoyé une erreur de validation, une commande a renvoyé un code de sortie différent de zéro, une connexion n'a pas pu être établie avant qu'une requête ne quitte la passerelle, ou une autorisation locale a refusé l'exécution. Un délai d'attente ne satisfait pas ce critère dès lors que l'envoi sortant a pu avoir lieu.

Le résultat partiel mérite sa propre catégorie lorsque le système distant fournit des preuves. Les API par lots et les scripts effectuent souvent une partie du travail avant d'échouer. Si un service renvoie une liste d'identifiants d'objets terminés suivie d'une erreur, enregistrez partial_effect, conservez les identifiants lorsque la politique l'autorise et capturez la raison indiquée par le service. Dire simplement « échoué » masque le travail précis de nettoyage que l'opérateur doit effectuer.

Les accusés de réception perdus nécessitent un enregistrement distinct

Ne transmettez plus les secrets API
Sallyport exécute les requêtes HTTP authentifiées sans transmettre à l'agent les secrets bearer, basic ou des en-têtes personnalisés.

Un accusé de réception perdu survient après que le récepteur a peut-être agi, mais avant que la passerelle ne reçoive un reçu final. Le cas est assez fréquent pour mériter une observation nommée plutôt qu'une erreur réseau générique.

La séquence semble généralement ordinaire jusqu'au dernier moment :

  1. La passerelle autorise et envoie une action.
  2. Le service distant l'accepte et effectue, ou met en file, le travail demandé.
  3. La réponse est retardée, la connexion se coupe ou le processus local s'arrête.
  4. La passerelle ne possède aucune preuve durable de l'achèvement, même si le système distant en possède peut-être une.

La première erreur consiste à écraser l'entrée d'origine lorsqu'une recherche ultérieure aboutit. Le journal donne alors l'impression que la passerelle connaissait le résultat au moment des faits. L'enquêteur a besoin des deux informations : l'appel initial s'est terminé sans accusé de réception, puis une vérification ultérieure a trouvé un résultat distant correspondant.

Ajoutez une observation :

{
  "action_id": "act_01JQ7M4V6K",
  "reconciliation": {
    "at": "2026-07-22T16:43:10Z",
    "method": "GET /v1/operations/release_01JQ7M4V6K",
    "remote_reference": "op_8f2c",
    "result": "succeeded"
  },
  "effect_outcome": "succeeded",
  "outcome_basis": "remote_operation_lookup"
}

La décision initiale de l'appelant reste timed_out. Ne la réécrivez pas en completed. L'appelant a bien subi un délai d'attente. Le système a ensuite appris que l'action distante avait réussi. Ces deux faits coexistent sans contradiction.

Un reçu distant n'est fiable que si sa corrélation l'est aussi. Faire correspondre un nom d'objet, l'heure actuelle ou du langage naturel fourni par l'agent est fragile. Préférez un jeton d'idempotence accepté par la cible, un identifiant d'opération renvoyé avant le début d'un travail long ou un identifiant de requête du fournisseur que la cible garantit comme unique pour la requête. Si la destination n'en propose aucun, utilisez une requête de lecture ciblée et indiquez pourquoi elle suffit ou pourquoi elle reste ambiguë.

Par exemple, découvrir un nouvel utilisateur nommé build-bot ne prouve pas quelle requête de création l'a produit. Découvrir un objet dont le jeton de requête enregistré est égal au jeton d'action original est beaucoup plus probant. Cette différence détermine si vous pouvez réessayer sans risque.

L'idempotence transforme la récupération en vérification plutôt qu'en pari

L'idempotence n'est pas une autorisation de réessayer ajoutée après coup. C'est un contrat établi avant l'envoi. Le client fournit un jeton stable et le service garantit que les requêtes répétées avec ce jeton désignent la même opération logique au lieu de créer de nouveaux effets.

Pour chaque intégration HTTP qui modifie l'état, posez au responsable du service quatre questions directes :

  • Accepte-t-il un jeton d'idempotence fourni par l'appelant ?
  • Quels champs de la requête doivent rester identiques lorsque le jeton est réutilisé ?
  • Combien de temps conserve-t-il la correspondance entre le jeton et le résultat ?
  • L'appelant peut-il récupérer le résultat original après une réponse perdue ?

Si les réponses restent vagues, ne présentez pas la nouvelle tentative automatique comme sûre. « Nous dédupliquons généralement » n'est pas un contrat. Une éviction du cache, un basculement régional ou une modification de l'analyseur de requêtes peut transformer cette hypothèse en travail dupliqué.

Lorsque la cible ne prend pas en charge l'idempotence, découpez une opération risquée si possible. Créez un brouillon durable avec une référence externe unique, vérifiez ce brouillon, puis lancez la commande irréversible avec l'identifiant qu'il a renvoyé. Cela ne rend pas toutes les opérations sûres, mais crée un point de vérification avant la partie coûteuse ou destructive.

Un flux de déploiement illustre cette différence. Un point de terminaison unique qui crée et démarre une version laisse peu de possibilités après la perte d'un accusé de réception. Un flux en deux appels peut créer une version avec l'identifiant d'action comme référence externe, rechercher cette référence après un délai d'attente et ne la démarrer qu'une fois qu'un identifiant de version est connu. Cet appel supplémentaire coûte généralement moins cher qu'une explication à fournir après une modification inattendue en production.

Ne générez jamais un nouveau jeton d'idempotence pour une nouvelle tentative automatique de la même action. Un nouveau jeton déclare que la tentative est une nouvelle requête logique. Cela peut être correct lorsqu'un humain répète volontairement le travail, mais annule la déduplication pendant la récupération. Conservez le jeton original dans l'enregistrement d'action et faites en sorte que la nouvelle tentative cite l'identifiant de l'action parente.

Un contrat d'idempotence aide aussi lors de la réponse aux incidents. Les enquêteurs peuvent poser une question concrète : « Quelle décision la cible a-t-elle prise pour le jeton X ? » Sans ce contrat, ils doivent déduire l'intention à partir des heures, des journaux et des noms. C'est lent, sujet aux erreurs et souvent impossible après l'expiration des périodes de conservation.

La fermeture SSH et la fin d'une commande sont deux faits différents

Bloquez l'envoi depuis le coffre
Verrouillez le coffre pour refuser toute action jusqu'au déverrouillage de la barrière matérielle du Mac.

SSH favorise une confusion similaire, car une session fermée donne l'impression que la commande s'est arrêtée. Ce n'est pas nécessairement le cas. Une rupture réseau peut interrompre le client alors que le processus distant continue sous son shell parent, son superviseur ou son gestionnaire de services. À l'inverse, un processus peut terminer son travail alors que le client ne reçoit pas le rapport de sortie.

RFC 4254 considère la fermeture du canal, la fin de fichier et le statut de sortie comme des événements de protocole distincts. Il recommande de renvoyer un statut de sortie lorsqu'une commande distante se termine, mais ne fait pas de la fermeture du canal la preuve que ce statut a été reçu. La spécification indique également que les pairs échangent des messages de fermeture avant de considérer chacun le canal comme fermé. Cela renseigne sur l'état du canal SSH, pas sur la réalisation d'une modification du système de fichiers ou d'un service avant la disparition du canal.

Enregistrez les preuves SSH comme des observations distinctes :

{
  "channel": "ssh",
  "observations": [
    {"kind": "command_request_sent"},
    {"kind": "stdout_received", "bytes": 1840},
    {"kind": "connection_lost"}
  ],
  "caller_disposition": "disconnected",
  "effect_outcome": "unknown_effect",
  "outcome_basis": "no_exit_status_or_remote_process_identity"
}

Si vous recevez un statut de sortie valide et une fermeture complète du canal après la sortie de la commande, vous disposez d'une preuve solide concernant le processus de commande, sans toutefois avoir la preuve absolue de chaque effet externe qu'il a déclenché. Un script peut envoyer avec succès un travail asynchrone et se terminer avec le code zéro avant la fin de ce travail. Enregistrez le résultat de la commande comme réussi, puis modélisez le travail externe comme une opération distincte si le système distant vous fournit un identifiant.

Les commandes ont besoin d'un plan de récupération avant d'être exécutées par un agent. Préférez les commandes qui affichent ou écrivent un identifiant d'opération durable. Pour un redémarrage de service, interrogez le gestionnaire de services avec un nom d'unité connu et comparez l'état avant et après. Pour une migration de base de données, consultez le registre des migrations plutôt que de faire confiance à la sortie du terminal. Pour une opération sur un fichier, vérifiez une empreinte de contenu et un marqueur de version ou de génération, pas seulement l'existence d'un chemin.

Évitez de considérer l'envoi d'un signal à un outil auxiliaire local comme la preuve que le processus distant s'est arrêté. Le signal peut arriver avant l'envoi distant, après l'achèvement de la commande distante ou après la rupture de la connexion. Enregistrez le signal comme un événement de l'appelant ou de la passerelle. Ne modifiez le résultat de l'effet que lorsque le point de terminaison distant fournit une preuve.

L'enquête commence par la chronologie, pas par une étiquette finale

Retrouvez l'exécution de l'agent à l'origine
Utilisez le journal Sessions pour identifier le processus de l'agent à l'origine d'une action avant d'en examiner le résultat.

Un enquêteur doit pouvoir reconstituer une action indéterminée sans deviner quelle ligne de journal est arrivée en premier. Il faut pour cela un identifiant d'action stable, un identifiant de session, un ordre monotone des événements dans la passerelle et des horodatages pour les événements observés. L'heure civile aide à faire les rapprochements, mais elle peut dériver d'un système à l'autre. Ne fondez pas toute votre conclusion sur deux horloges qui concordent à la milliseconde près.

Une bonne enquête pose les questions dans cet ordre :

  1. Qui a autorisé l'action et quel processus d'agent a envoyé la demande ?
  2. La passerelle a-t-elle franchi sa limite d'envoi ?
  3. Quelles observations de transport ont eu lieu après l'envoi ?
  4. Un reçu distant fiable est-il arrivé ?
  5. Dans le cas contraire, quelle requête de vérification peut identifier l'opération logique d'origine ?

Cette séquence évite une mauvaise habitude courante : commencer par les journaux distants, trouver un événement similaire et le déclarer comme réponse. Commencez par l'action prévue et ses éléments de corrélation. Évaluez ensuite si les preuves distantes correspondent exactement à cette opération.

L'enregistrement d'audit doit résister aux modifications discrètes. Si un opérateur peut remplacer unknown_effect par succeeded sans conserver l'état précédent ni la base de cette mise à jour, l'enregistrement devient une affirmation plutôt qu'une preuve. Les enregistrements en ajout uniquement, le chaînage par hachage et la vérification hors ligne rendent les modifications postérieures à un incident plus difficiles à dissimuler. Ils ne prouvent pas que tous les systèmes distants ont dit la vérité, mais ils préservent ce que la passerelle a observé et à quel moment elle en a appris davantage.

Sallyport conserve les exécutions d'agents et les actions individuelles dans des journaux distincts, projetés depuis un journal d'audit chiffré et chaîné par hachage, et sp audit verify peut vérifier la chaîne hors ligne sur le texte chiffré. Cette conception est utile ici, car une vérification ultérieure peut être enregistrée comme un nouveau fait sans effacer le délai d'attente ou la déconnexion d'origine.

Ne placez pas de corps de requête contenant des secrets dans une trace d'audit uniquement pour faciliter la réponse aux incidents. Stockez les cibles assainies, les empreintes de requêtes, les identifiants d'opération approuvés, les classifications de réponses et les références distantes minimales nécessaires à la vérification. Un journal qui résout une enquête en divulguant des identifiants crée lui-même l'incident suivant.

Les noms de résultats doivent guider le comportement sûr de l'agent

Une taxonomie des résultats ne mérite sa place que si l'environnement d'exécution de l'agent réagit différemment à chaque résultat. Si chaque résultat autre qu'un succès entraîne une nouvelle tentative immédiate, les étiquettes d'audit détaillées ne sont que décoratives.

Appliquez ces règles opérationnelles :

  • Ne réessayez automatiquement après no_effect que si l'intention originale reste autorisée et pertinente.
  • Après rejected, ne réessayez qu'une fois que l'agent a modifié l'entrée invalide ou qu'un humain a résolu le conflit indiqué.
  • Vérifiez unknown_effect avant de relancer toute action qui modifie l'état.
  • Traitez partial_effect comme une tâche de nettoyage ou de continuation, pas comme une nouvelle opération sans historique.
  • Faites remonter le cas lorsque la vérification ne peut pas identifier une seule opération distante correspondante.

C'est sur la dernière règle que les équipes perdent patience. Elles veulent que l'agent continue. Cette réaction est compréhensible pour une requête de lecture, mais elle est imprudente pour les actions qui dépensent de l'argent, modifient des accès, changent la production ou suppriment des données. Une action non résolue doit rester visible jusqu'à ce qu'une personne ou une requête distante fiable comble le manque de preuves.

Votre processus d'approbation ne doit pas masquer cette distinction. Un humain qui a approuvé une action a approuvé une tentative, pas un nombre illimité de nouvelles tentatives après un résultat inconnu. Si la tentative suivante peut créer un second effet, indiquez qu'il s'agit d'une nouvelle tentative d'une action indéterminée et demandez une nouvelle décision lorsque le risque le justifie.

Construisez ce modèle avant d'ajouter d'autres canaux ou davantage de comportements autonomes. Le premier délai d'attente après une modification importante par un agent est le pire moment pour découvrir que votre journal d'audit ne possède que deux résultats : succès et ce que le client a bien voulu voir.

FAQ

Que signifie « effet inconnu » dans un journal d'audit ?

Utilisez « effet inconnu » lorsque l'action a pu atteindre le système distant, mais que votre passerelle ne peut pas prouver le résultat final. Un délai d'attente du client, une réponse perdue ou une connexion SSH interrompue entrent dans cette catégorie si l'envoi a pu avoir lieu. Ne remplacez pas cette incertitude par « échec », car cela rendrait une nouvelle tentative plus trompeusement sûre.

Quand une action d'agent peut-elle être marquée comme n'ayant aucun effet ?

N'enregistrez « aucun effet » que lorsque l'action n'a jamais franchi la limite d'envoi, ou lorsqu'un système distant fiable prouve qu'il a refusé la requête avant de l'exécuter. Une annulation locale avant l'écriture sur le socket en est un bon exemple. Un délai d'attente après la sortie des données du processus n'en est pas un.

Un délai d'attente d'API signifie-t-il que l'action a échoué ?

Un délai d'attente indique que l'appelant a cessé d'attendre. Il ne dit pas si le service a reçu la requête, l'a mise en file, l'a exécutée, ou l'a terminée juste après l'abandon de l'appelant. Traitez tout délai d'attente sur une action qui modifie l'état comme un effet inconnu jusqu'à ce qu'une vérification apporte une autre preuve.

Une requête annulée est-elle la même chose qu'une requête échouée ?

Une annulation signifie que l'appelant ne veut plus recevoir le résultat. Elle peut survenir avant l'envoi, pendant le transfert, après l'acceptation distante ou après l'exécution, mais avant l'accusé de réception. Ce sont des événements différents qui nécessitent des résultats d'audit différents.

Qu'est-ce qu'un accusé de réception perdu ?

Un accusé de réception perdu survient lorsque le système distant a peut-être terminé le travail, mais que la passerelle ne reçoit jamais la réponse finale. C'est fréquent après une interruption réseau ou l'arrêt d'un processus. Enregistrez l'absence de reçu séparément du résultat de l'action afin que l'enquêteur voie pourquoi l'état reste inconnu.

Un agent doit-il réessayer après un délai d'attente ?

Ne relancez pas automatiquement une requête qui modifie l'état après un résultat indéterminé. Commencez par utiliser un jeton d'idempotence, une requête de lecture de vérification ou une recherche d'opération propre au fournisseur. Si aucune de ces options n'existe, demandez une décision humaine, car la seconde requête peut dupliquer la première.

Les codes HTTP 408 ou 504 peuvent-ils prouver que rien ne s'est passé ?

Les codes d'état HTTP décrivent ce que sait le serveur ou la passerelle qui répond, et non une vérité universelle sur l'effet produit par la cible. RFC 9110 définit 408 comme un message de requête incomplet reçu par le serveur et 504 comme une attente trop longue d'une réponse en amont par une passerelle. Aucun de ces codes ne prouve qu'une action en aval n'a eu aucun effet.

Une déconnexion SSH signifie-t-elle que la commande distante s'est arrêtée ?

Un statut de sortie SSH prouve que la commande distante s'est terminée et a transmis un code via le canal. Un canal fermé sans statut de sortie fournit une preuve plus faible, car la connexion peut s'interrompre alors que la commande continue. Enregistrez séparément la fin de la sortie, le statut de sortie et la fermeture du canal.

Quels champs doit contenir l'événement d'audit d'une action indéterminée ?

Un événement utile enregistre l'intention, la décision d'autorisation, la tentative d'envoi, les étapes du transport, l'accusé de réception distant, le résultat observé et toute vérification ultérieure. Il doit aussi contenir des identifiants de corrélation stables et des empreintes de requête assainies. Ne stockez pas d'identifiants ni de contenus sensibles bruts uniquement pour donner au journal une apparence plus complète.

Comment une vérification ultérieure doit-elle mettre à jour un enregistrement d'audit ?

Conservez l'événement initial immuable et ajoutez un événement de vérification ultérieure qui cite le même identifiant d'action. Vous préservez ainsi ce que les opérateurs savaient au moment donné, au lieu de réécrire l'historique après une recherche. L'enquêteur peut aussi distinguer une confirmation tardive d'une action dont la réussite était connue immédiatement.

Sallyport

Sallyport exécute les appels d'API et les commandes SSH à la place de votre agent IA. Les clés restent dans un coffre-fort local sur votre Mac ; vous approuvez chaque exécution et chaque action est consignée dans un journal scellé.

© 2026 Sallyport · Open source sous Apache-2.0 · Oleg Sotnikov