CAT-K8: the search index is in the module's memory (bleve), built from the ledger and kept as it writes

ask and holds on the ledger answer from a full-text index of the heads and the current versions' text and clauses; it is
built at start (index not built is the answer meanwhile), a new version replaces its record's documents, a reserved,
withdrawn or retracted record has none. A new pure Go dependency, bleve.

Issue 1966.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 12:12:44 +01:00
parent 7bf0e991d8
commit a4e3a9cbe0
5 changed files with 389 additions and 9 deletions
@@ -0,0 +1,221 @@
package main
// The search index (novox/hq to-be 55 §1, ADR 0597 §12): a full-text index in the module's own memory, written with the
// pure Go library bleve. At start the module reads every head from the ledger and the bodies of every current version into
// it, then keeps it current as it writes; `ask` and `holds` answer from it, and refuse with "index not built" while it is
// built. Nothing but the module writes it and nothing outside it reads it.
import (
"context"
"errors"
"fmt"
"sort"
"strings"
"sync"
"time"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/analysis/lang/en"
"github.com/blevesearch/bleve/v2/mapping"
"github.com/blevesearch/bleve/v2/search/query"
)
// ErrIndexNotBuilt is the answer of a question asked while the index is built.
var ErrIndexNotBuilt = errors.New("index not built: the search index is being built from the ledger; ask again in a moment (get, list and propose answer at once)")
// searchIndex is the index and what it holds.
type searchIndex struct {
mu sync.Mutex
idx bleve.Index
built bool
builtAt time.Time
docs int
// docsOf are the documents each record has in the index, so a new version replaces them.
docsOf map[Key][]string
}
func newSearchIndex() (*searchIndex, error) {
m := bleve.NewIndexMapping()
text := mapping.NewTextFieldMapping()
text.Analyzer = en.AnalyzerName
doc := bleve.NewDocumentMapping()
for _, f := range []string{"title", "topic", "text", "clause"} {
doc.AddFieldMappingsAt(f, text)
}
m.DefaultMapping = doc
idx, err := bleve.NewMemOnly(m)
if err != nil {
return nil, err
}
return &searchIndex{idx: idx, docsOf: map[Key][]string{}}, nil
}
type indexDoc struct {
Title string `json:"title,omitempty"`
Topic string `json:"topic,omitempty"`
Text string `json:"text,omitempty"`
Clause string `json:"clause,omitempty"`
}
// put replaces the documents of a record by those of its served version: its title, topic and sections as one document,
// and each clause in force or proposed as one of its own. A reserved, withdrawn or retracted record has none.
func (s *searchIndex) put(r *Record) error {
s.mu.Lock()
defer s.mu.Unlock()
key := r.Key()
b := s.idx.NewBatch()
for _, id := range s.docsOf[key] {
b.Delete(id)
}
delete(s.docsOf, key)
if r.Status != StatusReserved && r.Status != StatusWithdrawn && r.Status != StatusRetracted {
var body strings.Builder
for _, sec := range r.Sections {
body.WriteString(sec.Text + "\n")
}
id := fmt.Sprintf("%s/%d", key.Kind, key.Number)
if err := b.Index(id, indexDoc{Title: r.Title, Topic: r.Topic, Text: body.String()}); err != nil {
return err
}
ids := []string{id}
for _, c := range r.Clauses {
if c.Status == ClauseRetracted {
continue
}
cid := fmt.Sprintf("%s#%d", id, c.N)
if err := b.Index(cid, indexDoc{Clause: c.Text}); err != nil {
return err
}
ids = append(ids, cid)
}
s.docsOf[key] = ids
}
s.docs = 0
for _, ids := range s.docsOf {
s.docs += len(ids)
}
return s.idx.Batch(b)
}
// search ranks the documents against the question's words: a title weighs twice, as the in-memory ranking did.
func (s *searchIndex) search(question string, limit int) ([]Hit, error) {
s.mu.Lock()
built := s.built
s.mu.Unlock()
if !built {
return nil, ErrIndexNotBuilt
}
var words []string
for _, w := range wordsOf(question) {
if !askingWords[w] && len(w) >= 3 {
words = append(words, w)
}
}
if len(words) == 0 {
return nil, nil
}
var should []query.Query
for _, w := range words {
for field, boost := range map[string]float64{"title": 2, "topic": 1, "text": 0.05, "clause": 1} {
q := bleve.NewMatchQuery(w)
q.SetField(field)
q.SetBoost(boost)
should = append(should, q)
}
}
req := bleve.NewSearchRequestOptions(bleve.NewDisjunctionQuery(should...), 5000, 0, false)
res, err := s.idx.Search(req)
if err != nil {
return nil, err
}
var hits []Hit
for _, h := range res.Hits {
var kind string
var number, clause int
rest := h.ID
if i := strings.IndexByte(rest, '#'); i >= 0 {
if _, err := fmt.Sscanf(rest[i+1:], "%d", &clause); err != nil {
continue
}
rest = rest[:i]
}
if i := strings.IndexByte(rest, '/'); i >= 0 {
kind = rest[:i]
if _, err := fmt.Sscanf(rest[i+1:], "%d", &number); err != nil {
continue
}
}
hits = append(hits, Hit{Key: Key{kind, number}, Clause: clause, Rank: h.Score})
}
sort.SliceStable(hits, func(i, j int) bool {
if hits[i].Rank != hits[j].Rank {
return hits[i].Rank > hits[j].Rank
}
if hits[i].Key != hits[j].Key {
return hits[i].Key.Number > hits[j].Key.Number
}
return hits[i].Clause < hits[j].Clause
})
if limit > 0 && len(hits) > limit {
hits = hits[:limit]
}
return hits, nil
}
// IndexState says how the index stands: built or not, when, and how many documents it holds.
type IndexState struct {
Built bool `json:"built"`
BuiltAt time.Time `json:"built-at,omitempty"`
Docs int `json:"documents"`
}
func (s *searchIndex) state() IndexState {
s.mu.Lock()
defer s.mu.Unlock()
return IndexState{Built: s.built, BuiltAt: s.builtAt, Docs: s.docs}
}
// BuildIndex reads every record from the ledger into the index and marks it built; asked again it builds it anew.
func (s *ledgerStore) BuildIndex(ctx context.Context) error {
idx, err := newSearchIndex()
if err != nil {
return err
}
all, err := s.All(ctx)
if err != nil {
return err
}
for _, e := range all {
if err := idx.put(e.Current); err != nil {
return err
}
}
idx.mu.Lock()
idx.built, idx.builtAt = true, time.Now().UTC()
idx.mu.Unlock()
s.mu.Lock()
s.index = idx
s.mu.Unlock()
return nil
}
// IndexState is how the module's index stands.
func (s *ledgerStore) IndexState() IndexState {
s.mu.Lock()
idx := s.index
s.mu.Unlock()
if idx == nil {
return IndexState{}
}
return idx.state()
}
// indexed keeps the index current with a version the store wrote.
func (s *ledgerStore) indexed(r *Record, current bool) {
if s.index == nil || !current {
return
}
if err := s.index.put(r); err != nil && s.logf != nil {
s.logf("[mesh-knowledge] the search index could not take %s: %v", r.Key(), err)
}
}
@@ -0,0 +1,66 @@
package main
import (
"errors"
"testing"
)
// The search index (to-be 55 §1, AC52): built from the ledger at start, refusing "index not built" meanwhile, kept current
// as the module writes, and answering the questions the knowledge base is asked as the in-memory ranking does: the records
// the questions are about come first.
func TestTheSearchIndexAnswersTheQuestionsAsTheStoreDoes(t *testing.T) {
f := newFakeLedger(t)
ls := newLedgerStore(f, newFakeStates())
w := newWorld(t, ls, fixture())
w.k.States = newFakeStates()
ls.indexAsync = true
if _, err := ls.Search(t.Context(), "merge window", 5); !errors.Is(err, ErrIndexNotBuilt) {
t.Fatalf("a question before the index was built: %v", err)
}
if _, err := w.k.Import("import@test", ImportAsk{}, fixture()); err != nil {
t.Fatal(err)
}
if err := ls.BuildIndex(t.Context()); err != nil {
t.Fatal(err)
}
if st := ls.IndexState(); !st.Built || st.Docs < 20 {
t.Fatalf("%+v", st)
}
mem := imported(t, newMemStore())
for _, q := range []string{"merge window", "how is the tool runtime chosen", "what holds about resolved names", "a knowledge base the mesh writes"} {
want, _ := mem.k.Store.Search(t.Context(), q, 3)
got, err := ls.Search(t.Context(), q, 8)
if err != nil {
t.Fatal(err)
}
// The ranking differs (the index weighs by how rare a word is), so the record the store puts first is among the
// first few of the index's.
found := false
for _, h := range got {
found = found || (len(want) > 0 && h.Key == want[0].Key)
}
if len(want) > 0 && !found {
t.Errorf("%q: the store puts %v first, the index %v", q, want[0], got)
}
}
// A new version is in the index at once; a withdrawn record is out of it.
r, _ := w.k.ReserveNumber("author@g14", KindDecision, "a test record")
if hits, _ := ls.Search(t.Context(), "zebra quantum", 5); len(hits) != 0 {
t.Fatalf("%v", hits)
}
p := valid(r.Number)
p.Title = "Zebra quantum processors"
p.Sections[2].Text = "A zebra quantum processor."
if _, err := w.k.Propose("author@g14", p); err != nil {
t.Fatal(err)
}
if hits, _ := ls.Search(t.Context(), "zebra quantum", 5); len(hits) == 0 || hits[0].Key.Number != r.Number {
t.Fatalf("a proposed record is not in the index: %v", hits)
}
if _, err := w.k.WithdrawRecord("author@g14", Key{KindDecision, r.Number}, "not needed"); err != nil {
t.Fatal(err)
}
if hits, _ := ls.Search(t.Context(), "zebra quantum", 5); len(hits) != 0 {
t.Fatalf("a withdrawn record is in the index: %v", hits)
}
}
@@ -93,6 +93,10 @@ type ledgerStore struct {
// drafted are the sections written for a draft and named by no version yet: a version that carries one reuses its // drafted are the sections written for a draft and named by no version yet: a version that carries one reuses its
// write-section and writes none again. // write-section and writes none again.
drafted map[Key][]sectionRef drafted map[Key][]sectionRef
// index is the search index of the module's memory, nil until built.
index *searchIndex
indexAsync bool
logf func(format string, a ...any)
} }
// newLedgerStore is the store over a pipe and the module's states. // newLedgerStore is the store over a pipe and the module's states.
@@ -350,13 +354,13 @@ func (s *ledgerStore) Create(ctx context.Context, v Version) error {
if err != nil { if err != nil {
return err return err
} }
return s.commit(ctx, k, operationFor(nil, v, true), &entryHead{CurrentVersion: 1, Versions: 1, Current: ptr(stripped(v.Record, refs))}, v, refs) return s.commit(ctx, k, operationFor(nil, v, true), &entryHead{CurrentVersion: 1, Versions: 1, Current: ptr(stripped(v.Record, refs))}, v, refs, true)
} }
func ptr[T any](v T) *T { return &v } func ptr[T any](v T) *T { return &v }
// commit appends the operation that carries the new head and the version, and holds the head it derived. // commit appends the operation that carries the new head and the version, and holds the head it derived.
func (s *ledgerStore) commit(ctx context.Context, k Key, op string, e *entryHead, v Version, refs []sectionRef) error { func (s *ledgerStore) commit(ctx context.Context, k Key, op string, e *entryHead, v Version, refs []sectionRef, current bool) error {
body := map[string]any{"kind": k.Kind, "number": k.Number, "entry": e, body := map[string]any{"kind": k.Kind, "number": k.Number, "entry": e,
"version": versionHead{N: v.N, By: v.By, At: v.At, Why: v.Why, Insight: v.Insight, Record: stripped(v.Record, refs)}, "version": versionHead{N: v.N, By: v.By, At: v.At, Why: v.Why, Insight: v.Insight, Record: stripped(v.Record, refs)},
"pending-sections": map[string]any{}} "pending-sections": map[string]any{}}
@@ -366,6 +370,7 @@ func (s *ledgerStore) commit(ctx context.Context, k Key, op string, e *entryHead
} }
s.heads[k] = &headState{Kind: k.Kind, Number: k.Number, Entry: e, Sequence: seq} s.heads[k] = &headState{Kind: k.Kind, Number: k.Number, Entry: e, Sequence: seq}
delete(s.drafted, k) delete(s.drafted, k)
s.indexed(v.Record, current)
return nil return nil
} }
@@ -455,7 +460,7 @@ func (s *ledgerStore) Save(ctx context.Context, v Version, current, clearPending
if clearPending { if clearPending {
e.Pending, e.PendingVersion = nil, 0 e.Pending, e.PendingVersion = nil, 0
} }
return s.commit(ctx, k, operationFor(old, v, current), &e, v, refs) return s.commit(ctx, k, operationFor(old, v, current), &e, v, refs, current)
} }
func (s *ledgerStore) Versions(_ context.Context, k Key) ([]Version, error) { func (s *ledgerStore) Versions(_ context.Context, k Key) ([]Version, error) {
@@ -493,14 +498,24 @@ func (s *ledgerStore) Versions(_ context.Context, k Key) ([]Version, error) {
return out, nil return out, nil
} }
// Search ranks the served versions as the in-memory store does, over every record; the index of the module's memory // Search ranks the served versions from the index of the module's memory; it is built on the first question when no start
// replaces it (the search index of to-be 55 §1). // built it, and refuses with "index not built" while a start builds it.
func (s *ledgerStore) Search(ctx context.Context, question string, limit int) ([]Hit, error) { func (s *ledgerStore) Search(ctx context.Context, question string, limit int) ([]Hit, error) {
all, err := s.All(ctx) s.mu.Lock()
if err != nil { idx, async := s.index, s.indexAsync
return nil, err s.mu.Unlock()
if idx == nil {
if async {
return nil, ErrIndexNotBuilt
}
if err := s.BuildIndex(ctx); err != nil {
return nil, err
}
s.mu.Lock()
idx = s.index
s.mu.Unlock()
} }
return searchEntries(all, question, limit), nil return idx.search(question, limit)
} }
func (s *ledgerStore) Inbound(_ context.Context, k Key) ([]Inbound, error) { func (s *ledgerStore) Inbound(_ context.Context, k Key) ([]Inbound, error) {
+26
View File
@@ -10,19 +10,45 @@ require (
) )
require ( require (
github.com/RoaringBitmap/roaring/v2 v2.14.5 // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op // indirect github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op // indirect
github.com/bits-and-blooms/bitset v1.24.2 // indirect
github.com/blevesearch/bleve/v2 v2.6.3 // indirect
github.com/blevesearch/bleve_index_api v1.4.1 // indirect
github.com/blevesearch/geo v0.2.8 // indirect
github.com/blevesearch/go-faiss v1.1.5 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.2.0 // indirect
github.com/blevesearch/scorch_segment_api/v2 v2.4.11 // indirect
github.com/blevesearch/segment v0.9.1 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
github.com/blevesearch/vellum v1.2.1 // indirect
github.com/blevesearch/zapx/v11 v11.4.3 // indirect
github.com/blevesearch/zapx/v12 v12.4.3 // indirect
github.com/blevesearch/zapx/v13 v13.4.3 // indirect
github.com/blevesearch/zapx/v14 v14.4.3 // indirect
github.com/blevesearch/zapx/v15 v15.4.3 // indirect
github.com/blevesearch/zapx/v16 v16.3.4 // indirect
github.com/blevesearch/zapx/v17 v17.2.5 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/go-tpm v0.9.8 // indirect github.com/google/go-tpm v0.9.8 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede // indirect
github.com/klauspost/compress v1.20.0 // indirect github.com/klauspost/compress v1.20.0 // indirect
github.com/minio/highwayhash v1.0.4 // indirect github.com/minio/highwayhash v1.0.4 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/nats-io/jwt/v2 v2.8.1 // indirect github.com/nats-io/jwt/v2 v2.8.1 // indirect
github.com/nats-io/nkeys v0.4.16 // indirect github.com/nats-io/nkeys v0.4.16 // indirect
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
go.etcd.io/bbolt v1.4.0 // indirect
golang.org/x/crypto v0.57.0 // indirect golang.org/x/crypto v0.57.0 // indirect
golang.org/x/sync v0.23.0 // indirect golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect golang.org/x/text v0.42.0 // indirect
golang.org/x/time v0.15.0 // indirect golang.org/x/time v0.15.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
) )
+52
View File
@@ -1,10 +1,54 @@
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 h1:aI1DhZAuqVBXbybSqhLNOGX5rUOrn9T0cHNCDUQF7IQ= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 h1:aI1DhZAuqVBXbybSqhLNOGX5rUOrn9T0cHNCDUQF7IQ=
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
github.com/RoaringBitmap/roaring/v2 v2.14.5 h1:ckd0o545JqDPeVJDgeFoaM21eBixUnlWfYgjE5VnyWw=
github.com/RoaringBitmap/roaring/v2 v2.14.5/go.mod h1:eq4wdNXxtJIS/oikeCzdX1rBzek7ANzbth041hrU8Q4=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/bits-and-blooms/bitset v1.24.2 h1:M7/NzVbsytmtfHbumG+K2bremQPMJuqv1JD3vOaFxp0=
github.com/bits-and-blooms/bitset v1.24.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/blevesearch/bleve/v2 v2.6.3 h1:+TvSTA10Kr5c8Dj7gidTIufor8fg7pIj4rQu2Vmw9L0=
github.com/blevesearch/bleve/v2 v2.6.3/go.mod h1:cXYhNm5W1L8az+qt5j3D+zoVe268ZR34ymfFy6PDvdg=
github.com/blevesearch/bleve_index_api v1.4.1 h1:CYIyecFlI+/RYjzUm+NmDjYbSvk870Bb7f+Vl4b12q8=
github.com/blevesearch/bleve_index_api v1.4.1/go.mod h1:xvd48t5XMeeioWQ5/jZvgLrV98flT2rdvEJ3l/ki4Ko=
github.com/blevesearch/geo v0.2.8 h1:nNgtlEfLzeWH4/UJZD4k5kP+E4cI+ogfmSti0XGnWNM=
github.com/blevesearch/geo v0.2.8/go.mod h1:07qi9wrXpXWIscoMrKBykIdBdrWxnyVV4tmpq1eT8YQ=
github.com/blevesearch/go-faiss v1.1.5 h1:/IU5lkOahH9Ghfk9n3F6N0XD7PYVXZJWmNDc9TtXuco=
github.com/blevesearch/go-faiss v1.1.5/go.mod h1:w3W9AiWsFRGVaMG+/cmJi7iHEAuGyC6blsgO1EzCK/M=
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
github.com/blevesearch/mmap-go v1.2.0 h1:l33nNKPFcBjJUMwem6sAYJPUzhUCABoK9FxZDGiFNBI=
github.com/blevesearch/mmap-go v1.2.0/go.mod h1:Vd6+20GBhEdwJnU1Xohgt88XCD/CTWcqbCNxkZpyBo0=
github.com/blevesearch/scorch_segment_api/v2 v2.4.11 h1:VTXi18tB7YQMWSM/K16+z7ji1hK5PwvlS7MtzRCAJus=
github.com/blevesearch/scorch_segment_api/v2 v2.4.11/go.mod h1:OHLLgtco0DySTL1uVESnmObFqn64MRX3aCKNQtXPi9M=
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A=
github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ=
github.com/blevesearch/vellum v1.2.1 h1:PYryJDqBHjLM6n3YindZSQcrseaMs8QpcsrrAOpwwj8=
github.com/blevesearch/vellum v1.2.1/go.mod h1:uEcfBJz7mAOf0Kvq6qoEKQQkLODBF46SINYNkZNae4k=
github.com/blevesearch/zapx/v11 v11.4.3 h1:PTZOO5loKpHC/x/GzmPZNa9cw7GZIQxd5qRjwij9tHY=
github.com/blevesearch/zapx/v11 v11.4.3/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc=
github.com/blevesearch/zapx/v12 v12.4.3 h1:eElXvAaAX4m04t//CGBQAtHNPA+Q6A1hHZVrN3LSFYo=
github.com/blevesearch/zapx/v12 v12.4.3/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58=
github.com/blevesearch/zapx/v13 v13.4.3 h1:qsdhRhaSpVnqDFlRiH9vG5+KJ+dE7KAW9WyZz/KXAiE=
github.com/blevesearch/zapx/v13 v13.4.3/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk=
github.com/blevesearch/zapx/v14 v14.4.3 h1:GY4Hecx0C6UTmiNC2pKdeA2rOKiLR5/rwpU9WR51dgM=
github.com/blevesearch/zapx/v14 v14.4.3/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8=
github.com/blevesearch/zapx/v15 v15.4.3 h1:iJiMJOHrz216jyO6lS0m9RTCEkprUnzvqAI2lc/0/CU=
github.com/blevesearch/zapx/v15 v15.4.3/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw=
github.com/blevesearch/zapx/v16 v16.3.4 h1:hDAqA8qusZTNbPEL7//w5P65UZ2de6yhSeUaTbp0Po0=
github.com/blevesearch/zapx/v16 v16.3.4/go.mod h1:zqkPPqs9GS9FzVWzCO3Wf1X044yWAV17+4zb+FTiEHg=
github.com/blevesearch/zapx/v17 v17.2.5 h1:1A3bXvT/8XkEVaUQBfD0jQBAO8kSQEiCwgrRNPKp0TE=
github.com/blevesearch/zapx/v17 v17.2.5/go.mod h1:8SHp6q+3FNVCqPyRiTFZDSRm1WA2G8Q3zCk8lRBfhT4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
@@ -15,10 +59,14 @@ github.com/jackc/pgx/v5 v5.11.0 h1:IzBBtyK9AHqf98cctWFifYSci2hgQR/cd56wB4p+ogg=
github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede h1:YrgBGwxMRK0Vq0WSCWFaZUnTsrA/PZE/xs1QZh+/edg=
github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA=
github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clgl4= github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clgl4=
github.com/minio/highwayhash v1.0.4/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= github.com/minio/highwayhash v1.0.4/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU= github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg= github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
github.com/nats-io/nats-server/v2 v2.11.17 h1:GKEghcFK6A+aFx11Yf1LjgLC3txAwvyhnYzhBIQZA8I= github.com/nats-io/nats-server/v2 v2.11.17 h1:GKEghcFK6A+aFx11Yf1LjgLC3txAwvyhnYzhBIQZA8I=
@@ -36,6 +84,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
@@ -47,6 +97,8 @@ golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=