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
This commit is contained in:
Claude committed 2026-10-16 06:54:35 +00:00
1 parent db1f20c0a4
commit 92e9adee7d
15 files changed
+1416 -25

No files matched your search

+40 -25
View File
@@ -138,6 +138,11 @@ func recallGet(id string) (recallBlock, bool) {
if !ok {
return recallBlock{}, false
}
return recallGetSeq(seq)
}
// recallGetSeq ramène un bloc par sa séquence (aussi servi à la façade).
func recallGetSeq(seq uint64) (recallBlock, bool) {
var blk recallBlock
found := false
_ = view(bkRecall, func(b *bolt.Bucket) error {
@@ -155,6 +160,27 @@ func recallGet(id string) (recallBlock, bool) {
return blk, found
}
// recallAll : tous les blocs lisibles, par séquence croissante (un bloc
// chiffré sous une mémoire verrouillée n'en fait pas partie).
func recallAll() []recallBlock {
var out []recallBlock
_ = view(bkRecall, func(b *bolt.Bucket) error {
return b.ForEach(func(_, v []byte) error {
var blk recallBlock
dec, err := decodeMemContent(v)
if err != nil {
return nil
}
if json.Unmarshal(dec, &blk) != nil {
return nil
}
out = append(out, blk)
return nil
})
})
return out
}
// recallSearch cherche dans toute l'archive par recouvrement de mots-clés.
// Score = nombre de termes distincts de la requête présents dans (libellé +
// contenu), le libellé comptant double (un mot du titre est plus signifiant).
@@ -176,33 +202,22 @@ func recallSearch(query string, limit int) []recallBlock {
score int
}
var hits []scored
_ = view(bkRecall, func(b *bolt.Bucket) error {
return b.ForEach(func(_, v []byte) error {
var blk recallBlock
dec, err := decodeMemContent(v)
if err != nil {
return nil // chiffré et verrouillé : ce bloc ne participe pas
for _, blk := range recallAll() {
label := strings.ToLower(blk.Label)
body := strings.ToLower(blk.Content)
score := 0
for t := range terms {
if strings.Contains(label, t) {
score += 2
}
if json.Unmarshal(dec, &blk) != nil {
return nil
if strings.Contains(body, t) {
score++
}
label := strings.ToLower(blk.Label)
body := strings.ToLower(blk.Content)
score := 0
for t := range terms {
if strings.Contains(label, t) {
score += 2
}
if strings.Contains(body, t) {
score++
}
}
if score > 0 {
hits = append(hits, scored{blk, score})
}
return nil
})
})
}
if score > 0 {
hits = append(hits, scored{blk, score})
}
}
sort.Slice(hits, func(i, j int) bool {
if hits[i].score != hits[j].score {
return hits[i].score > hits[j].score