Compare commits

..

2 Commits

Author SHA1 Message Date
Tim Lingo 21d3516426 measure: claim-24 unfloored semantic leg vs bm25lex baseline - net +0, NOT-SHOWN
gains q14,q25 (gold at global cosine rank 1, previously discarded by the 0.60
floor); losses q15,q28 (the semantic leg was EMPTY on those queries under the
floor, so filling it turns a 2-leg rotation into a 3-leg one and halves the
associative leg's share of the top 5). Guards held: exact_rare 6/6, phrase 7/7,
nonsense 2/3, superseded 2/3 outranks. recall@10 61.8->65.4pp, latency 0.99x.
Baseline reproduced from source (results-bm25base-rerun.json is byte-identical
to the committed results-bm25lex.json), candidate deterministic across 2 runs.
2026-08-07 16:33:50 -05:00
Tim Lingo 65c50073b8 feat(engram): restore claim 24 verbatim - unfloored semantic leg + corpus-vocabulary gate
The read-path semantic leg was gated at ENGRAM_EMBED_SEED_MIN (0.60) and
rescaled onto [0.60,1]. That constant is defined as the HippoRAG SEED-JOIN
threshold; claim 24 authorises a ranking with no threshold at all. Measured:
the floor is not a quality gate (paraphrase targets 0.459-0.657 vs nonsense
nearest neighbours 0.553-0.622 - overlapping distributions). What holds the
nonsense controls is corpus vocabulary, so the floor is replaced by an
explicit nhits==0 gate: no record contains any query token -> return nothing.
2026-08-07 16:23:32 -05:00
14 changed files with 939 additions and 1102 deletions
-43
View File
@@ -1,43 +0,0 @@
import json,sys,pickle,numpy as np,itertools
sys.path.insert(0,'.')
from policy2 import legs3,outcome,G,NODES,merge
# cache per-query leg id-lists, floored and unfloored
cache={}
for q in G['queries']:
Lf,Sf,Af=legs3(q['query'])
Lu,Su,Au=legs3(q['query'],unfloor=True)
cache[q['id']]=dict(L=Lf,Sf=Sf,A=Af,Su=Su,Au=Au)
pickle.dump(cache,open('ceil.pkl','wb'))
def mrg(pattern,L,S,A,lim=10):
out=[];p={'L':0,'S':0,'A':0};src={'L':L,'S':S,'A':A}
i=0
while len(out)<lim:
prog=False
for ch in pattern:
lst=src[ch]
if p[ch]<len(lst):
x=lst[p[ch]];p[ch]+=1;prog=True
if x not in out: out.append(x)
if len(out)>=lim: return out
if not prog: break
return out
def ev(pattern,unfl):
res={}
for q in G['queries']:
c=cache[q['id']]
S=c['Su'] if unfl else c['Sf']
ids=[NODES[i]['id'] for i in mrg(pattern,c['L'],S,c['A'],10)]
res[q['id']]=outcome(q,ids)
return res
base=ev('LSA',False)
print("baseline",sum(base.values()))
best=[]
pats=['LSA','LAS','SLA','ALS','SAL','ASL','LSSA','LSASA','LSAA','LSSAA','LSAS','SSLA','LLSA','SALSA','LSAAS']
for unfl in (False,True):
for p in pats:
r=ev(p,unfl)
g=sorted(k for k in base if r[k] and not base[k]);l=sorted(k for k in base if base[k] and not r[k])
best.append((len(g)-len(l),p,unfl,g,l))
best.sort(reverse=True)
for n,p,u,g,l in best[:10]:
print("net=%+d pat=%-6s unfloor=%s gains=%s losses=%s"%(n,p,u,g,l))
@@ -1,6 +1,6 @@
{
"baseline": "bm25lex",
"candidate": "wsclaim24",
"candidate": "claim24",
"n_shared_queries": 38,
"fixed_by_candidate": [
"q14",
@@ -8,13 +8,11 @@
],
"broken_by_candidate": [
"q15",
"q28",
"q33",
"q34"
"q28"
],
"discordant": 6,
"net_queries": -2,
"mcnemar_exact_p": 0.6875,
"discordant": 4,
"net_queries": 0,
"mcnemar_exact_p": 1.0,
"min_detectable_swing_queries": 6,
"observed_run_to_run_drift_queries": 0,
"noise_floor_queries": 6,
@@ -82,22 +80,22 @@
"n_scored": 35,
"hit@5": 0.7428571428571429,
"recall@5": 0.5768475572047,
"recall@10": 0.6563414759843332,
"recall@10": 0.6537440733869305,
"precision@5": 0.19428571428571437,
"mrr@10": 0.5026530612244898,
"nonsense_clean": "0/3",
"mrr@10": 0.5021428571428572,
"nonsense_clean": "2/3",
"superseded_outranks": "2/3",
"latency_ms_p50": 524.8,
"latency_ms_p95": 738.7,
"latency_ms_max": 755.8,
"latency_ms_p50": 1173.7,
"latency_ms_p95": 1623.0,
"latency_ms_max": 1647.9,
"errors": 0,
"by_category": {
"associative": {
"n": 6,
"hit@5": 0.5,
"recall@5": 0.07575757575757576,
"recall@10": 0.13636363636363635,
"mrr@10": 0.23214285714285712
"recall@10": 0.12121212121212122,
"mrr@10": 0.22916666666666666
},
"exact_rare": {
"n": 6,
@@ -108,8 +106,8 @@
},
"nonsense": {
"n": 3,
"clean": 0,
"avg_false_positives": 10.0
"clean": 2,
"avg_false_positives": 3.3333333333333335
},
"paraphrase": {
"n": 13,
@@ -137,6 +135,12 @@
},
"repeat_variance": {
"baseline": {
"runs": 3,
"hit@5_min": 0.7428571428571429,
"hit@5_max": 0.7428571428571429,
"spread_queries": 0
},
"candidate": {
"runs": 2,
"hit@5_min": 0.7428571428571429,
"hit@5_max": 0.7428571428571429,
@@ -1,146 +0,0 @@
{
"baseline": "bm25lex",
"candidate": "wordstart",
"n_shared_queries": 38,
"fixed_by_candidate": [
"q35"
],
"broken_by_candidate": [],
"discordant": 1,
"net_queries": 1,
"mcnemar_exact_p": 1.0,
"min_detectable_swing_queries": 6,
"observed_run_to_run_drift_queries": 0,
"noise_floor_queries": 6,
"verdict": "no measurable difference",
"baseline_aggregate": {
"n_queries": 38,
"n_scored": 35,
"hit@5": 0.7428571428571429,
"recall@5": 0.5536485340056769,
"recall@10": 0.6175677497106068,
"precision@5": 0.20000000000000007,
"mrr@10": 0.5021428571428571,
"nonsense_clean": "2/3",
"superseded_outranks": "2/3",
"latency_ms_p50": 1184.4,
"latency_ms_p95": 1620.0,
"latency_ms_max": 1655.4,
"errors": 0,
"by_category": {
"associative": {
"n": 6,
"hit@5": 0.6666666666666666,
"recall@5": 0.08857808857808858,
"recall@10": 0.23310023310023312,
"mrr@10": 0.25
},
"exact_rare": {
"n": 6,
"hit@5": 1.0,
"recall@5": 1.0,
"recall@10": 1.0,
"mrr@10": 1.0
},
"nonsense": {
"n": 3,
"clean": 2,
"avg_false_positives": 3.3333333333333335
},
"paraphrase": {
"n": 13,
"hit@5": 0.6153846153846154,
"recall@5": 0.6153846153846154,
"recall@10": 0.6153846153846154,
"mrr@10": 0.2846153846153846
},
"phrase": {
"n": 7,
"hit@5": 1.0,
"recall@5": 0.5494614512471656,
"recall@10": 0.6023242630385487,
"mrr@10": 0.8214285714285714
},
"superseded": {
"n": 3,
"hit@5": 0.3333333333333333,
"recall@5": 0.3333333333333333,
"recall@10": 0.6666666666666666,
"mrr@10": 0.20833333333333334,
"outranks": 2
}
}
},
"candidate_aggregate": {
"n_queries": 38,
"n_scored": 35,
"hit@5": 0.7428571428571429,
"recall@5": 0.5536485340056769,
"recall@10": 0.6175677497106068,
"precision@5": 0.20000000000000007,
"mrr@10": 0.5021428571428571,
"nonsense_clean": "3/3",
"superseded_outranks": "2/3",
"latency_ms_p50": 542.6,
"latency_ms_p95": 741.3,
"latency_ms_max": 758.8,
"errors": 0,
"by_category": {
"associative": {
"n": 6,
"hit@5": 0.6666666666666666,
"recall@5": 0.08857808857808858,
"recall@10": 0.23310023310023312,
"mrr@10": 0.25
},
"exact_rare": {
"n": 6,
"hit@5": 1.0,
"recall@5": 1.0,
"recall@10": 1.0,
"mrr@10": 1.0
},
"nonsense": {
"n": 3,
"clean": 3,
"avg_false_positives": 0.0
},
"paraphrase": {
"n": 13,
"hit@5": 0.6153846153846154,
"recall@5": 0.6153846153846154,
"recall@10": 0.6153846153846154,
"mrr@10": 0.2846153846153846
},
"phrase": {
"n": 7,
"hit@5": 1.0,
"recall@5": 0.5494614512471656,
"recall@10": 0.6023242630385487,
"mrr@10": 0.8214285714285714
},
"superseded": {
"n": 3,
"hit@5": 0.3333333333333333,
"recall@5": 0.3333333333333333,
"recall@10": 0.6666666666666666,
"mrr@10": 0.20833333333333334,
"outranks": 2
}
}
},
"repeat_variance": {
"baseline": {
"runs": 2,
"hit@5_min": 0.7428571428571429,
"hit@5_max": 0.7428571428571429,
"spread_queries": 0
},
"candidate": {
"runs": 2,
"hit@5_min": 0.7428571428571429,
"hit@5_max": 0.7428571428571429,
"spread_queries": 0
}
}
}
+110
View File
@@ -0,0 +1,110 @@
import numpy as np, json, urllib.request, collections, math, re, sys, time, pickle, os
SP="/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad"
EV="/Users/timlingo/Development/neuron-technologies/_wt-bm25lex/tools/retrieval-eval/"
np.seterr(all='ignore')
t0=time.time()
M=np.load(SP+'/emb.npy'); eids=open(SP+'/ids.txt',encoding='utf-8',errors='surrogateescape').read().split('\n')
eidx={k:i for i,k in enumerate(eids)}
d=json.load(open('/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json',encoding='utf-8',errors='surrogateescape'))
STRUCT={"identity","contains","superseded_by","references","embodies","demonstrated_by","canonical-self","depends_on","currently_holds","activates"}
adj=collections.defaultdict(list)
for e in d['edges']:
if e.get('relation') not in STRUCT: continue
w=float(e.get('weight') or 0.0)
adj[e['from_id']].append((e['to_id'],w)); adj[e['to_id']].append((e['from_id'],w))
nodes=d['nodes']
N={n['id']:n for n in nodes}
PRINT=re.compile(r'^[\x20-\x7e]+$')
ids=[]; hay=[]; dl=[]; sal=[]; addressable=[]
for n in nodes:
i=n.get('id') or ''
h=((n.get('content') or '')+'\x00'+(n.get('label') or '')+'\x00'+(n.get('tags') or '')).lower()
ids.append(i); hay.append(h); dl.append(len(h)); sal.append(float(n.get('salience') or 0.0))
addressable.append(bool(PRINT.match(i)))
del d
NN=len(ids); avgdl=sum(dl)/NN
print("nodes=%d avgdl=%.0f %.1fs"%(NN,avgdl,time.time()-t0),file=sys.stderr)
gold={q['id']:q for q in json.load(open(EV+"gold_set.json"),)['queries']}
CACHE={}
def emb(t):
if t in CACHE: return CACHE[t]
b=json.dumps({"model":"nomic-embed-text","prompt":t}).encode()
r=urllib.request.Request("http://127.0.0.1:11434/api/embeddings",data=b,headers={"Content-Type":"application/json"})
v=np.array(json.load(urllib.request.urlopen(r,timeout=60))["embedding"],dtype=np.float32)
v=v/(np.linalg.norm(v)+1e-9); CACHE[t]=v; return v
K1,B=1.2,0.75
def lexleg(query, lim=10):
toks=[]
for w in query.split():
wl=w.lower()
if wl not in toks: toks.append(wl)
nt=len(toks)
masks=[]; df=[0]*nt
for i in range(NN):
if not addressable[i]: continue
h=hay[i]; m=0; sc=0
for t in range(nt):
if toks[t] in h: m|=(1<<t); sc+=1; df[t]+=1
if sc: masks.append((i,m,sc))
idf=[math.log(1.0+(NN-df[t]+0.5)/(df[t]+0.5)) for t in range(nt)]
scored=[]
for i,m,sc in masks:
norm=1.0-B+B*dl[i]/avgdl
s=0.0
for t in range(nt):
if m&(1<<t): s+=idf[t]*(K1+1.0)/(1.0+K1*norm)
scored.append((s,i))
scored.sort(key=lambda x:(-x[0], -sal[x[1]]))
return [ids[i] for s,i in scored[:lim]], len(masks), sum(df)
FIRE=0.02; DECAY=0.7; DEPTH=2; SEED_MIN=0.60; ASSOC_MAX=64
def assoc(seeds, s):
act={x:1.0 for x in seeds}; seen={x:2 for x in seeds}
Q=[(x,0) for x in seeds]; h=0
while h<len(Q):
cur,hop=Q[h]; h+=1
if hop>=DEPTH: continue
p=act[cur]
for oid,w in adj.get(cur,()):
n=N.get(oid)
if not n or n.get('node_type') in ('Tag','InternalStateEvent'): continue
na=p*w*DECAY*float(n.get('salience') or 0.0)
if na<FIRE: continue
if oid in seen and na<=act.get(oid,0): continue
act[oid]=na
if oid not in seen: seen[oid]=1
Q.append((oid,hop+1))
out=[]
for k,v in seen.items():
if v!=1 or k not in eidx: continue
c=float(s[eidx[k]])
if c<=0: continue
out.append((c,k))
out.sort(reverse=True)
return [k for c,k in out[:ASSOC_MAX]]
LEGS={}
for qid,q in gold.items():
v=emb(q['query']); s=M@v; s[~np.isfinite(s)]=-1
L,nmatch,dfsum=lexleg(q['query'])
ordr=np.argsort(-s)
Sall=[eids[j] for j in ordr[:40] if PRINT.match(eids[j] or '')]
seeds=[x for x in L[:3] if x in N]
seeds=seeds+[eids[j] for j in ordr[:8] if eids[j] in N and eids[j] not in seeds and PRINT.match(eids[j] or '')]
A=assoc(seeds,s) if seeds else []
A=[x for x in A if PRINT.match(x or '')]
LEGS[qid]=dict(L=L,Sall=Sall,A=A,scos={x:float(s[eidx[x]]) for x in set(Sall[:20]+A[:20]+list(q.get('relevant') or [])) if x in eidx},nmatch=nmatch)
pickle.dump(LEGS,open(SP+'/legs6.pkl','wb'))
FOCUS=['q14','q17','q23','q24','q25','q30','q32','q33','q34','q35','q36','q37','q38']
for qid in FOCUS:
q=gold[qid]; g=LEGS[qid]; rel=set(q.get('relevant') or [])
def rk(lst):
for i,x in enumerate(lst):
if x in rel: return i+1
return None
print("%s %-12s nmatch=%-6d Lrank=%s Srank=%s Arank=%s |A|=%d"%(
qid,q['category'],g['nmatch'],rk(g['L']),rk(g['Sall']),rk(g['A']),len(g['A'])))
for r in list(rel)[:2]:
print(" rel cos=%.3f"%(g['scos'].get(r,-9)))
print(" topS cos:", ["%.3f"%g['scos'].get(x,-9) for x in g['Sall'][:3]])
print("elapsed %.1fs"%(time.time()-t0),file=sys.stderr)
-117
View File
@@ -1,117 +0,0 @@
import json,pickle,os,math,urllib.request,numpy as np
S='/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/sim/'
C=pickle.load(open(S+'corpus.pkl','rb'))
NODES=C['nodes']; EDGES=C['edges']; N=len(NODES)
E=np.load(S+'emb.npy'); HAVE=np.load(S+'have.npy')
En=E/np.maximum(np.linalg.norm(E,axis=1,keepdims=True),1e-12)
LAYERS={int(l['layer_id']):l for l in (C['layers'] or [])} if C['layers'] else {}
TRANS=set(i for i,l in LAYERS.items() if l.get('transparent'))
def addressable(s):
if not s: return False
return all(0x20<=ord(ch)<=0x7e for ch in s)
ADDR=np.array([addressable(n['id']) for n in NODES])
OK=np.array([ (n['layer_id'] not in TRANS) and ADDR[i] for i,n in enumerate(NODES)])
SAL=np.array([n['salience'] for n in NODES])
LOW=[ (n['content']+'\x00'+n['label']+'\x00'+n['tags']).lower() for n in NODES]
DL=np.array([float(len(n['content'])+len(n['label'])+len(n['tags'])) for n in NODES])
IDX={}
for i,n in enumerate(NODES):
IDX.setdefault(n['id'],i)
STRUCT={"identity","contains","superseded_by","references","embodies","demonstrated_by","canonical-self","depends_on","currently_holds","activates"}
ADJ_F=[[] for _ in range(N)]; ADJ_T=[[] for _ in range(N)]
for e in EDGES:
a=IDX.get(e['from']); b=IDX.get(e['to'])
if a is None or b is None: continue
ADJ_F[a].append((e,b)); ADJ_T[b].append((e,a))
EXCL=np.array([n['node_type'] in ('Tag','InternalStateEvent') for n in NODES])
avgdl_all=None
def tokenize(q):
out=[]
for t in q.split():
if not any(t.lower()==x.lower() for x in out): out.append(t)
return out
_qcache={}
def qemb(q):
if q in _qcache: return _qcache[q]
body=json.dumps({"model":"nomic-embed-text","prompt":q}).encode()
r=urllib.request.urlopen(urllib.request.Request("http://127.0.0.1:11434/api/embeddings",data=body,headers={"Content-Type":"application/json"}),timeout=30)
v=np.array(json.loads(r.read())["embedding"],dtype=np.float32)
v=v/np.linalg.norm(v); _qcache[q]=v; return v
K1,B=1.2,0.75
SEED_MIN=0.60; SEED_K=8; ASSOC_SEEDS=3; DEPTH=2; FIRE=0.02; AMAX=64; DECAY=0.7
def legs(query):
toks=tokenize(query)
masks=[];
hit_idx=[]; hit_mask=[]
df=[0]*len(toks)
lt=[t.lower() for t in toks]
for i in range(N):
if not OK[i]: continue
s=LOW[i]; m=0
for t,tok in enumerate(lt):
if tok in s: m|=(1<<t)
if m:
hit_idx.append(i); hit_mask.append(m)
for t in range(len(toks)):
if m>>t&1: df[t]+=1
dl_n=int(OK.sum()); avgdl=float(DL[OK].sum()/max(dl_n,1))
idf=[math.log(1.0+((dl_n-d+0.5)/(d+0.5))) for d in df]
L=[]
for j,i in enumerate(hit_idx):
norm=1.0-B+B*(DL[i]/avgdl); w=0.0
for t in range(len(toks)):
if hit_mask[j]>>t&1: w+=idf[t]*(K1+1.0)/(1.0+K1*norm)
L.append((i,w,SAL[i]))
L.sort(key=lambda x:(-x[1],-x[2]))
qv=qemb(query)
cos=En@qv
cos=np.where(HAVE&OK,cos,-2.0)
order=np.argsort(-cos)
semfull=[(int(i),float(cos[i])) for i in order[:400]]
Sleg=[(i,(c-SEED_MIN)/(1-SEED_MIN)) for i,c in semfull if c>SEED_MIN]
semseed=[i for i,c in semfull[:SEED_K] if c>0.0]
# assoc
act={}; seen={}; qq=[]
for i,_,_ in L[:ASSOC_SEEDS]:
act[i]=1.0; seen[i]=2; qq.append((i,0))
for i in semseed:
if i in seen: continue
act[i]=1.0; seen[i]=2; qq.append((i,0))
qh=0
while qh<len(qq):
cur,h=qq[qh]; qh+=1
if h>=DEPTH: continue
parent=act[cur]
for e,oi in ADJ_F[cur]+ADJ_T[cur]:
if e['rel'] not in STRUCT: continue
if EXCL[oi]: continue
na=parent*e['w']*DECAY*SAL[oi]
if na<FIRE: continue
if seen.get(oi) and na<=act.get(oi,0): continue
act[oi]=na
if not seen.get(oi): seen[oi]=1
if len(qq)<AMAX*4: qq.append((oi,h+1))
A=[]
for i,st in seen.items():
if st!=1: continue
if not OK[i] or not HAVE[i]: continue
c=float(cos[i])
if c<=0.0: continue
A.append((i,c))
A.sort(key=lambda x:-x[1]); A=A[:AMAX]
return L,Sleg,A,cos
def interleave3(L,Sl,A,lim=10):
out=[]; li=si=ai=0
while len(out)<lim and (li<len(L) or si<len(Sl) or ai<len(A)):
if li<len(L):
if L[li][0] not in out: out.append(L[li][0])
li+=1
if len(out)>=lim: break
if si<len(Sl):
if Sl[si][0] not in out: out.append(Sl[si][0])
si+=1
if len(out)>=lim: break
if ai<len(A):
if A[ai][0] not in out: out.append(A[ai][0])
ai+=1
return out
-102
View File
@@ -1,102 +0,0 @@
import json,sys,pickle,numpy as np
sys.path.insert(0,'.')
from legs import *
GP='/Users/timlingo/Development/neuron-technologies/_wt-bm25lex/tools/retrieval-eval/'
G=json.load(open(GP+'gold_set.json'))
def legs3(query, sem_sal=False, assoc_sal=False, unfloor=False, sem_cap=None):
toks=tokenize(query)
hit_idx=[];hit_mask=[];df=[0]*len(toks);lt=[t.lower() for t in toks]
for i in range(N):
if not OK[i]: continue
s=LOW[i];m=0
for t,tok in enumerate(lt):
if tok in s: m|=(1<<t)
if m:
hit_idx.append(i);hit_mask.append(m)
for t in range(len(toks)):
if m>>t&1: df[t]+=1
dl_n=int(OK.sum());avgdl=float(DL[OK].sum()/max(dl_n,1))
idf=[math.log(1.0+((dl_n-d+0.5)/(d+0.5))) for d in df]
L=[]
for j,i in enumerate(hit_idx):
norm=1.0-B+B*(DL[i]/avgdl);w=0.0
for t in range(len(toks)):
if hit_mask[j]>>t&1: w+=idf[t]*(K1+1.0)/(1.0+K1*norm)
L.append((i,w,SAL[i]))
L.sort(key=lambda x:(-x[1],-x[2]))
if not L: return [],[],[]
qv=qemb(query);cos=En@qv;cos=np.where(HAVE&OK,cos,-2.0)
order=np.argsort(-cos)[:600]
cand=[int(i) for i in order if cos[i]>(0.0 if unfloor else SEED_MIN)]
key=(lambda i:(SAL[i] if sem_sal else 1.0)*float(cos[i]))
Sl=sorted(cand,key=lambda i:-key(i))
if sem_cap: Sl=Sl[:sem_cap]
semseed=[int(i) for i in order[:SEED_K] if cos[i]>0.0]
act={};seen={};qq=[]
for i,_,_ in L[:ASSOC_SEEDS]:
act[i]=1.0;seen[i]=2;qq.append((i,0))
for i in semseed:
if i in seen: continue
act[i]=1.0;seen[i]=2;qq.append((i,0))
qh=0
while qh<len(qq):
cur,h=qq[qh];qh+=1
if h>=DEPTH: continue
parent=act[cur]
for e,oi in ADJ_F[cur]+ADJ_T[cur]:
if e['rel'] not in STRUCT: continue
if EXCL[oi]: continue
na=parent*e['w']*DECAY*SAL[oi]
if na<FIRE: continue
if seen.get(oi) and na<=act.get(oi,0): continue
act[oi]=na
if not seen.get(oi): seen[oi]=1
if len(qq)<AMAX*4: qq.append((oi,h+1))
A=[]
for i,st in seen.items():
if st!=1 or not OK[i] or not HAVE[i]: continue
c=float(cos[i])
if c<=0.0: continue
A.append((i,(SAL[i] if assoc_sal else 1.0)*c))
A.sort(key=lambda x:-x[1]);A=[i for i,_ in A[:AMAX]]
return [i for i,_,_ in L],Sl,A
def merge(L,S,A,lim=10):
out=[];li=si=ai=0
while len(out)<lim and (li<len(L) or si<len(S) or ai<len(A)):
if li<len(L):
if L[li] not in out: out.append(L[li])
li+=1
if len(out)>=lim: break
if si<len(S):
if S[si] not in out: out.append(S[si])
si+=1
if len(out)>=lim: break
if ai<len(A):
if A[ai] not in out: out.append(A[ai])
ai+=1
return out
def outcome(q,ids):
c=q['category']
if c=='nonsense': return len(ids)==0
if c=='superseded':
a,b=q['must_outrank']
if a not in ids: return False
if b not in ids: return True
return ids.index(a)<ids.index(b)
return any(x in ids[:5] for x in q['relevant'])
def run(**kw):
return {q['id']:outcome(q,[NODES[i]['id'] for i in merge(*legs3(q['query'],**kw),10)]) for q in G['queries']}
base=run()
print("baseline",sum(base.values()),"/38 misses:",[k for k,v in base.items() if not v])
import itertools
for name,kw in [
('sem_sal(floored)',dict(sem_sal=True)),
('unfloor',dict(unfloor=True)),
('unfloor+sem_sal',dict(unfloor=True,sem_sal=True)),
('assoc_sal',dict(assoc_sal=True)),
('unfloor+sem_sal+assoc_sal',dict(unfloor=True,sem_sal=True,assoc_sal=True)),
('sem_sal+assoc_sal(floored)',dict(sem_sal=True,assoc_sal=True)),
]:
r=run(**kw)
g=sorted(k for k in base if r[k] and not base[k]); l=sorted(k for k in base if base[k] and not r[k])
print("%-28s net=%+d gains=%s losses=%s"%(name,len(g)-len(l),g,l))
@@ -1,15 +1,15 @@
{
"label": "wordstart",
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-wordstart",
"soul_md5": "32d4cf77672658a5f49dc7c9213e3ba2",
"label": "bm25base-rerun",
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-bm25base",
"soul_md5": "36c8dfa09c073b85fe7e00b02904d0ed",
"corpus": "/Users/timlingo/neuron-eval-corpora/snapshot-pre-repair-20260806-embedded.json",
"corpus_nodes": 78768,
"corpus_edges": 14214,
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-bm25lex/tools/retrieval-eval/gold_set.json",
"limit": 10,
"port": 7894,
"wall_clock_s": 28.9,
"child_pid": 1420,
"wall_clock_s": 50.6,
"child_pid": 93451,
"child_confirmed_dead": true,
"aggregate": {
"n_queries": 38,
@@ -19,11 +19,11 @@
"recall@10": 0.6175677497106068,
"precision@5": 0.20000000000000007,
"mrr@10": 0.5021428571428571,
"nonsense_clean": "3/3",
"nonsense_clean": "2/3",
"superseded_outranks": "2/3",
"latency_ms_p50": 542.6,
"latency_ms_p95": 741.3,
"latency_ms_max": 758.8,
"latency_ms_p50": 1186.1,
"latency_ms_p95": 1632.5,
"latency_ms_max": 1669.8,
"errors": 0,
"by_category": {
"associative": {
@@ -42,8 +42,8 @@
},
"nonsense": {
"n": 3,
"clean": 3,
"avg_false_positives": 0.0
"clean": 2,
"avg_false_positives": 3.3333333333333335
},
"paraphrase": {
"n": 13,
@@ -78,7 +78,7 @@
"mem-7f61beb4-271c-4feb-9f6e-1c9c837a6226"
],
"n_returned": 1,
"latency_ms": 170.4,
"latency_ms": 302.9,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -103,7 +103,7 @@
"ctx-74ed"
],
"n_returned": 10,
"latency_ms": 210.4,
"latency_ms": 336.7,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -119,7 +119,7 @@
"mem-1ba7c67d-85b9-4c2e-9fe2-39f8b0477091"
],
"n_returned": 1,
"latency_ms": 167.1,
"latency_ms": 290.2,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -135,7 +135,7 @@
"mem-89c02aae-d3ca-43f9-9e5d-eb369896276c"
],
"n_returned": 1,
"latency_ms": 166.9,
"latency_ms": 307.3,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -153,7 +153,7 @@
"project-Add_inference_url_config_to_Neuron_MCP__Route_summarization_gen_tasks_to_Pantheon__keep_frontier_for_complex_reasoning_"
],
"n_returned": 3,
"latency_ms": 162.3,
"latency_ms": 331.2,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -169,7 +169,7 @@
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99"
],
"n_returned": 1,
"latency_ms": 162.2,
"latency_ms": 302.2,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -194,7 +194,7 @@
"bl-b8af6601-a8cb-41b5-aef5-ab8a57432dd5"
],
"n_returned": 10,
"latency_ms": 306.7,
"latency_ms": 595.3,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -219,7 +219,7 @@
"knw-e94982a2-358d-4f2f-af31-8ee0fcec07c6"
],
"n_returned": 10,
"latency_ms": 261.2,
"latency_ms": 526.1,
"error": null,
"hit@5": 1.0,
"recall@5": 0.1875,
@@ -244,7 +244,7 @@
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
],
"n_returned": 10,
"latency_ms": 272.9,
"latency_ms": 516.8,
"error": null,
"hit@5": 1.0,
"recall@5": 0.3333333333333333,
@@ -269,7 +269,7 @@
"bl-18a9d1e4-1484-474c-bf6b-c6173212181b"
],
"n_returned": 10,
"latency_ms": 265.5,
"latency_ms": 558.8,
"error": null,
"hit@5": 1.0,
"recall@5": 0.1111111111111111,
@@ -294,7 +294,7 @@
"kn-6061318f-046b-4935-907d-8eafdce14930"
],
"n_returned": 10,
"latency_ms": 271.1,
"latency_ms": 513.4,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -315,11 +315,11 @@
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
"bl-967536a0-d49d-44fb-8cfb-b31b40bcbfae",
"bl-8b58d9bc-352b-4842-a7f8-a6254b5d1e25",
"?Q??m?;?u?'",
"2c56a7a9-5323-4ce4-ba09-35836ba15d54",
"bl-39cec462-c80c-4970-a3aa-91fe83053bde"
],
"n_returned": 10,
"latency_ms": 412.6,
"latency_ms": 867.9,
"error": null,
"hit@5": 1.0,
"recall@5": 0.21428571428571427,
@@ -338,13 +338,13 @@
"?",
"bl-ec84b63d-b278-4944-8d7f-4aa7a51c0315",
"?",
"mem-fb44a2fc-7405-41ff-87b3-84643ac07313",
"830ca37a-d334-4e41-ba89-64893dc8d628",
"?",
"mem-a3c97012-5fa3-4915-a839-2c75c72005e0",
"ce9636dc-85a5-4dae-9e07-74ea2fcc6307",
"?"
],
"n_returned": 10,
"latency_ms": 377.3,
"latency_ms": 752.9,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -361,15 +361,15 @@
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
"knw-d788a210-613b-4c49-9486-88bbc9d4716f",
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
"66c63082-b4da-4aa1-8fee-848db8a83210",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"mem-a535f205-bc4c-4058-9171-6263c496044a",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"mem-0228da71-d7f7-4f3b-b7b3-c5eede42b62a",
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
"ctx-4a41"
],
"n_returned": 10,
"latency_ms": 758.8,
"latency_ms": 1591.4,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -387,14 +387,14 @@
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"mem-16efddd1-c43d-4a42-9d78-f54fb82bd277",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"7452eb8f-be01-4b55-aec1-ff0c29e790f6",
"f0eb6b13-909c-4674-91ef-23301d3abc8b",
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
"532277bf-2959-4beb-ae0d-b018c97678ee",
"30a44d10-2487-420e-bf61-3892e4343c92",
"54608b69-78b6-4239-b60f-b8206cfecacc",
"d4015bd7-c592-4ed8-8574-1f15ad37af75"
"bfb5809e-d19a-4d3f-8c1a-796db622ad9d"
],
"n_returned": 10,
"latency_ms": 741.3,
"latency_ms": 1660.1,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -407,19 +407,19 @@
"category": "paraphrase",
"query": "choosing an uncomfortable fact over a pleasant fiction",
"returned": [
"tag-fiction",
"mem-ef878e30-5851-4e82-8588-745415108941",
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
"knw-4aebd815-4eaf-49d7-954b-03595f3d48be",
"mem-8d690e9d-a7e9-4062-b2f8-e2064294e463",
"tag-fiction",
"knw-8fd9836c-cc39-49df-8d61-babda626cc88",
"mem-ce793303-c5a5-4586-a232-a3426edd9ec7",
"mem-8d690e9d-a7e9-4062-b2f8-e2064294e463",
"knw-e94982a2-358d-4f2f-af31-8ee0fcec07c6",
"mem-443bd012-fc9a-4088-b236-de5157a1ef92",
"mem-ce793303-c5a5-4586-a232-a3426edd9ec7",
"knw-d357b6bb-ad8a-4791-b516-426aea45fa5b",
"mem-ca4d6a34-d354-413f-bc86-126cc17ca81c"
"mem-443bd012-fc9a-4088-b236-de5157a1ef92"
],
"n_returned": 10,
"latency_ms": 642.2,
"latency_ms": 1345.5,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -432,19 +432,19 @@
"category": "paraphrase",
"query": "a tight payload beats a bloated one",
"returned": [
"bl-680b24a9-edc3-4a9d-847a-bff0b46b568c",
"bl-8de20bcf-7149-4f48-b67c-e7f9758fd6e5",
"bl-798d135f-3987-4ccd-8de6-70ca2f358337",
"08f0d1e2-8d0e-42e3-9f0a-8186ae31ec7e",
"bl-680b24a9-edc3-4a9d-847a-bff0b46b568c",
"knw-08559f5c-2306-4220-a146-398c74f1643c",
"4da5dbaf-46e5-4f3e-b474-f60d9f8241d3",
"bl-164b520b-c503-49db-89f9-bd2fdf4215f5",
"knw-f6ed7d00-bf7d-42ce-9e40-77cf3406e918",
"mem-434be7c8-88cb-4039-b79a-1da4ac4de783",
"1219277c-1b95-45ec-95a2-07b4a47a4d92",
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
"a708dd6e-fe73-4f2f-a21e-89daa0985487",
"08f0d1e2-8d0e-42e3-9f0a-8186ae31ec7e",
"bl-79ce4464-5dd6-49bd-9b0c-9803549d0665"
],
"n_returned": 10,
"latency_ms": 537.2,
"latency_ms": 1070.7,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -459,17 +459,17 @@
"returned": [
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"mem-e5cc63c0-8701-49d6-855a-e387fe087771",
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
"mem-75e490d1-f0a9-4b73-8cfc-8daecfaf6f38",
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
"a1000001-0000-0000-0000-000000000010",
"015644f5-8194-4af0-800d-dd4a0cd71396",
"bfad516b-c306-4c4c-874a-a347c46c05c2",
"kn-e0423482-cfa5-4796-8689-8495c93b66bc"
"a1000001-0000-0000-0000-000000000009",
"bl-448bc514-c2f1-4520-a9b1-1f3a73678d26",
"a1000001-0000-0000-0000-000000000012",
"43098881-e044-482b-8e92-471728a8ba8b",
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
"mem-e5cc63c0-8701-49d6-855a-e387fe087771",
"a1000001-0000-0000-0000-000000000001"
],
"n_returned": 10,
"latency_ms": 725.1,
"latency_ms": 1395.8,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -486,15 +486,15 @@
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
"knw-7902acca-604e-409b-8faf-ad85424211d0",
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
"345b6420-e004-4d2e-b55c-6a729393fa99",
"d6b12ecf-702b-4101-b1bb-09ed9b220b29",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"mem-92a7fdc5-9dd0-48cf-a691-506058de3838",
"c608a095-c98b-4bfa-bfe1-1611c1320290",
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
"a1000001-0000-0000-0000-000000000010",
"451ae007-4219-4096-89fe-fa2e045fbeb1",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e"
],
"n_returned": 10,
"latency_ms": 562.8,
"latency_ms": 1243.4,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -519,7 +519,7 @@
"bl-ef2bac68-e119-4139-b529-c7a1404ae3ac"
],
"n_returned": 10,
"latency_ms": 686.5,
"latency_ms": 1598.7,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -544,7 +544,7 @@
"bl-286b562a-5299-40e0-a32a-afa9cbdfe995"
],
"n_returned": 10,
"latency_ms": 584.2,
"latency_ms": 1379.6,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -557,19 +557,19 @@
"category": "paraphrase",
"query": "what shifts tells you where to cut a system apart",
"returned": [
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
"5a2c118a-87bd-4239-97a7-9e02c5991983",
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
"bl-4c5b385e-135a-4663-8521-96af0b491121",
"mem-ef878e30-5851-4e82-8588-745415108941",
"knw-12b4b913-7a25-4b0d-844c-504c01d6725e",
"bl-2b00aeb0-c0fa-4a9f-8f30-4207e98b3d52",
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
"knw-9707256e-ed44-4042-bd88-f90fa514e1cf",
"34356a36-0df5-4020-8dcc-5e7a423f8d4c",
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
"knw-0087493b-25cd-45b0-bf46-c078c5b49718",
"mem-22f5f665-3ad2-4063-88b0-915849a795f5",
"bl-4c5b385e-135a-4663-8521-96af0b491121",
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21"
],
"n_returned": 10,
"latency_ms": 719.6,
"latency_ms": 1632.5,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -584,17 +584,17 @@
"returned": [
"bl-8dd70cac-866d-4ff2-b9fe-b4b3c5f094bb",
"mem-b43f6ef4-2f5a-418d-b5ce-3f21520cf6b8",
"knw-7902acca-604e-409b-8faf-ad85424211d0",
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
"a1000001-0000-0000-0000-000000000001",
"kn-58874a74-b96f-4883-9e08-45707f4bd3ee",
"bl-1b58b05c-9305-4f06-a586-a08c96008027",
"a0edad47-5f77-4fc3-a546-1e85f8c68e77",
"a1000001-0000-0000-0000-000000000001",
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
"96497334-b18f-495c-9228-eeb8182bdc38",
"mem-024598a9-ed2e-4eeb-b1e1-5410856ff132",
"ctx-4a41",
"mem-5708f4c9-3d61-4182-8543-2843698931e6"
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"knw-ed33e669-0790-44cb-a036-958d605c6fea"
],
"n_returned": 10,
"latency_ms": 634.6,
"latency_ms": 1491.9,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -607,19 +607,19 @@
"category": "paraphrase",
"query": "loved for the unedited self and not the polished exterior",
"returned": [
"077d064f-3489-4c05-9aca-3782f96b51db",
"knw-f9ce17a7-17fc-431f-8f23-695b670ec4fa",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
"27e1b1a4-ad0b-49d9-812f-fedf43b8aabe",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"knw-f9ce17a7-17fc-431f-8f23-695b670ec4fa",
"bl-87c93185-b2bf-40af-ae23-3c830c007abf",
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
"077d064f-3489-4c05-9aca-3782f96b51db",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
"fce2792a-53fc-4d4a-be3b-42bd6ceb1ba7",
"75e036d3-c170-4e3f-acc2-e456a6850ee2",
"a1000001-0000-0000-0000-000000000001"
],
"n_returned": 10,
"latency_ms": 674.2,
"latency_ms": 1535.5,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -638,13 +638,13 @@
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"mem-5624ec9d-62ba-4aba-8a3d-6afec6c09dd4",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"mem-a16deccb-16a7-419c-a013-ff824a4daa15",
"a1000001-0000-0000-0000-000000000009",
"mem-833dbbcd-2400-4594-bb35-93b023049ac0",
"a1000001-0000-0000-0000-000000000009",
"mem-759e78ca-5394-4244-aa39-1c1468bc5f3e",
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd"
],
"n_returned": 10,
"latency_ms": 571.6,
"latency_ms": 1249.8,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -657,19 +657,19 @@
"category": "paraphrase",
"query": "a childhood offering no solid foundation to inherit",
"returned": [
"mem-b99efff0-00e6-40c8-9c5b-730330eef33b",
"bl-3f57bc69-7285-4f4a-a861-2de52efca058",
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
"knw-f6ed7d00-bf7d-42ce-9e40-77cf3406e918",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"knw-23c27d3b-e0d2-43a8-a80c-0a44477ae18a",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
"tag-childhood",
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21"
"bl-0d8c5dfa-e163-4fef-a58b-56b0d076c5a8",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"mem-b99efff0-00e6-40c8-9c5b-730330eef33b",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
"tag-childhood"
],
"n_returned": 10,
"latency_ms": 603.4,
"latency_ms": 1351.0,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -690,11 +690,11 @@
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21",
"766de879-f9d0-4a07-b6df-b43ee13763d8",
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
"efe53612-6914-4936-8e3b-1e694eb174e5",
"3499d5da-0e9c-4de4-9bc4-8941b14e0b1f",
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c"
],
"n_returned": 10,
"latency_ms": 656.2,
"latency_ms": 1438.4,
"error": null,
"hit@5": 1.0,
"recall@5": 0.18181818181818182,
@@ -719,7 +719,7 @@
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71"
],
"n_returned": 10,
"latency_ms": 536.9,
"latency_ms": 1110.1,
"error": null,
"hit@5": 1.0,
"recall@5": 0.07692307692307693,
@@ -744,7 +744,7 @@
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c"
],
"n_returned": 10,
"latency_ms": 562.4,
"latency_ms": 1186.1,
"error": null,
"hit@5": 1.0,
"recall@5": 0.18181818181818182,
@@ -769,7 +769,7 @@
"mem-ab34c2f7-3243-424b-affa-25555f6cf9cc"
],
"n_returned": 10,
"latency_ms": 556.6,
"latency_ms": 1193.1,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -794,7 +794,7 @@
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e"
],
"n_returned": 10,
"latency_ms": 542.6,
"latency_ms": 1201.5,
"error": null,
"hit@5": 1.0,
"recall@5": 0.09090909090909091,
@@ -808,18 +808,18 @@
"query": "man of the house six years old expectation",
"returned": [
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"knw-528dbc37-eabc-4b75-a7a5-65bf38d6018a",
"knw-729fc901-8335-44c4-9f3a-b150b4aa0915",
"knw-d357b6bb-ad8a-4791-b516-426aea45fa5b",
"knw-473f3f24-20f6-4f39-8589-3709538eb6ac",
"mem-a0b7cfda-bc9e-4f40-b9a9-1722cf3f8263",
"knw-7902acca-604e-409b-8faf-ad85424211d0",
"knw-528dbc37-eabc-4b75-a7a5-65bf38d6018a",
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
"4f698ae6-c40e-464e-9798-50350991a188",
"719aa819-00a9-4f4b-a857-4f9fe5ad44d7",
"knw-473f3f24-20f6-4f39-8589-3709538eb6ac",
"?Z?<S???K ?",
"knw-7902acca-604e-409b-8faf-ad85424211d0",
"'?T?a\"B~-?8",
"kn-6061318f-046b-4935-907d-8eafdce14930"
],
"n_returned": 10,
"latency_ms": 683.5,
"latency_ms": 1424.8,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -833,7 +833,7 @@
"query": "zqxjvw plimforth grebulon",
"returned": [],
"n_returned": 0,
"latency_ms": 350.4,
"latency_ms": 705.7,
"error": null,
"clean": true,
"false_positives": 0
@@ -844,7 +844,7 @@
"query": "flarnbistle quommetry",
"returned": [],
"n_returned": 0,
"latency_ms": 258.4,
"latency_ms": 484.4,
"error": null,
"clean": true,
"false_positives": 0
@@ -853,12 +853,23 @@
"id": "q35",
"category": "nonsense",
"query": "xxqzzt vurblenacht throom",
"returned": [],
"n_returned": 0,
"latency_ms": 348.4,
"returned": [
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
"?V?",
"knw-6b48dce2-f21c-452a-9db5-4e6aa61c87ca",
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
"?m?\\}Q??6??",
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
"?m?\\}Q??6??",
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
"kn-333542cb-6dab-4662-9725-bf7440d28bf7"
],
"n_returned": 10,
"latency_ms": 740.2,
"error": null,
"clean": true,
"false_positives": 0
"clean": false,
"false_positives": 10
},
{
"id": "q36",
@@ -871,13 +882,13 @@
"kn-b7e98d63-8b83-4911-b4d0-990602a7f575",
"tag-__darma____cgi____patents____self-improvement____character-preservation____autonomous____kotlin____architecture__",
"knw-e047bb42-dc5b-4383-9e88-e508dc03abe3",
"mem-c17aefb1-38b5-4ced-af50-fe524127e1a4",
"mem-e6327f52-2bda-4ce7-9471-2fffd1e172de",
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
"bl-145a0985-2382-400f-a7c5-c335c5e30a72",
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5"
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5",
"bl-145a0985-2382-400f-a7c5-c335c5e30a72"
],
"n_returned": 10,
"latency_ms": 664.5,
"latency_ms": 1307.7,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -902,10 +913,10 @@
"a1000001-0000-0000-0000-000000000002",
"3cf706a1-3825-45d8-b0a9-06cae6cdf5b8",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"de3b6428-b76c-4c44-90e0-bf1dd6998027"
"7ac62daa-2eac-4c7a-a97e-e4203fc1b57b"
],
"n_returned": 10,
"latency_ms": 747.3,
"latency_ms": 1669.8,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -933,7 +944,7 @@
"mem-3a2cf162-d93b-4f29-86f2-5066fb7fe1f5"
],
"n_returned": 10,
"latency_ms": 504.2,
"latency_ms": 1018.2,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -1,37 +1,37 @@
{
"label": "wsclaim24",
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-wsclaim24",
"soul_md5": "a377d9c0e5282e842ed98384c8b50d2c",
"label": "claim24",
"soul_binary": "/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad/soul-claim24",
"soul_md5": "676ebffb91f00046dcea895f5aa7efba",
"corpus": "/Users/timlingo/neuron-eval-corpora/snapshot-pre-repair-20260806-embedded.json",
"corpus_nodes": 78768,
"corpus_edges": 14214,
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-eval/tools/retrieval-eval/gold_set.json",
"gold_set": "/Users/timlingo/Development/neuron-technologies/_wt-bm25lex/tools/retrieval-eval/gold_set.json",
"limit": 10,
"port": 7893,
"wall_clock_s": 29.9,
"child_pid": 99726,
"wall_clock_s": 52.3,
"child_pid": 92441,
"child_confirmed_dead": true,
"aggregate": {
"n_queries": 38,
"n_scored": 35,
"hit@5": 0.7428571428571429,
"recall@5": 0.5768475572047,
"recall@10": 0.6563414759843332,
"recall@10": 0.6537440733869305,
"precision@5": 0.19428571428571437,
"mrr@10": 0.5026530612244898,
"nonsense_clean": "0/3",
"mrr@10": 0.5021428571428572,
"nonsense_clean": "2/3",
"superseded_outranks": "2/3",
"latency_ms_p50": 524.8,
"latency_ms_p95": 738.7,
"latency_ms_max": 755.8,
"latency_ms_p50": 1173.7,
"latency_ms_p95": 1623.0,
"latency_ms_max": 1647.9,
"errors": 0,
"by_category": {
"associative": {
"n": 6,
"hit@5": 0.5,
"recall@5": 0.07575757575757576,
"recall@10": 0.13636363636363635,
"mrr@10": 0.23214285714285712
"recall@10": 0.12121212121212122,
"mrr@10": 0.22916666666666666
},
"exact_rare": {
"n": 6,
@@ -42,8 +42,8 @@
},
"nonsense": {
"n": 3,
"clean": 0,
"avg_false_positives": 10.0
"clean": 2,
"avg_false_positives": 3.3333333333333335
},
"paraphrase": {
"n": 13,
@@ -87,7 +87,7 @@
"696e609c-da7a-4394-8a0c-106ba07dc6c3"
],
"n_returned": 10,
"latency_ms": 173.2,
"latency_ms": 284.2,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -112,7 +112,7 @@
"ctx-fae1"
],
"n_returned": 10,
"latency_ms": 158.1,
"latency_ms": 338.1,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -137,7 +137,7 @@
"x??I?cB?]p?"
],
"n_returned": 10,
"latency_ms": 160.8,
"latency_ms": 300.4,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -162,7 +162,7 @@
"mem-2d1ea831-cccd-4f0f-86b9-2cbbc89dc3e0"
],
"n_returned": 10,
"latency_ms": 158.0,
"latency_ms": 285.2,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -187,7 +187,7 @@
"bl-2632242e-80b1-4d88-8368-7065b5de5b34"
],
"n_returned": 10,
"latency_ms": 170.3,
"latency_ms": 318.5,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -212,7 +212,7 @@
"??"
],
"n_returned": 10,
"latency_ms": 175.8,
"latency_ms": 331.3,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -237,7 +237,7 @@
"bl-39dad13d-7105-4049-8224-dc3c34fdb1f3"
],
"n_returned": 10,
"latency_ms": 293.8,
"latency_ms": 582.9,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -257,12 +257,12 @@
"mem-c9bec303-a638-4a11-a490-f38410d448cf",
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
"knw-f671966c-3387-4848-abca-b5deec122e00",
"7cf3f825-d7b6-4864-b0ae-52939cf1ae84",
"2795fdbb-ee2a-4009-aa30-3f1c25b6e77c",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"knw-4aebd815-4eaf-49d7-954b-03595f3d48be"
],
"n_returned": 10,
"latency_ms": 251.2,
"latency_ms": 520.6,
"error": null,
"hit@5": 1.0,
"recall@5": 0.1875,
@@ -287,7 +287,7 @@
"kn-f230b362-b201-4402-9833-4160c89ab3d4"
],
"n_returned": 10,
"latency_ms": 264.4,
"latency_ms": 531.5,
"error": null,
"hit@5": 1.0,
"recall@5": 0.2222222222222222,
@@ -312,7 +312,7 @@
"tag-harmonic-framework"
],
"n_returned": 10,
"latency_ms": 262.5,
"latency_ms": 502.8,
"error": null,
"hit@5": 1.0,
"recall@5": 0.1111111111111111,
@@ -337,7 +337,7 @@
"??_/Pr?????"
],
"n_returned": 10,
"latency_ms": 257.7,
"latency_ms": 506.1,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -358,11 +358,11 @@
"bl-2515d870-e35e-443b-ba20-5150bbc73fed",
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
"bl-a0982e7c-e165-4da3-a11d-619fa0b535b0",
"?Q??m?;?u?'",
"2c56a7a9-5323-4ce4-ba09-35836ba15d54",
"knw-cf13b883-d947-4cf8-b86b-cd9c6f0748d6"
],
"n_returned": 10,
"latency_ms": 393.5,
"latency_ms": 861.8,
"error": null,
"hit@5": 1.0,
"recall@5": 0.21428571428571427,
@@ -381,13 +381,13 @@
"7774a16c-1027-4e3b-a21e-67f1f95a4acd",
"?",
"bl-3c719d9a-cba1-47f4-b097-52cdeccc7c0d",
"mem-fb44a2fc-7405-41ff-87b3-84643ac07313",
"830ca37a-d334-4e41-ba89-64893dc8d628",
"?",
"mem-ce88adf9-3f3c-47ac-a7d3-83af7b290e68",
"ce9636dc-85a5-4dae-9e07-74ea2fcc6307",
"?"
],
"n_returned": 10,
"latency_ms": 333.4,
"latency_ms": 758.5,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -406,13 +406,13 @@
"knw-d788a210-613b-4c49-9486-88bbc9d4716f",
"art-4a99aa1a-489b-4b43-958b-25217adb1aad",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
"66c63082-b4da-4aa1-8fee-848db8a83210",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"mem-a535f205-bc4c-4058-9171-6263c496044a"
],
"n_returned": 10,
"latency_ms": 755.8,
"latency_ms": 1590.9,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -429,15 +429,15 @@
"art-79042b8b-6192-440f-90b0-60708f7e6325",
"mem-16efddd1-c43d-4a42-9d78-f54fb82bd277",
"daf9d558-2265-49b0-b4fb-be0b80f3cdb1",
"bfb5809e-d19a-4d3f-8c1a-796db622ad9d",
"863bfd72-50d2-487f-85ae-ecd48e2a501f",
"art-ddfcd045-2c3b-4a1e-9966-fec5ce44e1dd",
"f3364a57-956a-4e78-a500-b3b66a4e3066",
"5c1c3404-ad4c-49f1-8c0c-81262812731e",
"15a90710-5372-4d3d-aee5-2d7287d2a492",
"341afa66-6a49-43fe-9d5b-3f1032bb6904",
"465fa29f-1ce3-4769-962a-1c32dfed8347",
"mem-da21c52c-04a5-4f92-8fba-f10aac47e027"
],
"n_returned": 10,
"latency_ms": 720.3,
"latency_ms": 1647.9,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -459,10 +459,10 @@
"mem-d1cfde0a-37f1-4bff-9a06-8eddbbf259f6",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"knw-f671966c-3387-4848-abca-b5deec122e00",
"tag-factions"
"mem-16efddd1-c43d-4a42-9d78-f54fb82bd277"
],
"n_returned": 10,
"latency_ms": 616.0,
"latency_ms": 1338.6,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -475,19 +475,19 @@
"category": "paraphrase",
"query": "a tight payload beats a bloated one",
"returned": [
"bl-680b24a9-edc3-4a9d-847a-bff0b46b568c",
"bl-8de20bcf-7149-4f48-b67c-e7f9758fd6e5",
"mem-628437a6-47b0-4d81-8112-7e78499723d5",
"bl-798d135f-3987-4ccd-8de6-70ca2f358337",
"08f0d1e2-8d0e-42e3-9f0a-8186ae31ec7e",
"bl-680b24a9-edc3-4a9d-847a-bff0b46b568c",
"knw-12b4b913-7a25-4b0d-844c-504c01d6725e",
"knw-08559f5c-2306-4220-a146-398c74f1643c",
"4da5dbaf-46e5-4f3e-b474-f60d9f8241d3",
"bl-164b520b-c503-49db-89f9-bd2fdf4215f5",
"o#?CW????y:",
"knw-f6ed7d00-bf7d-42ce-9e40-77cf3406e918",
"mem-434be7c8-88cb-4039-b79a-1da4ac4de783"
"1219277c-1b95-45ec-95a2-07b4a47a4d92"
],
"n_returned": 10,
"latency_ms": 518.5,
"latency_ms": 1060.5,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -506,13 +506,13 @@
"a1000001-0000-0000-0000-000000000010",
"bl-9ce4128a-9436-4b06-82bc-8a6faafa81e0",
"a1000001-0000-0000-0000-000000000009",
"mem-32203649-3213-4d6d-86fd-3d657ac70d77",
"43098881-e044-482b-8e92-471728a8ba8b",
"? t?'?B?+??",
"a1000001-0000-0000-0000-000000000012",
"mem-da21c52c-04a5-4f92-8fba-f10aac47e027"
"bl-448bc514-c2f1-4520-a9b1-1f3a73678d26"
],
"n_returned": 10,
"latency_ms": 742.9,
"latency_ms": 1388.8,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -534,10 +534,10 @@
"345b6420-e004-4d2e-b55c-6a729393fa99",
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"mem-92a7fdc5-9dd0-48cf-a691-506058de3838"
"74f4776a-d0ea-44e4-b94f-7c87d0179ef3"
],
"n_returned": 10,
"latency_ms": 549.8,
"latency_ms": 1231.7,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -562,7 +562,7 @@
"bl-ef2bac68-e119-4139-b529-c7a1404ae3ac"
],
"n_returned": 10,
"latency_ms": 682.4,
"latency_ms": 1590.7,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -587,7 +587,7 @@
"bl-56a50e97-9a85-4e81-b6c9-3e3d26482f1d"
],
"n_returned": 10,
"latency_ms": 575.0,
"latency_ms": 1380.0,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -600,19 +600,19 @@
"category": "paraphrase",
"query": "what shifts tells you where to cut a system apart",
"returned": [
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
"5a2c118a-87bd-4239-97a7-9e02c5991983",
"bl-06c13965-082b-417d-9561-93d6e958ae5d",
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
"bl-4c5b385e-135a-4663-8521-96af0b491121",
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
"knw-12b4b913-7a25-4b0d-844c-504c01d6725e",
"bl-2b00aeb0-c0fa-4a9f-8f30-4207e98b3d52",
"kn-22d77abe-b3c5-42fd-afcd-dcb87d924929",
"mem-7b74cac0-905f-4c35-9688-fbcce105a177",
"knw-9707256e-ed44-4042-bd88-f90fa514e1cf",
"34356a36-0df5-4020-8dcc-5e7a423f8d4c"
"bl-4c5b385e-135a-4663-8521-96af0b491121"
],
"n_returned": 10,
"latency_ms": 711.3,
"latency_ms": 1623.0,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -627,17 +627,17 @@
"returned": [
"bl-8dd70cac-866d-4ff2-b9fe-b4b3c5f094bb",
"mem-b43f6ef4-2f5a-418d-b5ce-3f21520cf6b8",
"knw-7902acca-604e-409b-8faf-ad85424211d0",
"knw-ed33e669-0790-44cb-a036-958d605c6fea",
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
"a0edad47-5f77-4fc3-a546-1e85f8c68e77",
"a1000001-0000-0000-0000-000000000001",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"bl-1b58b05c-9305-4f06-a586-a08c96008027",
"96497334-b18f-495c-9228-eeb8182bdc38",
"mem-024598a9-ed2e-4eeb-b1e1-5410856ff132",
"kn-78db5396-3dbc-4481-bfc7-e4e1422feb1c",
"mem-5708f4c9-3d61-4182-8543-2843698931e6"
"knw-ed33e669-0790-44cb-a036-958d605c6fea"
],
"n_returned": 10,
"latency_ms": 616.7,
"latency_ms": 1471.0,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -650,19 +650,19 @@
"category": "paraphrase",
"query": "loved for the unedited self and not the polished exterior",
"returned": [
"077d064f-3489-4c05-9aca-3782f96b51db",
"27e1b1a4-ad0b-49d9-812f-fedf43b8aabe",
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd",
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"bl-87c93185-b2bf-40af-ae23-3c830c007abf",
"knw-c72597c5-c23d-4c08-8e9e-996dadf26a99",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"27e1b1a4-ad0b-49d9-812f-fedf43b8aabe",
"077d064f-3489-4c05-9aca-3782f96b51db",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
"fce2792a-53fc-4d4a-be3b-42bd6ceb1ba7"
"kn-6061318f-046b-4935-907d-8eafdce14930"
],
"n_returned": 10,
"latency_ms": 658.4,
"latency_ms": 1516.6,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -687,7 +687,7 @@
"mem-a16deccb-16a7-419c-a013-ff824a4daa15"
],
"n_returned": 10,
"latency_ms": 566.3,
"latency_ms": 1224.2,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -700,19 +700,19 @@
"category": "paraphrase",
"query": "a childhood offering no solid foundation to inherit",
"returned": [
"mem-b99efff0-00e6-40c8-9c5b-730330eef33b",
"bl-3f57bc69-7285-4f4a-a861-2de52efca058",
"kn-a99cefe3-5e83-4050-98d8-6c69f57c7c71",
"knw-2c46cfb4-6d4e-4822-8a1a-7d743c1e4329",
"knw-f6ed7d00-bf7d-42ce-9e40-77cf3406e918",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"knw-23c27d3b-e0d2-43a8-a80c-0a44477ae18a",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"kn-f230b362-b201-4402-9833-4160c89ab3d4",
"tag-childhood",
"bl-0d8c5dfa-e163-4fef-a58b-56b0d076c5a8",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"mem-b99efff0-00e6-40c8-9c5b-730330eef33b",
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"kn-5b606390-a52d-4ca2-8e0e-eba141d13440",
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21"
],
"n_returned": 10,
"latency_ms": 589.6,
"latency_ms": 1335.9,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -733,11 +733,11 @@
"766de879-f9d0-4a07-b6df-b43ee13763d8",
"mem-5f76880b-bafb-4716-8e15-90f8ef59bebc",
"kn-e0423482-cfa5-4796-8689-8495c93b66bc",
"28ae74a1-9d47-4874-9279-43c1f90c0f64",
"3499d5da-0e9c-4de4-9bc4-8941b14e0b1f",
"mem-bce80169-2d46-4b3e-9ebe-8498e26f0a89"
],
"n_returned": 10,
"latency_ms": 627.8,
"latency_ms": 1421.9,
"error": null,
"hit@5": 1.0,
"recall@5": 0.18181818181818182,
@@ -762,7 +762,7 @@
"5eb24168-c2d3-4842-85db-2070e0e14923"
],
"n_returned": 10,
"latency_ms": 524.3,
"latency_ms": 1102.3,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -787,7 +787,7 @@
"?V?"
],
"n_returned": 10,
"latency_ms": 526.0,
"latency_ms": 1173.7,
"error": null,
"hit@5": 1.0,
"recall@5": 0.18181818181818182,
@@ -812,7 +812,7 @@
"???I?cB?Zx?"
],
"n_returned": 10,
"latency_ms": 526.0,
"latency_ms": 1187.7,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -837,7 +837,7 @@
"kn-13f60407-7b70-4db1-964f-ea1f8196efbd"
],
"n_returned": 10,
"latency_ms": 524.8,
"latency_ms": 1192.0,
"error": null,
"hit@5": 1.0,
"recall@5": 0.09090909090909091,
@@ -853,85 +853,63 @@
"kn-eb1b9e18-3dc6-4b9b-9cc6-86e0ae6b6be8",
"mem-5305665c-6b5b-45b7-89ae-5d2fb0b896ac",
"4f698ae6-c40e-464e-9798-50350991a188",
"mem-a0b7cfda-bc9e-4f40-b9a9-1722cf3f8263",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"knw-35940684-abc4-42f0-b942-818f66b1f69a",
"kn-6061318f-046b-4935-907d-8eafdce14930",
"?Z?<S???K ?",
"mem-a0b7cfda-bc9e-4f40-b9a9-1722cf3f8263",
"kn-db9f141b-dbe3-4037-92e0-4bb9be0e5e6e",
"719aa819-00a9-4f4b-a857-4f9fe5ad44d7",
"mem-d396d789-0f7f-4366-a008-5d8801c8f2eb",
"kn-0bb4f021-56de-4947-a35b-a37209e7ba21"
"'?T?a\"B~-?8",
"mem-d396d789-0f7f-4366-a008-5d8801c8f2eb"
],
"n_returned": 10,
"latency_ms": 668.9,
"latency_ms": 1425.3,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
"recall@10": 0.18181818181818182,
"recall@10": 0.09090909090909091,
"precision@5": 0.0,
"mrr@10": 0.14285714285714285
"mrr@10": 0.125
},
{
"id": "q33",
"category": "nonsense",
"query": "zqxjvw plimforth grebulon",
"returned": [
"$\\?l????T?",
"project-Deploy_Ollama_on_Legion_k8s__Traefik_route_at_ollama_neuralplatform_ai__8B_model_seeded_",
"c??Z??I?E??",
"?^?l????K8?",
"${????X?6#E",
"???Z??I?b??",
"??m???|Y`0?",
"??m???|Y`0?",
"??m???|Y`0?",
"=?m???|YH??"
],
"n_returned": 10,
"latency_ms": 338.4,
"returned": [],
"n_returned": 0,
"latency_ms": 714.9,
"error": null,
"clean": false,
"false_positives": 10
"clean": true,
"false_positives": 0
},
{
"id": "q34",
"category": "nonsense",
"query": "flarnbistle quommetry",
"returned": [
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??"
],
"n_returned": 10,
"latency_ms": 248.9,
"returned": [],
"n_returned": 0,
"latency_ms": 496.0,
"error": null,
"clean": false,
"false_positives": 10
"clean": true,
"false_positives": 0
},
{
"id": "q35",
"category": "nonsense",
"query": "xxqzzt vurblenacht throom",
"returned": [
"bl-4476e856-c567-4b49-8ff7-d7dca3e5715e",
"?V?",
"knw-6b48dce2-f21c-452a-9db5-4e6aa61c87ca",
"knw-920c891f-bb8c-48c4-9afc-018ef12dcdc4",
"?m?\\}Q??6??",
"8cbb60c5-4999-4ec1-8682-2592aedc4249",
"kn-66a21179-2adc-4b19-a109-880cf4674d7d",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??",
"?m?\\}Q??6??"
"knw-723551f5-1950-42a3-8b89-b6a06913cef0",
"kn-333542cb-6dab-4662-9725-bf7440d28bf7"
],
"n_returned": 10,
"latency_ms": 338.6,
"latency_ms": 729.4,
"error": null,
"clean": false,
"false_positives": 10
@@ -947,13 +925,13 @@
"kn-b7e98d63-8b83-4911-b4d0-990602a7f575",
"tag-__darma____cgi____patents____self-improvement____character-preservation____autonomous____kotlin____architecture__",
"knw-e047bb42-dc5b-4383-9e88-e508dc03abe3",
"mem-c17aefb1-38b5-4ced-af50-fe524127e1a4",
"mem-e6327f52-2bda-4ce7-9471-2fffd1e172de",
"bl-145a0985-2382-400f-a7c5-c335c5e30a72",
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff",
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5"
"mem-82b93b21-a865-410f-9ec1-fc54121d9bb5",
"bl-5b17bd3b-0c41-46cb-a710-6fa4429692ff"
],
"n_returned": 10,
"latency_ms": 644.8,
"latency_ms": 1306.9,
"error": null,
"hit@5": 1.0,
"recall@5": 1.0,
@@ -962,7 +940,7 @@
"mrr@10": 0.5,
"outranks": true,
"rank_correct": 2,
"rank_stale": 9
"rank_stale": 10
},
{
"id": "q37",
@@ -978,10 +956,10 @@
"13705072-4515-4124-963d-083af490494f",
"3cf706a1-3825-45d8-b0a9-06cae6cdf5b8",
"kn-5de5a9ac-fd15-45ab-bf18-77566781cf40",
"4f225001-3a51-4a68-8d38-c8ecac3412de"
"96eb59a0-5603-4c9e-835c-1de53f2319bc"
],
"n_returned": 10,
"latency_ms": 738.7,
"latency_ms": 1647.4,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
@@ -1009,7 +987,7 @@
"mem-3a2cf162-d93b-4f29-86f2-5066fb7fe1f5"
],
"n_returned": 10,
"latency_ms": 498.6,
"latency_ms": 1003.4,
"error": null,
"hit@5": 0.0,
"recall@5": 0.0,
+135
View File
@@ -0,0 +1,135 @@
import numpy as np, json, urllib.request, collections, math, re, sys, time
SP="/private/tmp/claude-501/-Users-timlingo/82369039-a20e-4b5a-8a5e-28234a57b996/scratchpad"
EV="/Users/timlingo/Development/neuron-technologies/_wt-bm25lex/tools/retrieval-eval/"
np.seterr(all='ignore'); t0=time.time()
M=np.load(SP+'/emb.npy'); eids=open(SP+'/ids.txt',encoding='utf-8',errors='surrogateescape').read().split('\n')
eidx={k:i for i,k in enumerate(eids)}
d=json.load(open('/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json',encoding='utf-8',errors='surrogateescape'))
STRUCT={"identity","contains","superseded_by","references","embodies","demonstrated_by","canonical-self","depends_on","currently_holds","activates"}
adj=collections.defaultdict(list)
for e in d['edges']:
if e.get('relation') not in STRUCT: continue
w=float(e.get('weight') or 0.0)
adj[e['from_id']].append((e['to_id'],w)); adj[e['to_id']].append((e['from_id'],w))
nodes=d['nodes']; N={n['id']:n for n in nodes}
PRINT=re.compile(r'^[\x20-\x7e]+$')
ids=[];hay=[];dl=[];sal=[];addr=[]
for n in nodes:
i=n.get('id') or ''
h=((n.get('content') or '')+'\x00'+(n.get('label') or '')+'\x00'+(n.get('tags') or '')).lower()
ids.append(i);hay.append(h);dl.append(len(h));sal.append(float(n.get('salience') or 0.0));addr.append(bool(PRINT.match(i)))
del d
NN=len(ids); avgdl=sum(dl)/NN
gold={q['id']:q for q in json.load(open(EV+"gold_set.json"))['queries']}
CACHE={}
def emb(t):
if t in CACHE: return CACHE[t]
b=json.dumps({"model":"nomic-embed-text","prompt":t}).encode()
r=urllib.request.Request("http://127.0.0.1:11434/api/embeddings",data=b,headers={"Content-Type":"application/json"})
v=np.array(json.load(urllib.request.urlopen(r,timeout=60))["embedding"],dtype=np.float32)
v=v/(np.linalg.norm(v)+1e-9); CACHE[t]=v; return v
K1,B=1.2,0.75
LEXC={}
def lexleg(qid,query,lim=10):
if qid in LEXC: return LEXC[qid]
toks=[]
for w in query.split():
wl=w.lower()
if wl not in toks: toks.append(wl)
nt=len(toks); masks=[]; df=[0]*nt
for i in range(NN):
if not addr[i]: continue
h=hay[i]; m=0; sc=0
for t in range(nt):
if toks[t] in h: m|=(1<<t); sc+=1; df[t]+=1
if sc: masks.append((i,m))
idf=[math.log(1.0+(NN-df[t]+0.5)/(df[t]+0.5)) for t in range(nt)]
scored=[]
for i,m in masks:
norm=1.0-B+B*dl[i]/avgdl; s=0.0
for t in range(nt):
if m&(1<<t): s+=idf[t]*(K1+1.0)/(1.0+K1*norm)
scored.append((s,i))
scored.sort(key=lambda x:(-x[0],-sal[x[1]]))
LEXC[qid]=([ids[i] for s,i in scored[:lim]], len(masks))
return LEXC[qid]
FIRE=0.02; DECAY=0.7; DEPTH=2; SEED_MIN=0.60; ASSOC_MAX=64
def assoc(seeds, s, use_cos, order):
act={x:1.0 for x in seeds}; seen={x:2 for x in seeds}
Q=[(x,0) for x in seeds]; h=0
while h<len(Q):
cur,hop=Q[h]; h+=1
if hop>=DEPTH: continue
p=act[cur]
for oid,w in adj.get(cur,()):
n=N.get(oid)
if not n or n.get('node_type') in ('Tag','InternalStateEvent'): continue
c=1.0
if use_cos:
j=eidx.get(oid)
c=max(0.0,float(s[j])) if j is not None else 0.0
na=p*w*DECAY*float(n.get('salience') or 0.0)*c
if na<FIRE: continue
if oid in seen and na<=act.get(oid,0): continue
act[oid]=na
if oid not in seen: seen[oid]=1
Q.append((oid,hop+1))
out=[]
for k,v in seen.items():
if v!=1 or k not in eidx: continue
c=float(s[eidx[k]])
if c<=0: continue
out.append((act[k] if order=='act' else c,k))
out.sort(reverse=True)
return [k for c,k in out[:ASSOC_MAX] if PRINT.match(k or '')]
def inter(legs,lim=10):
out=[];idx=[0]*len(legs)
while len(out)<lim and any(idx[i]<len(legs[i]) for i in range(len(legs))):
for i in range(len(legs)):
if idx[i]<len(legs[i]):
if legs[i][idx[i]] not in out: out.append(legs[i][idx[i]])
idx[i]+=1
if len(out)>=lim: break
return out
def run(floor, vocabgate, use_cos, order):
res={}; legs={}
for qid,q in gold.items():
v=emb(q['query']); s=M@v; s[~np.isfinite(s)]=-1
L,nmatch=lexleg(qid,q['query'])
if vocabgate and nmatch==0:
res[qid]=[]; legs[qid]=([],[],[]); continue
ordr=np.argsort(-s)
S=[eids[j] for j in ordr[:10] if PRINT.match(eids[j] or '') and (not floor or s[j]>SEED_MIN)]
seeds=[x for x in L[:3] if x in N]
seeds=seeds+[eids[j] for j in ordr[:8] if eids[j] in N and eids[j] not in seeds and PRINT.match(eids[j] or '')]
A=assoc(seeds,s,use_cos,order) if seeds else []
res[qid]=inter([L,S,A]); legs[qid]=(L,S,A)
return res,legs
def score(res,label,base=None):
det={}
for qid,q in gold.items():
out=res[qid][:5]
if q['category']=='nonsense': ok=(len(res[qid])==0)
elif q['category']=='superseded':
must=q.get('must_outrank') or {}; ok=False
for good,bad in (must.items() if isinstance(must,dict) else []):
ok = good in res[qid] and (bad not in res[qid] or res[qid].index(good)<res[qid].index(bad))
if not must: ok=any(r in out for r in q['relevant'])
else: ok=any(r in out for r in q['relevant'])
det[qid]=ok
line="%-34s true=%d/38"%(label,sum(det.values()))
if base is not None:
dd=[q for q in sorted(gold) if det[q]!=base[q]]
line+=" moved=%d gains=%s losses=%s"%(len(dd),[q for q in dd if det[q]],[q for q in dd if not det[q]])
print(line, flush=True)
return det
if __name__=="__main__":
b,_=run(True,False,False,'cos'); base=score(b,'BASE bm25lex replica')
for lab,args in [
("A floor-off+vocabgate", (False,True,False,'cos')),
("B A+cos-in-traversal", (False,True,True ,'cos')),
("C A+cos-trav+act-order", (False,True,True ,'act')),
("D floor-off NO gate", (False,False,False,'cos')),
]:
r,_=run(*args); score(r,lab,base)
print("elapsed %.1fs"%(time.time()-t0),file=sys.stderr)
+32
View File
@@ -0,0 +1,32 @@
exec(open('sim6.py').read().split('if __name__')[0])
HASSTRUCT=set(adj.keys())
print("nodes with >=1 structural edge:",len(HASSTRUCT),file=sys.stderr)
def run2(sfilter, seedout, lim=10):
res={}
for qid,q in gold.items():
v=emb(q['query']); s=M@v; s[~np.isfinite(s)]=-1
L,nmatch=lexleg(qid,q['query'])
if nmatch==0: res[qid]=[]; continue
ordr=np.argsort(-s)
cand=[eids[j] for j in ordr[:200] if PRINT.match(eids[j] or '')]
S=[x for x in cand if (not sfilter or x in HASSTRUCT)][:10]
seeds=[x for x in L[:3] if x in N]
semseeds=[eids[j] for j in ordr[:8] if eids[j] in N and eids[j] not in seeds and PRINT.match(eids[j] or '')]
seeds=seeds+semseeds
A=assoc(seeds,s,False,'cos') if seeds else []
if seedout:
extra=[(float(s[eidx[x]]),x) for x in semseeds if x in HASSTRUCT and x in eidx]
merged=[(float(s[eidx[x]]),x) for x in A if x in eidx]+extra
merged.sort(reverse=True)
seen=set(); A=[]
for c,x in merged:
if x in seen: continue
seen.add(x); A.append(x)
A=A[:ASSOC_MAX]
res[qid]=inter([L,S,A])
return res
b,_=run(True,False,False,'cos'); base=score(b,'BASE bm25lex replica')
a,_=run(False,True,False,'cos'); score(a,'A floor-off+vocabgate',base)
score(run2(False,True),'E A+struct-seeds-in-graphleg',base)
score(run2(True,False),'F A+S-restricted-to-graph',base)
score(run2(True,True),'G E+F',base)
+30
View File
@@ -0,0 +1,30 @@
exec(open('sim6.py').read().split('if __name__')[0])
HASSTRUCT=set(adj.keys())
import json as _j
d2=_j.load(open('/Users/timlingo/neuron-memory-backups/snapshot-pre-repair-20260806.json',encoding='utf-8',errors='surrogateescape'))
ANYEDGE=set()
for e in d2['edges']: ANYEDGE.add(e['from_id']); ANYEDGE.add(e['to_id'])
del d2
print("struct=%d anyedge=%d"%(len(HASSTRUCT),len(ANYEDGE)),file=sys.stderr)
def run4(pool, nlegs, lim=10):
P = HASSTRUCT if pool=='struct' else ANYEDGE
res={}
for qid,q in gold.items():
v=emb(q['query']); s=M@v; s[~np.isfinite(s)]=-1
L,nmatch=lexleg(qid,q['query'])
if nmatch==0: res[qid]=[]; continue
ordr=np.argsort(-s)
cand=[eids[j] for j in ordr[:3000] if PRINT.match(eids[j] or '')]
S=cand[:10]
G=[x for x in cand if x in P][:10]
seeds=[x for x in L[:3] if x in N]
seeds=seeds+[eids[j] for j in ordr[:8] if eids[j] in N and eids[j] not in seeds and PRINT.match(eids[j] or '')]
A=assoc(seeds,s,False,'cos') if seeds else []
legs=[L,S,G,A] if nlegs==4 else [L,G,A]
res[qid]=inter(legs)
return res
b,_=run(True,False,False,'cos'); base=score(b,'BASE bm25lex replica')
score(run4('struct',4),'I 4leg L,S,G(struct),A',base)
score(run4('any',4), 'J 4leg L,S,G(anyedge),A',base)
score(run4('struct',3),'K 3leg L,G(struct),A',base)
score(run4('any',3), 'L 3leg L,G(anyedge),A',base)
-92
View File
@@ -1,92 +0,0 @@
import json,sys,pickle,numpy as np
sys.path.insert(0,'.')
from legs import *
GP='/Users/timlingo/Development/neuron-technologies/_wt-bm25lex/tools/retrieval-eval/'
G=json.load(open(GP+'gold_set.json'))
def wstart(s,tok):
i=s.find(tok)
while i!=-1:
if i==0 or not s[i-1].isalnum(): return True
i=s.find(tok,i+1)
return False
def legs4(query, wordstart=False, unfloor=False):
toks=tokenize(query); lt=[t.lower() for t in toks]
hit_idx=[];hit_mask=[];df=[0]*len(toks)
for i in range(N):
if not OK[i]: continue
s=LOW[i];m=0
for t,tok in enumerate(lt):
if tok in s and (not wordstart or wstart(s,tok)): m|=(1<<t)
if m:
hit_idx.append(i);hit_mask.append(m)
for t in range(len(toks)):
if m>>t&1: df[t]+=1
dl_n=int(OK.sum());avgdl=float(DL[OK].sum()/max(dl_n,1))
idf=[math.log(1.0+((dl_n-d+0.5)/(d+0.5))) for d in df]
L=[]
for j,i in enumerate(hit_idx):
norm=1.0-B+B*(DL[i]/avgdl);w=0.0
for t in range(len(toks)):
if hit_mask[j]>>t&1: w+=idf[t]*(K1+1.0)/(1.0+K1*norm)
L.append((i,w,SAL[i]))
L.sort(key=lambda x:(-x[1],-x[2]))
if not L: return [],[],[]
qv=qemb(query);cos=En@qv;cos=np.where(HAVE&OK,cos,-2.0)
order=np.argsort(-cos)[:600]
Sl=[int(i) for i in order if cos[i]>(0.0 if unfloor else SEED_MIN)]
semseed=[int(i) for i in order[:SEED_K] if cos[i]>0.0]
act={};seen={};qq=[]
for i,_,_ in L[:ASSOC_SEEDS]:
act[i]=1.0;seen[i]=2;qq.append((i,0))
for i in semseed:
if i in seen: continue
act[i]=1.0;seen[i]=2;qq.append((i,0))
qh=0
while qh<len(qq):
cur,h=qq[qh];qh+=1
if h>=DEPTH: continue
parent=act[cur]
for e,oi in ADJ_F[cur]+ADJ_T[cur]:
if e['rel'] not in STRUCT or EXCL[oi]: continue
na=parent*e['w']*DECAY*SAL[oi]
if na<FIRE: continue
if seen.get(oi) and na<=act.get(oi,0): continue
act[oi]=na
if not seen.get(oi): seen[oi]=1
if len(qq)<AMAX*4: qq.append((oi,h+1))
A=sorted([(i,float(cos[i])) for i,st in seen.items() if st==1 and OK[i] and HAVE[i] and cos[i]>0.0],key=lambda x:-x[1])[:AMAX]
return [i for i,_,_ in L],Sl,[i for i,_ in A]
def merge(L,S,A,lim=10):
out=[];li=si=ai=0
while len(out)<lim and (li<len(L) or si<len(S) or ai<len(A)):
if li<len(L):
if L[li] not in out: out.append(L[li])
li+=1
if len(out)>=lim: break
if si<len(S):
if S[si] not in out: out.append(S[si])
si+=1
if len(out)>=lim: break
if ai<len(A):
if A[ai] not in out: out.append(A[ai])
ai+=1
return out
def outcome(q,ids):
c=q['category']
if c=='nonsense': return len(ids)==0
if c=='superseded':
a,b=q['must_outrank']
if a not in ids: return False
if b not in ids: return True
return ids.index(a)<ids.index(b)
return any(x in ids[:5] for x in q['relevant'])
def run(**kw):
return {q['id']:outcome(q,[NODES[i]['id'] for i in merge(*legs4(q['query'],**kw),10)]) for q in G['queries']}
base=run()
print("baseline",sum(base.values()),"misses",[k for k,v in base.items() if not v])
for name,kw in [('wordstart',dict(wordstart=True)),
('unfloor',dict(unfloor=True)),
('wordstart+unfloor',dict(wordstart=True,unfloor=True))]:
r=run(**kw)
g=sorted(k for k in base if r[k] and not base[k]);l=sorted(k for k in base if base[k] and not r[k])
print("%-20s net=%+d gains=%s losses=%s"%(name,len(g)-len(l),g,l))
+41 -58
View File
@@ -7327,39 +7327,6 @@ static int istr_contains(const char* hay, const char* needle) {
return 0;
}
/* Word-START-anchored variant of istr_contains.
*
* WHY. The retrieval match primitive is a raw substring test, so a query token
* matches ANYWHERE inside a corpus word: "throom" matches "bathroom", "cat"
* matches "concatenate". Measured on this corpus over the 38-query gold set,
* that is not a rare accident it is the bulk of some queries' candidate
* sets. q28's lexical leg is 36,954 records of which only 13 contain a query
* token at a word start (99.96% mid-word noise); six other queries carry
* ~20,500 mid-word-only records each; and the nonsense control q35
* ("xxqzzt vurblenacht throom") returns 7 records ALL of which match only
* mid-word, which is the entire reason that control has been dirty since main.
*
* WHAT CHANGES. A token must begin at a word boundary the preceding
* character is not alphanumeric. Suffixes are still matched ("value" still
* hits "values", "unjailbreakable" still hits "unjailbreakables"), so this is
* strictly a prefix anchor, not whole-word equality; whole-word equality would
* break the morphological matching the phrase category depends on.
*
* PROVENANCE, stated honestly: this restores no engram claim. Will's design
* has no lexical leg at all (05-detailed-description l.64 takes "one or more
* seed node UUIDs representing the current active context" as its input), so
* the lexical leg is the seed-finding step that feeds the designed mechanism.
* Cleaner seeds serve that mechanism; they do not replace it. */
static int istr_contains_wordstart(const char* hay, const char* needle) {
if (!hay || !needle || !*needle) return 0;
size_t nl = strlen(needle);
for (const char* p = hay; *p; p++) {
if (p != hay && isalnum((unsigned char)p[-1])) continue;
if (strncasecmp(p, needle, nl) == 0) return 1;
}
return 0;
}
/* ── Tokenized query matching ───────────────────────────────────────────
* The engram query surface (search / activate / goal-bias) historically
* matched the ENTIRE raw query string as a single case-insensitive
@@ -7412,9 +7379,9 @@ static int engram_node_match_score(const EngramNode* n,
char toks[][ENGRAM_QTOK_LEN], int ntok) {
int score = 0;
for (int t = 0; t < ntok; t++) {
if (istr_contains_wordstart(n->content, toks[t]) ||
istr_contains_wordstart(n->label, toks[t]) ||
istr_contains_wordstart(n->tags, toks[t]))
if (istr_contains(n->content, toks[t]) ||
istr_contains(n->label, toks[t]) ||
istr_contains(n->tags, toks[t]))
score++;
}
return score;
@@ -7429,9 +7396,9 @@ static uint32_t engram_node_match_mask(const EngramNode* n,
char toks[][ENGRAM_QTOK_LEN], int ntok) {
uint32_t m = 0;
for (int t = 0; t < ntok && t < 32; t++) {
if (istr_contains_wordstart(n->content, toks[t]) ||
istr_contains_wordstart(n->label, toks[t]) ||
istr_contains_wordstart(n->tags, toks[t]))
if (istr_contains(n->content, toks[t]) ||
istr_contains(n->label, toks[t]) ||
istr_contains(n->tags, toks[t]))
m |= (uint32_t)1u << t;
}
return m;
@@ -9687,12 +9654,25 @@ el_val_t engram_search_json(el_val_t query, el_val_t limit) {
}
if (sem && n->emb && n->emb_dim == qdim) {
double c = eg_cosine(n->emb, qv, qdim);
/* Semantic leg: identical to eg_sem_term(), which is
* left in place and still used by engram_search().
* Inlined here only so one cosine serves both uses. */
if (c > ENGRAM_EMBED_SEED_MIN) {
double sv = (c - ENGRAM_EMBED_SEED_MIN) / (1.0 - ENGRAM_EMBED_SEED_MIN);
if (sv > 1.0) sv = 1.0;
/* Semantic leg, claim 24 verbatim: "returning the node
* records whose embedding vectors have the HIGHEST
* COSINE SIMILARITY to a query vector" — a ranking, with
* no threshold anywhere in the claim. The leg used to be
* gated at ENGRAM_EMBED_SEED_MIN and rescaled onto
* [SEED_MIN,1]; that constant is defined (l.6083) as the
* SEED-JOIN threshold for the HippoRAG pass, and reusing
* it as a result filter is not authorised by claim 24.
* Measured on this corpus, it is also not a quality
* gate: true paraphrase targets score 0.459-0.657 while
* the nonsense controls' own nearest neighbours score
* 0.553-0.622 the distributions overlap, so no value
* of the constant separates them. What actually holds
* the nonsense control is corpus vocabulary (see the
* nhits==0 gate below), not cosine magnitude.
* Claim 32: clamp the cosine to [0,1] rather than let a
* negative value invert the signal. */
if (c > 0.0) {
double sv = c > 1.0 ? 1.0 : c;
sem[nsem].idx = i; sem[nsem].sem = sv; nsem++;
}
/* Graph seeds: top-K by RAW cosine, insertion-ordered. */
@@ -9710,6 +9690,21 @@ el_val_t engram_search_json(el_val_t query, el_val_t limit) {
}
}
}
/* CORPUS-VOCABULARY GATE — the thing that actually keeps an
* unfloored semantic leg from answering gibberish.
* nhits == 0 means NO stored record contains ANY query token
* anywhere in its content, label or tags: the query is outside
* the graph's vocabulary entirely. A vector index always has a
* nearest neighbour, so without this gate the semantic leg
* answers "zqxjvw plimforth grebulon" with its 0.55-cosine
* garbage. It is also the honest reading of Will's retrieval
* contract: 05-detailed-description l.64 has the caller supply
* "one or more seed node UUIDs representing the current active
* context", and every leg here is downstream of finding those
* seeds. No seeds, no retrieval the graph declines rather
* than confabulates. Suppressing the graph seeds too keeps the
* associative leg from running off the semantic top-K alone. */
if (nhits == 0) { nsem = 0; nsemseed = 0; }
/* BM25-shaped lexical score. Binary term frequency (the match
* primitive is a substring test, not a count), Lucene-form IDF,
* and length normalisation over the corpus mean. A token that
@@ -9745,19 +9740,7 @@ el_val_t engram_search_json(el_val_t query, el_val_t limit) {
? engram_assoc_leg(g, hits, nhits, semseed, nsemseed,
qv, qdim, assoc, ENGRAM_ASSOC_MAX)
: 0;
/* Corpus-vocabulary gate. If no stored record contains ANY
* query token in its content, label or tags, the query is
* outside this graph's vocabulary: there are no seeds, and
* 05-detailed-description l.64 makes retrieval downstream of
* seeds ("the caller provides one or more seed node UUIDs
* representing the current active context"). No seeds, no
* retrieval the graph declines rather than confabulating a
* nearest neighbour for gibberish. The mechanism is iteration
* 6's (feat/claim24-unfloored-semantic); it is required here
* because word-start matching empties the lexical leg for
* q35-style queries whose only "hits" were mid-word, and the
* semantic leg would otherwise answer them anyway. */
int64_t* order = (nhits > 0) ? malloc((size_t)lim * sizeof(int64_t)) : NULL;
int64_t* order = malloc((size_t)lim * sizeof(int64_t));
if (order) {
int64_t no = engram_interleave3(hits, nhits, sem, nsem,
assoc, nassoc, lim, order);