Files
Loki/docs/superpowers/specs/2026-10-16-rust-migration-lot29-telemetrie-design.md
T
Claude 8a61879bfd Lot 29 : télémétrie des complétions de la façade
Quand la façade tient la conversation (LOKI_CHAT=rust), ses complétions
rejoignent l'anneau de télémétrie du Go (perf_log.go) au lieu de passer
inaperçues : /api/perf/summary les compte, l'optimiseur en tire ses
poids, et l'interface reçoit à nouveau la perte de cache.

- chat/perf.rs : perfRecFromStats, perfRecFromWire (lu sans échec
  possible, mêmes tolérances que perfNum, timings d'un autre type
  présents mais vides comme le Go) et perfPrefix (FNV-1a cumulé) ;
- la boucle du tour range chaque complétion lue, numérotée dans le tour,
  avec ses empreintes si elle est complète ; une complétion coupée par un
  stop est rangée incomplète ; la dernière statistique porte la nature,
  la perte, ce qui s'est intercalé et l'alerte ;
- natures : main (tour), verify (vérification du mode Code), compact
  (résumé de compaction, rangé dès que la réponse se lit) ;
- le Go (/internal/v1/perf/record) range le relevé comme les siens et
  calcule l'alerte au seuil du preset actif, jamais pour un preset
  externe.

Tests : relevés et empreintes (chat/perf.rs), télémétrie de la boucle
(complète, coupée), du vrai hôte et des résumés (tests/lot6.rs),
TestFacadePerf côté Go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
2026-10-16 01:17:49 +00:00

3.3 KiB

Lot 29 — Télémétrie des complétions de la façade

Contexte

Le Go range chaque complétion dans un anneau en mémoire (perf_log.go). Pour chacune, il note :

  • combien du prompt venait du cache, combien a été recalculé ;
  • à quelle vitesse ;
  • ce que le décodage spéculatif a gardé.

Il expose des agrégats sur /api/perf/summary. Il calcule aussi la perte de cache d'une complétion : ce que le cache aurait dû reprendre de la précédente complétion de la même discussion, et n'a pas repris. Il nomme ce qui s'est intercalé entre les deux, et signale la perte à l'interface au-delà d'un seuil tiré du preset.

Quand la façade tient la conversation (LOKI_CHAT=rust), ses complétions n'apparaissaient nulle part. Le résumé des performances ignorait les tours ; l'optimiseur tirait ses poids d'une télémétrie vide ; l'interface ne recevait jamais la perte de cache.

Le lot

Les complétions de la façade rejoignent l'anneau du Go :

  • chat/perf.rs porte la partie « relevé » :

    • perfRecFromStats (complétion streamée) ;
    • perfRecFromWire (réponse non streamée, lue sans échec possible, avec les mêmes tolérances que perfNum) ;
    • perfPrefix (empreintes FNV-1a cumulées des messages envoyés).
  • TurnHost::perf range une complétion. La boucle du tour l'appelle :

    • après chaque complétion lue, complète ou non, numérotée dans le tour ;
    • avec les empreintes seulement si elle est complète ;
    • pour une complétion coupée par un stop, rangée incomplète.

    La dernière statistique d'une complétion complète porte la nature, la perte de cache, ce qui s'est intercalé et l'alerte, comme celle du Go.

  • La nature : main pour un tour, verify pour la vérification du mode Code, compact pour un résumé de compaction. Le résumé est rangé dès que sa réponse se lit, sans empreintes.

  • Le Go (/internal/v1/perf/record) range le relevé comme les siens : numéro, instant, perte de cache, ce qui s'est intercalé. Il calcule l'alerte au seuil du preset actif (perfLostAlertAt), jamais pour un preset externe.

/api/perf/summary reste au Go, qui tient l'anneau.

Tests

  • chat/perf.rs :
    • relevé d'une réponse entière : nombres en chaîne, valeurs hors bornes, octet parasite, cache d'OpenAI, timings d'un autre type ;
    • empreintes cumulées, FNV-1a de référence ;
    • relevé au format du Go.
  • La boucle du tour :
    • deux complétions numérotées, nature et totaux, empreintes qui se prolongent ;
    • dernière statistique avec la perte vue par le Go ;
    • complétion coupée rangée incomplète, sans statistique finale.
  • Le vrai hôte (tests/lot6.rs) :
    • complétions d'un tour rangées par le Go, rattachées à la discussion ;
    • résumés de compaction (rangés si la réponse se lit, pas sinon).
  • Le Go (TestFacadePerf) :
    • première complétion, perte et ce qui s'est intercalé, alerte ;
    • preset externe sans alerte, complétion incomplète ;
    • champs envoyés en trop ignorés, corps illisible, GET refusé.

Écarts assumés

  • Les empreintes sont calculées sur le JSON des messages tel que Rust l'écrit (sans l'échappement HTML du Go). Elles ne se comparent qu'entre complétions de la même discussion et de la même nature, toutes produites par la façade.
  • Une complétion coupée par un stop est rangée sans ses compteurs partiels.