Files
Loki/docs/superpowers/specs/2026-10-16-rust-migration-lot46-recall-design.md
T
Claude 92e9adee7d Lot 46 : outils recall et recall_search exécutés par la façade
Les deux outils qui rappellent un bloc archivé par la compaction ne passent
plus par /tool/exec du Go : src/recall.rs porte toolRecall et
toolRecallSearch (id tolérant comme recallIDToSeq, mots-clés en minuscules
rune par rune comme strings.ToLower, score libellé double et plus récent
d'abord, limites, extraits et textes du Go). L'archive reste au Go, seul à
tenir la séquence de la base, qui la sert à la façade
(GET /internal/v1/recall/block?seq=N et /internal/v1/recall/blocks, blocs
chiffrés sous une mémoire verrouillée exclus) ; ses propres outils passent
par les mêmes lectures. Go injoignable : l'appel passe par lui.

Parité : journal de 41 appels sur une archive de 35 blocs tiré du Go
(parity_recall_test.go → tests/parity_recall/recall.json), rejoué par
tests/recall.rs ; un tour de la façade qui rappelle et cherche
(tests/lot6.rs) ; TestRecallInterneLecture côté Go.

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

98 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lot 46 — Outils recall et recall_search dans la façade
## Contexte
La compaction résume les vieux tours d'une discussion. Avant de résumer un
gros bloc (un code, une page, un diff), elle l'archive verbatim sous un id
court (`r7`) que le résumé cite. L'agent a deux outils pour le retrouver :
- `recall(id)` rend le bloc exact ;
- `recall_search(query)` retrouve un bloc et son id par mots-clés, même
sorti du résumé courant.
La façade compacte elle-même et archive par le Go
(`/internal/v1/recall/archive`, lot 6) : l'id vient de la séquence de la
base, que seul le Go tient. Les deux outils passaient encore par
`/internal/v1/tool/exec`.
## Le lot
`src/recall.rs` porte `toolRecall` et `toolRecallSearch`
(`chat_recall.go`) :
- **l'id tolérant** (`recallIDToSeq`) :
- espaces, un préfixe `r` puis un préfixe `R`, espaces encore ;
- des chiffres seulement : ni signe, ni dépassement de 64 bits ;
- un id mal formé ne lit pas l'archive ;
- **les mots-clés** (`recallTokens`) :
- mise en minuscules rune par rune, comme `strings.ToLower` (`İ`
donne `i`, `Σ` donne `σ`) ;
- coupés sur tout ce qui n'est ni `a`–`z`, ni `0`–`9`, ni `à`–`ÿ` ;
- deux runes au moins ;
- **le score** :
- un point par terme présent dans le contenu, deux dans le libellé ;
- à égalité, le plus récent d'abord ;
- 5 résultats par défaut, 20 au plus, limite tronquée comme
`int(float64)` ;
- **les textes**, mêmes que le Go :
- id ou requête manquants ;
- bloc introuvable (id cité par `%q`) ;
- bloc rappelé verbatim ;
- liste des résultats avec un extrait d'une ligne de 160 runes ;
- aucun résultat.
L'archive reste au Go, qui la sert à la façade :
- `GET /internal/v1/recall/block?seq=N` : le bloc (200), ou 404 s'il est
absent ou chiffré sous une mémoire verrouillée ;
- `GET /internal/v1/recall/blocks` : tous les blocs lisibles, par séquence
croissante.
`recallGet` et `recallSearch` du Go passent par les mêmes lectures
(`recallGetSeq`, `recallAll`).
`GoTurnHost::exec_tool` exécute les deux outils avant le repli sur le Go.
Si le Go ne répond pas, l'appel passe par lui.
## Parité
`internal/loki/parity_recall_test.go` archive 35 blocs variés :
- accents et casse Unicode ;
- balises et entités ;
- bloc vide ;
- premières lignes longues ;
- vingt-cinq blocs semblables.
Il tire ensuite du Go un journal de 41 appels
(`tests/parity_recall/recall.json`), avec les blocs tels que l'archive les
sert :
- `recall` :
- id absent, non texte, blanc ;
- variantes de préfixe et d'espaces ;
- zéros de tête ;
- mal formé, négatif, signe plus, zéro, absent, démesuré ;
- guillemets dans l'id ;
- `recall_search` :
- requête absente, non texte, blanche ;
- mots trop courts ;
- casse, accents, `İ`, grec hors des mots ;
- souligné coupé ;
- extraits bornés ;
- limites : une, tronquée, négative, par défaut, au plus, en texte
ignorée ;
- aucun résultat ;
- ponctuation.
`tests/recall.rs` le rejoue : le faux Go sert les mêmes blocs. Il vérifie
aussi le repli quand le Go ne répond pas.
D'autres tests complètent :
- `tests/lot6.rs` (`recall_par_la_facade`) : un tour de la façade rappelle
et cherche sans passer par `/tool/exec` ;
- `TestRecallInterneLecture` : les deux lectures du Go (absent, seq
illisible, méthode refusée, ordre) ;
- tests unitaires : ids, mots-clés, score, extraits, textes.